From e116cadf3f0e377a9864711a711e12280b871982 Mon Sep 17 00:00:00 2001 From: john30 Date: Mon, 3 Oct 2016 15:22:19 +0200 Subject: [PATCH] added isNumeric() to DataType and use this instead of checking typeid(NumberDataType), added isMaster argument to readSymbols() and writeSymbols() --- src/lib/ebus/data.cpp | 38 +++++++++++++++++--------------------- src/lib/ebus/data.h | 28 +++++++++++++++------------- src/lib/ebus/datatype.cpp | 18 ++++++++++-------- src/lib/ebus/datatype.h | 34 +++++++++++++++++++++------------- 4 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index 637e4ee3..1c263c43 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -225,7 +225,6 @@ result_t SingleDataField::create(const string id, const unsigned char length, const PartType partType, int divisor, map values, SingleDataField* &returnField) { - DataType* dataType = DataTypeList::getInstance()->get(id, length==REMAIN_LEN ? 0 : length); if (!dataType) { return RESULT_ERR_NOTFOUND; @@ -251,14 +250,7 @@ result_t SingleDataField::create(const string id, const unsigned char length, return RESULT_ERR_OUT_OF_RANGE; // invalid length } } - if (typeid(*dataType)==typeid(StringDataType) - || typeid(*dataType)==typeid(DateTimeDataType)) { - if (divisor != 0 || !values.empty()) - return RESULT_ERR_INVALID_ARG; // cannot set divisor or values for string field - returnField = new SingleDataField(name, comment, unit, (StringDataType*)dataType, partType, byteCount); - return RESULT_OK; - } - if (typeid(*dataType)==typeid(NumberDataType)) { + if (dataType->isNumeric()) { NumberDataType* numType = (NumberDataType*)dataType; if (values.empty() && numType->hasFlag(DAY)) { for (unsigned int i = 0; i < sizeof(dayNames) / sizeof(dayNames[0]); i++) @@ -278,7 +270,11 @@ result_t SingleDataField::create(const string id, const unsigned char length, returnField = new ValueListDataField(name, comment, unit, numType, partType, byteCount, values); return RESULT_OK; } - return RESULT_ERR_NOTFOUND; + if (divisor != 0 || !values.empty()) { + return RESULT_ERR_INVALID_ARG; // cannot set divisor or values for string field + } + returnField = new SingleDataField(name, comment, unit, (StringDataType*)dataType, partType, byteCount); + return RESULT_OK; } void SingleDataField::dump(ostream& output) @@ -366,7 +362,7 @@ result_t SingleDataField::read(const PartType partType, output << m_name << "="; } - result_t result = readSymbols(data, offset, output, outputFormat); + result_t result = readSymbols(data, m_partType==pt_masterData, offset, output, outputFormat); if (result != RESULT_OK) return result; @@ -407,21 +403,21 @@ result_t SingleDataField::write(istringstream& input, default: return RESULT_ERR_INVALID_PART; } - return writeSymbols(input, (const unsigned char)offset, data, length); + return writeSymbols(input, (const unsigned char)offset, data, m_partType==pt_masterData, length); } -result_t SingleDataField::readSymbols(SymbolString& input, +result_t SingleDataField::readSymbols(SymbolString& input, const bool isMaster, const unsigned char offset, ostringstream& output, OutputFormat outputFormat) { - return m_dataType->readSymbols(input, offset, m_length, output, outputFormat); + return m_dataType->readSymbols(input, isMaster, offset, m_length, output, outputFormat); } result_t SingleDataField::writeSymbols(istringstream& input, const unsigned char offset, - SymbolString& output, unsigned char* usedLength) + SymbolString& output, const bool isMaster, unsigned char* usedLength) { - return m_dataType->writeSymbols(input, offset, m_length, output, usedLength); + return m_dataType->writeSymbols(input, offset, m_length, output, isMaster, usedLength); } SingleDataField* SingleDataField::clone() @@ -436,7 +432,7 @@ result_t SingleDataField::derive(string name, string comment, { if (m_partType != pt_any && partType == pt_any) return RESULT_ERR_INVALID_PART; // cannot create a template from a concrete instance - bool numeric = typeid(*m_dataType)==typeid(NumberDataType); + bool numeric = m_dataType->isNumeric(); if (!numeric && (divisor != 0 || !values.empty())) return RESULT_ERR_INVALID_ARG; // cannot set divisor or values for non-numeric field if (name.empty()) @@ -463,7 +459,7 @@ result_t SingleDataField::derive(string name, string comment, bool SingleDataField::hasField(const char* fieldName, bool numeric) { - bool numericType = typeid(*m_dataType)==typeid(NumberDataType); + bool numericType = m_dataType->isNumeric(); return numeric==numericType && (fieldName==NULL || fieldName==m_name); } @@ -478,7 +474,7 @@ unsigned char SingleDataField::getLength(PartType partType, unsigned char maxLen bool SingleDataField::hasFullByteOffset(bool after) { - if (m_length > 1 || typeid(*m_dataType) != typeid(NumberDataType)) { + if (m_length > 1 || !m_dataType->isNumeric()) { return true; } NumberDataType* num = (NumberDataType*)m_dataType; @@ -540,7 +536,7 @@ void ValueListDataField::dump(ostream& output) dumpString(output, m_comment); } -result_t ValueListDataField::readSymbols(SymbolString& input, +result_t ValueListDataField::readSymbols(SymbolString& input, const bool isMaster, const unsigned char offset, ostringstream& output, OutputFormat outputFormat) { @@ -571,7 +567,7 @@ result_t ValueListDataField::readSymbols(SymbolString& input, result_t ValueListDataField::writeSymbols(istringstream& input, const unsigned char offset, - SymbolString& output, unsigned char* usedLength) + SymbolString& output, const bool isMaster, unsigned char* usedLength) { NumberDataType* numType = (NumberDataType*)m_dataType; if (isIgnored()) diff --git a/src/lib/ebus/data.h b/src/lib/ebus/data.h index 5dac75fd..852ac472 100644 --- a/src/lib/ebus/data.h +++ b/src/lib/ebus/data.h @@ -261,9 +261,9 @@ public: * Note: the caller needs to free the created instance. */ static result_t create(const string id, const unsigned char length, - const string name, const string comment, const string unit, - const PartType partType, int divisor, map values, - SingleDataField* &returnField); + const string name, const string comment, const string unit, + const PartType partType, int divisor, map values, + SingleDataField* &returnField); /** * Get the value unit. @@ -288,9 +288,9 @@ public: // @copydoc virtual result_t derive(string name, string comment, - string unit, const PartType partType, - int divisor, map values, - vector& fields); + string unit, const PartType partType, + int divisor, map values, + vector& fields); /** * Get whether this field uses a full byte offset. @@ -327,26 +327,28 @@ protected: /** * Internal method for reading the field from a @a SymbolString. * @param input the unescaped @a SymbolString to read the binary value from. + * @param isMaster whether the @a SymbolString is the master part. * @param offset the offset in the @a SymbolString. * @param output the ostringstream to append the formatted value to. * @param outputFormat the @a OutputFormat options to use. * @return @a RESULT_OK on success, or an error code. */ - virtual result_t readSymbols(SymbolString& input, - const unsigned char offset, - ostringstream& output, OutputFormat outputFormat); + virtual result_t readSymbols(SymbolString& input, const bool isMaster, + const unsigned char offset, + ostringstream& output, OutputFormat outputFormat); /** * Internal method for writing the field to a @a SymbolString. * @param input the @a istringstream to parse the formatted value from. * @param offset the offset in the @a SymbolString. * @param output the unescaped @a SymbolString to write the binary value to. + * @param isMaster whether the @a SymbolString is the master part. * @param usedLength the variable in which to store the used length in bytes, or NULL. * @return @a RESULT_OK on success, or an error code. */ virtual result_t writeSymbols(istringstream& input, - const unsigned char offset, - SymbolString& output, unsigned char* usedLength); + const unsigned char offset, + SymbolString& output, const bool isMaster, unsigned char* usedLength); protected: @@ -408,14 +410,14 @@ public: protected: // @copydoc - virtual result_t readSymbols(SymbolString& input, + 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, unsigned char* usedLength); + SymbolString& output, const bool isMaster, unsigned char* usedLength); private: diff --git a/src/lib/ebus/datatype.cpp b/src/lib/ebus/datatype.cpp index 55b00263..7bdc83d7 100644 --- a/src/lib/ebus/datatype.cpp +++ b/src/lib/ebus/datatype.cpp @@ -140,8 +140,9 @@ result_t StringDataType::readRawValue(SymbolString& input, const unsigned char o return RESULT_EMPTY; } -result_t StringDataType::readSymbols(SymbolString& input, const unsigned char baseOffset, - const unsigned char length, ostringstream& output, OutputFormat outputFormat) +result_t StringDataType::readSymbols(SymbolString& input, const bool isMaster, + const unsigned char baseOffset, const unsigned char length, + ostringstream& output, OutputFormat outputFormat) { size_t start = 0, count = length; int incr = 1; @@ -182,7 +183,7 @@ result_t StringDataType::readSymbols(SymbolString& input, const unsigned char ba result_t StringDataType::writeSymbols(istringstream& input, unsigned char baseOffset, const unsigned char length, - SymbolString& output, unsigned char* usedLength) + SymbolString& output, const bool isMaster, unsigned char* usedLength) { size_t start = 0, count = length; bool remainder = count==REMAIN_LEN && hasFlag(ADJ); @@ -261,8 +262,9 @@ result_t DateTimeDataType::readRawValue(SymbolString& input, const unsigned char return RESULT_EMPTY; } -result_t DateTimeDataType::readSymbols(SymbolString& input, const unsigned char baseOffset, - const unsigned char length, ostringstream& output, OutputFormat outputFormat) +result_t DateTimeDataType::readSymbols(SymbolString& input, const bool isMaster, + const unsigned char baseOffset, const unsigned char length, + ostringstream& output, OutputFormat outputFormat) { size_t start = 0, count = length; int incr = 1; @@ -365,7 +367,7 @@ result_t DateTimeDataType::readSymbols(SymbolString& input, const unsigned char result_t DateTimeDataType::writeSymbols(istringstream& input, unsigned char baseOffset, const unsigned char length, - SymbolString& output, unsigned char* usedLength) + SymbolString& output, const bool isMaster, unsigned char* usedLength) { size_t start = 0, count = length; bool remainder = count==REMAIN_LEN && hasFlag(ADJ); @@ -625,7 +627,7 @@ result_t NumberDataType::readRawValue(SymbolString& input, return RESULT_OK; } -result_t NumberDataType::readSymbols(SymbolString& input, +result_t NumberDataType::readSymbols(SymbolString& input, const bool isMaster, const unsigned char baseOffset, const unsigned char length, ostringstream& output, OutputFormat outputFormat) { @@ -769,7 +771,7 @@ result_t NumberDataType::writeRawValue(unsigned int value, result_t NumberDataType::writeSymbols(istringstream& input, const unsigned char baseOffset, const unsigned char length, - SymbolString& output, unsigned char* usedLength) + SymbolString& output, const bool isMaster, unsigned char* usedLength) { unsigned int value; diff --git a/src/lib/ebus/datatype.h b/src/lib/ebus/datatype.h index 2e4403f4..91aec3fd 100644 --- a/src/lib/ebus/datatype.h +++ b/src/lib/ebus/datatype.h @@ -99,6 +99,7 @@ static const unsigned int REQ = 0x40; //!< value may not be NULL static const unsigned int HCD = 0x80; //!< binary representation is hex converted to decimal and interpreted as 2 digits (also requires #BCD) 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 NUM = 0x400; //!< numeric type with base class @a NumberDataType /** @@ -178,15 +179,20 @@ public: bool hasFlag(const unsigned int flag) const { return (m_flags & flag) != 0; } /** - * @return whether this field is ignored. + * @return whether this type is ignored. */ bool isIgnored() const { return hasFlag(IGN); } /** - * @return whether this field has an . + * @return whether this type has an adjustable length. */ bool isAdjustableLength() const { return hasFlag(ADJ); } + /** + * @return whether this field is derived from @a NumberDataType. + */ + bool isNumeric() const { return hasFlag(NUM); } + /** * @return the replacement value (fill-up value for @a StringDataType, no replacement if equal to @a NumberDataType#minValue). */ @@ -216,13 +222,14 @@ public: /** * Internal method for reading the field from a @a SymbolString. * @param input the unescaped @a SymbolString to read the binary value from. + * @param isMaster whether the @a SymbolString is the master part. * @param offset the offset in the @a SymbolString. * @param length the number of symbols to read. * @param output the ostringstream to append the formatted value to. * @param outputFormat the @a OutputFormat options to use. * @return @a RESULT_OK on success, or an error code. */ - virtual result_t readSymbols(SymbolString& input, + virtual result_t readSymbols(SymbolString& input, const bool isMaster, const unsigned char offset, const unsigned char length, ostringstream& output, OutputFormat outputFormat) = 0; @@ -232,12 +239,13 @@ public: * @param offset the offset in the @a SymbolString. * @param length the number of symbols to write, or @a REMAIN_LEN. * @param output the unescaped @a SymbolString to write the binary value to. + * @param isMaster whether the @a SymbolString is the master part. * @param usedLength the variable in which to store the used length in bytes, or NULL. * @return @a RESULT_OK on success, or an error code. */ virtual result_t writeSymbols(istringstream& input, const unsigned char offset, const unsigned char length, - SymbolString& output, unsigned char* usedLength) = 0; + SymbolString& output, const bool isMaster, unsigned char* usedLength) = 0; protected: @@ -286,14 +294,14 @@ public: unsigned int& value); // @copydoc - virtual result_t readSymbols(SymbolString& input, + virtual result_t readSymbols(SymbolString& input, const bool isMaster, const unsigned char offset, const unsigned char length, ostringstream& output, OutputFormat outputFormat); // @copydoc virtual result_t writeSymbols(istringstream& input, const unsigned char offset, const unsigned char length, - SymbolString& output, unsigned char* usedLength); + SymbolString& output, const bool isMaster, unsigned char* usedLength); private: @@ -344,14 +352,14 @@ public: unsigned int& value); // @copydoc - virtual result_t readSymbols(SymbolString& input, + virtual result_t readSymbols(SymbolString& input, const bool isMaster, const unsigned char offset, const unsigned char length, ostringstream& output, OutputFormat outputFormat); // @copydoc virtual result_t writeSymbols(istringstream& input, const unsigned char offset, const unsigned char length, - SymbolString& output, unsigned char* usedLength); + SymbolString& output, const bool isMaster, unsigned char* usedLength); private: @@ -383,7 +391,7 @@ public: */ NumberDataType(const string id, const unsigned char bitCount, const unsigned short flags, const unsigned int replacement, const unsigned int minValue, const unsigned int maxValue, const int divisor) - : DataType(id, bitCount, flags, replacement), m_minValue(minValue), m_maxValue(maxValue), m_divisor(divisor), m_precision(calcPrecision(divisor)), m_firstBit(0), m_baseType(NULL) {} + : DataType(id, bitCount, flags|NUM, replacement), m_minValue(minValue), m_maxValue(maxValue), m_divisor(divisor), m_precision(calcPrecision(divisor)), m_firstBit(0), m_baseType(NULL) {} /** * Constructs a new instance for less than 8 bits. @@ -396,7 +404,7 @@ public: */ NumberDataType(const string id, const unsigned char bitCount, const unsigned short flags, const unsigned int replacement, const short firstBit, const int divisor) - : DataType(id, bitCount, flags, replacement), m_minValue(0), m_maxValue((1<