added constant value data types

This commit is contained in:
john30
2016-12-10 23:51:10 +01:00
parent cc7f61f78d
commit 1fec0f693c
5 changed files with 176 additions and 5 deletions
+92 -4
View File
@@ -101,11 +101,21 @@ result_t DataField::create(vector<string>::iterator& it,
} }
map<unsigned int, string> values; map<unsigned int, string> values;
string constantValue;
bool verifyValue = false;
if (it != end) { if (it != end) {
const string divisorStr = *it++; // [divisor|values] const string divisorStr = *it++; // [divisor|values]
if (!divisorStr.empty()) { if (!divisorStr.empty()) {
if (divisorStr.find('=') == string::npos) { size_t equalPos = divisorStr.find('=');
if (equalPos == string::npos) {
divisor = parseSignedInt(divisorStr.c_str(), 10, -MAX_DIVISOR, MAX_DIVISOR, result); divisor = parseSignedInt(divisorStr.c_str(), 10, -MAX_DIVISOR, MAX_DIVISOR, result);
} else if (equalPos == 0 && divisorStr.length() > 1) {
verifyValue = divisorStr[1]=='='; // == forced verification of constant value
if (verifyValue && divisorStr.length() == 1) {
result = RESULT_ERR_INVALID_LIST;
break;
}
constantValue = divisorStr.substr(equalPos+(verifyValue?2:1));
} else { } else {
istringstream stream(divisorStr); istringstream stream(divisorStr);
while (getline(stream, token, VALUE_SEPARATOR)) { while (getline(stream, token, VALUE_SEPARATOR)) {
@@ -190,12 +200,14 @@ result_t DataField::create(vector<string>::iterator& it,
} }
transform(typeName.begin(), typeName.end(), typeName.begin(), ::toupper); transform(typeName.begin(), typeName.end(), typeName.begin(), ::toupper);
SingleDataField* add = NULL; SingleDataField* add = NULL;
result = SingleDataField::create(typeName, length, firstType ? name : "", firstType ? comment : "", firstType ? unit : "", partType, divisor, values, add); result = SingleDataField::create(typeName, length, firstType ? name : "", firstType ? comment : "", firstType ? unit : "", partType, divisor, values, constantValue, verifyValue, add);
if (add != NULL) { if (add != NULL) {
fields.push_back(add); fields.push_back(add);
} else if (result == RESULT_OK) { } else if (result == RESULT_OK) {
result = RESULT_ERR_NOTFOUND; // type not found result = RESULT_ERR_NOTFOUND; // type not found
} }
} else if (!constantValue.empty()) {
result = RESULT_ERR_INVALID_ARG; // invalid value list
} else { // template[:name] } else { // template[:name]
string fieldName; string fieldName;
bool lastType = stream.eof(); bool lastType = stream.eof();
@@ -241,7 +253,7 @@ void DataField::dumpString(ostream& output, const string str, const bool prepend
result_t SingleDataField::create(const string id, const unsigned char length, result_t SingleDataField::create(const string id, const unsigned char length,
const string name, const string comment, const string unit, const string name, const string comment, const string unit,
const PartType partType, int divisor, map<unsigned int, string> values, const PartType partType, int divisor, map<unsigned int, string> values,
SingleDataField* &returnField) const string constantValue, const bool verifyValue, SingleDataField* &returnField)
{ {
DataType* dataType = DataTypeList::getInstance()->get(id, length==REMAIN_LEN ? (unsigned char)0 : length); DataType* dataType = DataTypeList::getInstance()->get(id, length==REMAIN_LEN ? (unsigned char)0 : length);
if (!dataType) { if (!dataType) {
@@ -268,6 +280,10 @@ result_t SingleDataField::create(const string id, const unsigned char length,
return RESULT_ERR_OUT_OF_RANGE; // invalid length return RESULT_ERR_OUT_OF_RANGE; // invalid length
} }
} }
if (!constantValue.empty()) {
returnField = new ConstantDataField(name, comment, unit, dataType, partType, byteCount, constantValue, verifyValue);
return RESULT_OK;
}
if (dataType->isNumeric()) { if (dataType->isNumeric()) {
NumberDataType* numType = (NumberDataType*)dataType; NumberDataType* numType = (NumberDataType*)dataType;
if (values.empty() && numType->hasFlag(DAY)) { if (values.empty() && numType->hasFlag(DAY)) {
@@ -285,7 +301,6 @@ result_t SingleDataField::create(const string id, const unsigned char length,
if (values.begin()->first < numType->getMinValue() || values.rbegin()->first > numType->getMaxValue()) { if (values.begin()->first < numType->getMinValue() || values.rbegin()->first > numType->getMaxValue()) {
return RESULT_ERR_OUT_OF_RANGE; return RESULT_ERR_OUT_OF_RANGE;
} }
//TODO add special field for fixed values (exactly one value in the list of values)
returnField = new ValueListDataField(name, comment, unit, numType, partType, byteCount, values); returnField = new ValueListDataField(name, comment, unit, numType, partType, byteCount, values);
return RESULT_OK; return RESULT_OK;
} }
@@ -621,6 +636,79 @@ result_t ValueListDataField::writeSymbols(istringstream& input,
} }
ConstantDataField* ConstantDataField::clone()
{
return new ConstantDataField(*this);
}
result_t ConstantDataField::derive(string name, string comment,
string unit, const PartType partType,
int divisor, map<unsigned int, string> values,
vector<SingleDataField*>& fields)
{
if (m_partType != pt_any && partType == pt_any)
return RESULT_ERR_INVALID_PART; // cannot create a template from a concrete instance
if (name.empty())
name = m_name;
if (comment.empty())
comment = m_comment;
if (unit.empty())
unit = m_unit;
if (divisor != 0)
return RESULT_ERR_INVALID_ARG; // cannot use other than current divisor for constant value field
if (!values.empty()) {
return RESULT_ERR_INVALID_ARG; // cannot use value list for constant value field
}
fields.push_back(new ConstantDataField(name, comment, unit, m_dataType, partType, m_length, m_value, m_verify));
return RESULT_OK;
}
void ConstantDataField::dump(ostream& output)
{
output << setw(0) << dec; // initialize formatting
dumpString(output, m_name, false);
output << FIELD_SEPARATOR;
if (m_partType == pt_masterData)
output << "m";
else if (m_partType == pt_slaveData)
output << "s";
output << FIELD_SEPARATOR;
if (!m_dataType->dump(output, m_length)) { // no divisor appended
output << (m_verify?"==":"=") << m_value;
} // else: impossible since divisor is not allowed for ConstantDataField
dumpString(output, m_unit);
dumpString(output, m_comment);
}
result_t ConstantDataField::readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset,
ostringstream& output, OutputFormat outputFormat)
{
ostringstream coutput;
result_t result = SingleDataField::readSymbols(input, isMaster, offset, coutput, 0);
if (result != RESULT_OK) {
return result;
}
if (m_verify) {
string value = coutput.str();
FileReader::trim(value);
if (value!=m_value) {
return RESULT_ERR_OUT_OF_RANGE;
}
}
return RESULT_OK;
}
result_t ConstantDataField::writeSymbols(istringstream& input,
const unsigned char offset,
SymbolString& output, const bool isMaster, unsigned char* usedLength)
{
istringstream cinput(m_value);
return SingleDataField::writeSymbols(cinput, offset, output, isMaster, usedLength);
}
DataFieldSet* DataFieldSet::s_identFields = NULL; DataFieldSet* DataFieldSet::s_identFields = NULL;
DataFieldSet* DataFieldSet::getIdentFields() DataFieldSet* DataFieldSet::getIdentFields()
+67 -1
View File
@@ -256,6 +256,8 @@ public:
* @param partType the message part in which the field is stored. * @param partType the message part in which the field is stored.
* @param divisor the extra divisor (negative for reciprocal) to apply on the value, or 1 for none (if applicable). * @param divisor the extra divisor (negative for reciprocal) to apply on the value, or 1 for none (if applicable).
* @param values the value=text assignments. * @param values the value=text assignments.
* @param constantValue the constant value as string, or empty.
* @param verifyValue whether to verify the read value against the constant value.
* @param returnField the variable in which the created @a SingleDataField instance shall be stored. * @param returnField the variable in which the created @a SingleDataField instance shall be stored.
* @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.
@@ -263,7 +265,7 @@ public:
static result_t create(const string id, const unsigned char length, static result_t create(const string id, const unsigned char length,
const string name, const string comment, const string unit, const string name, const string comment, const string unit,
const PartType partType, int divisor, map<unsigned int, string> values, const PartType partType, int divisor, map<unsigned int, string> values,
SingleDataField* &returnField); const string constantValue, const bool verifyValue, SingleDataField* &returnField);
/** /**
* Get the value unit. * Get the value unit.
@@ -427,6 +429,70 @@ private:
}; };
/**
* A data field with a constant value.
*/
class ConstantDataField : public SingleDataField
{
public:
/**
* Constructs a new instance.
* @param name the field name.
* @param comment the field comment.
* @param unit the value unit.
* @param dataType the data type definition.
* @param partType the message part in which the field is stored.
* @param length the number of symbols in the message part in which the field is stored.
* @param value the constant value.
* @param verify whether to verify the read value against the constant value.
*/
ConstantDataField(const string name, const string comment,
const string unit, DataType* dataType, const PartType partType,
const unsigned char length, const string value, const bool verify)
: SingleDataField(name, comment, unit, dataType, partType, length),
m_value(value), m_verify(verify) {}
/**
* Destructor.
*/
virtual ~ConstantDataField() {}
// @copydoc
virtual ConstantDataField* clone();
// @copydoc
virtual result_t derive(string name, string comment,
string unit, const PartType partType, int divisor,
map<unsigned int, string> values,
vector<SingleDataField*>& fields);
// @copydoc
virtual void dump(ostream& output);
protected:
// @copydoc
virtual result_t readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset,
ostringstream& output, OutputFormat outputFormat);
// @copydoc
virtual result_t writeSymbols(istringstream& input,
const unsigned char offset,
SymbolString& output, const bool isMaster, unsigned char* usedLength);
private:
/** the constant value. */
const string m_value;
/** whether to verify the read value against the constant value. */
const bool m_verify;
};
/** /**
* A set of @a DataField instances. * A set of @a DataField instances.
*/ */
+1
View File
@@ -103,6 +103,7 @@ static const unsigned int EXP = 0x100; //!< exponential numeric representation
static const unsigned int DAY = 0x200; //!< forced value list defaulting to week days static const unsigned int DAY = 0x200; //!< forced value list defaulting to week days
static const unsigned int NUM = 0x400; //!< numeric type with base class @a NumberDataType static const unsigned int NUM = 0x400; //!< numeric type with base class @a NumberDataType
static const unsigned int SPE = 0x800; //!< special marker for certain types static const unsigned int SPE = 0x800; //!< special marker for certain types
static const unsigned int CON = 0x1000; //!< marker for a constant value
/** /**
+12
View File
@@ -62,6 +62,10 @@ int main()
{"x,,str:24", "abcdefghijklmnopqrstuvwx", "10fe0700186162636465666768696a6b6c6d6e6f707172737475767778", "00", ""}, {"x,,str:24", "abcdefghijklmnopqrstuvwx", "10fe0700186162636465666768696a6b6c6d6e6f707172737475767778", "00", ""},
{"x,,str:*", "abcde", "10fe0700056162636465", "00", ""}, {"x,,str:*", "abcde", "10fe0700056162636465", "00", ""},
{"x,,str,2", "", "", "", "c"}, {"x,,str,2", "", "", "", "c"},
{"x,,str:10,=dummy", "", "10fe07000a48616c6c6f2044752120", "00", "W"},
{"x,,str:10,==dummy", "", "10fe07000a48616c6c6f2044752120", "00", "rW"},
{"x,,str:10,=dummy", "", "10fe07000a64756d6d792020202020", "00", ""},
{"x,,str:10,==dummy", "", "10fe07000a64756d6d792020202020", "00", ""},
{"x,,nts:10", "Hallo, Du!", "10fe07000a48616c6c6f2c20447521", "00", ""}, {"x,,nts:10", "Hallo, Du!", "10fe07000a48616c6c6f2c20447521", "00", ""},
{"x,,nts:10", "Hallo, Du!", "10fe07000a48616c6c6f2c20447521", "00", ""}, {"x,,nts:10", "Hallo, Du!", "10fe07000a48616c6c6f2c20447521", "00", ""},
{"x,,nts:10", "Hallo, Du", "10fe07000a48616c6c6f2c20447500", "00", ""}, {"x,,nts:10", "Hallo, Du", "10fe07000a48616c6c6f2c20447500", "00", ""},
@@ -78,6 +82,10 @@ int main()
{"x,,hex:*", "48 61 6c 6c 6f", "10fe07000548616c6c6f", "00", ""}, {"x,,hex:*", "48 61 6c 6c 6f", "10fe07000548616c6c6f", "00", ""},
{"x,,hex:11", "", "10fe07000a48616c6c6f2c20447521", "00", "rW"}, {"x,,hex:11", "", "10fe07000a48616c6c6f2c20447521", "00", "rW"},
{"x,,hex,2", "", "", "", "c"}, {"x,,hex,2", "", "", "", "c"},
{"x,,hex:5,=48 61 6c 6c 6f", "", "10fe070005ababababab", "00", "W"},
{"x,,hex:5,==48 61 6c 6c 6f", "", "10fe070005ababababab", "00", "rW"},
{"x,,hex:5,=48 61 6c 6c 6f", "", "10fe07000548616c6c6f", "00", ""},
{"x,,hex:5,==48 61 6c 6c 6f", "", "10fe07000548616c6c6f", "00", ""},
{"x,,bda", "26.10.2014","10fe07000426100614", "00", ""}, // Sunday {"x,,bda", "26.10.2014","10fe07000426100614", "00", ""}, // Sunday
{"x,,bda", "01.01.2000","10fe07000401010500", "00", ""}, // Saturday {"x,,bda", "01.01.2000","10fe07000401010500", "00", ""}, // Saturday
{"x,,bda", "31.12.2099","10fe07000431120399", "00", ""}, // Thursday {"x,,bda", "31.12.2099","10fe07000431120399", "00", ""}, // Thursday
@@ -255,6 +263,10 @@ int main()
{"x,,uch", "-", "10feffff01ff", "00", ""}, {"x,,uch", "-", "10feffff01ff", "00", ""},
{"x,,uch,10", "3.8", "10feffff0126", "00", ""}, {"x,,uch,10", "3.8", "10feffff0126", "00", ""},
{"x,,uch,-10", "380","10feffff0126", "00", ""}, {"x,,uch,-10", "380","10feffff0126", "00", ""},
{"x,,uch,=48", "", "10feffff01ab", "00", "W"},
{"x,,uch,==48", "", "10feffff01ab", "00", "rW"},
{"x,,uch,=48", "", "10feffff0130", "00", ""},
{"x,,uch,==48", "", "10feffff0130", "00", ""},
{"x,,sch", "-90", "10feffff01a6", "00", ""}, {"x,,sch", "-90", "10feffff01a6", "00", ""},
{"x,,sch", "0", "10feffff0100", "00", ""}, {"x,,sch", "0", "10feffff0100", "00", ""},
{"x,,sch", "-1", "10feffff01ff", "00", ""}, {"x,,sch", "-1", "10feffff01ff", "00", ""},
+4
View File
@@ -65,8 +65,10 @@ int main()
{"temp2,D2B,,°C,Temperatur", "", "", "", "template"}, {"temp2,D2B,,°C,Temperatur", "", "", "", "template"},
{"power,UCH,,kW", "", "", "", "template"}, {"power,UCH,,kW", "", "", "", "template"},
{"sensor,UCH,0=ok;85=circuit;170=cutoff,,Fühlerstatus", "", "", "", "template"}, {"sensor,UCH,0=ok;85=circuit;170=cutoff,,Fühlerstatus", "", "", "", "template"},
{"sensorc,UCH,=85,,Fühlerstatus", "", "", "", "template"},
{"pumpstate,UCH,0=off;1=on;2=overrun,,Pumpenstatus", "", "", "", "template"}, {"pumpstate,UCH,0=off;1=on;2=overrun,,Pumpenstatus", "", "", "", "template"},
{"tempsensor,temp;sensor,,Temperatursensor", "", "", "", "template"}, {"tempsensor,temp;sensor,,Temperatursensor", "", "", "", "template"},
{"tempsensorc,temp;sensorc,,Temperatursensor", "", "", "", "template"},
{"r,,Status01,VL/RL/AussenTemp/VLWW/SpeicherTemp/Status,,08,B511,01,,,temp1;temp1;temp2;temp1;temp1;pumpstate","28.0;24.0;4.938;35.0;41.0;4","ff08b5110101","093830f00446520400ff","d"}, {"r,,Status01,VL/RL/AussenTemp/VLWW/SpeicherTemp/Status,,08,B511,01,,,temp1;temp1;temp2;temp1;temp1;pumpstate","28.0;24.0;4.938;35.0;41.0;4","ff08b5110101","093830f00446520400ff","d"},
{"r,message circuit,message name,message comment,,25,B509,0d2800,,,tempsensor", "temp=-14.00 Temperatursensor [Temperatur];sensor=ok [Fühlerstatus]", "ff25b509030d2800", "0320ff00", "mD"}, {"r,message circuit,message name,message comment,,25,B509,0d2800,,,tempsensor", "temp=-14.00 Temperatursensor [Temperatur];sensor=ok [Fühlerstatus]", "ff25b509030d2800", "0320ff00", "mD"},
{"r,message circuit,message name,message comment,,25,B509,0d2800,,,tempsensor,,field unit,field comment", "temp=-14.00 field unit [field comment];sensor=ok [Fühlerstatus]", "ff25b509030d2800", "0320ff00", "mD"}, {"r,message circuit,message name,message comment,,25,B509,0d2800,,,tempsensor,,field unit,field comment", "temp=-14.00 field unit [field comment];sensor=ok [Fühlerstatus]", "ff25b509030d2800", "0320ff00", "mD"},
@@ -74,6 +76,8 @@ int main()
{"r,message circuit,message name,message comment,,25,B509,0d2800,,,tempsensor,,field unit,field comment", "\n \"temp\": {\"value\": -14.00, \"unit\": \"field unit\", \"comment\": \"field comment\"},\n \"sensor\": {\"value\": \"ok\", \"comment\": \"Fühlerstatus\"}", "ff25b509030d2800", "0320ff00", "mJ"}, {"r,message circuit,message name,message comment,,25,B509,0d2800,,,tempsensor,,field unit,field comment", "\n \"temp\": {\"value\": -14.00, \"unit\": \"field unit\", \"comment\": \"field comment\"},\n \"sensor\": {\"value\": \"ok\", \"comment\": \"Fühlerstatus\"}", "ff25b509030d2800", "0320ff00", "mJ"},
{"r,message circuit,message name,message comment,,25,B509,0d2800,,,temp,,field unit,field comment,,,sensor", "temp=-14.00 field unit [field comment];sensor=ok [Fühlerstatus]", "ff25b509030d2800", "0320ff00", "mD"}, {"r,message circuit,message name,message comment,,25,B509,0d2800,,,temp,,field unit,field comment,,,sensor", "temp=-14.00 field unit [field comment];sensor=ok [Fühlerstatus]", "ff25b509030d2800", "0320ff00", "mD"},
{"r,message circuit,message name,message comment,,25,B509,0d2800,,,D2C,,°C,Temperatur,,,sensor", "\n \"0\": {\"name\": \"\", \"value\": -14.00},\n \"1\": {\"name\": \"sensor\", \"value\": \"ok\"}", "ff25b509030d2800", "0320ff00", "mj"}, {"r,message circuit,message name,message comment,,25,B509,0d2800,,,D2C,,°C,Temperatur,,,sensor", "\n \"0\": {\"name\": \"\", \"value\": -14.00},\n \"1\": {\"name\": \"sensor\", \"value\": \"ok\"}", "ff25b509030d2800", "0320ff00", "mj"},
{"r,,name,,,25,B509,0d2800,,,tempsensorc", "-14.00", "ff25b509030d2800", "0320ff55", "m"},
{"r,,name,,,25,B509,0d28,,m,sensorc,,,,,,temp", "-14.00", "ff25b509030d2855", "0220ff", "m"},
{"u,,first,,,fe,0700,,x,,bda", "26.10.2014", "fffe07000426100614", "00", "p"}, {"u,,first,,,fe,0700,,x,,bda", "26.10.2014", "fffe07000426100614", "00", "p"},
{"u,broadcast,hwStatus,,,fe,b505,27,,,UCH,,,,,,UCH,,,,,,UCH,,,", "0;19;0", "10feb505042700130097", "00", ""}, {"u,broadcast,hwStatus,,,fe,b505,27,,,UCH,,,,,,UCH,,,,,,UCH,,,", "0;19;0", "10feb505042700130097", "00", ""},
{"w,,first,,,15,b509,0400,date,,bda", "26.10.2014", "ff15b50906040026100614", "00", "m"}, {"w,,first,,,15,b509,0400,date,,bda", "26.10.2014", "ff15b50906040026100614", "00", "m"},