/** * Digital Voice Modem - Host Software * GPLv2 Open Source. Use is subject to license terms. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * @package DVM / Host Software * */ // // Based on code from the MMDVMHost project. (https://github.com/g4klx/MMDVMHost) // Licensed under the GPLv2 License (https://opensource.org/licenses/GPL-2.0) // /* * Copyright (C) 2018-2019 by Bryan Biedenkapp N2PLL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if !defined(__LOOKUP_TABLE_H__) #define __LOOKUP_TABLE_H__ #include "Defines.h" #include "Log.h" #include "Thread.h" #include "Timer.h" #include "Mutex.h" #include #include #include #include #include #include namespace lookups { // --------------------------------------------------------------------------- // Class Declaration // Implements a abstract threading class that contains base logic for // building tables of data. // --------------------------------------------------------------------------- template class HOST_SW_API LookupTable : public Thread { public: /// Initializes a new instance of the LookupTable class. /// Full-path to the lookup table file. /// Interval of time to reload the channel identity table. LookupTable(const std::string& filename, uint32_t reloadTime) : Thread(), m_filename(filename), m_reloadTime(reloadTime) { /* stub */ } /// Finalizes a instance of the LookupTable class. virtual ~LookupTable() { /* stub */ } /// virtual void entry() { Timer timer(1U, 60U * m_reloadTime); timer.start(); while (!m_stop) { sleep(1000U); timer.clock(); if (timer.hasExpired()) { load(); timer.start(); } } } /// Stops and unloads this lookup table. virtual void stop() { if (m_reloadTime == 0U) { delete this; return; } m_stop = true; wait(); } /// Reads the lookup table from the specified lookup table file. /// True, if lookup table was read, otherwise false. virtual bool read() { bool ret = load(); if (m_reloadTime > 0U) run(); return ret; } /// Clears all entries from the lookup table. virtual void clear() { m_mutex.lock(); { m_table.clear(); } m_mutex.unlock(); } /// Helper to check if this lookup table has the specified unique ID. /// Unique ID to check for. /// True, if the lookup table has an entry by the specified unique ID, otherwise false. virtual bool hasEntry(uint32_t id) { m_mutex.lock(); { try { m_table.at(id); return true; } catch (...) { return false; } } m_mutex.unlock(); return false; } /// Finds a table entry in this lookup table. /// Unique identifier for table entry. /// Table entry. virtual T find(uint32_t id) = 0; protected: std::string m_filename; uint32_t m_reloadTime; std::unordered_map m_table; Mutex m_mutex; bool m_stop; bool m_acl; /// Parses a table entry from the passed comma delimited string. /// Comma delimited string to process into table entry. /// Table entry. virtual T parse(std::string tableEntry) = 0; /// Loads the table from the passed lookup table file. /// True, if lookup table was loaded, otherwise false. virtual bool load() { if (strlen(m_filename.c_str()) <= 0) { return false; } FILE* fp = ::fopen(m_filename.c_str(), "rt"); if (fp == NULL) { LogError(LOG_HOST, "Cannot open the lookup file - %s", m_filename.c_str()); return false; } // clear table clear(); m_mutex.lock(); { char buffer[100U]; while (::fgets(buffer, 100U, fp) != NULL) { if (buffer[0U] == '#') continue; std::string strbuf = buffer; char* p1 = ::strtok(buffer, ",\r\n"); if (p1 != NULL) { uint32_t id = (uint32_t)::atoi(p1); m_table[id] = parse(strbuf); } } } m_mutex.unlock(); ::fclose(fp); size_t size = m_table.size(); if (size == 0U) return false; LogInfoEx(LOG_HOST, "Loaded %u entries into lookup table", size); return true; } }; } // namespace lookups #endif // __LOOKUP_TABLE_H__