unified getFirstAvailable(), add name and comment prefix from defaults, better error message on missing conditional derived message, formatting

This commit is contained in:
john30
2016-11-19 11:42:15 +01:00
parent c8aedf2bf5
commit 4e8ac82074
+68 -38
View File
@@ -206,11 +206,18 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
return RESULT_ERR_EOF; return RESULT_ERR_EOF;
if (name.length() == 0) if (name.length() == 0)
return RESULT_ERR_INVALID_ARG; // empty name return RESULT_ERR_INVALID_ARG; // empty name
defaultPos++; string defStr = getDefault("", defaults, defaultPos++);
if (defStr.length() > 0) {
name = defStr+name; // prefix default name
}
string comment = getDefault(*it++, defaults, defaultPos++); // [comment] string comment = *it++; // [comment]
if (it == end) if (it == end)
return RESULT_ERR_EOF; return RESULT_ERR_EOF;
defStr = getDefault("", defaults, defaultPos++);
if (defStr.length() > 0) {
name = defStr+name; // prefix default comment
}
str = getDefault(*it++, defaults, defaultPos++).c_str(); // [QQ[;QQ]*] str = getDefault(*it++, defaults, defaultPos++).c_str(); // [QQ[;QQ]*]
if (it == end) if (it == end)
@@ -415,8 +422,9 @@ Message* Message::derive(const unsigned char dstAddress, const bool extendCircui
bool Message::checkIdPrefix(vector<unsigned char>& id) bool Message::checkIdPrefix(vector<unsigned char>& id)
{ {
if (id.size() > m_id.size()) if (id.size() > m_id.size()) {
return false; return false;
}
for (size_t pos = 0; pos < id.size(); pos++) { for (size_t pos = 0; pos < id.size(); pos++) {
if (id[pos] != m_id[pos]) { if (id[pos] != m_id[pos]) {
return false; return false;
@@ -428,23 +436,25 @@ bool Message::checkIdPrefix(vector<unsigned char>& id)
bool Message::checkId(SymbolString& master, unsigned char* index) bool Message::checkId(SymbolString& master, unsigned char* index)
{ {
unsigned char idLen = getIdLength(); unsigned char idLen = getIdLength();
if (master.size() < 5 + idLen) // QQ, ZZ, PB, SB, NN if (master.size() < 5+idLen) { // QQ, ZZ, PB, SB, NN
return false; return false;
}
for (unsigned char pos = 0; pos < idLen; pos++) { for (unsigned char pos = 0; pos < idLen; pos++) {
if (m_id[2+pos] != master[5 + pos]) if (m_id[2+pos] != master[5+pos])
return false; return false;
} }
if (index) if (index) {
*index = 0; *index = 0;
}
return true; return true;
} }
bool Message::checkId(Message& other) bool Message::checkId(Message& other)
{ {
unsigned char idLen = getIdLength(); unsigned char idLen = getIdLength();
if (idLen != other.getIdLength() || getCount() > 1) // only equal for non-chained messages if (idLen != other.getIdLength() || getCount() > 1) { // only equal for non-chained messages
return false; return false;
}
return other.checkIdPrefix(m_id); return other.checkIdPrefix(m_id);
} }
@@ -789,28 +799,29 @@ Message* ChainedMessage::derive(const unsigned char dstAddress, const unsigned c
bool ChainedMessage::checkId(SymbolString& master, unsigned char* index) bool ChainedMessage::checkId(SymbolString& master, unsigned char* index)
{ {
unsigned char idLen = getIdLength(); unsigned char idLen = getIdLength();
unsigned char chainPrefixLength = (unsigned char)(m_id.size()-2); // minimum is 2 if (master.size() < 5+idLen) { // QQ, ZZ, PB, SB, NN
if (master.size() < 5 + idLen) // QQ, ZZ, PB, SB, NN
return false; return false;
for (unsigned char pos=0; pos<chainPrefixLength; pos++) {
if (m_id[2+pos] != master[5 + pos])
return false; // chain prefix mismatch
} }
unsigned char chainPrefixLength = Message::getIdLength();
for (unsigned char pos = 0; pos < chainPrefixLength; pos++) {
if (m_id[2+pos] != master[5+pos]) {
return false; // chain prefix mismatch
}
}
for (unsigned char checkIndex=0; checkIndex<m_ids.size(); checkIndex++) { // check suffix for each part for (unsigned char checkIndex=0; checkIndex<m_ids.size(); checkIndex++) { // check suffix for each part
vector<unsigned char> id = m_ids[checkIndex]; vector<unsigned char> id = m_ids[checkIndex];
bool found = false; bool found = false;
for (unsigned char pos=chainPrefixLength; pos<idLen; pos++) { for (unsigned char pos=chainPrefixLength; pos<idLen; pos++) {
if (id[2+pos] != master[5 + pos]) { if (id[2+pos] != master[5+pos]) {
found = false; found = false;
break; break;
} }
found = true; found = true;
} }
if (found) { if (found) {
if (index) if (index) {
*index = checkIndex; *index = checkIndex;
}
return true; return true;
} }
} }
@@ -997,25 +1008,38 @@ void ChainedMessage::dumpColumn(ostream& output, size_t column, bool withConditi
} }
Message* getFirstAvailable(vector<Message*> &messages, unsigned char idLength=0, SymbolString* master=NULL) { /**
* Get the first available @a Message from the list.
* @param messages the list of @a Message instances to check.
* @param sameIdExtAs the optional @a Message to check for having the same ID.
*/
Message* getFirstAvailable(vector<Message*> &messages, SymbolString* sameIdExtAs) {
for (vector<Message*>::iterator msgIt = messages.begin(); msgIt != messages.end(); msgIt++) { for (vector<Message*>::iterator msgIt = messages.begin(); msgIt != messages.end(); msgIt++) {
Message* message = *msgIt; Message* message = *msgIt;
if (master && !message->checkId(*master)) if (sameIdExtAs && !message->checkId(*sameIdExtAs)) {
continue; continue;
}
if (message->isAvailable()) if (message->isAvailable()) {
return *msgIt; return message;
}
} }
return NULL; return NULL;
} }
Message* getFirstAvailable(vector<Message*> &messages, Message& sameIdExtAs) { /**
* Get the first available @a Message from the list.
* @param messages the list of @a Message instances to check.
* @param sameIdExtAs the optional @a Message to check for having the same ID.
*/
Message* getFirstAvailable(vector<Message*> &messages, Message* sameIdExtAs=NULL) {
for (vector<Message*>::iterator msgIt = messages.begin(); msgIt != messages.end(); msgIt++) { for (vector<Message*>::iterator msgIt = messages.begin(); msgIt != messages.end(); msgIt++) {
Message* message = *msgIt; Message* message = *msgIt;
if (!message->checkId(sameIdExtAs)) if (sameIdExtAs && !message->checkId(*sameIdExtAs)) {
continue; continue;
if (message->isAvailable()) }
if (message->isAvailable()) {
return message; return message;
}
} }
return NULL; return NULL;
} }
@@ -1227,11 +1251,12 @@ result_t SimpleCondition::resolve(MessageMap* messages, ostringstream& errorMess
message = message->derive(m_dstAddress, true); message = message->derive(m_dstAddress, true);
messages->add(message); messages->add(message);
} else { } else {
message = getFirstAvailable(*derived, *message); Message* first = getFirstAvailable(*derived, message);
if (message==NULL) { if (first==NULL) {
errorMessage << ": conditional derived message not found"; errorMessage << ": conditional derived message " << message->getCircuit() << "." << message->getName() << " for " << hex << setw(2) << setfill('0') << static_cast<unsigned>(m_dstAddress) << " not found" ;
return RESULT_ERR_INVALID_ARG; return RESULT_ERR_INVALID_ARG;
} }
message = first;
} }
} }
@@ -1376,8 +1401,9 @@ string Instruction::getDestination()
result_t LoadInstruction::execute(MessageMap* messages, ostringstream& log, void (*loadInfoFunc)(MessageMap* messages, const unsigned char address, string filename)) { result_t LoadInstruction::execute(MessageMap* messages, ostringstream& log, void (*loadInfoFunc)(MessageMap* messages, const unsigned char address, string filename)) {
result_t result = messages->readFromFile(m_filename, false, m_defaultDest, m_defaultCircuit, m_defaultSuffix); result_t result = messages->readFromFile(m_filename, false, m_defaultDest, m_defaultCircuit, m_defaultSuffix);
if (log.tellp()>0) if (log.tellp()>0) {
log << ", "; log << ", ";
}
if (result!=RESULT_OK) { if (result!=RESULT_OK) {
log << "error " << (isSingleton() ? "loading " : "including ") << m_filename << " for \"" << getDestination() << "\": " << getResultCode(result); log << "error " << (isSingleton() ? "loading " : "including ") << m_filename << " for \"" << getDestination() << "\": " << getResultCode(result);
return result; return result;
@@ -1408,7 +1434,7 @@ result_t MessageMap::add(Message* message, bool storeByName)
if (!m_addAll) { if (!m_addAll) {
map<unsigned long long, vector<Message*> >::iterator keyIt = m_messagesByKey.find(key); map<unsigned long long, vector<Message*> >::iterator keyIt = m_messagesByKey.find(key);
if (keyIt != m_messagesByKey.end()) { if (keyIt != m_messagesByKey.end()) {
Message* other = getFirstAvailable(keyIt->second, *message); Message* other = getFirstAvailable(keyIt->second, message);
if (other != NULL) { if (other != NULL) {
if (!conditional) { if (!conditional) {
return RESULT_ERR_DUPLICATE; // duplicate key return RESULT_ERR_DUPLICATE; // duplicate key
@@ -1846,15 +1872,19 @@ deque<Message*> MessageMap::findAll(const string& circuit, const string& name, c
Message* MessageMap::find(SymbolString& master, bool anyDestination, Message* MessageMap::find(SymbolString& master, bool anyDestination,
const bool withRead, const bool withWrite, const bool withPassive) const bool withRead, const bool withWrite, const bool withPassive)
{ {
if (master.size() < 5) if (master.size() < 5) {
return NULL; return NULL;
}
unsigned char maxIdLength = master[4]; unsigned char maxIdLength = master[4];
if (maxIdLength > m_maxIdLength) if (maxIdLength > m_maxIdLength) {
maxIdLength = m_maxIdLength; maxIdLength = m_maxIdLength;
if (master.size() < 5+maxIdLength) }
if (master.size() < 5+maxIdLength) {
return NULL; return NULL;
if (maxIdLength == 0 && anyDestination && master[2] == 0x07 && master[3] == 0x04) }
if (maxIdLength == 0 && anyDestination && master[2] == 0x07 && master[3] == 0x04) {
return m_scanMessage; return m_scanMessage;
}
unsigned long long baseKey = (unsigned long long)getMasterNumber(master[0]) << (8 * 7); // QQ address for passive message unsigned long long baseKey = (unsigned long long)getMasterNumber(master[0]) << (8 * 7); // QQ address for passive message
baseKey |= (unsigned long long)(anyDestination ? SYN : master[1]) << (8 * 6); // ZZ address baseKey |= (unsigned long long)(anyDestination ? SYN : master[1]) << (8 * 6); // ZZ address
baseKey |= (unsigned long long)master[2] << (8 * 5); // PB baseKey |= (unsigned long long)master[2] << (8 * 5); // PB
@@ -1873,7 +1903,7 @@ Message* MessageMap::find(SymbolString& master, bool anyDestination,
if (withPassive) { if (withPassive) {
it = m_messagesByKey.find(key); it = m_messagesByKey.find(key);
if (it != m_messagesByKey.end()) { if (it != m_messagesByKey.end()) {
Message* message = getFirstAvailable(it->second, idLength, &master); Message* message = getFirstAvailable(it->second, &master);
if (message) if (message)
return message; return message;
} }
@@ -1881,7 +1911,7 @@ Message* MessageMap::find(SymbolString& master, bool anyDestination,
key &= ~ID_SOURCE_MASK; key &= ~ID_SOURCE_MASK;
it = m_messagesByKey.find(key & ~ID_SOURCE_MASK); // try again without specific source master it = m_messagesByKey.find(key & ~ID_SOURCE_MASK); // try again without specific source master
if (it != m_messagesByKey.end()) { if (it != m_messagesByKey.end()) {
Message* message = getFirstAvailable(it->second, idLength, &master); Message* message = getFirstAvailable(it->second, &master);
if (message) if (message)
return message; return message;
} }
@@ -1892,7 +1922,7 @@ Message* MessageMap::find(SymbolString& master, bool anyDestination,
if (withRead) { if (withRead) {
it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_READ); // try again with special value for active read it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_READ); // try again with special value for active read
if (it != m_messagesByKey.end()) { if (it != m_messagesByKey.end()) {
Message* message = getFirstAvailable(it->second, idLength, &master); Message* message = getFirstAvailable(it->second, &master);
if (message) if (message)
return message; return message;
} }
@@ -1900,7 +1930,7 @@ Message* MessageMap::find(SymbolString& master, bool anyDestination,
if (withWrite) { if (withWrite) {
it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_WRITE); // try again with special value for active write it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_WRITE); // try again with special value for active write
if (it != m_messagesByKey.end()) { if (it != m_messagesByKey.end()) {
Message* message = getFirstAvailable(it->second, idLength, &master); Message* message = getFirstAvailable(it->second, &master);
if (message) if (message)
return message; return message;
} }