use defines for values in source mask of message key and simplified a bit (in preparation of #278), documentation
This commit is contained in:
+51
-32
@@ -45,12 +45,24 @@ using std::endl;
|
||||
/** the bit mask for the ID length and combined ID bytes in the message key. */
|
||||
#define ID_LENGTH_AND_IDS_MASK ((7LL << (8 * 7 + 5)) | 0xffffffffLL)
|
||||
|
||||
/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active read message. */
|
||||
/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active write message. */
|
||||
#define ID_SOURCE_ACTIVE_WRITE (0x1fLL << (8 * 7))
|
||||
|
||||
/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active write message. */
|
||||
/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active read message. */
|
||||
#define ID_SOURCE_ACTIVE_READ (0x1eLL << (8 * 7))
|
||||
|
||||
/**
|
||||
* the bits in the @a ID_SOURCE_MASK for arbitrary source and active write message
|
||||
* to a master (same value as ID_SOURCE_ACTIVE_WRITE for now).
|
||||
*/
|
||||
#define ID_SOURCE_ACTIVE_WRITE_MASTER (0x1fLL << (8 * 7))
|
||||
|
||||
/**
|
||||
* the bits in the @a ID_SOURCE_MASK for arbitrary source and active read message
|
||||
* to a master (same value as ID_SOURCE_ACTIVE_WRITE for now).
|
||||
*/
|
||||
#define ID_SOURCE_ACTIVE_READ_MASTER (0x1eLL << (8 * 7))
|
||||
|
||||
/** special value for invalid message key. */
|
||||
#define INVALID_KEY 0xffffffffffffffffLL
|
||||
|
||||
@@ -161,7 +173,8 @@ uint64_t Message::createKey(const vector<symbol_t>& id, bool isWrite, bool isPas
|
||||
if (isPassive) {
|
||||
key |= (uint64_t)getMasterNumber(srcAddress) << (8 * 7); // 0..25
|
||||
} else {
|
||||
key |= (isWrite ? 0x1fLL : 0x1eLL) << (8 * 7); // special values for active
|
||||
key |= isMaster(dstAddress) ? (isWrite ? ID_SOURCE_ACTIVE_WRITE_MASTER : ID_SOURCE_ACTIVE_READ_MASTER)
|
||||
: (isWrite ? ID_SOURCE_ACTIVE_WRITE : ID_SOURCE_ACTIVE_READ); // special values for active
|
||||
}
|
||||
key |= (uint64_t)dstAddress << (8 * 6);
|
||||
int exp = 5;
|
||||
@@ -202,7 +215,7 @@ uint64_t Message::createKey(const MasterSymbolString& master, size_t maxIdLength
|
||||
|
||||
uint64_t Message::createKey(symbol_t pb, symbol_t sb, bool broadcast) {
|
||||
uint64_t key = 0;
|
||||
key |= (broadcast ? 0x1fLL : 0x1eLL) << (8 * 7); // special values for active
|
||||
key |= broadcast ? ID_SOURCE_ACTIVE_WRITE : ID_SOURCE_ACTIVE_READ; // special values for active
|
||||
key |= (uint64_t)(broadcast ? BROADCAST : SYN) << (8 * 6);
|
||||
key |= (uint64_t)pb << (8 * 5);
|
||||
key |= (uint64_t)sb << (8 * 4);
|
||||
@@ -1270,6 +1283,7 @@ void ChainedMessage::dumpField(const string& fieldName, bool withConditions, ost
|
||||
* @param sameIdExtAs the optional @a MasterSymbolString to check for having the same ID.
|
||||
* @param onlyAvailable true to include only available messages (default true), false to also include messages that
|
||||
* are currently not available (e.g. due to unresolved or false conditions).
|
||||
* @return the first available @a Message from the list.
|
||||
*/
|
||||
Message* getFirstAvailable(const vector<Message*>& messages, const MasterSymbolString* sameIdExtAs,
|
||||
const bool onlyAvailable = true) {
|
||||
@@ -1290,6 +1304,7 @@ Message* getFirstAvailable(const vector<Message*>& messages, const MasterSymbolS
|
||||
* @param sameIdExtAs the optional @a Message to check for having the same ID.
|
||||
* @param onlyAvailable true to include only available messages (default true), false to also include messages that
|
||||
* are currently not available (e.g. due to unresolved or false conditions).
|
||||
* @return the first available @a Message from the list.
|
||||
*/
|
||||
Message* getFirstAvailable(const vector<Message*>& messages, const Message* sameIdExtAs = nullptr,
|
||||
const bool onlyAvailable = true) {
|
||||
@@ -2569,6 +2584,14 @@ void MessageMap::findAll(const string& circuit, const string& name, const string
|
||||
}
|
||||
}
|
||||
|
||||
Message* MessageMap::getFirstAvailableFromIterator(const map<uint64_t, vector<Message*> >::const_iterator& it,
|
||||
const MasterSymbolString* sameIdExtAs, bool onlyAvailable) const {
|
||||
if (it != m_messagesByKey.end()) {
|
||||
return getFirstAvailable(it->second, sameIdExtAs, onlyAvailable);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination,
|
||||
bool withRead, bool withWrite, bool withPassive, bool onlyAvailable) const {
|
||||
if (anyDestination && master.size() >= 5 && master[4] == 0 && master[2] == 0x07 && master[3] == 0x04) {
|
||||
@@ -2579,6 +2602,7 @@ Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination,
|
||||
if (baseKey == INVALID_KEY) {
|
||||
return nullptr;
|
||||
}
|
||||
bool isWriteDest = isMaster(master[1]) || master[1] == BROADCAST;
|
||||
size_t maxIdLength = Message::getKeyLength(baseKey);
|
||||
for (size_t idLength = maxIdLength; true; idLength--) {
|
||||
uint64_t key = baseKey;
|
||||
@@ -2594,44 +2618,39 @@ Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination,
|
||||
}
|
||||
}
|
||||
}
|
||||
map<uint64_t, vector<Message*> >::const_iterator it;
|
||||
Message* message;
|
||||
if (withPassive) {
|
||||
it = m_messagesByKey.find(key);
|
||||
if (it != m_messagesByKey.end()) {
|
||||
Message* message = getFirstAvailable(it->second, &master, onlyAvailable);
|
||||
message = getFirstAvailableFromIterator(m_messagesByKey.find(key), &master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
if ((key & ID_SOURCE_MASK) != 0) {
|
||||
key &= ~ID_SOURCE_MASK;
|
||||
if (withPassive) {
|
||||
// try again without specific source master
|
||||
message = getFirstAvailableFromIterator(m_messagesByKey.find(key), &master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
if ((key & ID_SOURCE_MASK) != 0) {
|
||||
key &= ~ID_SOURCE_MASK;
|
||||
it = m_messagesByKey.find(key & ~ID_SOURCE_MASK); // try again without specific source master
|
||||
if (it != m_messagesByKey.end()) {
|
||||
Message* message = getFirstAvailable(it->second, &master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
key &= ~ID_SOURCE_MASK;
|
||||
}
|
||||
if (withRead) {
|
||||
it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_READ); // try again with special value for active read
|
||||
if (it != m_messagesByKey.end()) {
|
||||
Message* message = getFirstAvailable(it->second, &master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
// try again with special value for active read
|
||||
message = getFirstAvailableFromIterator(
|
||||
m_messagesByKey.find(key | (isWriteDest ? ID_SOURCE_ACTIVE_READ_MASTER : ID_SOURCE_ACTIVE_READ)),
|
||||
&master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
if (withWrite) {
|
||||
it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_WRITE); // try again with special value for active write
|
||||
if (it != m_messagesByKey.end()) {
|
||||
Message* message = getFirstAvailable(it->second, &master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
// try again with special value for active write
|
||||
message = getFirstAvailableFromIterator(
|
||||
m_messagesByKey.find(key | (isWriteDest ? ID_SOURCE_ACTIVE_WRITE_MASTER : ID_SOURCE_ACTIVE_WRITE)),
|
||||
&master, onlyAvailable);
|
||||
if (message) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
if (idLength == 0) {
|
||||
|
||||
@@ -1410,6 +1410,17 @@ class MessageMap : public MappedFileReader {
|
||||
bool completeMatch, bool withRead, bool withWrite, bool withPassive, bool includeEmptyLevel, bool onlyAvailable,
|
||||
time_t since, time_t until, bool changedSince, deque<Message*>* messages) const;
|
||||
|
||||
/**
|
||||
* Get the first available @a Message from the first map iterator entry.
|
||||
* @param it the map iterator with list of @a Message instances to check.
|
||||
* @param sameIdExtAs the optional @a MasterSymbolString to check for having the same ID.
|
||||
* @param onlyAvailable true to include only available messages (default true), false to also include messages that
|
||||
* are currently not available (e.g. due to unresolved or false conditions).
|
||||
* @return the first available @a Message from the first map iterator entry.
|
||||
*/
|
||||
Message* getFirstAvailableFromIterator(const map<uint64_t, vector<Message*> >::const_iterator& it,
|
||||
const MasterSymbolString* sameIdExtAs, bool onlyAvailable) const;
|
||||
|
||||
/**
|
||||
* Find the @a Message instance for the specified master data.
|
||||
* @param master the @a MasterSymbolString for identifying the @a Message.
|
||||
|
||||
Executable → Regular
+6
-2
@@ -173,7 +173,11 @@ int main() {
|
||||
{"w,,x,,,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:6,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "1;1;1;0;0;0", "ff08b509030e0700", "00", "di" },
|
||||
{"w,,x,,,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:6,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "1;0;0;0;0;1", "ff08b509030e0104", "00", "di" },
|
||||
{"w,,x,,,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:6,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "0;0;1;0;1;1", "ff08b509030e0406", "00", "di" },
|
||||
{"*r,cir*cuit#level,na*me,com*ment,ff,75,b509,0d", "", "", "", "" },
|
||||
{"r,470,ccTimer.Monday,,,15,B515,0002,,,IGN:1,,,,from,,TTM", "", "", "", "M"},
|
||||
{"w,470,ccTimer.Monday,,,10,B515,0002,from,,TTM", "", "", "", "kM*"},
|
||||
{"", "19:00", "3115b515020002", "080272", "kd"},
|
||||
{"", "19:00", "3110b51503000272", "00", "kd"},
|
||||
{"*r,cir*cuit#level,na*me,com*ment,ff,75,b509,0d", "", "", "", ""},
|
||||
{"r,CIRCUIT,NAME,COMMENT,,,,0100,field,,UCH", "r,cirCIRCUITcuit,naNAMEme,comCOMMENTment,ff,75,b509,0d0100,field,s,UCH,,,: field=42", "ff75b509030d0100", "012a", "DN"},
|
||||
{"r,CIRCUIT,NAME,COMMENT,,,,0100,field,,UCH",
|
||||
// "\"naNAMEme\": {r,cirCIRCUITcuit,naNAMEme,comCOMMENTment,ff,75,b509,0d0100,field,s,UCH,,,: field=42"
|
||||
@@ -420,7 +424,7 @@ int main() {
|
||||
result = message->decodeLastData(false, nullptr, -1,
|
||||
(decodeVerbose?OF_NAMES|OF_UNITS|OF_COMMENTS:0)|(decodeJson?OF_NAMES|OF_JSON:0), &output);
|
||||
if (result != RESULT_OK) {
|
||||
cout << " \"" << check[2] << "\" / \"" << check[3] << "\": decode error: "
|
||||
cout << " \"" << check[2] << "\" / \"" << check[3] << "\": decode error " << (message->isWrite() ? "write: " : "read: ")
|
||||
<< getResultCode(result) << endl;
|
||||
error = true;
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user