removed template param, moved tolower() to FileReader

This commit is contained in:
john30
2015-11-22 09:31:11 +01:00
parent d97ea29aa5
commit bf172b3688
3 changed files with 54 additions and 41 deletions
+20 -11
View File
@@ -25,8 +25,8 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <algorithm>
#include <vector> #include <vector>
#include <map>
/** @file filereader.h /** @file filereader.h
* Helper class and constants for reading configuration files. * Helper class and constants for reading configuration files.
@@ -56,7 +56,6 @@ extern unsigned int parseInt(const char* str, int base, const unsigned int minVa
/** /**
* An abstract class that support reading definitions from a file. * An abstract class that support reading definitions from a file.
*/ */
template<typename T>
class FileReader class FileReader
{ {
public: public:
@@ -75,11 +74,10 @@ public:
/** /**
* Read the definitions from a file. * Read the definitions from a file.
* @param filename the name of the file being read. * @param filename the name of the file being read.
* @param arg an argument to pass to @a addFromFile().
* @param verbose whether to verbosely log problems. * @param verbose whether to verbosely log problems.
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success, or an error code.
*/ */
virtual result_t readFromFile(const string filename, T arg=NULL, bool verbose=false) virtual result_t readFromFile(const string filename, bool verbose=false)
{ {
ifstream ifs; ifstream ifs;
ifs.open(filename.c_str(), ifstream::in); ifs.open(filename.c_str(), ifstream::in);
@@ -134,10 +132,10 @@ public:
if (result == RESULT_OK) if (result == RESULT_OK)
continue; continue;
} else } else
result = addFromFile(it, end, arg, &defaults, filename, lineNo); result = addFromFile(it, end, &defaults, filename, lineNo);
} }
else else
result = addFromFile(it, end, arg, NULL, filename, lineNo); result = addFromFile(it, end, NULL, filename, lineNo);
if (result != RESULT_OK) { if (result != RESULT_OK) {
if (!verbose) { if (!verbose) {
@@ -181,7 +179,8 @@ public:
*/ */
virtual result_t addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row, virtual result_t addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row,
vector<string>::iterator& begin, string defaultDest, string defaultCircuit, vector<string>::iterator& begin, string defaultDest, string defaultCircuit,
const string& filename, unsigned int lineNo) { const string& filename, unsigned int lineNo)
{
defaults.push_back(row); defaults.push_back(row);
begin = row.end(); begin = row.end();
return RESULT_OK; return RESULT_OK;
@@ -191,21 +190,21 @@ public:
* Add a definition that was read from a file. * Add a definition that was read from a file.
* @param begin an iterator to the first column of the definition row to read. * @param begin an iterator to the first column of the definition row to read.
* @param end the end iterator of the definition row to read. * @param end the end iterator of the definition row to read.
* @param arg the argument passed to @a readFromFile().
* @param defaults all previously read default rows (initial star char removed), or NULL if not supported. * @param defaults all previously read default rows (initial star char removed), or NULL if not supported.
* @param filename the name of the file being read. * @param filename the name of the file being read.
* @param lineNo the current line number in the file being read. * @param lineNo the current line number in the file being read.
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success, or an error code.
*/ */
virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end, virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end,
T arg, vector< vector<string> >* defaults, vector< vector<string> >* defaults,
const string& filename, unsigned int lineNo) = 0; const string& filename, unsigned int lineNo) = 0;
/** /**
* Left and right trim the string. * Left and right trim the string.
* @param str the @a string to trim. * @param str the @a string to trim.
*/ */
static void trim(string& str) { static void trim(string& str)
{
size_t pos = str.find_first_not_of(" \t"); size_t pos = str.find_first_not_of(" \t");
if (pos!=string::npos) { if (pos!=string::npos) {
str.erase(0, pos); str.erase(0, pos);
@@ -216,13 +215,23 @@ public:
} }
} }
/**
* Convert all upper case characters in the string to lower case.
* @param str the @a string to convert.
*/
static void tolower(string& str)
{
transform(str.begin(), str.end(), str.begin(), ::tolower);
}
/** /**
* Split the line into fields. * Split the line into fields.
* @param line the @a string with the line to split. * @param line the @a string with the line to split.
* @param row the @a vector to which to add the fields. * @param row the @a vector to which to add the fields.
* @return true if the line was split, false if the line was completely empty or a comment line. * @return true if the line was split, false if the line was completely empty or a comment line.
*/ */
static bool splitFields(string& line, vector<string>& row) { static bool splitFields(string& line, vector<string>& row)
{
row.clear(); row.clear();
trim(line); trim(line);
// skip empty lines and comments // skip empty lines and comments
+25 -23
View File
@@ -23,7 +23,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <cstring> #include <cstring>
#include <algorithm>
#include <locale> #include <locale>
#include <iomanip> #include <iomanip>
#include <climits> #include <climits>
@@ -42,6 +41,8 @@ using namespace std;
/** the maximum poll priority for a @a Message referred to by a @a Condition. */ /** the maximum poll priority for a @a Message referred to by a @a Condition. */
#define POLL_PRIORITY_CONDITION 5 #define POLL_PRIORITY_CONDITION 5
extern DataFieldTemplates* getTemplates(const string filename);
Message::Message(const string circuit, const string name, Message::Message(const string circuit, const string name,
const bool isWrite, const bool isPassive, const string comment, const bool isWrite, const bool isPassive, const string comment,
const unsigned char srcAddress, const unsigned char dstAddress, const unsigned char srcAddress, const unsigned char dstAddress,
@@ -199,7 +200,7 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
string token; string token;
bool first = true; bool first = true;
while (getline(stream, token, VALUE_SEPARATOR) != 0) { while (getline(stream, token, VALUE_SEPARATOR) != 0) {
DataFieldTemplates::trim(token); FileReader::trim(token);
unsigned char dstAddress = (unsigned char)parseInt(token.c_str(), 16, 0, 0xff, result); unsigned char dstAddress = (unsigned char)parseInt(token.c_str(), 16, 0, 0xff, result);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
@@ -614,13 +615,6 @@ void Message::dump(ostream& output, vector<size_t>* columns)
} }
} }
string strtolower(const string& str)
{
string ret(str);
transform(ret.begin(), ret.end(), ret.begin(), ::tolower);
return ret;
}
Message* getFirstAvailable(vector<Message*> &messages) { Message* getFirstAvailable(vector<Message*> &messages) {
for (vector<Message*>::iterator msgIt = messages.begin(); msgIt != messages.end(); msgIt++) for (vector<Message*>::iterator msgIt = messages.begin(); msgIt != messages.end(); msgIt++)
if ((*msgIt)->isAvailable()) if ((*msgIt)->isAvailable())
@@ -659,7 +653,7 @@ result_t Condition::create(const string condName, vector<string>::iterator& it,
string str; string str;
vector<unsigned int> valueRanges; vector<unsigned int> valueRanges;
while (getline(stream, str, VALUE_SEPARATOR) != 0) { while (getline(stream, str, VALUE_SEPARATOR) != 0) {
DataFieldTemplates::trim(str); FileReader::trim(str);
if (str.length()==0) if (str.length()==0)
return RESULT_ERR_INVALID_ARG; return RESULT_ERR_INVALID_ARG;
bool upto = str[0]=='<'; bool upto = str[0]=='<';
@@ -842,8 +836,10 @@ result_t MessageMap::add(Message* message, bool storeByName)
bool isPassive = message->isPassive(); bool isPassive = message->isPassive();
if (storeByName) { if (storeByName) {
bool isWrite = message->isWrite(); bool isWrite = message->isWrite();
string circuit = strtolower(message->getCircuit()); string circuit = message->getCircuit();
string name = strtolower(message->getName()); FileReader::tolower(circuit);
string name = message->getName();
FileReader::tolower(name);
string nameKey = string(isPassive ? "P" : (isWrite ? "W" : "R")) + circuit + FIELD_SEPARATOR + name; string nameKey = string(isPassive ? "P" : (isWrite ? "W" : "R")) + circuit + FIELD_SEPARATOR + name;
if (!m_addAll) { if (!m_addAll) {
map<string, vector<Message*> >::iterator nameIt = m_messagesByName.find(nameKey); map<string, vector<Message*> >::iterator nameIt = m_messagesByName.find(nameKey);
@@ -914,7 +910,7 @@ result_t MessageMap::addDefaultFromFile(vector< vector<string> >& defaults, vect
} }
if (row.size()>5 && defaultDest.length()>0 && row[5].length()==0) if (row.size()>5 && defaultDest.length()>0 && row[5].length()==0)
row[5] = defaultDest; // set default destination row[5] = defaultDest; // set default destination
return FileReader<DataFieldTemplates*>::addDefaultFromFile(defaults, row, begin, defaultDest, defaultCircuit, filename, lineNo); return FileReader::addDefaultFromFile(defaults, row, begin, defaultDest, defaultCircuit, filename, lineNo);
} }
result_t MessageMap::readConditions(string& types, const string& filename, Condition*& condition) result_t MessageMap::readConditions(string& types, const string& filename, Condition*& condition)
@@ -955,7 +951,7 @@ result_t MessageMap::readConditions(string& types, const string& filename, Condi
} }
result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end, result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end,
DataFieldTemplates* arg, vector< vector<string> >* defaults, vector< vector<string> >* defaults,
const string& filename, unsigned int lineNo) const string& filename, unsigned int lineNo)
{ {
vector<string>::iterator restart = begin; vector<string>::iterator restart = begin;
@@ -971,15 +967,16 @@ result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<s
return RESULT_ERR_INVALID_ARG; return RESULT_ERR_INVALID_ARG;
result = RESULT_ERR_EOF; result = RESULT_ERR_EOF;
DataFieldTemplates* templates = getTemplates(filename);
istringstream stream(types); istringstream stream(types);
string type; string type;
vector<Message*> messages; vector<Message*> messages;
while (getline(stream, type, VALUE_SEPARATOR) != 0) { while (getline(stream, type, VALUE_SEPARATOR) != 0) {
DataFieldTemplates::trim(type); FileReader::trim(type);
*restart = type; *restart = type;
begin = restart; begin = restart;
messages.clear(); messages.clear();
result = Message::create(begin, end, defaults, condition, filename, arg, messages); result = Message::create(begin, end, defaults, condition, filename, templates, messages);
for (vector<Message*>::iterator it = messages.begin(); it != messages.end(); it++) { for (vector<Message*>::iterator it = messages.begin(); it != messages.end(); it++) {
Message* message = *it; Message* message = *it;
if (result == RESULT_OK) { if (result == RESULT_OK) {
@@ -1045,8 +1042,10 @@ vector<Message*>* MessageMap::getByKey(const unsigned long long key) {
Message* MessageMap::find(const string& circuit, const string& name, const bool isWrite, const bool isPassive) Message* MessageMap::find(const string& circuit, const string& name, const bool isWrite, const bool isPassive)
{ {
string lcircuit = strtolower(circuit); string lcircuit = circuit;
string lname = strtolower(name); FileReader::tolower(lcircuit);
string lname = name;
FileReader::tolower(lname);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
string key; string key;
if (i == 0) if (i == 0)
@@ -1070,9 +1069,10 @@ deque<Message*> MessageMap::findAll(const string& circuit, const string& name, c
const bool withRead, const bool withWrite, const bool withPassive) const bool withRead, const bool withWrite, const bool withPassive)
{ {
deque<Message*> ret; deque<Message*> ret;
string lcircuit = circuit;
string lcircuit = strtolower(circuit); FileReader::tolower(lcircuit);
string lname = strtolower(name); string lname = name;
FileReader::tolower(lname);
bool checkCircuit = lcircuit.length() > 0; bool checkCircuit = lcircuit.length() > 0;
bool checkName = name.length() > 0; bool checkName = name.length() > 0;
bool checkPb = pb >= 0; bool checkPb = pb >= 0;
@@ -1083,12 +1083,14 @@ deque<Message*> MessageMap::findAll(const string& circuit, const string& name, c
if (!message) if (!message)
continue; continue;
if (checkCircuit) { if (checkCircuit) {
string check = strtolower(message->getCircuit()); string check = message->getCircuit();
FileReader::tolower(check);
if (completeMatch ? (check != lcircuit) : (check.find(lcircuit) == check.npos)) if (completeMatch ? (check != lcircuit) : (check.find(lcircuit) == check.npos))
continue; continue;
} }
if (checkName) { if (checkName) {
string check = strtolower(message->getName()); string check = message->getName();
FileReader::tolower(check);
if (completeMatch ? (check != lname) : (check.find(lname) == check.npos)) if (completeMatch ? (check != lname) : (check.find(lname) == check.npos))
continue; continue;
} }
+9 -7
View File
@@ -32,7 +32,7 @@
* eBUS to and from readable values. * eBUS to and from readable values.
* *
* A @a Message has a unique numeric key (see Message#getKey()) as well as a * A @a Message has a unique numeric key (see Message#getKey()) as well as a
* unique name and circuit (@see Message#getCircuit() and Message#getName()). * unique name and circuit (see Message#getCircuit() and Message#getName()).
* The numeric key is built from the message type (active/passive, read/write), * The numeric key is built from the message type (active/passive, read/write),
* the source and destination address, the primary and secondary command byte, * the source and destination address, the primary and secondary command byte,
* as well as additional command ID bytes (see Message#getId()). * as well as additional command ID bytes (see Message#getId()).
@@ -45,11 +45,13 @@
* certain conditions only, it may have assigned a @a Condition instance. * certain conditions only, it may have assigned a @a Condition instance.
* *
* A @a Condition is either a @a SimpleCondition referencing another * A @a Condition is either a @a SimpleCondition referencing another
* @a Message, field, and field value, or a @a CombinedCondition referencing * @a Message, numeric field, and field value, or a @a CombinedCondition
* two or more other @a Condition instances. * applying a logical AND on two or more other @a Condition instances.
* *
* The @a MessageMap stores all @a Message and @a Condition instances by their * The @a MessageMap stores all @a Message and @a Condition instances by their
* unique keys, and also keeps track of messages with polling enabled. * unique keys, and also keeps track of messages with polling enabled. It reads
* the instances from configuration files by inheriting the @a FileReader
* template class.
*/ */
using namespace std; using namespace std;
@@ -631,7 +633,7 @@ private:
/** /**
* Holds a map of all known @a Message instances. * Holds a map of all known @a Message instances.
*/ */
class MessageMap : public FileReader<DataFieldTemplates*> class MessageMap : public FileReader
{ {
public: public:
@@ -639,7 +641,7 @@ public:
* Construct a new instance. * Construct a new instance.
* @param addAll whether to add all messages, even if duplicate. * @param addAll whether to add all messages, even if duplicate.
*/ */
MessageMap(const bool addAll=false) : FileReader<DataFieldTemplates*>::FileReader(true), MessageMap(const bool addAll=false) : FileReader::FileReader(true),
m_addAll(addAll), m_maxIdLength(0), m_messageCount(0), m_conditionalMessageCount(0), m_passiveMessageCount(0) m_addAll(addAll), m_maxIdLength(0), m_messageCount(0), m_conditionalMessageCount(0), m_passiveMessageCount(0)
{ {
m_scanMessage = new Message(false, false, 0x07, 0x04, DataFieldSet::getIdentFields(), true); m_scanMessage = new Message(false, false, 0x07, 0x04, DataFieldSet::getIdentFields(), true);
@@ -678,7 +680,7 @@ public:
// @copydoc // @copydoc
virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end, virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end,
DataFieldTemplates* arg, vector< vector<string> >* defaults, vector< vector<string> >* defaults,
const string& filename, unsigned int lineNo); const string& filename, unsigned int lineNo);
/** /**