reduced DataField::read() and ::write() to a single SymbolString, adjusted message accordingly

This commit is contained in:
john30
2014-12-06 16:44:52 +01:00
parent b831df5eca
commit 382da6215c
6 changed files with 99 additions and 118 deletions
+48 -58
View File
@@ -357,35 +357,39 @@ void SingleDataField::dump(ostream& output)
output << FIELD_SEPARATOR << m_dataType.name; output << FIELD_SEPARATOR << m_dataType.name;
} }
result_t SingleDataField::read(SymbolString& masterData, unsigned char masterOffset, result_t SingleDataField::read(const PartType partType,
SymbolString& slaveData, unsigned char slaveOffset, SymbolString& data, unsigned char offset,
ostringstream& output, ostringstream& output, bool leadingSeparator,
bool verbose, char separator) bool verbose, char separator)
{ {
SymbolString& input = m_partType != pt_slaveData ? masterData : slaveData; if (partType != m_partType)
unsigned char offset; return RESULT_OK;
switch (m_partType) switch (m_partType)
{ {
case pt_masterData: case pt_masterData:
offset = 5 + masterOffset; // skip QQ ZZ PB SB NN offset += 5; // skip QQ ZZ PB SB NN
break; break;
case pt_slaveData: case pt_slaveData:
offset = 1 + slaveOffset; // skip NN offset += 1; // skip NN
break; break;
default: default:
return RESULT_ERR_INVALID_PART; return RESULT_ERR_INVALID_PART;
} }
if (isIgnored() == true) { if (isIgnored() == true) {
if (offset + m_length > input.size()) { if (offset + m_length > data.size()) {
return RESULT_ERR_INVALID_POS; return RESULT_ERR_INVALID_POS;
} }
return RESULT_OK; return RESULT_OK;
} }
if (leadingSeparator == true)
output << separator;
if (verbose == true) if (verbose == true)
output << m_name << "="; output << m_name << "=";
result_t result = readSymbols(input, offset, output); result_t result = readSymbols(data, offset, output);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
@@ -398,24 +402,24 @@ result_t SingleDataField::read(SymbolString& masterData, unsigned char masterOff
} }
result_t SingleDataField::write(istringstream& input, result_t SingleDataField::write(istringstream& input,
SymbolString& masterData, unsigned char masterOffset, const PartType partType, SymbolString& data,
SymbolString& slaveData, unsigned char slaveOffset, unsigned char offset, char separator)
char separator)
{ {
SymbolString& output = m_partType != pt_slaveData ? masterData : slaveData; if (partType != m_partType)
unsigned char offset; return RESULT_OK;
switch (m_partType) switch (m_partType)
{ {
case pt_masterData: case pt_masterData:
offset = 5 + masterOffset; // skip QQ ZZ PB SB NN offset += 5; // skip QQ ZZ PB SB NN
break; break;
case pt_slaveData: case pt_slaveData:
offset = 1 + slaveOffset; // skip NN offset += 1; // skip NN
break; break;
default: default:
return RESULT_ERR_INVALID_PART; return RESULT_ERR_INVALID_PART;
} }
return writeSymbols(input, offset, output); return writeSymbols(input, offset, data);
} }
@@ -1050,41 +1054,32 @@ void DataFieldSet::dump(ostream& output)
(*it)->dump(output); (*it)->dump(output);
} }
result_t DataFieldSet::read(SymbolString& masterData, unsigned char masterOffset, result_t DataFieldSet::read(const PartType partType,
SymbolString& slaveData, unsigned char slaveOffset, SymbolString& data, unsigned char offset,
ostringstream& output, bool verbose, char separator) ostringstream& output, bool leadingSeparator,
bool verbose, char separator)
{ {
if (verbose) if (verbose)
output << m_name << "={ "; output << m_name << "={ ";
bool first = true; bool previousFullByteOffset = true;
unsigned char offsets[3];
memset(offsets, 0, sizeof(offsets));
offsets[pt_masterData] = masterOffset;
offsets[pt_slaveData] = slaveOffset;
bool previousFullByteOffset[] = { true, true, true };
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;
bool ignored = field->isIgnored(); if (partType != pt_any && field->getPartType() != partType)
PartType partType = field->getPartType(); continue;
if (ignored == false) { if (previousFullByteOffset == false && field->hasFullByteOffset(false) == false)
if (first) offset--;
first = false;
else
output << separator;
}
if (previousFullByteOffset[partType] == false && field->hasFullByteOffset(false) == false)
offsets[partType]--;
result_t result = field->read(masterData, offsets[pt_masterData], slaveData, offsets[pt_slaveData], output, verbose, separator); //cout<<"read "<<field->getName().c_str()<<" in part "<<static_cast<unsigned>(field->getPartType())<<" offset "<<static_cast<unsigned>(offsets[field->getPartType()])<<endl;
result_t result = field->read(partType, data, offset, output, leadingSeparator, verbose, separator);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
offsets[partType] += field->getLength(partType); offset += field->getLength(partType);
previousFullByteOffset = field->hasFullByteOffset(true);
previousFullByteOffset[partType] = field->hasFullByteOffset(true); leadingSeparator |= field->isIgnored() == false;
} }
if (verbose == true) { if (verbose == true) {
@@ -1097,43 +1092,38 @@ result_t DataFieldSet::read(SymbolString& masterData, unsigned char masterOffset
} }
result_t DataFieldSet::write(istringstream& input, result_t DataFieldSet::write(istringstream& input,
SymbolString& masterData, unsigned char masterOffset, const PartType partType, SymbolString& data,
SymbolString& slaveData, unsigned char slaveOffset, unsigned char offset, char separator)
char separator)
{ {
string token; string token;
unsigned char offsets[3]; bool previousFullByteOffset = true;
memset(offsets, 0, sizeof(offsets));
offsets[pt_masterData] = masterOffset;
offsets[pt_slaveData] = slaveOffset;
bool previousFullByteOffset[] = { true, true, true };
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;
bool ignored = field->isIgnored(); if (partType != pt_any && field->getPartType() != partType)
PartType partType = field->getPartType(); continue;
if (previousFullByteOffset[partType] == false && field->hasFullByteOffset(false) == false) if (previousFullByteOffset == false && field->hasFullByteOffset(false) == false)
offsets[partType]--; offset--;
result_t result; result_t result;
if (m_fields.size() > 1) { if (m_fields.size() > 1) {
if (ignored == true) if (field->isIgnored() == true)
token.clear(); token.clear();
else if (getline(input, token, separator) == 0) else if (getline(input, token, separator) == 0)
return RESULT_ERR_EOF; // incomplete token.clear();
istringstream single(token); istringstream single(token);
result = (*it)->write(single, masterData, offsets[pt_masterData], slaveData, offsets[pt_slaveData], separator); result = (*it)->write(single, partType, data, offset, separator);
} }
else else
result = (*it)->write(input, masterData, offsets[pt_masterData], slaveData, offsets[pt_slaveData], separator); result = (*it)->write(input, partType, data, offset, separator);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
offsets[partType] += field->getLength(partType); offset += field->getLength(partType);
previousFullByteOffset[partType] = field->hasFullByteOffset(true); previousFullByteOffset = field->hasFullByteOffset(true);
} }
return RESULT_OK; return RESULT_OK;
+28 -48
View File
@@ -164,33 +164,33 @@ public:
*/ */
virtual void dump(ostream& output) = 0; virtual void dump(ostream& output) = 0;
/** /**
* @brief Reads the value from the master or slave @a SymbolString. * @brief Reads the value from the @a SymbolString.
* @param masterData the unescaped master data @a SymbolString for reading binary data. * @param partType the @a PartType of the data.
* @param masterOffset the additional offset to add for reading the master data. * @param data the unescaped data @a SymbolString for reading binary data.
* @param slaveData the unescaped slave data @a SymbolString for reading binary data. * @param offset the additional offset to add for reading binary data.
* @param slaveOffset the additional offset to add for reading the slave data.
* @param output the @a ostringstream to append the formatted value to. * @param output the @a ostringstream to append the formatted value to.
* @param leadingSeparator whether to prepend a separator before the formatted value.
* @param verbose whether to prepend the name, append the unit (if present), and append * @param verbose whether to prepend the name, append the unit (if present), and append
* the comment in square brackets (if present). * the comment in square brackets (if present).
* @param separator the separator character between multiple fields. * @param separator the separator character between multiple fields.
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success (or if the partType does not match), or an error code.
*/ */
virtual result_t read(SymbolString& masterData, unsigned char masterOffset, virtual result_t read(const PartType partType,
SymbolString& slaveData, unsigned char slaveOffset, SymbolString& data, unsigned char offset,
ostringstream& output, ostringstream& output, bool leadingSeparator=false,
bool verbose=false, char separator=';') = 0; bool verbose=false, char separator=';') = 0;
/** /**
* @brief Writes the value to the master or slave @a SymbolString. * @brief Writes the value to the master or slave @a SymbolString.
* @param input the @a istringstream to parse the formatted value from. * @param input the @a istringstream to parse the formatted value from.
* @param masterData the unescaped master data @a SymbolString for writing binary data. * @param partType the @a PartType of the data.
* @param slaveData the unescaped slave data @a SymbolString for writing binary data. * @param data the unescaped data @a SymbolString for writing binary data.
* @param offset the additional offset to add for writing binary data.
* @param separator the separator character between multiple fields. * @param separator the separator character between multiple fields.
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success, or an error code.
*/ */
virtual result_t write(istringstream& input, virtual result_t write(istringstream& input,
SymbolString& masterData, unsigned char masterOffset, const PartType partType, SymbolString& data,
SymbolString& slaveData, unsigned char slaveOffset, unsigned char offset, char separator=';') = 0;
char separator=';') = 0;
protected: protected:
@@ -255,34 +255,15 @@ public:
virtual bool hasFullByteOffset(bool after) { return true; } virtual bool hasFullByteOffset(bool after) { return true; }
// @copydoc // @copydoc
virtual void dump(ostream& output); virtual void dump(ostream& output);
/** // @copydoc
* @brief Reads the value from the master or slave @a SymbolString. virtual result_t read(const PartType partType,
* @param masterData the unescaped master data @a SymbolString for reading binary data. SymbolString& data, unsigned char offset,
* @param masterOffset the extra offset for reading master data. ostringstream& output, bool leadingSeparator=false,
* @param slaveData the unescaped slave data @a SymbolString for reading binary data. bool verbose=false, char separator=';');
* @param slaveOffset the extra offset for reading slave data. // @copydoc
* @param output the ostringstream to append the formatted value to.
* @param verbose whether to prepend the name, append the unit (if present), and append
* the comment in square brackets (if present).
* @return @a RESULT_OK on success, or an error code.
*/
virtual result_t read(SymbolString& masterData, unsigned char masterOffset,
SymbolString& slaveData, unsigned char slaveOffset,
ostringstream& output,
bool verbose, char separator);
/**
* @brief Writes the value to the master or slave @a SymbolString.
* @param input the @a istringstream to parse the formatted value from.
* @param masterData the unescaped master data @a SymbolString for writing binary data.
* @param masterOffset the extra offset for writing master data.
* @param slaveData the unescaped slave data @a SymbolString for writing binary data.
* @param slaveOffset the extra offset for writing slave data.
* @return @a RESULT_OK on success, or an error code.
*/
virtual result_t write(istringstream& input, virtual result_t write(istringstream& input,
SymbolString& masterData, unsigned char masterOffset, const PartType partType, SymbolString& data,
SymbolString& slaveData, unsigned char slaveOffset, unsigned char offset, char separator=';');//TODO replace
char separator);
protected: protected:
@@ -569,15 +550,14 @@ public:
// @copydoc // @copydoc
virtual void dump(ostream& output); virtual void dump(ostream& output);
// @copydoc // @copydoc
virtual result_t read(SymbolString& masterData, unsigned char masterOffset, virtual result_t read(const PartType partType,
SymbolString& slaveData, unsigned char slaveOffset, SymbolString& data, unsigned char offset,
ostringstream& output, ostringstream& output, bool leadingSeparator=false,
bool verbose, char separator); bool verbose=false, char separator=';');
// @copydoc // @copydoc
virtual result_t write(istringstream& input, virtual result_t write(istringstream& input,
SymbolString& masterData, unsigned char masterOffset, const PartType partType, SymbolString& data,
SymbolString& slaveData, unsigned char slaveOffset, unsigned char offset, char separator=';');
char separator);
private: private:
+9 -5
View File
@@ -264,18 +264,22 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
} }
SymbolString slaveData; result = m_data->write(input, pt_masterData, masterData, m_id.size() - 2, separator);
result = m_data->write(input, masterData, m_id.size() - 2, slaveData, 0, separator);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
result = masterData.push_back(masterData.getCRC(), false, false); // result = masterData.push_back(masterData.getCRC(), false, false); // TODO only if calculated
return result; return result;
} }
result_t Message::decode(SymbolString& masterData, SymbolString& slaveData, result_t Message::decode(const PartType partType, SymbolString& data,
ostringstream& output, char separator) ostringstream& output, char separator)
{ {
result_t result = m_data->read(masterData, m_id.size() - 2, slaveData, 0, output, false, separator); unsigned char offset;
if (partType == pt_masterData)
offset = m_id.size() - 2;
else
offset = 0;
result_t result = m_data->read(partType, data, offset, output, false, false, separator);
if (result != RESULT_OK) if (result != RESULT_OK)
return result; return result;
/*if (m_isPassive == false && answer == true) { /*if (m_isPassive == false && answer == true) {
+3 -3
View File
@@ -146,13 +146,13 @@ public:
istringstream& input, char separator=';'); istringstream& input, char separator=';');
/** /**
* @brief Decode a received message. * @brief Decode a received message.
* @param masterData the unescaped received master @a SymbolString. * @param partType the @a PartType of the data.
* @param slaveData the unescaped received slave @a SymbolString. * @param data the unescaped data @a SymbolString 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 separator the separator character between multiple fields. * @param separator the separator character between multiple fields.
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success, or an error code.
*/ */
result_t decode(SymbolString& masterData, SymbolString& slaveData, result_t decode(const PartType partType, SymbolString& data,
ostringstream& output, char separator=';'); ostringstream& output, char separator=';');
private: private:
+8 -3
View File
@@ -97,7 +97,7 @@ int main()
{"x;;uch:17", "", "10feffff00", "00", "c"}, {"x;;uch:17", "", "10feffff00", "00", "c"},
{"x;s;uch", "0", "1025ffff0310111213", "0300010203", "W"}, {"x;s;uch", "0", "1025ffff0310111213", "0300010203", "W"},
{"x;s;uch", "0", "1025ffff00", "0100", ""}, {"x;s;uch", "0", "1025ffff00", "0100", ""},
{"x;s;uch;;;;y;m;uch", "2;3","1025ffff0103", "0102", ""}, {"x;s;uch;;;;y;m;uch", "3;2","1025ffff0103", "0102", ""},
{"x;;uch", "38", "10feffff0126", "00", ""}, {"x;;uch", "38", "10feffff0126", "00", ""},
{"x;;uch", "0", "10feffff0100", "00", ""}, {"x;;uch", "0", "10feffff0100", "00", ""},
{"x;;uch", "254", "10feffff01fe", "00", ""}, {"x;;uch", "254", "10feffff01fe", "00", ""},
@@ -249,7 +249,10 @@ int main()
ostringstream output; ostringstream output;
SymbolString writeMstr = SymbolString(mstr.getDataStr().substr(0, 10), false); SymbolString writeMstr = SymbolString(mstr.getDataStr().substr(0, 10), false);
SymbolString writeSstr = SymbolString(sstr.getDataStr().substr(0, 2), false); SymbolString writeSstr = SymbolString(sstr.getDataStr().substr(0, 2), false);
result = fields->read(mstr, 0, sstr, 0, output, verbose); result = fields->read(pt_masterData, mstr, 0, output, false, verbose);
if (result == RESULT_OK) {
result = fields->read(pt_slaveData, sstr, 0, output, output.str().empty() == false, verbose);
}
if (failedRead == true) if (failedRead == true)
if (result == RESULT_OK) if (result == RESULT_OK)
cout << " failed read " << fields->getName() << " >" cout << " failed read " << fields->getName() << " >"
@@ -268,7 +271,9 @@ int main()
if (verbose == false) { if (verbose == false) {
istringstream input(expectStr); istringstream input(expectStr);
result = fields->write(input, writeMstr, 0, writeSstr, 0); result = fields->write(input, pt_masterData, writeMstr, 0);
if (result == RESULT_OK)
result = fields->write(input, pt_slaveData, writeSstr, 0);
if (failedWrite == true) { if (failedWrite == true) {
if (result == RESULT_OK) if (result == RESULT_OK)
cout << " failed write " << fields->getName() << " >" cout << " failed write " << fields->getName() << " >"
+3 -1
View File
@@ -149,7 +149,9 @@ int main()
SymbolString writeMstr = SymbolString(); SymbolString writeMstr = SymbolString();
if (message->isPassive() == true) { if (message->isPassive() == true) {
ostringstream output; ostringstream output;
result = message->decode(mstr, sstr, output); result = message->decode(pt_masterData, mstr, output);
if (result == RESULT_OK)
result = message->decode(pt_slaveData, sstr, output);
if (result != RESULT_OK) { if (result != RESULT_OK) {
cout << " \"" << inputStr << "\": decode error: " cout << " \"" << inputStr << "\": decode error: "
<< getResultCode(result) << endl; << getResultCode(result) << endl;