extract default destination and circuit from filename
This commit is contained in:
@@ -41,6 +41,7 @@ using namespace std;
|
||||
|
||||
extern void printErrorPos(ostream& out, vector<string>::iterator begin, const vector<string>::iterator end, vector<string>::iterator pos, string filename, size_t lineNo, result_t result);
|
||||
|
||||
extern unsigned int parseInt(const char* str, int base, const unsigned int minValue, const unsigned int maxValue, result_t& result, unsigned int* length);
|
||||
|
||||
/**
|
||||
* An abstract class that support reading definitions from a file.
|
||||
@@ -76,9 +77,26 @@ public:
|
||||
return RESULT_ERR_NOTFOUND;
|
||||
|
||||
string line;
|
||||
size_t firstDot = filename.find_first_of('.');
|
||||
string defaultDest = "";
|
||||
string defaultCircuit = "";
|
||||
if (firstDot==2) { // potential destination address, matches "^ZZ."
|
||||
result_t result;
|
||||
defaultDest = filename.substr(0, 2);
|
||||
int zz = parseInt(defaultDest.c_str(), 16, 0, 0xff, result, NULL);
|
||||
if (result!=RESULT_OK || !isValidAddress(zz))
|
||||
defaultDest = ""; // invalid: not in hex or no master/slave/broadcast address
|
||||
else {
|
||||
size_t lastDot = filename.find_last_of('.');
|
||||
if (lastDot>firstDot && lastDot-firstDot<=5) { // potential ident, matches "^ZZ.IDENT."
|
||||
defaultCircuit = filename.substr(firstDot+1, lastDot-firstDot);
|
||||
if (defaultCircuit.find_first_of(' ')!=string::npos)
|
||||
defaultCircuit = ""; // invalid: contains spaces
|
||||
}
|
||||
}
|
||||
}
|
||||
unsigned int lineNo = 0;
|
||||
vector<string> row;
|
||||
string token;
|
||||
vector< vector<string> > defaults;
|
||||
while (getline(ifs, line) != 0) {
|
||||
lineNo++;
|
||||
@@ -138,7 +156,7 @@ public:
|
||||
if (m_supportsDefaults) {
|
||||
if (line[0] == '*') {
|
||||
row[0] = row[0].substr(1);
|
||||
result = addDefaultFromFile(defaults, row, it, filename, lineNo);
|
||||
result = addDefaultFromFile(defaults, row, it, defaultDest, defaultCircuit, filename, lineNo);
|
||||
if (result == RESULT_OK)
|
||||
continue;
|
||||
} else
|
||||
@@ -175,11 +193,19 @@ public:
|
||||
* @param defaults the list to add the default row to.
|
||||
* @param row the default row (initial star char removed).
|
||||
* @param begin an iterator to the first column of the default row to read (for error reporting).
|
||||
* @param defaultDest the valid destination address extracted from the file name (from ZZ part), or empty.
|
||||
* @param defaultCircuit the valid circuit name extracted from the file name (from IDENT part), or empty.
|
||||
* @param filename the name of 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.
|
||||
*/
|
||||
virtual result_t addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row, vector<string>::iterator& begin, const string& filename, unsigned int lineNo) {
|
||||
virtual result_t addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row,
|
||||
vector<string>::iterator& begin, string defaultDest, string defaultCircuit,
|
||||
const string& filename, unsigned int lineNo) {
|
||||
if (row.size()>1 && defaultCircuit.length()>0 && row[1].length()==0)
|
||||
row[1] = defaultCircuit;
|
||||
if (row.size()>5 && defaultDest.length()>0 && row[5].length()==0)
|
||||
row[5] = defaultDest;
|
||||
defaults.push_back(row);
|
||||
begin = row.end();
|
||||
return RESULT_OK;
|
||||
@@ -195,7 +221,9 @@ public:
|
||||
* @param lineNo the current line number in the file being read.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
*/
|
||||
virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end, T arg, vector< vector<string> >* defaults, const string& filename, unsigned int lineNo) = 0;
|
||||
virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end,
|
||||
T arg, vector< vector<string> >* defaults,
|
||||
const string& filename, unsigned int lineNo) = 0;
|
||||
|
||||
/**
|
||||
* Left and right trim the string.
|
||||
|
||||
+27
-22
@@ -98,7 +98,7 @@ string getDefault(const string value, vector<string>* defaults, size_t pos)
|
||||
}
|
||||
|
||||
result_t Message::create(vector<string>::iterator& it, const vector<string>::iterator end,
|
||||
vector< vector<string> >* defaultsRows, map<string, Condition*>* conditions, const string& filename,
|
||||
vector< vector<string> >* defaultsRows, Condition* condition, const string& filename,
|
||||
DataFieldTemplates* templates, vector<Message*>& messages)
|
||||
{
|
||||
// [type],[circuit],name,[comment],[QQ[;QQ]*],[ZZ],[PBSB],[ID],fields...
|
||||
@@ -111,21 +111,6 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
||||
return RESULT_ERR_EOF;
|
||||
|
||||
string typeStr = *it++;
|
||||
Condition* condition = NULL;
|
||||
if (conditions && typeStr.length()>0 && typeStr[0]=='[') {
|
||||
// condition
|
||||
size_t pos = typeStr.find(']');
|
||||
if (pos!=string::npos) {
|
||||
string type = typeStr.substr(1, pos-1);
|
||||
string key = filename+":"+type;
|
||||
map<string, Condition*>::iterator it = conditions->find(key);
|
||||
if (it==conditions->end())
|
||||
return RESULT_ERR_NOTFOUND;
|
||||
condition = it->second;
|
||||
typeStr = typeStr.substr(pos+1);
|
||||
}
|
||||
}
|
||||
|
||||
const char* str = typeStr.c_str(); // [type]
|
||||
if (it == end)
|
||||
return RESULT_ERR_EOF;
|
||||
@@ -755,8 +740,10 @@ result_t MessageMap::add(Message* message)
|
||||
bool conditional = message->isConditional();
|
||||
map<unsigned long long, vector<Message*> >::iterator keyIt = m_messagesByKey.find(key);
|
||||
if (keyIt != m_messagesByKey.end()) {
|
||||
if (!conditional)
|
||||
return RESULT_ERR_DUPLICATE; // duplicate key
|
||||
vector<Message*>* messages = &keyIt->second;
|
||||
if (!messages->front()->isConditional() || !conditional)
|
||||
if (!messages->front()->isConditional())
|
||||
return RESULT_ERR_DUPLICATE; // duplicate key
|
||||
}
|
||||
bool isPassive = message->isPassive();
|
||||
@@ -798,7 +785,9 @@ result_t MessageMap::add(Message* message)
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
result_t MessageMap::addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row, vector<string>::iterator& begin, const string& filename, unsigned int lineNo)
|
||||
result_t MessageMap::addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row,
|
||||
vector<string>::iterator& begin, string defaultDest, string defaultCircuit,
|
||||
const string& filename, unsigned int lineNo)
|
||||
{
|
||||
// convert conditions in defaults
|
||||
string type = row[0];
|
||||
@@ -811,6 +800,8 @@ result_t MessageMap::addDefaultFromFile(vector< vector<string> >& defaults, vect
|
||||
if (it != m_conditions.end())
|
||||
return RESULT_ERR_DUPLICATE_NAME;
|
||||
|
||||
if (row.size()>1 && defaultCircuit.length()>0 && row[1].length()==0)
|
||||
row[1] = defaultCircuit;
|
||||
Condition* condition = NULL;
|
||||
result_t result = Condition::create(++begin, row.end(), condition);
|
||||
if (result!=RESULT_OK) {
|
||||
@@ -824,13 +815,28 @@ result_t MessageMap::addDefaultFromFile(vector< vector<string> >& defaults, vect
|
||||
m_conditions[key] = condition;
|
||||
return RESULT_OK;
|
||||
}
|
||||
return FileReader::addDefaultFromFile(defaults, row, begin, filename, lineNo);
|
||||
return FileReader::addDefaultFromFile(defaults, row, begin, defaultDest, defaultCircuit, filename, lineNo);
|
||||
}
|
||||
|
||||
result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end, DataFieldTemplates* arg, vector< vector<string> >* defaults, const string& filename, unsigned int lineNo)
|
||||
result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end,
|
||||
DataFieldTemplates* arg, vector< vector<string> >* defaults,
|
||||
const string& filename, unsigned int lineNo)
|
||||
{
|
||||
vector<string>::iterator restart = begin;
|
||||
Condition* condition = NULL;
|
||||
string types = *restart;
|
||||
if (types.length()>0 && types[0]=='[') {
|
||||
// condition
|
||||
size_t pos = types.find(']');
|
||||
if (pos!=string::npos) {
|
||||
string key = filename+":"+types.substr(1, pos-1);
|
||||
map<string, Condition*>::iterator it = m_conditions.find(key); // TODO add support for global conditions without filename
|
||||
if (it==m_conditions.end())
|
||||
return RESULT_ERR_NOTFOUND;
|
||||
condition = it->second;
|
||||
types = types.substr(pos+1);
|
||||
}
|
||||
}
|
||||
if (types.length() == 0)
|
||||
types.append("r");
|
||||
result_t result = RESULT_ERR_EOF;
|
||||
@@ -843,7 +849,7 @@ result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<s
|
||||
*restart = type;
|
||||
begin = restart;
|
||||
messages.clear();
|
||||
result = Message::create(begin, end, defaults, &m_conditions, filename, arg, messages);
|
||||
result = Message::create(begin, end, defaults, condition, filename, arg, messages);
|
||||
for (vector<Message*>::iterator it = messages.begin(); it != messages.end(); it++) {
|
||||
Message* message = *it;
|
||||
if (result == RESULT_OK) {
|
||||
@@ -858,7 +864,6 @@ result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<s
|
||||
}
|
||||
if (result != RESULT_OK)
|
||||
return result;
|
||||
begin = restart;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
* @param it the iterator to traverse for the definition parts.
|
||||
* @param end the iterator pointing to the end of the definition parts.
|
||||
* @param defaultsRows a @a vector with rows containing defaults, or NULL.
|
||||
* @param conditions the @a Condition instances by filename and condition name, or NULL.
|
||||
* @param condition the @a Condition instance for the message, or NULL.
|
||||
* @param filename the name of the file being read.
|
||||
* @param templates the @a DataFieldTemplates to be referenced by name, or NULL.
|
||||
* @param messages the @a vector to which to add created instances.
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
* Note: the caller needs to free the created instances.
|
||||
*/
|
||||
static result_t create(vector<string>::iterator& it, const vector<string>::iterator end,
|
||||
vector< vector<string> >* defaultsRows, map<string, Condition*>* conditions, const string& filename,
|
||||
vector< vector<string> >* defaultsRows, Condition* condition, const string& filename,
|
||||
DataFieldTemplates* templates, vector<Message*>& messages);
|
||||
|
||||
/**
|
||||
@@ -526,10 +526,14 @@ public:
|
||||
result_t add(Message* message);
|
||||
|
||||
// @copydoc
|
||||
virtual result_t addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row, vector<string>::iterator& begin, const string& filename, unsigned int lineNo);
|
||||
virtual result_t addDefaultFromFile(vector< vector<string> >& defaults, vector<string>& row,
|
||||
vector<string>::iterator& begin, string defaultDest, string defaultCircuit,
|
||||
const string& filename, unsigned int lineNo);
|
||||
|
||||
// @copydoc
|
||||
virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end, DataFieldTemplates* arg, vector< vector<string> >* defaults, const string& filename, unsigned int lineNo);
|
||||
virtual result_t addFromFile(vector<string>::iterator& begin, const vector<string>::iterator end,
|
||||
DataFieldTemplates* arg, vector< vector<string> >* defaults,
|
||||
const string& filename, unsigned int lineNo);
|
||||
|
||||
/**
|
||||
* Resolve all @a Condition instances.
|
||||
|
||||
Reference in New Issue
Block a user