unified getFirstAvailable(), add name and comment prefix from defaults, better error message on missing conditional derived message, formatting
This commit is contained in:
+68
-38
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user