fix for mqtt topic including field
This commit is contained in:
+30
-21
@@ -286,13 +286,13 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
|||||||
m_topicFields.push_back("name");
|
m_topicFields.push_back("name");
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < m_topicFields.size(); i++) {
|
for (size_t i = 0; i < m_topicFields.size(); i++) {
|
||||||
if (m_topicFields[i] == "fields") {
|
if (m_topicFields[i] == "field") {
|
||||||
m_publishByField = true;
|
m_publishByField = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_globalTopic = getTopic(NULL, -1, "global/");
|
m_globalTopic = getTopic(NULL, "global/");
|
||||||
m_mosquitto = NULL;
|
m_mosquitto = NULL;
|
||||||
if (mosquitto_lib_init() != MOSQ_ERR_SUCCESS) {
|
if (mosquitto_lib_init() != MOSQ_ERR_SUCCESS) {
|
||||||
logOtherError("mqtt", "unable to initialize");
|
logOtherError("mqtt", "unable to initialize");
|
||||||
@@ -489,7 +489,7 @@ void MqttHandler::run() {
|
|||||||
publishTopic(m_globalTopic+"running", "true");
|
publishTopic(m_globalTopic+"running", "true");
|
||||||
publishTopic(signalTopic, "false");
|
publishTopic(signalTopic, "false");
|
||||||
mosquitto_message_callback_set(m_mosquitto, on_message);
|
mosquitto_message_callback_set(m_mosquitto, on_message);
|
||||||
string subTopic = getTopic(NULL, -1, "#");
|
string subTopic = getTopic(NULL, "#");
|
||||||
mosquitto_subscribe(m_mosquitto, NULL, subTopic.c_str(), 0);
|
mosquitto_subscribe(m_mosquitto, NULL, subTopic.c_str(), 0);
|
||||||
while (isRunning()) {
|
while (isRunning()) {
|
||||||
handleTraffic();
|
handleTraffic();
|
||||||
@@ -557,7 +557,7 @@ void MqttHandler::handleTraffic() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string MqttHandler::getTopic(const Message* message, ssize_t fieldIndex, const string& suffix) {
|
string MqttHandler::getTopic(const Message* message, const string& suffix, const string& fieldName) {
|
||||||
ostringstream ret;
|
ostringstream ret;
|
||||||
for (size_t i = 0; i < m_topicStrs.size(); i++) {
|
for (size_t i = 0; i < m_topicStrs.size(); i++) {
|
||||||
ret << m_topicStrs[i];
|
ret << m_topicStrs[i];
|
||||||
@@ -565,8 +565,8 @@ string MqttHandler::getTopic(const Message* message, ssize_t fieldIndex, const s
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i < m_topicFields.size()) {
|
if (i < m_topicFields.size()) {
|
||||||
if (m_topicFields[i] == "fields" && fieldIndex >= 0) {
|
if (m_topicFields[i] == "field") {
|
||||||
ret << message->getFieldName(fieldIndex); // TODO skip ignored fields
|
ret << fieldName;
|
||||||
} else {
|
} else {
|
||||||
message->dumpField(m_topicFields[i], false, &ret);
|
message->dumpField(m_topicFields[i], false, &ret);
|
||||||
}
|
}
|
||||||
@@ -579,24 +579,33 @@ string MqttHandler::getTopic(const Message* message, ssize_t fieldIndex, const s
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MqttHandler::publishMessage(const Message* message, ostringstream* updates) {
|
void MqttHandler::publishMessage(const Message* message, ostringstream* updates) {
|
||||||
result_t result = message->decodeLastData(false, NULL, -1, 0, updates);
|
if (!m_publishByField) {
|
||||||
if (result != RESULT_OK) {
|
result_t result = message->decodeLastData(false, NULL, -1, 0, updates);
|
||||||
logOtherError("mqtt", "decode %s %s: %s", message->getCircuit().c_str(), message->getName().c_str(),
|
if (result != RESULT_OK) {
|
||||||
getResultCode(result));
|
logOtherError("mqtt", "decode %s %s: %s", message->getCircuit().c_str(), message->getName().c_str(),
|
||||||
|
getResultCode(result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
publishTopic(getTopic(message), updates->str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_publishByField) {
|
ssize_t index = 0;
|
||||||
ssize_t index = 0;
|
do {
|
||||||
istringstream input(updates->str());
|
string name = message->getFieldName(index);
|
||||||
string token;
|
if (name.empty()) {
|
||||||
while (getline(input, token, UI_FIELD_SEPARATOR)) {
|
break;
|
||||||
string topic = getTopic(message, index);
|
|
||||||
publishTopic(topic, token);
|
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
} else {
|
result_t result = message->decodeLastData(false, NULL, index, 0, updates);
|
||||||
publishTopic(getTopic(message), updates->str());
|
if (result != RESULT_OK) {
|
||||||
}
|
logOtherError("mqtt", "decode %s %s %s: %s", message->getCircuit().c_str(), message->getName().c_str(),
|
||||||
|
name.c_str(), getResultCode(result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
publishTopic(getTopic(message, "", name), updates->str());
|
||||||
|
updates->str("");
|
||||||
|
updates->clear();
|
||||||
|
index++;
|
||||||
|
} while (index < MAX_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttHandler::publishTopic(const string& topic, const string& data, bool retain) {
|
void MqttHandler::publishTopic(const string& topic, const string& data, bool retain) {
|
||||||
|
|||||||
@@ -97,11 +97,11 @@ class MqttHandler : public DataSink, public DataSource, public Thread {
|
|||||||
/**
|
/**
|
||||||
* Build the MQTT topic string for the @a Message.
|
* Build the MQTT topic string for the @a Message.
|
||||||
* @param message the @a Message to build the topic string for.
|
* @param message the @a Message to build the topic string for.
|
||||||
* @param fieldIndex the optional field index for the field column, or -1.
|
|
||||||
* @param suffix the optional suffix string to append.
|
* @param suffix the optional suffix string to append.
|
||||||
|
* @param fieldName the name of the singular field, or empty.
|
||||||
* @return the topic string.
|
* @return the topic string.
|
||||||
*/
|
*/
|
||||||
string getTopic(const Message* message, ssize_t fieldIndex = -1, const string& suffix = "");
|
string getTopic(const Message* message, const string& suffix = "", const string& fieldName = "");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare a @a Message and publish as topic.
|
* Prepare a @a Message and publish as topic.
|
||||||
|
|||||||
+20
-8
@@ -494,7 +494,7 @@ result_t SingleDataField::read(const SymbolString& data, size_t offset,
|
|||||||
if (offset + (remainder?1:m_length) > data.getDataSize()) {
|
if (offset + (remainder?1:m_length) > data.getDataSize()) {
|
||||||
return RESULT_ERR_INVALID_POS;
|
return RESULT_ERR_INVALID_POS;
|
||||||
}
|
}
|
||||||
if (isIgnored() || (fieldName != NULL && (m_name != fieldName || fieldIndex > 0))) {
|
if (isIgnored() || (fieldName != NULL && m_name != fieldName) || fieldIndex > 0) {
|
||||||
return RESULT_EMPTY;
|
return RESULT_EMPTY;
|
||||||
}
|
}
|
||||||
result_t res = m_dataType->readRawValue(offset, m_length, data, output);
|
result_t res = m_dataType->readRawValue(offset, m_length, data, output);
|
||||||
@@ -514,7 +514,7 @@ result_t SingleDataField::read(const SymbolString& data, size_t offset,
|
|||||||
if (offset + (remainder?1:m_length) > data.getDataSize()) {
|
if (offset + (remainder?1:m_length) > data.getDataSize()) {
|
||||||
return RESULT_ERR_INVALID_POS;
|
return RESULT_ERR_INVALID_POS;
|
||||||
}
|
}
|
||||||
if (isIgnored() || (fieldName != NULL && (m_name != fieldName || fieldIndex > 0))) {
|
if (isIgnored() || (fieldName != NULL && m_name != fieldName) || fieldIndex > 0) {
|
||||||
return RESULT_EMPTY;
|
return RESULT_EMPTY;
|
||||||
}
|
}
|
||||||
bool shortFormat = outputFormat & OF_SHORT;
|
bool shortFormat = outputFormat & OF_SHORT;
|
||||||
@@ -900,14 +900,26 @@ size_t DataFieldSet::getLength(PartType partType, size_t maxLength) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string DataFieldSet::getName(ssize_t fieldIndex) const {
|
string DataFieldSet::getName(ssize_t fieldIndex) const {
|
||||||
if (fieldIndex < 0) {
|
if (fieldIndex < (ssize_t)m_ignoredCount) {
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
if ((size_t)fieldIndex >= m_fields.size()) {
|
if ((size_t)fieldIndex + m_ignoredCount >= m_fields.size()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (m_uniqueNames) {
|
if (m_uniqueNames) {
|
||||||
return m_fields[fieldIndex]->getName(-1);
|
if (m_ignoredCount == 0) {
|
||||||
|
return m_fields[fieldIndex]->getName(-1);
|
||||||
|
}
|
||||||
|
ssize_t remain = fieldIndex;
|
||||||
|
for (const auto field : m_fields) {
|
||||||
|
if (field->isIgnored()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
remain--;
|
||||||
|
if (remain == 0) {
|
||||||
|
return field->getName(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ostringstream ostream;
|
ostringstream ostream;
|
||||||
ostream << static_cast<signed>(fieldIndex);
|
ostream << static_cast<signed>(fieldIndex);
|
||||||
@@ -973,7 +985,7 @@ result_t DataFieldSet::read(const SymbolString& data, size_t offset,
|
|||||||
if (result != RESULT_EMPTY) {
|
if (result != RESULT_EMPTY) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
if (findFieldIndex && fieldName == field->getName(-1)) {
|
if (findFieldIndex && !field->isIgnored() && (fieldName == NULL || fieldName == field->getName(-1))) {
|
||||||
if (fieldIndex == 0) {
|
if (fieldIndex == 0) {
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return RESULT_ERR_NOTFOUND;
|
return RESULT_ERR_NOTFOUND;
|
||||||
@@ -994,7 +1006,7 @@ result_t DataFieldSet::read(const SymbolString& data, size_t offset,
|
|||||||
result_t DataFieldSet::read(const SymbolString& data, size_t offset,
|
result_t DataFieldSet::read(const SymbolString& data, size_t offset,
|
||||||
bool leadingSeparator, const char* fieldName, ssize_t fieldIndex,
|
bool leadingSeparator, const char* fieldName, ssize_t fieldIndex,
|
||||||
OutputFormat outputFormat, ssize_t outputIndex, ostream* output) const {
|
OutputFormat outputFormat, ssize_t outputIndex, ostream* output) const {
|
||||||
bool previousFullByteOffset = true, found = false, findFieldIndex = fieldName != NULL && fieldIndex >= 0;
|
bool previousFullByteOffset = true, found = false, findFieldIndex = fieldIndex >= 0;
|
||||||
if (outputIndex < 0 && (!m_uniqueNames || ((outputFormat & OF_JSON) && !(outputFormat & OF_NAMES)))) {
|
if (outputIndex < 0 && (!m_uniqueNames || ((outputFormat & OF_JSON) && !(outputFormat & OF_NAMES)))) {
|
||||||
outputIndex = 0;
|
outputIndex = 0;
|
||||||
}
|
}
|
||||||
@@ -1020,7 +1032,7 @@ result_t DataFieldSet::read(const SymbolString& data, size_t offset,
|
|||||||
found = true;
|
found = true;
|
||||||
leadingSeparator = true;
|
leadingSeparator = true;
|
||||||
}
|
}
|
||||||
if (findFieldIndex && fieldName == field->getName(-1)) {
|
if (findFieldIndex && !field->isIgnored() && (fieldName == NULL || fieldName == field->getName(-1))) {
|
||||||
if (fieldIndex == 0) {
|
if (fieldIndex == 0) {
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return RESULT_ERR_NOTFOUND;
|
return RESULT_ERR_NOTFOUND;
|
||||||
|
|||||||
+17
-6
@@ -258,10 +258,10 @@ class DataField : public AttributedItem {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the specified field name.
|
* Get the specified field name.
|
||||||
* @param fieldIndex the index of the field, or -1 for this.
|
* @param fieldIndex the index of the field (excluding ignored fields), or -1 for this.
|
||||||
* @return the field name, or the index as string if not unique or not available.
|
* @return the field name, or the index as string is not unique or not available.
|
||||||
*/
|
*/
|
||||||
virtual string getName(ssize_t fieldIndex) const { return m_name; }
|
virtual string getName(ssize_t fieldIndex) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the field settings to the output.
|
* Dump the field settings to the output.
|
||||||
@@ -282,7 +282,7 @@ class DataField : public AttributedItem {
|
|||||||
* @param data the data @a SymbolString for reading binary data.
|
* @param data the data @a SymbolString for reading binary data.
|
||||||
* @param offset the additional offset to add for reading binary data.
|
* @param offset the additional offset to add for reading binary data.
|
||||||
* @param fieldName the name of the field to read, or NULL for the first field.
|
* @param fieldName the name of the field to read, or NULL for the first field.
|
||||||
* @param fieldIndex the optional index of the named field, or -1.
|
* @param fieldIndex the optional index of the field (either named or overall), or -1.
|
||||||
* @param output the variable in which to store the numeric value.
|
* @param output the variable in which to store the numeric value.
|
||||||
* @return @a RESULT_OK on success,
|
* @return @a RESULT_OK on success,
|
||||||
* or @a RESULT_EMPTY if the field was skipped (either if the partType does
|
* or @a RESULT_EMPTY if the field was skipped (either if the partType does
|
||||||
@@ -298,7 +298,7 @@ class DataField : public AttributedItem {
|
|||||||
* @param offset the additional offset to add for reading binary data.
|
* @param offset the additional offset to add for reading binary data.
|
||||||
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
||||||
* @param fieldName the optional name of a field to limit the output to.
|
* @param fieldName the optional name of a field to limit the output to.
|
||||||
* @param fieldIndex the optional index of the named field to limit the output to, or -1.
|
* @param fieldIndex the optional index of the field to limit the output to (either named or overall), or -1.
|
||||||
* @param outputFormat the @a OutputFormat options to use.
|
* @param outputFormat the @a OutputFormat options to use.
|
||||||
* @param outputIndex the optional index of the field when using an indexed output format, or -1.
|
* @param outputIndex the optional index of the field when using an indexed output format, or -1.
|
||||||
* @param output the @a ostream to append the formatted value to.
|
* @param output the @a ostream to append the formatted value to.
|
||||||
@@ -397,6 +397,11 @@ class SingleDataField : public DataField {
|
|||||||
*/
|
*/
|
||||||
bool hasFullByteOffset(bool after) const;
|
bool hasFullByteOffset(bool after) const;
|
||||||
|
|
||||||
|
// @copydoc
|
||||||
|
virtual string getName(ssize_t fieldIndex) const {
|
||||||
|
return isIgnored() || fieldIndex > 0 ? "" : m_name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the common prefix field settings to the output (name and part type).
|
* Dump the common prefix field settings to the output (name and part type).
|
||||||
* @param output the @a ostream to dump to.
|
* @param output the @a ostream to dump to.
|
||||||
@@ -404,7 +409,7 @@ class SingleDataField : public DataField {
|
|||||||
void dumpPrefix(ostream* output) const;
|
void dumpPrefix(ostream* output) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the common suffix field settings to the output (optiona unit and comment).
|
* Dump the common suffix field settings to the output (optional unit and comment).
|
||||||
* @param output the @a ostream to dump to.
|
* @param output the @a ostream to dump to.
|
||||||
*/
|
*/
|
||||||
void dumpSuffix(ostream* output) const;
|
void dumpSuffix(ostream* output) const;
|
||||||
@@ -596,9 +601,11 @@ class DataFieldSet : public DataField {
|
|||||||
DataFieldSet(const string& name, const vector<const SingleDataField*> fields)
|
DataFieldSet(const string& name, const vector<const SingleDataField*> fields)
|
||||||
: DataField(name), m_fields(fields) {
|
: DataField(name), m_fields(fields) {
|
||||||
bool uniqueNames = true;
|
bool uniqueNames = true;
|
||||||
|
size_t ignoredCount = 0;
|
||||||
map<string, string> names;
|
map<string, string> names;
|
||||||
for (auto field : fields) {
|
for (auto field : fields) {
|
||||||
if (field->isIgnored()) {
|
if (field->isIgnored()) {
|
||||||
|
ignoredCount++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
string name = field->getName(-1);
|
string name = field->getName(-1);
|
||||||
@@ -609,6 +616,7 @@ class DataFieldSet : public DataField {
|
|||||||
names[name] = name;
|
names[name] = name;
|
||||||
}
|
}
|
||||||
m_uniqueNames = uniqueNames;
|
m_uniqueNames = uniqueNames;
|
||||||
|
m_ignoredCount = ignoredCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -677,6 +685,9 @@ class DataFieldSet : public DataField {
|
|||||||
|
|
||||||
/** whether all fields have a unique name. */
|
/** whether all fields have a unique name. */
|
||||||
bool m_uniqueNames;
|
bool m_uniqueNames;
|
||||||
|
|
||||||
|
/** the number of ignored fields. */
|
||||||
|
size_t m_ignoredCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -741,7 +741,7 @@ result_t Message::decodeLastData(bool master, bool leadingSeparator, const char*
|
|||||||
ssize_t fieldIndex, OutputFormat outputFormat, ostream* output) const {
|
ssize_t fieldIndex, OutputFormat outputFormat, ostream* output) const {
|
||||||
result_t result;
|
result_t result;
|
||||||
if (master) {
|
if (master) {
|
||||||
result = m_data->read(m_lastMasterData, m_id.size() - 2, leadingSeparator, fieldName, fieldIndex,
|
result = m_data->read(m_lastMasterData, getIdLength(), leadingSeparator, fieldName, fieldIndex,
|
||||||
outputFormat, -1, output);
|
outputFormat, -1, output);
|
||||||
} else {
|
} else {
|
||||||
result = m_data->read(m_lastSlaveData, 0, leadingSeparator, fieldName, fieldIndex,
|
result = m_data->read(m_lastSlaveData, 0, leadingSeparator, fieldName, fieldIndex,
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ class Message : public AttributedItem {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the specified field name.
|
* Get the specified field name.
|
||||||
* @param fieldIndex the index of the field.
|
* @param fieldIndex the index of the field (excluding ignored fields).
|
||||||
* @return the field name, or the index as string if not unique or not available.
|
* @return the field name, or the index as string if not unique or not available.
|
||||||
*/
|
*/
|
||||||
virtual string getFieldName(ssize_t fieldIndex) const { return m_data->getName(fieldIndex); }
|
virtual string getFieldName(ssize_t fieldIndex) const { return m_data->getName(fieldIndex); }
|
||||||
@@ -456,10 +456,10 @@ class Message : public AttributedItem {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode the value from the last stored master or slave data.
|
* Decode the value from the last stored master or slave data.
|
||||||
* @param master true for deocding the master data, false for slave.
|
* @param master true for decoding the master data, false for slave.
|
||||||
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
||||||
* @param fieldName the optional name of a field to limit the output to.
|
* @param fieldName the optional name of a field to limit the output to.
|
||||||
* @param fieldIndex the optional index of the named field to limit the output to, or -1.
|
* @param fieldIndex the optional index of the field to limit the output to (either named or overall), or -1.
|
||||||
* @param outputFormat the @a OutputFormat options to use.
|
* @param outputFormat the @a OutputFormat options to use.
|
||||||
* @param output the @a ostream to append the formatted value to.
|
* @param output the @a ostream to append the formatted value to.
|
||||||
* @return @a RESULT_OK on success, or an error code.
|
* @return @a RESULT_OK on success, or an error code.
|
||||||
@@ -471,7 +471,7 @@ class Message : public AttributedItem {
|
|||||||
* Decode the value from the last stored master and slave data.
|
* Decode the value from the last stored master and slave data.
|
||||||
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
* @param leadingSeparator whether to prepend a separator before the formatted value.
|
||||||
* @param fieldName the optional name of a field to limit the output to.
|
* @param fieldName the optional name of a field to limit the output to.
|
||||||
* @param fieldIndex the optional index of the named field to limit the output to, or -1.
|
* @param fieldIndex the optional index of the field to limit the output to (either named or overall), or -1.
|
||||||
* @param outputFormat the @a OutputFormat options to use.
|
* @param outputFormat the @a OutputFormat options to use.
|
||||||
* @param output the @a ostream to append the formatted value to.
|
* @param output the @a ostream to append the formatted value to.
|
||||||
* @return @a RESULT_OK on success, or an error code.
|
* @return @a RESULT_OK on success, or an error code.
|
||||||
@@ -482,7 +482,7 @@ class Message : public AttributedItem {
|
|||||||
/**
|
/**
|
||||||
* Decode a particular numeric field value from the last stored data.
|
* Decode a particular numeric field value from the last stored data.
|
||||||
* @param fieldName the name of the field to decode, or NULL for the first field.
|
* @param fieldName the name of the field to decode, or NULL for the first field.
|
||||||
* @param fieldIndex the optional index of the named field, or -1.
|
* @param fieldIndex the optional index of the field (either named or overall), or -1.
|
||||||
* @param output the variable in which to store the value.
|
* @param output the variable in which to store the value.
|
||||||
* @return @a RESULT_OK on success, or an error code.
|
* @return @a RESULT_OK on success, or an error code.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -502,6 +502,10 @@ int main() {
|
|||||||
{"x,,temp;HEX:2", "18.004;13 14", "10fe07000401121314", "00", ""}, // reference to template and base type
|
{"x,,temp;HEX:2", "18.004;13 14", "10fe07000401121314", "00", ""}, // reference to template and base type
|
||||||
{"x,,temp;HEX:2", "temp=18.004;=13 14", "10fe07000401121314", "00", "v"}, // reference to template and base type
|
{"x,,temp;HEX:2", "temp=18.004;=13 14", "10fe07000401121314", "00", "v"}, // reference to template and base type
|
||||||
{"x,,temp:degrees;HEX:2", "degrees=18.004;=13 14", "10fe07000401121314", "00", "v"}, // reference to template and base type
|
{"x,,temp:degrees;HEX:2", "degrees=18.004;=13 14", "10fe07000401121314", "00", "v"}, // reference to template and base type
|
||||||
|
{"x,,uch;UCH;IGN;UCH", "41", "1008ffff00", "0426272829", "wi2"},
|
||||||
|
{"x,,uch,,,,x,,uch,,,,x,,ign,,,,x,,uch,,,,", "41", "1008ffff00", "0426272829", "wi2"},
|
||||||
|
{"x,,uch,,,,y,,uch,,,,x,,ign,,,,x,,uch,,,,", "41", "1008ffff00", "0426272829", "wIi1"},
|
||||||
|
{"x,,uch,,,,y,,uch,,,,z,,ign,,,,x,,uch,,,,", "41", "1008ffff00", "0426272829", "wIi1"},
|
||||||
};
|
};
|
||||||
DataFieldTemplates* templates = new DataFieldTemplates();
|
DataFieldTemplates* templates = new DataFieldTemplates();
|
||||||
unsigned int lineNo = 0;
|
unsigned int lineNo = 0;
|
||||||
@@ -535,6 +539,11 @@ int main() {
|
|||||||
bool failedReadMatch = flags.find('R') != string::npos;
|
bool failedReadMatch = flags.find('R') != string::npos;
|
||||||
bool failedWrite = flags.find('w') != string::npos;
|
bool failedWrite = flags.find('w') != string::npos;
|
||||||
bool failedWriteMatch = flags.find('W') != string::npos;
|
bool failedWriteMatch = flags.find('W') != string::npos;
|
||||||
|
const char* findName = flags.find('I') == string::npos ? NULL : "x";
|
||||||
|
ssize_t findIndex = -1;
|
||||||
|
if (flags.find('i') != string::npos) {
|
||||||
|
findIndex = parseSignedInt(flags.substr(flags.find('i')+1).c_str(), 10, 0, 9, &result);
|
||||||
|
}
|
||||||
OutputFormat verbosity = 0;
|
OutputFormat verbosity = 0;
|
||||||
if (flags.find("v") != string::npos) {
|
if (flags.find("v") != string::npos) {
|
||||||
verbosity |= OF_NAMES;
|
verbosity |= OF_NAMES;
|
||||||
@@ -572,7 +581,7 @@ int main() {
|
|||||||
dummystr.str("#");
|
dummystr.str("#");
|
||||||
result = reader.readLineFromStream(__FILE__, false, &dummystr, &lineNo, &row, &errorDescription, NULL, NULL);
|
result = reader.readLineFromStream(__FILE__, false, &dummystr, &lineNo, &row, &errorDescription, NULL, NULL);
|
||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
cout << "\"" << check[0] << "\": reader header error: " << getResultCode(result) << ", " << errorDescription
|
cout << "\"" << check[0] << "\": read header error: " << getResultCode(result) << ", " << errorDescription
|
||||||
<< endl;
|
<< endl;
|
||||||
error = true;
|
error = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -616,9 +625,9 @@ int main() {
|
|||||||
cout << " parse \"" << sstr.getStr().substr(0, 2) << "\" error: " << getResultCode(result) << endl;
|
cout << " parse \"" << sstr.getStr().substr(0, 2) << "\" error: " << getResultCode(result) << endl;
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
result = fields->read(mstr, 0, false, NULL, -1, verbosity|(numeric?OF_NUMERIC:0), -1, &output);
|
result = fields->read(mstr, 0, false, findName, findIndex, verbosity|(numeric?OF_NUMERIC:0), -1, &output);
|
||||||
if (result >= RESULT_OK) {
|
if (result >= RESULT_OK) {
|
||||||
result = fields->read(sstr, 0, !output.str().empty(), NULL, -1, verbosity|(numeric?OF_NUMERIC:0), -1, &output);
|
result = fields->read(sstr, 0, !output.str().empty(), findName, findIndex, verbosity|(numeric?OF_NUMERIC:0), -1, &output);
|
||||||
}
|
}
|
||||||
if (failedRead) {
|
if (failedRead) {
|
||||||
if (result >= RESULT_OK) {
|
if (result >= RESULT_OK) {
|
||||||
|
|||||||
Reference in New Issue
Block a user