removed template param, moved tolower() to FileReader
This commit is contained in:
+20
-11
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user