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;
/** 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,
const bool isPassive, const string comment,
const unsigned char srcAddress, const unsigned char dstAddress,
@@ -338,38 +341,39 @@ bool Message::isLessPollWeight(Message* other) {
result_t MessageMap::add(Message* message)
{
unsigned long long pkey = message->getKey();
bool isPassive = message->isPassive();
if (isPassive == true) {
map<unsigned long long, Message*>::iterator keyIt = m_passiveMessagesByKey.find(pkey);
if (keyIt != m_passiveMessagesByKey.end()) {
return RESULT_ERR_DUPLICATE; // duplicate key
}
unsigned long long key = message->getKey();
map<unsigned long long, Message*>::iterator keyIt = m_messagesByKey.find(key);
if (keyIt != m_messagesByKey.end()) {
return RESULT_ERR_DUPLICATE; // duplicate key
}
bool isPassive = message->isPassive();
bool isSet = message->isSet();
string clazz = message->getClass();
string name = message->getName();
string key = string(isPassive ? "P" : (isSet ? "W" : "R")) + clazz + FIELD_SEPARATOR + name;
map<string, Message*>::iterator nameIt = m_messagesByName.find(key);
string nameKey = string(isPassive ? "P" : (isSet ? "W" : "R")) + clazz + FIELD_SEPARATOR + name;
map<string, Message*>::iterator nameIt = m_messagesByName.find(nameKey);
if (nameIt != m_messagesByName.end()) {
return RESULT_ERR_DUPLICATE; // duplicate key
}
m_messagesByName[key] = message;
m_messagesByName[nameKey] = message;
m_messageCount++;
if (isPassive == true)
m_passiveMessageCount++;
key = string(isPassive ? "-P" : (isSet ? "-W" : "-R")) + name; // also store without class
m_messagesByName[key] = message; // last key without class overrides previous
if (message->isPassive() == true) {
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;
nameKey = string(isPassive ? "-P" : (isSet ? "-W" : "-R")) + name; // also store without class
nameIt = m_messagesByName.find(nameKey);
if (nameIt == m_messagesByName.end()) {
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_messagesByKey[key] = message;
if (message->getPollPriority() > 0)
m_pollMessages.push(message);
@@ -462,7 +466,6 @@ Message* MessageMap::find(SymbolString& master)
if (master.size() < 5+maxIdLength)
return NULL;
unsigned long long sourceMask = 0x1fLL << (8 * 7);
for (int idLength = maxIdLength; idLength >= m_minIdLength; idLength--) {
int exp = 7;
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++)
key |= (unsigned long long)master[5 + i] << (8 * exp--);
map<unsigned long long , Message*>::iterator it = m_passiveMessagesByKey.find(key);
if (it != m_passiveMessagesByKey.end())
map<unsigned long long , Message*>::iterator it = m_messagesByKey.find(key);
if (it != m_messagesByKey.end())
return it->second;
if ((key & sourceMask) != 0) {
key &= ~sourceMask; // try again without specific source master
it = m_passiveMessagesByKey.find(key);
if (it != m_passiveMessagesByKey.end())
if ((key & ID_SOURCE_MASK) != 0) {
it = m_messagesByKey.find(key & ~ID_SOURCE_MASK); // try again without specific source master
if (it != m_messagesByKey.end())
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;
@@ -505,7 +511,7 @@ void MessageMap::clear()
m_messageCount = 0;
m_messagesByName.clear();
// clear messages by key
m_passiveMessagesByKey.clear();
m_messagesByKey.clear();
m_minIdLength = 4;
m_maxIdLength = 0;
}
+13 -9
View File
@@ -144,8 +144,8 @@ public:
vector<unsigned char> getId() const { return m_id; }
/**
* @brief Return the key for storing in @a MessageSet.
* @return the key for storing in @a MessageSet.
* @brief Return the key for storing in @a MessageMap.
* @return the key for storing in @a MessageMap.
*/
unsigned long long getKey() { return m_key; }
@@ -244,7 +244,7 @@ private:
/** the primary, secondary, and optionally further command ID bytes. */
vector<unsigned char> m_id;
/** the key for storing in @a MessageSet. */
/** the key for storing in @a MessageMap. */
unsigned long long m_key;
/** the @a DataField for encoding/decoding the message. */
@@ -292,7 +292,8 @@ public:
/**
* @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.
@@ -350,13 +351,13 @@ public:
* @param passiveOnly true to count only passive messages, false to count all messages.
* @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.
* @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.
@@ -374,13 +375,16 @@ private:
unsigned char m_maxIdLength;
/** 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. */
map<string, Message*> m_messagesByName;
/** the known passive @a Message instances by key. */
map<unsigned long long, Message*> m_passiveMessagesByKey;
/** the known @a Message instances by key. */
map<unsigned long long, Message*> m_messagesByKey;
/** the known @a Message instances to poll, by priority. */
priority_queue<Message*, vector<Message*>, compareMessagePriority> m_pollMessages;