-
Notifications
You must be signed in to change notification settings - Fork 276
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
simply added UserDB* source code and modified Makefile. others are untouched.
- Loading branch information
Showing
11 changed files
with
337 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* | ||
* Copyright (C) 2020 by SASANO Takayoshi JG1UAA | ||
* | ||
* 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. | ||
*/ | ||
#include "UserDB.h" | ||
#include "Log.h" | ||
|
||
#include <cstdio> | ||
#include <cstring> | ||
#include <cctype> | ||
|
||
CUserDB::CUserDB() : | ||
m_table(), | ||
m_mutex() | ||
{ | ||
} | ||
|
||
CUserDB::~CUserDB() | ||
{ | ||
} | ||
|
||
bool CUserDB::lookup(unsigned int id, class CUserDBentry *entry) | ||
{ | ||
bool rv; | ||
|
||
m_mutex.lock(); | ||
|
||
try { | ||
if (entry != NULL) | ||
*entry = m_table.at(id); | ||
else | ||
m_table.at(id); | ||
|
||
rv = true; | ||
} catch (...) { | ||
rv = false; | ||
} | ||
|
||
m_mutex.unlock(); | ||
|
||
return rv; | ||
} | ||
|
||
bool CUserDB::load(std::string const& filename) | ||
{ | ||
FILE* fp = ::fopen(filename.c_str(), "r"); | ||
if (fp == NULL) { | ||
LogWarning("Cannot open ID lookup table - %s", filename.c_str()); | ||
return false; | ||
} | ||
|
||
m_mutex.lock(); | ||
|
||
// Remove the old entries; | ||
m_table.clear(); | ||
|
||
// set index for entries | ||
char buffer[256U]; | ||
if (::fgets(buffer, sizeof(buffer), fp) == NULL) { | ||
LogWarning("ID lookup file has no entry - %s", filename.c_str()); | ||
m_mutex.unlock(); | ||
::fclose(fp); | ||
return false; | ||
} | ||
|
||
// no index - set default | ||
std::unordered_map<std::string, int> index; | ||
if (!makeindex(buffer, index)) { | ||
::strncpy(buffer, "RADIO_ID,CALLSIGN,FIRST_NAME", sizeof(buffer)); | ||
makeindex(buffer, index); | ||
::rewind(fp); | ||
} | ||
|
||
while (::fgets(buffer, sizeof(buffer), fp) != NULL) { | ||
if (buffer[0U] != '#') | ||
parse(buffer, index); | ||
} | ||
|
||
::fclose(fp); | ||
|
||
size_t size = m_table.size(); | ||
m_mutex.unlock(); | ||
|
||
LogInfo("Loaded %u IDs to lookup table - %s", size, filename.c_str()); | ||
|
||
return (size != 0U); | ||
} | ||
|
||
bool CUserDB::makeindex(char* buf, std::unordered_map<std::string, int>& index) | ||
{ | ||
int i; | ||
char *p1, *p2; | ||
|
||
for (i = 0, p1 = tokenize(buf, &p2); p1 != NULL; | ||
i++, p1 = tokenize(p2, &p2)) { | ||
|
||
// create [column keyword] - [column number] table | ||
if (CUserDBentry::isValidKey(p1)) | ||
index[p1] = i; | ||
} | ||
|
||
try { | ||
index.at(keyRADIO_ID); | ||
index.at(keyCALLSIGN); | ||
return true; | ||
} catch (...) { | ||
return false; | ||
} | ||
} | ||
|
||
void CUserDB::parse(char* buf, std::unordered_map<std::string, int>& index) | ||
{ | ||
int i; | ||
char *p1, *p2; | ||
std::unordered_map<std::string, char*> ptr; | ||
unsigned int id; | ||
|
||
for (i = 0, p1 = tokenize(buf, &p2); p1 != NULL; | ||
i++, p1 = tokenize(p2, &p2)) { | ||
|
||
for (auto it = index.begin(); it != index.end(); it++) { | ||
// first: column keyword, second: column number | ||
if (it->second == i) { | ||
ptr[it->first] = p1; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
try { | ||
ptr.at(keyRADIO_ID); | ||
ptr.at(keyCALLSIGN); | ||
} catch (...) { | ||
return; | ||
} | ||
|
||
id = (unsigned int)::atoi(ptr[keyRADIO_ID]); | ||
toupper_string(ptr[keyCALLSIGN]); | ||
|
||
for (auto it = ptr.begin(); it != ptr.end(); it++) { | ||
// no need to regist radio ID | ||
if (it->first == keyRADIO_ID) | ||
continue; | ||
|
||
m_table[id].set(it->first, std::string(it->second)); | ||
} | ||
} | ||
|
||
void CUserDB::toupper_string(char* str) | ||
{ | ||
while (*str != '\0') { | ||
*str = ::toupper(*str); | ||
str++; | ||
} | ||
} | ||
|
||
char* CUserDB::tokenize(char* str, char** next) | ||
{ | ||
if (*str == '\0') | ||
return NULL; | ||
|
||
char* p = ::strpbrk(str, ",\t\r\n"); | ||
if (p == NULL) { | ||
*next = str + ::strlen(str); | ||
} else { | ||
*p = '\0'; | ||
*next = p + 1; | ||
} | ||
|
||
return str; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright (C) 2020 by SASANO Takayoshi JG1UAA | ||
* | ||
* 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(USERDB_H) | ||
#define USERDB_H | ||
|
||
#include "UserDBentry.h" | ||
#include "Mutex.h" | ||
|
||
class CUserDB { | ||
public: | ||
CUserDB(); | ||
~CUserDB(); | ||
|
||
bool lookup(unsigned int id, class CUserDBentry *entry); | ||
bool load(std::string const& filename); | ||
|
||
private: | ||
bool makeindex(char* buf, std::unordered_map<std::string, int>& index); | ||
void parse(char* buf, std::unordered_map<std::string, int>& index); | ||
void toupper_string(char* str); | ||
char* tokenize(char* str, char** next); | ||
|
||
std::unordered_map<unsigned int, class CUserDBentry> m_table; | ||
CMutex m_mutex; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (C) 2020 by SASANO Takayoshi JG1UAA | ||
* | ||
* 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. | ||
*/ | ||
#include "UserDBentry.h" | ||
#include <algorithm> | ||
|
||
CUserDBentry::CUserDBentry() : | ||
m_db() | ||
{ | ||
} | ||
|
||
CUserDBentry::~CUserDBentry() | ||
{ | ||
} | ||
|
||
const std::vector<std::string> CUserDBentry::keyList { | ||
keyRADIO_ID, keyCALLSIGN, keyFIRST_NAME, keyLAST_NAME, | ||
keyCITY, keySTATE, keyCOUNTRY, | ||
}; | ||
|
||
bool CUserDBentry::isValidKey(const std::string key) | ||
{ | ||
auto it = std::find(keyList.begin(), keyList.end(), key); | ||
return it != keyList.end(); | ||
} | ||
|
||
void CUserDBentry::set(const std::string key, const std::string value) | ||
{ | ||
if (isValidKey(key)) | ||
m_db[key] = value; | ||
} | ||
|
||
std::string CUserDBentry::get(const std::string key) | ||
{ | ||
try { | ||
return m_db.at(key); | ||
} catch (...) { | ||
return ""; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (C) 2020 by SASANO Takayoshi JG1UAA | ||
* | ||
* 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(USERDBENTRY_H) | ||
#define USERDBENTRY_H | ||
|
||
#include <string> | ||
#include <unordered_map> | ||
#include <vector> | ||
|
||
#define keyRADIO_ID "RADIO_ID" | ||
#define keyCALLSIGN "CALLSIGN" | ||
#define keyFIRST_NAME "FIRST_NAME" | ||
#define keyLAST_NAME "LAST_NAME" | ||
#define keyCITY "CITY" | ||
#define keySTATE "STATE" | ||
#define keyCOUNTRY "COUNTRY" | ||
|
||
class CUserDBentry { | ||
public: | ||
CUserDBentry(); | ||
~CUserDBentry(); | ||
|
||
static const std::vector<std::string> keyList; | ||
static bool isValidKey(const std::string key); | ||
|
||
void set(const std::string key, const std::string value); | ||
std::string get(const std::string key); | ||
|
||
private: | ||
std::unordered_map<std::string, std::string> m_db; | ||
}; | ||
|
||
#endif |
8ff3913
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
I would like to know why using key/value in UserDBentry for the CSV fields instead of using member fields?
a value object would be more straightforward here I think.
8ff3913
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm new to C++ and STL, and I didn't have idea to write with value object pattern.
This blog (written in Japanese) shows first class collection and it might help to write clean code (https://blog.sojiro.me/blog/2017/08/25/value-object-and-collection-object/), but can this collection maintain same flexibility for CSV fields as current implementation with key/value?
First of all, to reduce XXXtable (XXX means any field name) in program I choose using associative array.