increased max field lengths for STR and HEX to 31, renamed a dataType_s field, added dynamic max field length to DataField::create(), use named objects for JSON fields instead of array (or numbered if field names are not unique)

This commit is contained in:
john30
2015-12-27 22:41:50 +01:00
parent 2e2cf204e2
commit 81f490d74f
3 changed files with 79 additions and 51 deletions
+33 -28
View File
@@ -27,7 +27,7 @@
using namespace std; using namespace std;
static const dataType_t stringDataType = { static const dataType_t stringDataType = {
"STR",MAX_POS*8,bt_str, ADJ, ' ', 1, MAX_POS, 0 // >= 1 byte character string filled up with space "STR",MAX_LEN*8,bt_str, ADJ, ' ', 1, 0, 0 // >= 1 byte character string filled up with space
}; };
static const dataType_t pinDataType = { static const dataType_t pinDataType = {
@@ -40,9 +40,9 @@ static const dataType_t uchDataType = {
/** the known data field types. */ /** the known data field types. */
static const dataType_t dataTypes[] = { static const dataType_t dataTypes[] = {
{"IGN",MAX_POS*8,bt_str, IGN|ADJ, 0, 1, MAX_POS, 0}, // >= 1 byte ignored data {"IGN",MAX_LEN*8,bt_str, IGN|ADJ, 0, 1, 0, 0}, // >= 1 byte ignored data
stringDataType, stringDataType,
{"HEX",MAX_POS*8,bt_hexstr, ADJ, 0, 2, 47, 0}, // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d {"HEX",MAX_LEN*8,bt_hexstr, ADJ, 0, 2, 47, 0}, // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d
{"BDA", 32, bt_dat, BCD, 0xff, 10, 10, 0}, // date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is weekday Mon=0x00 - Sun=0x06, replacement 0xff) {"BDA", 32, bt_dat, BCD, 0xff, 10, 10, 0}, // date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is weekday Mon=0x00 - Sun=0x06, replacement 0xff)
{"BDA", 24, bt_dat, BCD, 0xff, 10, 10, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99, replacement 0xff) {"BDA", 24, bt_dat, BCD, 0xff, 10, 10, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99, replacement 0xff)
{"HDA", 32, bt_dat, 0, 0xff, 10, 10, 0}, // date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x1f,0x0c,WW,0x63, WW is weekday Mon=0x01 - Sun=0x07, replacement 0xff) {"HDA", 32, bt_dat, 0, 0xff, 10, 10, 0}, // date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x1f,0x0c,WW,0x63, WW is weekday Mon=0x01 - Sun=0x07, replacement 0xff)
@@ -190,7 +190,8 @@ result_t DataField::create(vector<string>::iterator& it,
const vector<string>::iterator end, const vector<string>::iterator end,
DataFieldTemplates* templates, DataField*& returnField, DataFieldTemplates* templates, DataField*& returnField,
const bool isWriteMessage, const bool isWriteMessage,
const bool isTemplate, const bool isBroadcastOrMasterDestination) const bool isTemplate, const bool isBroadcastOrMasterDestination,
const unsigned char maxFieldLength)
{ {
vector<SingleDataField*> fields; vector<SingleDataField*> fields;
string firstName, firstComment; string firstName, firstComment;
@@ -312,7 +313,7 @@ result_t DataField::create(vector<string>::iterator& it,
if (pos == string::npos) if (pos == string::npos)
length = 0; // no length specified length = 0; // no length specified
else { else {
length = (unsigned char)parseInt(token.substr(pos+1).c_str(), 10, 1, MAX_POS, result); length = (unsigned char)parseInt(token.substr(pos+1).c_str(), 10, 1, maxFieldLength, result);
if (result != RESULT_OK) if (result != RESULT_OK)
break; break;
} }
@@ -364,7 +365,7 @@ result_t SingleDataField::create(const char* typeNameStr, const unsigned char le
const PartType partType, int divisor, map<unsigned int, string> values, const PartType partType, int divisor, map<unsigned int, string> values,
SingleDataField* &returnField) SingleDataField* &returnField)
{ {
for (size_t i = 0; i < sizeof(dataTypes) / sizeof(dataType_t); i++) { for (size_t i = 0; i < sizeof(dataTypes) / sizeof(dataType_t); i++) { // TODO use a map
const dataType_t* dataType = &dataTypes[i]; const dataType_t* dataType = &dataTypes[i];
if (strcasecmp(typeNameStr, dataType->name) == 0) { if (strcasecmp(typeNameStr, dataType->name) == 0) {
unsigned char bitCount = dataType->bitCount; unsigned char bitCount = dataType->bitCount;
@@ -403,7 +404,7 @@ result_t SingleDataField::create(const char* typeNameStr, const unsigned char le
case bt_num: case bt_num:
if (values.empty() && (dataType->flags & DAY) != 0) { if (values.empty() && (dataType->flags & DAY) != 0) {
for (unsigned int i = 0; i < sizeof(dayNames) / sizeof(dayNames[0]); i++) for (unsigned int i = 0; i < sizeof(dayNames) / sizeof(dayNames[0]); i++)
values[dataType->minValueOrLength + i] = dayNames[i]; values[dataType->minValue + i] = dayNames[i];
} }
if (values.empty() || (dataType->flags & LST) == 0) { if (values.empty() || (dataType->flags & LST) == 0) {
if (divisor == 0) if (divisor == 0)
@@ -432,8 +433,7 @@ result_t SingleDataField::create(const char* typeNameStr, const unsigned char le
returnField = new NumberDataField(name, comment, unit, *dataType, partType, byteCount, bitCount, divisor); returnField = new NumberDataField(name, comment, unit, *dataType, partType, byteCount, bitCount, divisor);
return RESULT_OK; return RESULT_OK;
} }
if (values.begin()->first < dataType->minValueOrLength if (values.begin()->first < dataType->minValue || values.rbegin()->first > dataType->maxValue)
|| values.rbegin()->first > dataType->maxValueOrLength)
return RESULT_ERR_OUT_OF_RANGE; return RESULT_ERR_OUT_OF_RANGE;
if (divisor != 0) if (divisor != 0)
@@ -484,13 +484,12 @@ result_t SingleDataField::read(const PartType partType,
} }
return RESULT_EMPTY; return RESULT_EMPTY;
} }
return readRawValue(data, offset, output); return readRawValue(data, offset, output);
} }
result_t SingleDataField::read(const PartType partType, result_t SingleDataField::read(const PartType partType,
SymbolString& data, unsigned char offset, SymbolString& data, unsigned char offset,
ostringstream& output, OutputFormat outputFormat, ostringstream& output, OutputFormat outputFormat, signed char outputIndex,
bool leadingSeparator, const char* fieldName, signed char fieldIndex) bool leadingSeparator, const char* fieldName, signed char fieldIndex)
{ {
if (partType != m_partType) if (partType != m_partType)
@@ -514,17 +513,19 @@ result_t SingleDataField::read(const PartType partType,
return RESULT_EMPTY; return RESULT_EMPTY;
} }
if (leadingSeparator) { if (outputFormat & OF_JSON) {
if (outputFormat & OF_JSON) if (leadingSeparator)
output << ","; output << ",";
if (outputIndex>=0 || m_name.empty())
output << "\n \"" << static_cast<signed int>(outputIndex<0?0:outputIndex) << "\": {\"name\": \"" << m_name << "\"" << ", \"value\": ";
else else
output << "\n \"" << m_name << "\": {\"value\": ";
} else {
if (leadingSeparator)
output << UI_FIELD_SEPARATOR; output << UI_FIELD_SEPARATOR;
} if (outputFormat & OF_VERBOSE)
if (outputFormat & OF_JSON)
output << "\n {\"name\": \"" << m_name << "\"" << ", \"value\": ";
else if (outputFormat & OF_VERBOSE)
output << m_name << "="; output << m_name << "=";
}
result_t result = readSymbols(data, offset, output, outputFormat); result_t result = readSymbols(data, offset, output, outputFormat);
if (result != RESULT_OK) if (result != RESULT_OK)
@@ -626,7 +627,6 @@ result_t StringDataField::readSymbols(SymbolString& input, const unsigned char b
if (baseOffset + m_length > input.size()) { if (baseOffset + m_length > input.size()) {
return RESULT_ERR_INVALID_POS; return RESULT_ERR_INVALID_POS;
} }
if ((m_dataType.flags & REV) != 0) { // reverted binary representation (most significant byte first) if ((m_dataType.flags & REV) != 0) { // reverted binary representation (most significant byte first)
start = m_length - 1; start = m_length - 1;
incr = -1; incr = -1;
@@ -1158,13 +1158,13 @@ result_t NumberDataField::writeSymbols(istringstream& input,
if ((m_dataType.flags & SIG) != 0) { // signed value if ((m_dataType.flags & SIG) != 0) { // signed value
if ((value & (1 << (m_bitCount - 1))) != 0) { // negative signed value if ((value & (1 << (m_bitCount - 1))) != 0) { // negative signed value
if (value < m_dataType.minValueOrLength) if (value < m_dataType.minValue)
return RESULT_ERR_OUT_OF_RANGE; // value out of range return RESULT_ERR_OUT_OF_RANGE; // value out of range
} }
else if (value > m_dataType.maxValueOrLength) else if (value > m_dataType.maxValue)
return RESULT_ERR_OUT_OF_RANGE; // value out of range return RESULT_ERR_OUT_OF_RANGE; // value out of range
} }
else if (value < m_dataType.minValueOrLength || value > m_dataType.maxValueOrLength) else if (value < m_dataType.minValue || value > m_dataType.maxValue)
return RESULT_ERR_OUT_OF_RANGE; // value out of range return RESULT_ERR_OUT_OF_RANGE; // value out of range
} }
@@ -1194,8 +1194,7 @@ result_t ValueListDataField::derive(string name, string comment,
return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field
if (!values.empty()) { if (!values.empty()) {
if (values.begin()->first < m_dataType.minValueOrLength if (values.begin()->first < m_dataType.minValue || values.rbegin()->first > m_dataType.maxValue)
|| values.rbegin()->first > m_dataType.maxValueOrLength)
return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field
} }
else else
@@ -1437,19 +1436,23 @@ result_t DataFieldSet::read(const PartType partType,
result_t DataFieldSet::read(const PartType partType, result_t DataFieldSet::read(const PartType partType,
SymbolString& data, unsigned char offset, SymbolString& data, unsigned char offset,
ostringstream& output, OutputFormat outputFormat, ostringstream& output, OutputFormat outputFormat, signed char outputIndex,
bool leadingSeparator, const char* fieldName, signed char fieldIndex) bool leadingSeparator, const char* fieldName, signed char fieldIndex)
{ {
bool previousFullByteOffset = true, found = false, findFieldIndex = fieldName != NULL && fieldIndex >= 0; bool previousFullByteOffset = true, found = false, findFieldIndex = fieldName != NULL && fieldIndex >= 0;
if (!m_uniqueNames && outputIndex<0)
outputIndex = 0;
for (vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) { for (vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) {
SingleDataField* field = *it; SingleDataField* field = *it;
if (partType != pt_any && field->getPartType() != partType) if (partType != pt_any && field->getPartType() != partType) {
if (outputIndex>=0 && !field->isIgnored())
outputIndex++;
continue; continue;
}
if (!previousFullByteOffset && !field->hasFullByteOffset(false)) if (!previousFullByteOffset && !field->hasFullByteOffset(false))
offset--; offset--;
result_t result = field->read(partType, data, offset, output, outputFormat, leadingSeparator, fieldName, fieldIndex); result_t result = field->read(partType, data, offset, output, outputFormat, outputIndex, leadingSeparator, fieldName, fieldIndex);
if (result < RESULT_OK) if (result < RESULT_OK)
return result; return result;
@@ -1468,6 +1471,8 @@ result_t DataFieldSet::read(const PartType partType,
} }
fieldIndex--; fieldIndex--;
} }
if (outputIndex>=0 && !field->isIgnored())
outputIndex++;
} }
if (!found) { if (!found) {
+30 -8
View File
@@ -114,15 +114,18 @@ typedef struct dataType_s {
const unsigned char bitCount; //!< number of bits (maximum length if #ADJ flag is set, must be multiple of 8 with flag #BCD) const unsigned char bitCount; //!< number of bits (maximum length if #ADJ flag is set, must be multiple of 8 with flag #BCD)
const BaseType type; //!< base data type const BaseType type; //!< base data type
const unsigned short flags; //!< flags (like #BCD) const unsigned short flags; //!< flags (like #BCD)
const unsigned int replacement; //!< replacement value (fill-up value for #bt_str / #bt_hexstr, no replacement if equal to #minValueOrLength for #bt_num) const unsigned int replacement; //!< replacement value (fill-up value for #bt_str / #bt_hexstr, no replacement if equal to #minValue for #bt_num)
const unsigned int minValueOrLength; //!< minimum binary value (minimum length of string for @a StringDataField) const unsigned int minValue; //!< minimum binary value (ignored for @a StringDataField)
const unsigned int maxValueOrLength; //!< maximum binary value (maximum length of string for @a StringDataField) const unsigned int maxValue; //!< maximum binary value (ignored for @a StringDataField)
const short divisorOrFirstBit; //!< #bt_num: divisor (negative for reciprocal) or offset to first bit (if (#bitCount%8)!=0) const short divisorOrFirstBit; //!< #bt_num: divisor (negative for reciprocal) or offset to first bit (if (#bitCount%8)!=0)
} dataType_t; } dataType_t;
/** the maximum allowed position within master or slave data. */ /** the maximum allowed position within master or slave data. */
#define MAX_POS 24 #define MAX_POS 24
/** the maximum allowed field length. */
#define MAX_LEN 31
/** /**
* Parse an unsigned int value. * Parse an unsigned int value.
* @param str the string to parse. * @param str the string to parse.
@@ -198,13 +201,15 @@ public:
* @param isWriteMessage whether the field is part of a write message (default false). * @param isWriteMessage whether the field is part of a write message (default false).
* @param isTemplate true for creating a template @a DataField. * @param isTemplate true for creating a template @a DataField.
* @param isBroadcastOrMasterDestination true if the destination bus address is @a BRODCAST or a master address. * @param isBroadcastOrMasterDestination true if the destination bus address is @a BRODCAST or a master address.
* @param maxFieldLength the maximum allowed length of a single field (default @a MAX_POS).
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success, or an error code.
* Note: the caller needs to free the created instance. * Note: the caller needs to free the created instance.
*/ */
static result_t create(vector<string>::iterator& it, const vector<string>::iterator end, static result_t create(vector<string>::iterator& it, const vector<string>::iterator end,
DataFieldTemplates* templates, DataField*& returnField, DataFieldTemplates* templates, DataField*& returnField,
const bool isWriteMessage, const bool isWriteMessage,
const bool isTemplate, const bool isBroadcastOrMasterDestination); const bool isTemplate, const bool isBroadcastOrMasterDestination,
const unsigned char maxFieldLength=MAX_POS);
/** /**
* Dump the @a string optionally embedded in @a TEXT_SEPARATOR to the output. * Dump the @a string optionally embedded in @a TEXT_SEPARATOR to the output.
@@ -287,6 +292,7 @@ public:
* @param offset the additional offset to add for reading binary data. * @param offset the additional offset to add for reading binary data.
* @param output the @a ostringstream to append the formatted value to. * @param output the @a ostringstream to append the formatted value to.
* @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 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 named field to limit the output to, or -1.
@@ -296,7 +302,7 @@ public:
*/ */
virtual result_t read(const PartType partType, virtual result_t read(const PartType partType,
SymbolString& data, unsigned char offset, SymbolString& data, unsigned char offset,
ostringstream& output, OutputFormat outputFormat, ostringstream& output, OutputFormat outputFormat, signed char outputIndex=-1,
bool leadingSeparator=false, const char* fieldName=NULL, signed char fieldIndex=-1) = 0; bool leadingSeparator=false, const char* fieldName=NULL, signed char fieldIndex=-1) = 0;
/** /**
@@ -414,7 +420,7 @@ public:
// @copydoc // @copydoc
virtual result_t read(const PartType partType, virtual result_t read(const PartType partType,
SymbolString& data, unsigned char offset, SymbolString& data, unsigned char offset,
ostringstream& output, OutputFormat outputFormat, ostringstream& output, OutputFormat outputFormat, signed char outputIndex=-1,
bool leadingSeparator=false, const char* fieldName=NULL, signed char fieldIndex=-1); bool leadingSeparator=false, const char* fieldName=NULL, signed char fieldIndex=-1);
// @copydoc // @copydoc
@@ -738,7 +744,20 @@ public:
DataFieldSet(const string name, const string comment, DataFieldSet(const string name, const string comment,
const vector<SingleDataField*> fields) const vector<SingleDataField*> fields)
: DataField(name, comment), : DataField(name, comment),
m_fields(fields) {} m_fields(fields)
{
bool uniqueNames = true;
map<string, string> names;
for (vector<SingleDataField*>::const_iterator it=fields.begin(); it!=fields.end(); it++) {
string name = (*it)->getName();
if (name.empty() || names.find(name)!=names.end()) {
uniqueNames = false;
break;
}
names[name] = name;
}
m_uniqueNames = uniqueNames;
}
/** /**
* Destructor. * Destructor.
@@ -791,7 +810,7 @@ public:
// @copydoc // @copydoc
virtual result_t read(const PartType partType, virtual result_t read(const PartType partType,
SymbolString& data, unsigned char offset, SymbolString& data, unsigned char offset,
ostringstream& output, OutputFormat outputFormat, ostringstream& output, OutputFormat outputFormat, signed char outputIndex=-1,
bool leadingSeparator=false, const char* fieldName=NULL, signed char fieldIndex=-1); bool leadingSeparator=false, const char* fieldName=NULL, signed char fieldIndex=-1);
// @copydoc // @copydoc
@@ -807,6 +826,9 @@ private:
/** the @a vector of @a SingleDataField instances part of this set. */ /** the @a vector of @a SingleDataField instances part of this set. */
vector<SingleDataField*> m_fields; vector<SingleDataField*> m_fields;
/** whether all fields have a unique name. */
bool m_uniqueNames;
}; };
+9 -8
View File
@@ -119,10 +119,10 @@ int main()
{"x,,tth,2", "", "", "", "c"}, {"x,,tth,2", "", "", "", "c"},
{"x,,bdy", "Mon", "10fe07000300", "00", ""}, {"x,,bdy", "Mon", "10fe07000300", "00", ""},
{"x,,bdy", "Sun", "10fe07000306", "00", ""}, {"x,,bdy", "Sun", "10fe07000306", "00", ""},
{"x,,bdy", "", "10fe07000308", "00", "rw"}, {"x,,bdy", "8", "10fe07000308", "00", "w"},
{"x,,hdy", "Mon", "10fe07000301", "00", ""}, {"x,,hdy", "Mon", "10fe07000301", "00", ""},
{"x,,hdy", "Sun", "10fe07000307", "00", ""}, {"x,,hdy", "Sun", "10fe07000307", "00", ""},
{"x,,hdy", "", "10fe07000308", "00", "rw"}, {"x,,hdy", "8", "10fe07000308", "00", "w"},
{"x,,bcd", "26", "10feffff0126", "00", ""}, {"x,,bcd", "26", "10feffff0126", "00", ""},
{"x,,bcd", "0", "10feffff0100", "00", ""}, {"x,,bcd", "0", "10feffff0100", "00", ""},
{"x,,bcd", "99", "10feffff0199", "00", ""}, {"x,,bcd", "99", "10feffff0199", "00", ""},
@@ -273,10 +273,11 @@ int main()
{"x,,bi3:2,0=off;1=on","1", "10feffff0108", "00", "n"}, {"x,,bi3:2,0=off;1=on","1", "10feffff0108", "00", "n"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=on ja/nein [Wahrheitswert]", "10feffff0108", "00", "v"}, {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=on ja/nein [Wahrheitswert]", "10feffff0108", "00", "v"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=1 ja/nein [Wahrheitswert]", "10feffff0108", "00", "vn"}, {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=1 ja/nein [Wahrheitswert]", "10feffff0108", "00", "vn"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n {\"name\": \"x\", \"value\": \"on\"}", "10feffff0108", "00", "j"}, {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": \"on\"}", "10feffff0108", "00", "j"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n {\"name\": \"x\", \"value\": \"on\", \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vj"}, {",,bi3:2,0=off;1=on,ja/nein,Wahrheitswert", "\n \"0\": {\"name\": \"\", \"value\": \"on\"}", "10feffff0108", "00", "j"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n {\"name\": \"x\", \"value\": 1}", "10feffff0108", "00", "nj"}, {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": \"on\", \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vj"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n {\"name\": \"x\", \"value\": 1, \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vnj"}, {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": 1}", "10feffff0108", "00", "nj"},
{"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": 1, \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vnj"},
{"x,,uch,1=test;2=high;3=off;0x10=on","on","10feffff0110", "00", ""}, {"x,,uch,1=test;2=high;3=off;0x10=on","on","10feffff0110", "00", ""},
{"x,s,uch","3","1050ffff00", "0103", ""}, {"x,s,uch","3","1050ffff00", "0103", ""},
{"x,,d2b,,°C,Aussentemperatur","x=18.004 °C [Aussentemperatur]","10fe0700090112", "00", "v"}, {"x,,d2b,,°C,Aussentemperatur","x=18.004 °C [Aussentemperatur]","10fe0700090112", "00", "v"},
@@ -383,9 +384,9 @@ int main()
if (result != RESULT_OK) { if (result != RESULT_OK) {
cout << " parse \"" << sstr.getDataStr(true, false).substr(0, 2) << "\" error: " << getResultCode(result) << endl; cout << " parse \"" << sstr.getDataStr(true, false).substr(0, 2) << "\" error: " << getResultCode(result) << endl;
} }
result = fields->read(pt_masterData, mstr, 0, output, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|(json?OF_JSON:0), false); result = fields->read(pt_masterData, mstr, 0, output, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|(json?OF_JSON:0), -1, false);
if (result >= RESULT_OK) { if (result >= RESULT_OK) {
result = fields->read(pt_slaveData, sstr, 0, output, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|(json?OF_JSON:0), !output.str().empty()); result = fields->read(pt_slaveData, sstr, 0, output, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|(json?OF_JSON:0), -1, !output.str().empty());
} }
if (failedRead) if (failedRead)
if (result >= RESULT_OK) if (result >= RESULT_OK)