store bit count separately, added ignored type (IGN), moved field length definition from part to type and allow adjusting length for bit types, added PartType masterDataID, simplfied

This commit is contained in:
john30
2014-11-22 19:17:30 +01:00
parent 1f33218692
commit 24e46f5b44
3 changed files with 237 additions and 186 deletions
+182 -150
View File
@@ -29,11 +29,12 @@
/** the known data field types. */
static const dataType_t dataTypes[] = {
{"IGN",16*8,bt_str, IGN|ADJ, 0, 1, 16, 0, 0}, // >= 1 byte ignored data
{"STR",16*8,bt_str, ADJ, ' ', 1, 16, 0, 0}, // >= 1 byte character string filled up with space
{"HEX",16*8,bt_hexstr, ADJ, 0, 2, 47, 0, 0}, // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d
{"BDA", 32, bt_dat, BCD, 0, 10, 10, 0, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is ignored weekday)
{"BDA", 32, bt_dat, BCD, 0, 10, 10, 0, 0}, // date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is weekday)
{"BDA", 24, bt_dat, BCD, 0, 10, 10, 0, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99)
{"HDA", 32, bt_dat, 0, 0, 10, 10, 0, 0}, // date, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is ignored weekday) // TODO remove duplicate of BDA
{"HDA", 32, bt_dat, 0, 0, 10, 10, 0, 0}, // date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is weekday) // TODO remove duplicate of BDA
{"HDA", 24, bt_dat, 0, 0, 10, 10, 0, 0}, // date, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99) // TODO remove duplicate of BDA
{"BTI", 24, bt_tim, BCD|REV, 0, 8, 8, 0, 0}, // time in BCD, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x59,0x59,0x23)
{"HTM", 16, bt_tim, 0, 0, 5, 5, 0, 0}, // time as hh:mm, 00:00 - 23:59 (0x00,0x00 - 0x17,0x3b)
@@ -52,41 +53,14 @@ static const dataType_t dataTypes[] = {
{"D2C", 16, bt_num, SIG, 0x8000, 0x8001, 0x7fff, 16, 2}, // signed number (fraction 1/16), -2047.9 - +2047.9
{"ULG", 32, bt_num, LST, 0xffffffff, 0, 0xfffffffe, 1, 0}, // unsigned integer, 0 - 4294967294
{"SLG", 32, bt_num, SIG, 0x80000000, 0x80000001, 0xffffffff, 1, 0}, // signed integer, -2147483647 - +2147483647
{"BI0", 1, bt_num, LST, 0, 0, 0x1, 1, 0}, // single bit 0
{"BI1", 1, bt_num, LST, 0, 0, 0x1, 1, 1}, // single bit 1
{"BI2", 1, bt_num, LST, 0, 0, 0x1, 1, 2}, // single bit 2
{"BI3", 1, bt_num, LST, 0, 0, 0x1, 1, 3}, // single bit 3
{"BI4", 1, bt_num, LST, 0, 0, 0x1, 1, 4}, // single bit 4
{"BI5", 1, bt_num, LST, 0, 0, 0x1, 1, 5}, // single bit 5
{"BI6", 1, bt_num, LST, 0, 0, 0x1, 1, 6}, // single bit 6
{"BI7", 1, bt_num, LST, 0, 0, 0x1, 1, 7}, // single bit 7
{"B01", 2, bt_num, LST, 0, 0, 0x3, 1, 0}, // two bits 0-1
{"B12", 2, bt_num, LST, 0, 0, 0x3, 1, 1}, // two bits 1-2
{"B23", 2, bt_num, LST, 0, 0, 0x3, 1, 2}, // two bits 2-3
{"B34", 2, bt_num, LST, 0, 0, 0x3, 1, 3}, // two bits 3-4
{"B45", 2, bt_num, LST, 0, 0, 0x3, 1, 4}, // two bits 4-5
{"B56", 2, bt_num, LST, 0, 0, 0x3, 1, 5}, // two bits 5-6
{"B67", 2, bt_num, LST, 0, 0, 0x3, 1, 6}, // two bits 6-7
{"B02", 3, bt_num, LST, 0, 0, 0x7, 1, 0}, // three bits 0-2
{"B13", 3, bt_num, LST, 0, 0, 0x7, 1, 1}, // three bits 1-3
{"B24", 3, bt_num, LST, 0, 0, 0x7, 1, 2}, // three bits 2-4
{"B35", 3, bt_num, LST, 0, 0, 0x7, 1, 3}, // three bits 3-5
{"B46", 3, bt_num, LST, 0, 0, 0x7, 1, 4}, // three bits 4-6
{"B57", 3, bt_num, LST, 0, 0, 0x7, 1, 5}, // three bits 5-7
{"B03", 4, bt_num, LST, 0, 0, 0xf, 1, 0}, // four bits 0-3
{"B14", 4, bt_num, LST, 0, 0, 0xf, 1, 1}, // four bits 1-4
{"B25", 4, bt_num, LST, 0, 0, 0xf, 1, 2}, // four bits 2-5
{"B36", 4, bt_num, LST, 0, 0, 0xf, 1, 3}, // four bits 3-6
{"B47", 4, bt_num, LST, 0, 0, 0xf, 1, 4}, // four bits 4-7
{"B04", 5, bt_num, LST, 0, 0, 0x1f, 1, 0}, // five bits 0-4
{"B15", 5, bt_num, LST, 0, 0, 0x1f, 1, 1}, // five bits 1-5
{"B26", 5, bt_num, LST, 0, 0, 0x1f, 1, 2}, // five bits 2-6
{"B37", 5, bt_num, LST, 0, 0, 0x1f, 1, 3}, // five bits 3-7
{"B05", 6, bt_num, LST, 0, 0, 0x3f, 1, 0}, // six bits 0-5
{"B16", 6, bt_num, LST, 0, 0, 0x3f, 1, 1}, // six bits 1-6
{"B27", 6, bt_num, LST, 0, 0, 0x3f, 1, 2}, // six bits 2-7
{"B06", 7, bt_num, LST, 0, 0, 0x7f, 1, 0}, // seven bits 0-6
{"B17", 7, bt_num, LST, 0, 0, 0x7f, 1, 1}, // seven bits 1-7
{"BI0", 7, bt_num, ADJ|LST, 0, 0, 0xef, 1, 0}, // bit 0 (up to 7 bits until bit 6)
{"BI1", 7, bt_num, ADJ|LST, 0, 0, 0x7f, 1, 1}, // bit 1 (up to 7 bits until bit 7)
{"BI2", 6, bt_num, ADJ|LST, 0, 0, 0x3f, 1, 2}, // bit 2 (up to 6 bits until bit 7)
{"BI3", 5, bt_num, ADJ|LST, 0, 0, 0x1f, 1, 3}, // bit 3 (up to 5 bits until bit 7)
{"BI4", 4, bt_num, ADJ|LST, 0, 0, 0x0f, 1, 4}, // bit 4 (up to 4 bits until bit 7)
{"BI5", 3, bt_num, ADJ|LST, 0, 0, 0x07, 1, 5}, // bit 5 (up to 3 bits until bit 7)
{"BI6", 2, bt_num, ADJ|LST, 0, 0, 0x03, 1, 6}, // bit 6 (up to 2 bits until bit 7)
{"BI7", 1, bt_num, ADJ|LST, 0, 0, 0x01, 1, 7}, // bit 7
};
@@ -132,18 +106,17 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
std::string unit, comment;
PartType partType;
unsigned int divisor = 0;
unsigned char length;
const bool isTemplate = dstAddress == SYN;
std::string token;
if (it == end)
break;
// name;[m|s][len];type[;[divisor|values][;[unit][;[comment]]]]
// name;part;type[:len][;[divisor|values][;[unit][;[comment]]]]
const std::string name = *it++;
if (it == end)
break;
const char* posStr = (*it++).c_str();
const char* partStr = (*it++).c_str();
if (it == end)
break;
@@ -151,18 +124,17 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
firstName = name;
firstComment = comment;
}
if (dstAddress == BROADCAST || isMaster(dstAddress)
|| (isTemplate == false && isSetMessage == true && (posStr[0] == 0 || posStr[0] <= '9'))
|| posStr[0] == 'm') { // master data
partType = pt_masterData;
if (posStr[0] == 'm')
posStr++;
if (isTemplate == false && strcasecmp(partStr, "I") == 0) {
partType = pt_masterDataID;
}
else if ((isTemplate == false && isSetMessage == false && (posStr[0] == 0 || posStr[0] <= '9'))
|| posStr[0] == 's') { // slave data
else if (dstAddress == BROADCAST || isMaster(dstAddress)
|| (isTemplate == false && isSetMessage == true && partStr[0] == 0)
|| strcasecmp(partStr, "M") == 0) { // master data
partType = pt_masterData;
}
else if ((isTemplate == false && isSetMessage == false && partStr[0] == 0)
|| strcasecmp(partStr, "S") == 0) { // slave data
partType = pt_slaveData;
if (posStr[0] == 's')
posStr++;
}
else if (isTemplate) {
partType = pt_any;
@@ -172,17 +144,10 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
break;
}
if (posStr[0] == 0) {
length = 0;
}
else {
length = parseInt(posStr, 10, 1, MAX_POS, result);
if (result != RESULT_OK)
break;
}
const char* typeStr = (*it++).c_str();
if (typeStr[0] == 0) {
std::string typeStr = *it++;
if (typeStr.empty() == true) {
if (name.empty() == false || partStr[0] != 0)
result = RESULT_ERR_INVALID_ARG;
break;
}
@@ -190,7 +155,7 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
if (it != end) {
std::string divisorStr = *it++;
if (divisorStr.empty() == false) {
if (divisorStr.find_first_not_of("0123456789") == std::string::npos) {
if (divisorStr.find('=') == std::string::npos) {
divisor = parseInt(divisorStr.c_str(), 10, 1, 10000, result);
if (result != RESULT_OK)
break;
@@ -231,47 +196,73 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
comment.clear();
}
// check for reference(s) to templates
if (templates.empty() == false) {
std::istringstream stream(typeStr);
bool found = false;
while (std::getline(stream, token, VALUE_SEPARATOR) != 0) {
std::map< std::string, DataField*>::const_iterator ref = templates.find(token);
if (ref == templates.end()) {
if (found == false)
break; // fallback to direct definition
result = RESULT_ERR_INVALID_ARG; // cannot mix reference and direct definition
break;
size_t pos = typeStr.find(':');
unsigned char length;
if (pos == std::string::npos) {
length = 0;
// check for reference(s) to templates
if (templates.empty() == false) {
std::istringstream stream(typeStr);
bool found = false;
std::string lengthStr;
while (std::getline(stream, token, VALUE_SEPARATOR) != 0) {
std::map<std::string, DataField*>::const_iterator ref = templates.find(token);
if (ref == templates.end()) {
if (found == false)
break; // fallback to direct definition
result = RESULT_ERR_INVALID_ARG; // cannot mix reference and direct definition
break;
}
found = true;
result = ref->second->derive(name, comment, unit, partType, divisor, values, fields);
if (result != RESULT_OK)
break;
}
if (length > 1) {
result = RESULT_ERR_INVALID_ARG; // different length not possible for derivation
break;
}
found = true;
result = ref->second->derive(name, comment, unit, partType, divisor, values, fields);
if (result != RESULT_OK)
break;
if (found == true || result != RESULT_OK)
break; // TODO check for found == true
}
if (found == true || result != RESULT_OK)
break;
}
else {
length = parseInt(typeStr.substr(pos+1).c_str(), 10, 1, MAX_POS, result);
if (result != RESULT_OK)
break;
typeStr = typeStr.substr(0, pos);
}
SingleDataField* add = NULL;
const char* typeName = typeStr.c_str();
for (size_t i = 0; result == RESULT_OK && add == NULL && i < sizeof(dataTypes) / sizeof(dataTypes[0]); i++) {
dataType_t dataType = dataTypes[i];
if (strcasecmp(typeStr, dataType.name) == 0) {
unsigned char numBytes = (dataType.numBits + 7) / 8;
unsigned char useLength = length;
if ((dataType.flags & ADJ) != 0) {
if (useLength == 0)
useLength = 1; // minimum length defaults to 1
else if (useLength > numBytes) {
if (strcasecmp(typeName, dataType.name) == 0) {
unsigned char bitCount = dataType.maxBits;
unsigned char useLength = (bitCount + 7) / 8;
if ((dataType.flags & ADJ) != 0) { // adjustable length
if ((bitCount % 8) != 0) {
if (length == 0) {
useLength = 1; // default length: 1 byte
bitCount = 1; // default count: 1 bit
}
else if (length > bitCount) {
result = RESULT_ERR_INVALID_ARG; // invalid length
break;
}
else {
bitCount = length;
useLength = (length + 7) / 8;
}
}
else if (length == 0) {
useLength = 1; // default length: 1 byte
}
else if (length <= useLength) {
useLength = length;
}
else {
result = RESULT_ERR_INVALID_ARG; // invalid length
break;
}
}
else if (useLength == 0)
useLength = numBytes;
else if (useLength != numBytes)
else if (length > 0 && length != useLength)
continue; // check for another one with same name but different length
switch (dataType.type)
@@ -294,7 +285,7 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
else
divisor *= dataType.divisor;
add = new NumberDataField(name, comment, unit, dataType, partType, useLength, divisor);
add = new NumberDataField(name, comment, unit, dataType, partType, useLength, bitCount, divisor);
break;
}
if (values.begin()->first < dataType.minValueOrLength
@@ -303,7 +294,7 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
break;
}
add = new ValueListDataField(name, comment, unit, dataType, partType, useLength, values);
add = new ValueListDataField(name, comment, unit, dataType, partType, useLength, bitCount, values);
break;
}
}
@@ -330,22 +321,17 @@ result_t DataField::create(std::vector<std::string>::iterator& it,
}
bool SingleDataField::hasFullByteOffset()
{
return m_length > 1 || (m_dataType.numBits % 8) == 0
|| m_dataType.precisionOrFirstBit + (m_dataType.numBits % 8) >= 8;
}
result_t SingleDataField::read(SymbolString& masterData, unsigned char masterOffset,
SymbolString& slaveData, unsigned char slaveOffset,
std::ostringstream& output,
bool verbose, char separator)
{
SymbolString& input = m_partType == pt_masterData ? masterData : slaveData;
SymbolString& input = m_partType != pt_slaveData ? masterData : slaveData;
unsigned char offset;
switch (m_partType)
{
case pt_masterData:
case pt_masterDataID:
offset = 5 + masterOffset; // skip QQ ZZ PB SB NN
break;
case pt_slaveData:
@@ -355,7 +341,14 @@ result_t SingleDataField::read(SymbolString& masterData, unsigned char masterOff
return RESULT_ERR_INVALID_ARG; // invalid part type
}
if (verbose)
if (isIgnored() == true) {
if (offset + m_length > input.size()) {
return RESULT_ERR_INVALID_ARG;
}
return RESULT_OK;
}
if (verbose == true)
output << m_name << "=";
result_t result = readSymbols(input, offset, output);
@@ -375,11 +368,12 @@ result_t SingleDataField::write(std::istringstream& input,
SymbolString& slaveData, unsigned char slaveOffset,
char separator)
{
SymbolString& output = m_partType == pt_masterData ? masterData : slaveData;
SymbolString& output = m_partType != pt_slaveData ? masterData : slaveData;
unsigned char offset;
switch (m_partType)
{
case pt_masterData:
case pt_masterDataID:
offset = 5 + masterOffset; // skip QQ ZZ PB SB NN
break;
case pt_slaveData:
@@ -423,6 +417,7 @@ result_t StringDataField::readSymbols(SymbolString& input,
if (baseOffset + m_length > input.size()) {
return RESULT_ERR_INVALID_ARG;
}
if ((m_dataType.flags & REV) != 0) { // reverted binary representation (most significant byte first)
start = m_length - 1;
incr = -1;
@@ -494,6 +489,12 @@ result_t StringDataField::writeSymbols(std::istringstream& input,
incr = -1;
}
if (isIgnored() == true) {
for (size_t offset = start, i = 0; i < count; offset += incr, i++) {
output[baseOffset + offset] = m_dataType.replacement; // fill up with replacement
}
return RESULT_OK;
}
result_t result;
size_t i = 0;
for (size_t offset = start; i < count; offset += incr, i++) {
@@ -581,6 +582,12 @@ result_t StringDataField::writeSymbols(std::istringstream& input,
}
bool NumericDataField::hasFullByteOffset(bool after)
{
return m_length > 1 || (m_bitCount % 8) == 0
|| (after == true && m_bitOffset + (m_bitCount % 8) >= 8);
}
result_t NumericDataField::readRawValue(SymbolString& input,
unsigned char baseOffset, unsigned int& value)
{
@@ -619,9 +626,10 @@ result_t NumericDataField::readRawValue(SymbolString& input,
if ((m_dataType.flags & BCD) == 0) {
value >>= m_bitOffset;
if ((m_dataType.numBits % 8) != 0)
value &= (1 << m_dataType.numBits) - 1;
if ((m_bitCount % 8) != 0)
value &= (1 << m_bitCount) - 1;
}
return RESULT_OK;
}
@@ -638,8 +646,9 @@ result_t NumericDataField::writeRawValue(unsigned int value,
}
if ((m_dataType.flags & BCD) == 0) {
if ((m_dataType.numBits % 8) != 0)
value &= (1 << m_dataType.numBits) - 1;
if ((m_bitCount % 8) != 0 && (value & ~((1 << m_bitCount) - 1)) != 0)
return RESULT_ERR_INVALID_ARG;
value <<= m_bitOffset;
}
for (size_t offset = start, i = 0, exp = 1; i < count; offset += incr, i++) {
@@ -656,7 +665,7 @@ result_t NumericDataField::writeRawValue(unsigned int value,
ch = (value / exp) & 0xff;
exp = exp << 8;
}
if (offset == start && (m_dataType.numBits % 8) != 0 && baseOffset + offset < output.size())
if (offset == start && (m_bitCount % 8) != 0 && baseOffset + offset < output.size())
output[baseOffset + offset] |= ch;
else
output[baseOffset + offset] = ch;
@@ -687,10 +696,10 @@ result_t NumberDataField::derive(std::string name, std::string comment,
if (divisor != 1)
return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field
fields.push_back(new ValueListDataField(name, comment, unit, m_dataType, partType, m_length, values));
fields.push_back(new ValueListDataField(name, comment, unit, m_dataType, partType, m_length, m_bitCount, values));
}
else
fields.push_back(new NumberDataField(name, comment, unit, m_dataType, partType, m_length, divisor));
fields.push_back(new NumberDataField(name, comment, unit, m_dataType, partType, m_length, m_bitCount, divisor));
return RESULT_OK;
}
@@ -710,27 +719,27 @@ result_t NumberDataField::readSymbols(SymbolString& input,
return RESULT_OK;
}
bool negative = (m_dataType.flags & SIG) != 0 && (value & (1 << (m_dataType.numBits - 1))) != 0;
if (m_dataType.numBits == 32) {
bool negative = (m_dataType.flags & SIG) != 0 && (value & (1 << (m_bitCount - 1))) != 0;
if (m_bitCount == 32) {
if (negative == false) {
if (m_divisor <= 1)
output << static_cast<unsigned>(value);
else
output << std::setprecision((m_dataType.numBits % 8) == 0 ? m_dataType.precisionOrFirstBit : 0)
output << std::setprecision((m_bitCount % 8) == 0 ? m_dataType.precisionOrFirstBit : 0)
<< std::fixed << static_cast<float>(value / (float) m_divisor);
return RESULT_OK;
}
signedValue = (int) value; // negative signed value
}
else if (negative) // negative signed value
signedValue = (int) value - (1 << m_dataType.numBits);
signedValue = (int) value - (1 << m_bitCount);
else
signedValue = (int) value;
if (m_divisor <= 1)
output << static_cast<int>(signedValue);
else
output << std::setprecision((m_dataType.numBits % 8) == 0 ? m_dataType.precisionOrFirstBit : 0)
output << std::setprecision((m_bitCount % 8) == 0 ? m_dataType.precisionOrFirstBit : 0)
<< std::fixed << static_cast<float>(signedValue / (float) m_divisor);
return RESULT_OK;
@@ -742,18 +751,17 @@ result_t NumberDataField::writeSymbols(std::istringstream& input,
unsigned int value;
const char* str = input.str().c_str();
if (strcasecmp(str, NULL_VALUE) == 0)
// replacement value
value = m_dataType.replacement;
if (isIgnored() == true || strcasecmp(str, NULL_VALUE) == 0)
value = m_dataType.replacement; // replacement value
else if (str == NULL || *str == 0)
return RESULT_ERR_INVALID_ARG; // input too short
return RESULT_ERR_INVALID_ARG; // input too short//TODO LENGTH_SEPARATOR
else {
char* strEnd = NULL;
if (m_divisor <= 1) {
if ((m_dataType.flags & SIG) != 0) {
int signedValue = strtol(str, &strEnd, 10);
if (signedValue < 0 && m_dataType.numBits != 32)
value = (unsigned int) (signedValue + (1 << m_dataType.numBits));
if (signedValue < 0 && m_bitCount != 32)
value = (unsigned int) (signedValue + (1 << m_bitCount));
else
value = (unsigned int) signedValue;
}
@@ -771,8 +779,8 @@ result_t NumberDataField::writeSymbols(std::istringstream& input,
if ((m_dataType.flags & SIG) != 0) {
if (dvalue < -(1LL << (8 * m_length)) || dvalue >= (1LL << (8 * m_length)))
return RESULT_ERR_INVALID_ARG; // value out of range
if (dvalue < 0 && m_dataType.numBits != 32)
value = (unsigned int) (dvalue + (1 << m_dataType.numBits));
if (dvalue < 0 && m_bitCount != 32)
value = (unsigned int) (dvalue + (1 << m_bitCount));
else
value = (unsigned int) dvalue;
}
@@ -784,7 +792,7 @@ result_t NumberDataField::writeSymbols(std::istringstream& input,
}
if ((m_dataType.flags & SIG) != 0) { // signed value
if ((value & (1 << (m_dataType.numBits - 1))) != 0) { // negative signed value
if ((value & (1 << (m_bitCount - 1))) != 0) { // negative signed value
if (value < m_dataType.minValueOrLength)
return RESULT_ERR_INVALID_ARG; // value out of range
}
@@ -823,7 +831,7 @@ result_t ValueListDataField::derive(std::string name, std::string comment,
else
values = m_values;
fields.push_back(new ValueListDataField(name, comment, unit, m_dataType, partType, m_length, values));
fields.push_back(new ValueListDataField(name, comment, unit, m_dataType, partType, m_length, m_bitCount, values));
return RESULT_OK;
}
@@ -854,14 +862,17 @@ result_t ValueListDataField::readSymbols(SymbolString& input,
result_t ValueListDataField::writeSymbols(std::istringstream& input,
unsigned char baseOffset, SymbolString& output)
{
if (isIgnored() == true)
return writeRawValue(m_dataType.replacement, baseOffset, output); // replacement value
const char* str = input.str().c_str();
for (std::map<unsigned int, std::string>::iterator it = m_values.begin(); it != m_values.end(); it++)
if (it->second.compare(str) == 0)
return writeRawValue(it->first, baseOffset, output);
if (strcasecmp(str, NULL_VALUE) == 0) // replacement value
return writeRawValue(m_dataType.replacement, baseOffset, output);
if (strcasecmp(str, NULL_VALUE) == 0)
return writeRawValue(m_dataType.replacement, baseOffset, output); // replacement value
return RESULT_ERR_INVALID_ARG; // value assignment not found
}
@@ -878,15 +889,17 @@ unsigned char DataFieldSet::getLength(PartType partType)
{
unsigned char length = 0;
bool previousFullByteOffset[] = { true, true, true };
bool previousFullByteOffset[] = { true, true, true, true };
for (std::vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) {
SingleDataField* field = *it;
if (field->getPartType() == partType) {
length += field->getLength(partType);
if (previousFullByteOffset[partType] == false) {
if (previousFullByteOffset[partType] == false && field->hasFullByteOffset(false) == false)
length--;
}
previousFullByteOffset[partType] = field->hasFullByteOffset();
length += field->getLength(partType);
previousFullByteOffset[partType] = field->hasFullByteOffset(true);
}
}
@@ -918,29 +931,38 @@ result_t DataFieldSet::read(SymbolString& masterData, unsigned char masterOffset
output << m_name << "={ ";
bool first = true;
unsigned char offsets[] = { 0, masterOffset, slaveOffset };
bool previousFullByteOffset[] = { true, true, true };
unsigned char offsets[4];
memset(offsets, 0, sizeof(offsets));
offsets[pt_masterData] = masterOffset;
offsets[pt_slaveData] = slaveOffset;
bool previousFullByteOffset[] = { true, true, true, true };
for (std::vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) {
if (first)
first = false;
else
output << separator;
SingleDataField* field = *it;
bool ignored = field->isIgnored();
PartType partType = field->getPartType();
if (previousFullByteOffset[partType] == false) {
offsets[partType]--;
if (ignored == false) {
if (first)
first = false;
else
output << separator;
}
if (partType == pt_masterDataID)
partType = pt_masterData;
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);
if (result != RESULT_OK)
return result;
offsets[partType] += field->getLength(partType);
previousFullByteOffset[partType] = field->hasFullByteOffset();
previousFullByteOffset[partType] = field->hasFullByteOffset(true);
}
if (verbose) {
if (verbose == true) {
if (m_comment.length() > 0)
output << " [" << m_comment << "]";
output << "}";
@@ -956,18 +978,28 @@ result_t DataFieldSet::write(std::istringstream& input,
{
std::string token;
unsigned char offsets[] = { 0, masterOffset, slaveOffset };
bool previousFullByteOffset[] = { true, true, true };
unsigned char offsets[4];
memset(offsets, 0, sizeof(offsets));
offsets[pt_masterData] = masterOffset;
offsets[pt_slaveData] = slaveOffset;
bool previousFullByteOffset[] = { true, true, true, true };
for (std::vector<SingleDataField*>::iterator it = m_fields.begin(); it < m_fields.end(); it++) {
SingleDataField* field = *it;
bool ignored = field->isIgnored();
PartType partType = field->getPartType();
if (previousFullByteOffset[partType] == false) {
if (partType == pt_masterDataID)
partType = pt_masterData;
if (previousFullByteOffset[partType] == false && field->hasFullByteOffset(false) == false)
offsets[partType]--;
}
result_t result;
if (m_fields.size() > 1) {
if (std::getline(input, token, separator) == 0)
if (ignored == true)
token.clear();
else if (std::getline(input, token, separator) == 0)
return RESULT_ERR_INVALID_ARG; // incomplete
std::istringstream single(token);
result = (*it)->write(single, masterData, offsets[pt_masterData], slaveData, offsets[pt_slaveData], separator);
}
@@ -978,7 +1010,7 @@ result_t DataFieldSet::write(std::istringstream& input,
return result;
offsets[partType] += field->getLength(partType);
previousFullByteOffset[partType] = field->hasFullByteOffset();
previousFullByteOffset[partType] = field->hasFullByteOffset(true);
}
return RESULT_OK;