diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index 1f223aee..acca836d 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -1087,7 +1087,7 @@ string MainLoop::executeFind(vector &args, string levels) { bool configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false, hexFormat = false, userLevel = true; OutputFormat verbosity = 0; - vector fieldIds; + vector fieldNames; string circuit; vector id; while (args.size() > argPos && args[argPos][0] == '-') { @@ -1121,7 +1121,7 @@ string MainLoop::executeFind(vector &args, string levels) { argPos = 0; // print usage break; } - if (!Message::extractFieldIds(args[argPos], fieldIds)) { + if (!Message::extractFieldNames(args[argPos], fieldNames)) { argPos = 0; // print usage break; } @@ -1231,11 +1231,11 @@ string MainLoop::executeFind(vector &args, string levels) { result << endl; } message->dump(result); - } else if (!fieldIds.empty()) { + } else if (!fieldNames.empty()) { if (found) { result << endl; } - message->dump(result, &fieldIds); + message->dump(result, &fieldNames); } else { if (found) { result << endl; diff --git a/src/ebusd/mqtthandler.cpp b/src/ebusd/mqtthandler.cpp index 0385feb0..ccc76adb 100644 --- a/src/ebusd/mqtthandler.cpp +++ b/src/ebusd/mqtthandler.cpp @@ -176,13 +176,6 @@ static const char* knownFieldNames[] = { "field", }; -/** the known topic field IDs. */ -static const size_t knownFieldIds[] = { - MESSAGEFIELD_CIRCUIT, - MESSAGEFIELD_NAME, - MESSAGEFIELD_DATAFIELDS, -}; - /** the number of known field names. */ static const size_t knownFieldCount = sizeof(knownFieldNames) / sizeof(char*); @@ -194,7 +187,7 @@ static const size_t knownFieldCount = sizeof(knownFieldNames) / sizeof(char*); * @param fields the @a vector to which the field parts shall be added. * @return true on success, false on malformed topic template. */ -bool parseTopic(const string topic, vector &strs, vector &fields) { +bool parseTopic(const string topic, vector &strs, vector &fields) { size_t lastpos = 0; size_t end = topic.length(); vector columns; @@ -208,17 +201,17 @@ bool parseTopic(const string topic, vector &strs, vector &fields break; } } - if (idx== knownFieldCount) { + if (idx == knownFieldCount) { // TODO could allow custom attributes here return false; } - size_t fieldId = knownFieldIds[idx]; - for (vector::iterator it=fields.begin(); it != fields.end(); it++) { - if (*it == fieldId) { + string fieldName = knownFieldNames[idx]; + for (auto& it : fields) { + if (it == fieldName) { return false; // duplicate column } } strs.push_back(topic.substr(lastpos, pos-lastpos)); - fields.push_back(fieldId); + fields.push_back(fieldName); lastpos = pos+1+len; pos = topic.find('%', lastpos); } @@ -288,12 +281,12 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap* m_topicStrs[0] = str+"/"; } } - m_topicFields.push_back(MESSAGEFIELD_CIRCUIT); // circuit + m_topicFields.push_back("circuit"); m_topicStrs.push_back("/"); - m_topicFields.push_back(MESSAGEFIELD_NAME); // name + m_topicFields.push_back("name"); } else { for (size_t i = 0; i < m_topicFields.size(); i++) { - if (m_topicFields[i] == MESSAGEFIELD_DATAFIELDS) { // fields + if (m_topicFields[i] == "fields") { m_publishByField = true; break; } @@ -439,17 +432,14 @@ void MqttHandler::notifyTopic(string topic, string data) { if (field.empty()) { return; } - switch (m_topicFields[idx-1]) { - case MESSAGEFIELD_CIRCUIT: + string fieldName = m_topicFields[idx-1]; + if (fieldName == "circuit") { circuit = field; - break; - case MESSAGEFIELD_NAME: + } else if (fieldName == "name") { name = field; - break; - case MESSAGEFIELD_DATAFIELDS: + } else if (fieldName == "fields") { // field = field; // TODO add support for writing a single field - break; - default: + } else { return; } } @@ -576,7 +566,7 @@ string MqttHandler::getTopic(Message* message, ssize_t fieldIndex) { break; } if (i < m_topicFields.size()) { - if (m_topicFields[i] == MESSAGEFIELD_DATAFIELDS && fieldIndex >= 0) { + if (m_topicFields[i] == "fields" && fieldIndex >= 0) { ret << message->getFieldName(fieldIndex); // TODO skip ignored fields } else { message->dumpField(ret, m_topicFields[i]); diff --git a/src/ebusd/mqtthandler.h b/src/ebusd/mqtthandler.h index 58d9df0c..04dc9823 100644 --- a/src/ebusd/mqtthandler.h +++ b/src/ebusd/mqtthandler.h @@ -124,7 +124,7 @@ class MqttHandler : public DataSink, public DataSource, public Thread { vector m_topicStrs; /** the MQTT topic field parts. */ - vector m_topicFields; + vector m_topicFields; /** the global topic prefix. */ string m_globalTopic; diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index 29e8be63..35688002 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -38,45 +38,37 @@ using std::setw; /** the week day names. */ static const char* dayNames[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; -size_t getDataFieldId(const string name) { - if (name == "name" || name.find("field") != string::npos) { - return DATAFIELD_NAME; +/** the default field map for field templates. */ +static const char* defaultTemplateFieldMap[] = { + "name", "*type", "divisor/values", "unit", "comment", + "*name", "type", "divisor/values", "unit", "comment", +}; + + + +string getDataFieldName(const string name) { + if (name.find("name") != string::npos || name.find("field") != string::npos) { + return "name"; } if (name.find("part") != string::npos) { - return DATAFIELD_PART; + return "part"; } if (name.find("type") != string::npos) { - return DATAFIELD_TYPE; - } - if (name.find("divisor") != string::npos || name.find("values") != string::npos) { - return DATAFIELD_DIVISORVALUES; - } - if (name == "unit") { - return DATAFIELD_UNIT; - } - if (name == "comment") { - return DATAFIELD_COMMENT; - } - return UINT_MAX; -} - -string getDataFieldName(const size_t fieldId) { - switch (fieldId) { - case DATAFIELD_NAME: - return "name"; - case DATAFIELD_PART: - return "part"; - case DATAFIELD_TYPE: return "type"; - case DATAFIELD_DIVISORVALUES: - return "divisor/values"; - case DATAFIELD_UNIT: - return "unit"; - case DATAFIELD_COMMENT: - return "comment"; - default: - return ""; } + if (name.find("divisor") != string::npos) { + if (name.find("values") != string::npos) { + return "divisor/values"; + } + return "divisor"; + } + if (name == "values" || name == "unit") { + return name; + } + if (name.find("comment") != string::npos) { + return "comment"; + } + return ""; } @@ -117,7 +109,7 @@ void AttributedItem::appendJson(ostream& output, const string name, const string if (prependFieldSeparator) { output << FIELD_SEPARATOR; } - output << "\"" << name << "\": "; + output << " \"" << name << "\": "; if (plain) { output << value; } else { @@ -1132,24 +1124,8 @@ result_t DataFieldTemplates::getFieldMap(vector& row, string& errorDescr // name[:usename],basetype[:len]|template[:usename][,[divisor|values][,[unit][,[comment]]]] if (row.empty()) { // default map does not include separate field name - row.push_back("name"); - for (size_t cnt = 0; cnt < 2; cnt++) { - bool first = true; - for (size_t fieldId = DATAFIELD_RANGE_MIN; fieldId <= DATAFIELD_RANGE_MAX; fieldId++) { - if (cnt == 0 && fieldId == DATAFIELD_NAME) { - continue; - } - if (fieldId == DATAFIELD_PART) { // not included in default map - continue; - } - // subsequent fields start with field name - if (first) { - first = false; - row.push_back("*"+getDataFieldName(fieldId)); - } else { - row.push_back(getDataFieldName(fieldId)); - } - } + for (auto col : defaultTemplateFieldMap) { + row.push_back(col); } return RESULT_OK; } @@ -1159,9 +1135,9 @@ result_t DataFieldTemplates::getFieldMap(vector& row, string& errorDescr string useName = name; tolower(useName); if (inDataFields) { - size_t fieldId = getDataFieldId(useName); - if (fieldId != UINT_MAX) { - useName = getDataFieldName(fieldId); + string chkName = getDataFieldName(useName); + if (!chkName.empty()) { + useName = chkName; if (seen.find(useName) != seen.end()) { if (seen.find("type") == seen.end()) { errorDescription = "missing type"; @@ -1174,9 +1150,9 @@ result_t DataFieldTemplates::getFieldMap(vector& row, string& errorDescr if (useName == "name" && seen.find("name") == seen.end()) { // keep first name for template } else { - size_t fieldId = getDataFieldId(useName); - if (fieldId != UINT_MAX) { - useName = getDataFieldName(fieldId); + string chkName = getDataFieldName(useName); + if (!chkName.empty()) { + useName = chkName; if (seen.find("name") == seen.end()) { errorDescription = "missing name"; return RESULT_ERR_EOF; // require at least name diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index d2bc34e6..715c1845 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -57,109 +57,52 @@ using std::endl; /** the maximum poll priority for a @a Message referred to by a @a Condition. */ #define POLL_PRIORITY_CONDITION 5 -/** the known field names (pairs of full length name and short length name). */ -static const char* knownFieldNames[] = { - "type", "t", - "circuit", "c", - "level", "l", - "name", "n", - "comment", "co", - "qq", "q", - "zz", "z", - "pbsb", "p", - "id", "i", - "fields", "f", +/** the known full length field names. */ +static const char* knownFieldNamesFull[] = { + "type", "circuit", "level", "name", "comment", "qq", "zz", "pbsb", "id", "fields", }; -/** the known field IDs according to @a knownFieldNames. */ -static const size_t knownFieldIds[] = { - MESSAGEFIELD_TYPE, MESSAGEFIELD_TYPE, - MESSAGEFIELD_CIRCUIT, MESSAGEFIELD_CIRCUIT, - MESSAGEFIELD_LEVEL, MESSAGEFIELD_LEVEL, - MESSAGEFIELD_NAME, MESSAGEFIELD_NAME, - MESSAGEFIELD_COMMENT, MESSAGEFIELD_COMMENT, - MESSAGEFIELD_QQ, MESSAGEFIELD_QQ, - MESSAGEFIELD_ZZ, MESSAGEFIELD_ZZ, - MESSAGEFIELD_PBSB, MESSAGEFIELD_PBSB, - MESSAGEFIELD_ID, MESSAGEFIELD_ID, - MESSAGEFIELD_DATAFIELDS, MESSAGEFIELD_DATAFIELDS, +/** the known full length field names. */ +static const char* knownFieldNamesShort[] = { + "t", "c", "l", "n", "co", "q", "z", "p", "i", "f", }; /** the number of known field names. */ -static const size_t knownFieldCount = sizeof(knownFieldNames) / sizeof(char*); +static const size_t knownFieldCount = sizeof(knownFieldNamesFull) / sizeof(char*); + +/** the default field map for messages. */ +static const char* defaultMessageFieldMap[] = { // access level not included in default map + "type", "circuit", "name", "comment", "qq", "zz", "pbsb", "id", + "*name", "part", "type", "divisor/values", "unit", "comment", +}; extern DataFieldTemplates* getTemplates(const string filename); /** - * Get the message field ID for the given field name. - * @param name the field name. - * @return the field ID, or @a UINT_MAX if not found. + * Get the normalized message field name for the given name. + * @param name the input field name. + * @return the normalized message field name, or empty if unknown. */ -size_t getMessageFieldId(const string name) { +string getMessageFieldName(const string name) { if (name.find("type") != string::npos) { - return MESSAGEFIELD_TYPE; - } - if (name == "circuit") { - return MESSAGEFIELD_CIRCUIT; - } - if (name == "level") { - return MESSAGEFIELD_LEVEL; - } - if (name == "name") { - return MESSAGEFIELD_NAME; - } - if (name == "comment") { - return MESSAGEFIELD_COMMENT; - } - if (name == "qq") { - return MESSAGEFIELD_QQ; - } - if (name == "zz") { - return MESSAGEFIELD_ZZ; - } - if (name == "pbsb") { - return MESSAGEFIELD_PBSB; - } - if (name == "id") { - return MESSAGEFIELD_ID; - } - return UINT_MAX; -} - - -/** - * Get the message field name for the given field ID. - * @param fieldId the field ID. - * @param withDataFields whether to include the data fields ID or not. - * @return the field name, or empty if not found. - */ -string getMessageFieldName(size_t fieldId, bool withDataFields = true) { - switch (fieldId) { - case MESSAGEFIELD_TYPE: return "type"; - case MESSAGEFIELD_CIRCUIT: - return "circuit"; - case MESSAGEFIELD_LEVEL: - return "level"; - case MESSAGEFIELD_NAME: - return "name"; - case MESSAGEFIELD_COMMENT: - return "comment"; - case MESSAGEFIELD_QQ: - return "qq"; - case MESSAGEFIELD_ZZ: - return "zz"; - case MESSAGEFIELD_PBSB: - return "pbsb"; - case MESSAGEFIELD_ID: - return "id"; - case MESSAGEFIELD_DATAFIELDS: - return withDataFields ? "fields" : ""; - default: - return ""; } + if (name == "circuit" || name == "level" || name == "qq" || name == "zz" || name == "pbsb" || name == "id") { + return name; + } + if (name.find("name") != string::npos) { + return "name"; + } + if (name.find("comment") == 0) { + return "comment"; + } + return ""; } +/* case MESSAGEFIELD_DATAFIELDS: + return withDataFields ? "fields" : ""; + */ + Message::Message(const string circuit, const string level, const string name, const bool isWrite, const bool isPassive, const map& attributes, const symbol_t srcAddress, const symbol_t dstAddress, @@ -187,11 +130,11 @@ Message::Message(const string circuit, const string level, const string name, : AttributedItem(name), m_circuit(circuit), m_level(level), m_isWrite(broadcast), m_isPassive(false), m_srcAddress(SYN), m_dstAddress(broadcast ? BROADCAST : SYN), - m_id({pb, sb}), m_data(data), m_deleteData(deleteData), + m_id({pb, sb}), m_key(createKey(pb, sb, broadcast)), + m_data(data), m_deleteData(deleteData), m_pollPriority(0), m_usedByCondition(false), m_isScanMessage(true), m_condition(NULL), - m_lastUpdateTime(0), m_lastChangeTime(0), m_pollCount(0), m_lastPollTime(0), - m_key(createKey(pb, sb, broadcast)) { + m_lastUpdateTime(0), m_lastChangeTime(0), m_pollCount(0), m_lastPollTime(0) { } @@ -352,6 +295,10 @@ result_t Message::create(map row, vector< map > level = circuit.substr(pos+1); circuit.resize(pos); } + if (circuit.empty()) { + errorDescription = "circuit"; + return RESULT_ERR_MISSING_ARG; // empty circuit + } string name = getDefault(pluck(row, "name"), defaults, "name", true, true); // name if (name.empty()) { errorDescription = "name"; @@ -545,25 +492,26 @@ Message* Message::createScanMessage(bool broadcast) { return new Message("scan", "", "", 0x07, 0x04, broadcast, DataFieldSet::getIdentFields(), !broadcast); } -bool Message::extractFieldIds(string str, vector& fields, bool checkAbbreviated) { +bool Message::extractFieldNames(string str, vector& fields, bool checkAbbreviated) { istringstream input(str); vector row; string column; while (getline(input, column, FIELD_SEPARATOR)) { size_t idx = knownFieldCount; for (size_t i = 0; i < knownFieldCount; i++) { - if (column == knownFieldNames[i]) { + if (column == knownFieldNamesFull[i]) { idx = i; break; } - if (!checkAbbreviated) { - i++; + if (checkAbbreviated && column == knownFieldNamesShort[i]) { + idx = i; + break; } } - if (idx == knownFieldCount) { - return false; - } - fields.push_back(knownFieldIds[idx]); + if (idx != knownFieldCount) { + column = knownFieldNamesFull[idx]; + } // else: custom attribute + fields.push_back(column); } return !fields.empty(); } @@ -874,11 +822,34 @@ bool Message::isLessPollWeight(const Message* other) const { return false; } -void Message::dumpHeader(ostream& output, vector* fieldIds) { +void Message::dumpHeader(ostream& output, vector* fieldNames) { bool first = true; - if (fieldIds == NULL) { - for (size_t fieldId = MESSAGEFIELD_RANGE_MIN; fieldId <= MESSAGEFIELD_RANGE_MAX; fieldId++) { - if (fieldId == MESSAGEFIELD_LEVEL) { + if (fieldNames == NULL) { + for (auto fieldName : defaultMessageFieldMap) { + if (first) { + first = false; + } else { + output << FIELD_SEPARATOR; + } + output << fieldName; + } + return; + } + for (auto fieldName : *fieldNames) { + if (first) { + first = false; + } else { + output << FIELD_SEPARATOR; + } + output << fieldName; + } +} + +void Message::dump(ostream& output, vector* fieldNames, bool withConditions) const { + bool first = true; + if (fieldNames == NULL) { + for (auto fieldName : knownFieldNamesFull) { + if (fieldName == "level") { continue; // access level not included in default dump format } if (first) { @@ -886,67 +857,22 @@ void Message::dumpHeader(ostream& output, vector* fieldIds) { } else { output << FIELD_SEPARATOR; } - if (fieldId == MESSAGEFIELD_DATAFIELDS) { - bool dataFirst = true; - for (size_t dataFieldId = DATAFIELD_RANGE_MIN; dataFieldId <= DATAFIELD_RANGE_MAX; dataFieldId++) { - // subsequent fields start with field name - if (dataFirst) { - dataFirst = false; - output << "*"; - } else { - output << FIELD_SEPARATOR; - } - output << getDataFieldName(dataFieldId); - } - } else { - output << getMessageFieldName(fieldId, false); - } + dumpField(output, fieldName, withConditions); } return; } - for (auto fieldId : *fieldIds) { + for (auto fieldName : *fieldNames) { if (first) { first = false; } else { output << FIELD_SEPARATOR; } - string name = getMessageFieldName(fieldId, false); - if (name.empty()) { - name = getDataFieldName(fieldId); - } - output << name; + dumpField(output, fieldName, withConditions); } } -void Message::dump(ostream& output, vector* fieldIds, bool withConditions) const { - bool first = true; - if (fieldIds == NULL) { - for (size_t fieldId = MESSAGEFIELD_RANGE_MIN; fieldId <= MESSAGEFIELD_RANGE_MAX; fieldId++) { - if (fieldId == MESSAGEFIELD_LEVEL) { - continue; // access level not included in default dump format - } - if (first) { - first = false; - } else { - output << FIELD_SEPARATOR; - } - dumpField(output, fieldId, withConditions); - } - return; - } - for (auto fieldId : *fieldIds) { - if (first) { - first = false; - } else { - output << FIELD_SEPARATOR; - } - dumpField(output, fieldId, withConditions); - } -} - -void Message::dumpField(ostream& output, size_t fieldId, bool withConditions) const { - switch (fieldId) { - case MESSAGEFIELD_TYPE: +void Message::dumpField(ostream& output, string fieldName, bool withConditions) const { + if (fieldName == "type") { if (withConditions && m_condition != NULL) { m_condition->dump(output); } @@ -963,45 +889,49 @@ void Message::dumpField(ostream& output, size_t fieldId, bool withConditions) co output << static_cast(m_pollPriority); } } - break; - case MESSAGEFIELD_CIRCUIT: + return; + } + if (fieldName == "circuit") { dumpString(output, m_circuit, false); - break; - case MESSAGEFIELD_LEVEL: + return; + } + if (fieldName == "level") { dumpString(output, m_level, false); - break; - case MESSAGEFIELD_NAME: + return; + } + if (fieldName == "name") { dumpString(output, m_name, false); - break; - case MESSAGEFIELD_COMMENT: - dumpAttribute(output, "comment", false); - break; - case MESSAGEFIELD_QQ: + return; + } + if (fieldName == "qq") { if (m_srcAddress != SYN) { output << hex << setw(2) << setfill('0') << static_cast(m_srcAddress); } - break; - case MESSAGEFIELD_ZZ: + return; + } + if (fieldName == "zz") { if (m_dstAddress != SYN) { output << hex << setw(2) << setfill('0') << static_cast(m_dstAddress); } - break; - case MESSAGEFIELD_PBSB: + return; + } + if (fieldName == "pbsb") { for (vector::const_iterator it = m_id.begin(); it < m_id.begin()+2 && it < m_id.end(); it++) { output << hex << setw(2) << setfill('0') << static_cast(*it); } - break; - case MESSAGEFIELD_ID: + return; + } + if (fieldName == "id") { for (vector::const_iterator it = m_id.begin()+2; it < m_id.end(); it++) { output << hex << setw(2) << setfill('0') << static_cast(*it); } - break; - case MESSAGEFIELD_DATAFIELDS: - m_data->dump(output); - break; - default: - break; + return; } + if (fieldName == "fields") { + m_data->dump(output); + return; + } + dumpAttribute(output, fieldName, false); } void Message::decode(ostringstream& output, OutputFormat outputFormat, bool leadingSeparator, @@ -1278,9 +1208,9 @@ result_t ChainedMessage::combineLastParts() { return result; } -void ChainedMessage::dumpField(ostream& output, size_t fieldId, bool withConditions) const { - if (fieldId != MESSAGEFIELD_ID) { - Message::dumpField(output, fieldId, withConditions); +void ChainedMessage::dumpField(ostream& output, string fieldName, bool withConditions) const { + if (fieldName != "id") { + Message::dumpField(output, fieldName, withConditions); return; } bool first = true; @@ -1847,21 +1777,8 @@ result_t MessageMap::getFieldMap(vector& row, string& errorDescription) // unit,comment // minimum: type,name,PBSB,field,datatype if (row.empty()) { - for (size_t fieldId = MESSAGEFIELD_RANGE_MIN; fieldId <= MESSAGEFIELD_RANGE_MAX; fieldId++) { - if (fieldId == MESSAGEFIELD_LEVEL) { - continue; // level not part of default field list - } - if (fieldId == MESSAGEFIELD_DATAFIELDS) { - continue; // data fields are handled below - } - row.push_back(getMessageFieldName(fieldId)); - } - for (size_t fieldId = DATAFIELD_RANGE_MIN; fieldId <= DATAFIELD_RANGE_MAX; fieldId++) { - if (fieldId == DATAFIELD_RANGE_MIN) { - row.push_back("*" + getDataFieldName(fieldId)); // field repetition - } else { - row.push_back(getDataFieldName(fieldId)); - } + for (auto col : defaultMessageFieldMap) { + row.push_back(col); } return RESULT_OK; } @@ -1871,9 +1788,9 @@ result_t MessageMap::getFieldMap(vector& row, string& errorDescription) string useName = name; tolower(useName); if (inDataFields) { - size_t fieldId = getDataFieldId(useName); - if (fieldId != UINT_MAX) { - useName = getDataFieldName(fieldId); + string chkName = getDataFieldName(useName); + if (!chkName.empty()) { + useName = chkName; if (seen.find(useName) != seen.end()) { if (seen.find("name") == seen.end() || seen.find("type") == seen.end()) { errorDescription = "missing field name/type as of already seen "+useName; @@ -1883,13 +1800,13 @@ result_t MessageMap::getFieldMap(vector& row, string& errorDescription) } } } else { - size_t fieldId = getMessageFieldId(useName); - if (fieldId != UINT_MAX && (fieldId != MESSAGEFIELD_NAME || seen.find("name") == seen.end())) { - useName = getMessageFieldName(fieldId); + string chkName = getMessageFieldName(useName); + if (!chkName.empty() && (chkName != "name" || seen.find("name") == seen.end())) { + useName = chkName; } else { - fieldId = getDataFieldId(useName); - if (fieldId != UINT_MAX) { - useName = getDataFieldName(fieldId); + chkName = getDataFieldName(useName); + if (!chkName.empty()) { + useName = chkName; if (seen.find("type") == seen.end() || seen.find("name") == seen.end() || seen.find("pbsb") == seen.end()) { errorDescription = "missing message name/type/pbsb"; return RESULT_ERR_EOF; // require at least type, name, and pbsb diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 14111662..078dbf11 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -68,42 +68,6 @@ class SimpleCondition; class CombinedCondition; class MessageMap; -/** the field ID in @a Message::dump() for the message type. */ -#define MESSAGEFIELD_TYPE (DATAFIELD_RANGE_MAX+1) - -/** the field ID in @a Message::dump() for the circuit name. */ -#define MESSAGEFIELD_CIRCUIT (MESSAGEFIELD_TYPE+1) - -/** the field ID in @a Message::dump() for the access level. */ -#define MESSAGEFIELD_LEVEL (MESSAGEFIELD_CIRCUIT+1) - -/** the field ID in @a Message::dump() for the message name. */ -#define MESSAGEFIELD_NAME (MESSAGEFIELD_LEVEL+1) - -/** the field ID in @a Message::dump() for the message comment. */ -#define MESSAGEFIELD_COMMENT (MESSAGEFIELD_NAME+1) - -/** the field ID in @a Message::dump() for the source address QQ. */ -#define MESSAGEFIELD_QQ (MESSAGEFIELD_COMMENT+1) - -/** the field ID in @a Message::dump() for the destination address QQ. */ -#define MESSAGEFIELD_ZZ (MESSAGEFIELD_QQ+1) - -/** the field ID in @a Message::dump() for the PBSB bytes. */ -#define MESSAGEFIELD_PBSB (MESSAGEFIELD_ZZ+1) - -/** the field ID in @a Message::dump() for the ID field (after the PBSB bytes). */ -#define MESSAGEFIELD_ID (MESSAGEFIELD_PBSB+1) - -/** the field ID in @a Message::dump() for the data field(s). */ -#define MESSAGEFIELD_DATAFIELDS (MESSAGEFIELD_ID+1) - -/** the marker field ID for the minimum field ID. */ -#define MESSAGEFIELD_RANGE_MIN MESSAGEFIELD_TYPE - -/** the marker field ID for the maximum field ID. */ -#define MESSAGEFIELD_RANGE_MAX MESSAGEFIELD_DATAFIELDS - /** * Defines parameters of a message sent or received on the bus. @@ -235,13 +199,13 @@ class Message : public AttributedItem { static Message* createScanMessage(bool broadcast = false); /** - * Extract the known field IDs from the input string. + * Extract the known field names from the input string. * @param str the input string with the field names separated by @a FIELD_SEPARATOR. - * @param fields the vector to update with the extracted field IDs with. + * @param fields the vector to update with the extracted normalized field names with. * @param checkAbbreviated true to also check for abbreviated field names. * @return true when all fields are valid. */ - static bool extractFieldIds(string str, vector& fields, bool checkAbbreviated = true); + static bool extractFieldNames(string str, vector& fields, bool checkAbbreviated = true); /** * Set that this is a special scanning @a Message instance. @@ -577,25 +541,25 @@ class Message : public AttributedItem { /** * Write the message definition header or parts of it to the @a ostream. * @param output the @a ostream to append the formatted value to. - * @param fieldIds the list of field IDs to write, or NULL for all (see @p MESSAGEFIELD_TYPE constants). + * @param fieldNames the list of field names to write, or NULL for all. */ - static void dumpHeader(ostream& output, vector* fieldIds = NULL); + static void dumpHeader(ostream& output, vector* fieldNames = NULL); /** * Write the message definition or parts of it to the @a ostream. * @param output the @a ostream to append the formatted value to. - * @param fieldIds the list of field IDs to write, or NULL for all (see @p MESSAGEFIELD_TYPE constants). + * @param fieldNames the list of field names to write, or NULL for all. * @param withConditions whether to include the optional conditions prefix. */ - void dump(ostream& output, vector* fieldIds = NULL, bool withConditions = false) const; + void dump(ostream& output, vector* fieldNames = NULL, bool withConditions = false) const; /** * Write the specified field to the @a ostream. * @param output the @a ostream to append the formatted value to. - * @param fieldId the field ID to write (see @p MESSAGEFIELD_TYPE constants). + * @param fieldName the field name to write. * @param withConditions whether to include the optional conditions prefix. */ - virtual void dumpField(ostream& output, size_t fieldId, bool withConditions = false) const; + virtual void dumpField(ostream& output, string fieldName, bool withConditions = false) const; /** * Decode the message from the last stored data. @@ -765,7 +729,7 @@ class ChainedMessage : public Message { protected: // @copydoc - void dumpField(ostream& output, size_t fieldId, bool withConditions = false) const override; + void dumpField(ostream& output, string fieldName, bool withConditions = false) const override; private: