use active message definitions for parsing other-initiated messages as well

This commit is contained in:
john30
2014-12-28 09:03:57 +01:00
parent a376b14b4a
commit bf3680bbf4
2 changed files with 47 additions and 37 deletions
+34 -28
View File
@@ -27,6 +27,9 @@
using namespace std; using namespace std;
/** the bit mask of the source master number in the message key. */
#define ID_SOURCE_MASK (0x1fLL << (8 * 7))
Message::Message(const string clazz, const string name, const bool isSet, Message::Message(const string clazz, const string name, const bool isSet,
const bool isPassive, const string comment, const bool isPassive, const string comment,
const unsigned char srcAddress, const unsigned char dstAddress, const unsigned char srcAddress, const unsigned char dstAddress,
@@ -338,38 +341,39 @@ bool Message::isLessPollWeight(Message* other) {
result_t MessageMap::add(Message* message) result_t MessageMap::add(Message* message)
{ {
unsigned long long pkey = message->getKey(); unsigned long long key = message->getKey();
bool isPassive = message->isPassive(); map<unsigned long long, Message*>::iterator keyIt = m_messagesByKey.find(key);
if (isPassive == true) { if (keyIt != m_messagesByKey.end()) {
map<unsigned long long, Message*>::iterator keyIt = m_passiveMessagesByKey.find(pkey); return RESULT_ERR_DUPLICATE; // duplicate key
if (keyIt != m_passiveMessagesByKey.end()) {
return RESULT_ERR_DUPLICATE; // duplicate key
}
} }
bool isPassive = message->isPassive();
bool isSet = message->isSet(); bool isSet = message->isSet();
string clazz = message->getClass(); string clazz = message->getClass();
string name = message->getName(); string name = message->getName();
string key = string(isPassive ? "P" : (isSet ? "W" : "R")) + clazz + FIELD_SEPARATOR + name; string nameKey = string(isPassive ? "P" : (isSet ? "W" : "R")) + clazz + FIELD_SEPARATOR + name;
map<string, Message*>::iterator nameIt = m_messagesByName.find(key); map<string, Message*>::iterator nameIt = m_messagesByName.find(nameKey);
if (nameIt != m_messagesByName.end()) { if (nameIt != m_messagesByName.end()) {
return RESULT_ERR_DUPLICATE; // duplicate key return RESULT_ERR_DUPLICATE; // duplicate key
} }
m_messagesByName[key] = message; m_messagesByName[nameKey] = message;
m_messageCount++; m_messageCount++;
if (isPassive == true)
m_passiveMessageCount++;
key = string(isPassive ? "-P" : (isSet ? "-W" : "-R")) + name; // also store without class nameKey = string(isPassive ? "-P" : (isSet ? "-W" : "-R")) + name; // also store without class
m_messagesByName[key] = message; // last key without class overrides previous nameIt = m_messagesByName.find(nameKey);
if (nameIt == m_messagesByName.end()) {
if (message->isPassive() == true) { m_messagesByName[nameKey] = message; // only store first key without class
unsigned char idLength = message->getId().size() - 2;
if (idLength < m_minIdLength)
m_minIdLength = idLength;
if (idLength > m_maxIdLength)
m_maxIdLength = idLength;
m_passiveMessagesByKey[pkey] = message;
} }
unsigned char idLength = message->getId().size() - 2;
if (idLength < m_minIdLength)
m_minIdLength = idLength;
if (idLength > m_maxIdLength)
m_maxIdLength = idLength;
m_messagesByKey[key] = message;
if (message->getPollPriority() > 0) if (message->getPollPriority() > 0)
m_pollMessages.push(message); m_pollMessages.push(message);
@@ -462,7 +466,6 @@ Message* MessageMap::find(SymbolString& master)
if (master.size() < 5+maxIdLength) if (master.size() < 5+maxIdLength)
return NULL; return NULL;
unsigned long long sourceMask = 0x1fLL << (8 * 7);
for (int idLength = maxIdLength; idLength >= m_minIdLength; idLength--) { for (int idLength = maxIdLength; idLength >= m_minIdLength; idLength--) {
int exp = 7; int exp = 7;
unsigned long long key = (unsigned long long)idLength << (8 * exp + 5); unsigned long long key = (unsigned long long)idLength << (8 * exp + 5);
@@ -473,16 +476,19 @@ Message* MessageMap::find(SymbolString& master)
for (unsigned char i=0; i<idLength; i++) for (unsigned char i=0; i<idLength; i++)
key |= (unsigned long long)master[5 + i] << (8 * exp--); key |= (unsigned long long)master[5 + i] << (8 * exp--);
map<unsigned long long , Message*>::iterator it = m_passiveMessagesByKey.find(key); map<unsigned long long , Message*>::iterator it = m_messagesByKey.find(key);
if (it != m_passiveMessagesByKey.end()) if (it != m_messagesByKey.end())
return it->second; return it->second;
if ((key & sourceMask) != 0) { if ((key & ID_SOURCE_MASK) != 0) {
key &= ~sourceMask; // try again without specific source master it = m_messagesByKey.find(key & ~ID_SOURCE_MASK); // try again without specific source master
it = m_passiveMessagesByKey.find(key); if (it != m_messagesByKey.end())
if (it != m_passiveMessagesByKey.end())
return it->second; return it->second;
} }
it = m_messagesByKey.find(key | ID_SOURCE_MASK); // try again with special value for active
if (it != m_messagesByKey.end())
return it->second;
} }
return NULL; return NULL;
@@ -505,7 +511,7 @@ void MessageMap::clear()
m_messageCount = 0; m_messageCount = 0;
m_messagesByName.clear(); m_messagesByName.clear();
// clear messages by key // clear messages by key
m_passiveMessagesByKey.clear(); m_messagesByKey.clear();
m_minIdLength = 4; m_minIdLength = 4;
m_maxIdLength = 0; m_maxIdLength = 0;
} }
+13 -9
View File
@@ -144,8 +144,8 @@ public:
vector<unsigned char> getId() const { return m_id; } vector<unsigned char> getId() const { return m_id; }
/** /**
* @brief Return the key for storing in @a MessageSet. * @brief Return the key for storing in @a MessageMap.
* @return the key for storing in @a MessageSet. * @return the key for storing in @a MessageMap.
*/ */
unsigned long long getKey() { return m_key; } unsigned long long getKey() { return m_key; }
@@ -244,7 +244,7 @@ private:
/** the primary, secondary, and optionally further command ID bytes. */ /** the primary, secondary, and optionally further command ID bytes. */
vector<unsigned char> m_id; vector<unsigned char> m_id;
/** the key for storing in @a MessageSet. */ /** the key for storing in @a MessageMap. */
unsigned long long m_key; unsigned long long m_key;
/** the @a DataField for encoding/decoding the message. */ /** the @a DataField for encoding/decoding the message. */
@@ -292,7 +292,8 @@ public:
/** /**
* @brief Construct a new instance. * @brief Construct a new instance.
*/ */
MessageMap() : FileReader<DataFieldTemplates*>::FileReader(true), m_minIdLength(4), m_maxIdLength(0), m_messageCount(0) {} MessageMap() : FileReader<DataFieldTemplates*>::FileReader(true),
m_minIdLength(4), m_maxIdLength(0), m_messageCount(0), m_passiveMessageCount(0) {}
/** /**
* @brief Destructor. * @brief Destructor.
@@ -350,13 +351,13 @@ public:
* @param passiveOnly true to count only passive messages, false to count all messages. * @param passiveOnly true to count only passive messages, false to count all messages.
* @return the the number of stored @a Message instances. * @return the the number of stored @a Message instances.
*/ */
int size(const bool passiveOnly=false) { return passiveOnly ? m_passiveMessagesByKey.size() : m_messageCount; } size_t size(const bool passiveOnly=false) { return passiveOnly ? m_passiveMessageCount : m_messageCount; }
/** /**
* @brief Get the number of stored @a Message instances with a poll priority. * @brief Get the number of stored @a Message instances with a poll priority.
* @return the the number of stored @a Message instances with a poll priority. * @return the the number of stored @a Message instances with a poll priority.
*/ */
int sizePoll() { return m_pollMessages.size(); } size_t sizePoll() { return m_pollMessages.size(); }
/** /**
* @brief Get the next @a Message to poll. * @brief Get the next @a Message to poll.
@@ -374,13 +375,16 @@ private:
unsigned char m_maxIdLength; unsigned char m_maxIdLength;
/** the number of distinct @a Message instances stored in @a m_messagesByName. */ /** the number of distinct @a Message instances stored in @a m_messagesByName. */
int m_messageCount; size_t m_messageCount;
/** the number of distinct passive @a Message instances stored in @a m_messagesByKey. */
size_t m_passiveMessageCount;
/** the known @a Message instances by class and name. */ /** the known @a Message instances by class and name. */
map<string, Message*> m_messagesByName; map<string, Message*> m_messagesByName;
/** the known passive @a Message instances by key. */ /** the known @a Message instances by key. */
map<unsigned long long, Message*> m_passiveMessagesByKey; map<unsigned long long, Message*> m_messagesByKey;
/** the known @a Message instances to poll, by priority. */ /** the known @a Message instances to poll, by priority. */
priority_queue<Message*, vector<Message*>, compareMessagePriority> m_pollMessages; priority_queue<Message*, vector<Message*>, compareMessagePriority> m_pollMessages;