From cfe66cbf6f929b221749be067de55e4fbba6c6d0 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 19 Feb 2017 11:36:44 +0100 Subject: [PATCH] also check allowed range in NumberDataType::readSymbols(), added appendSeparatorDivisor param to DataType::dump(), added iterator access to DataTypeList --- src/lib/ebus/datatype.cpp | 32 ++++++++++++++++++++++++++------ src/lib/ebus/datatype.h | 18 +++++++++++++++--- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/lib/ebus/datatype.cpp b/src/lib/ebus/datatype.cpp index 647327d4..91161ef5 100644 --- a/src/lib/ebus/datatype.cpp +++ b/src/lib/ebus/datatype.cpp @@ -135,7 +135,7 @@ void printErrorPos(ostream& out, vector::iterator begin, const vector(length); } } - output << FIELD_SEPARATOR; + if (appendSeparatorDivisor) { + output << FIELD_SEPARATOR; + } return false; } @@ -594,11 +596,14 @@ unsigned char NumberDataType::calcPrecision(const int divisor) { return precision; } -bool NumberDataType::dump(ostream& output, unsigned char length) const { +bool NumberDataType::dump(ostream& output, unsigned char length, const bool appendSeparatorDivisor) const { if (m_bitCount < 8) { - DataType::dump(output, m_bitCount); + DataType::dump(output, m_bitCount, appendSeparatorDivisor); } else { - DataType::dump(output, length); + DataType::dump(output, length, appendSeparatorDivisor); + } + if (!appendSeparatorDivisor) { + return false; } if (m_baseType) { if (m_baseType->m_divisor != m_divisor) { @@ -710,6 +715,7 @@ result_t NumberDataType::readRawValue(SymbolString& input, if (m_bitCount < 8) { value &= (1 << m_bitCount) - 1; } + return RESULT_OK; } @@ -734,7 +740,21 @@ result_t NumberDataType::readSymbols(SymbolString& input, const bool isMaster, return RESULT_OK; } - bool negative = hasFlag(SIG) && (value & (1 << (m_bitCount - 1))) != 0; + bool negative; + if (hasFlag(SIG)) { // signed value + negative = (value & (1 << (m_bitCount - 1))) != 0; + if (negative) { // negative signed value + if (value < m_minValue) { + return RESULT_ERR_OUT_OF_RANGE; // value out of range + } + } else if (value > m_maxValue) { + return RESULT_ERR_OUT_OF_RANGE; // value out of range + } + } else if (value < m_minValue || value > m_maxValue) { + return RESULT_ERR_OUT_OF_RANGE; // value out of range + } else { + negative = false; + } if (m_bitCount == 32) { if (hasFlag(EXP)) { // IEEE 754 binary32 float val; diff --git a/src/lib/ebus/datatype.h b/src/lib/ebus/datatype.h index 1c3d167c..ceb16cdd 100644 --- a/src/lib/ebus/datatype.h +++ b/src/lib/ebus/datatype.h @@ -212,12 +212,13 @@ class DataType { /** * Dump the type identifier with the specified length and optionally the - * divisor to the output (@a FIELD_SEPARATOR is always appended!). + * divisor to the output. * @param output the @a ostream to dump to. * @param length the number of symbols to read/write. + * @param appendSeparatorDivisor whether to append a @a FIELD_SEPARATOR followed by the divisor (if available). * @return true when a non-default divisor was written to the output. */ - virtual bool dump(ostream& output, const unsigned char length) const; + virtual bool dump(ostream& output, const unsigned char length, const bool appendSeparatorDivisor = true) const; /** * Internal method for reading the numeric raw value from a @a SymbolString. @@ -435,7 +436,7 @@ class NumberDataType : public DataType { static unsigned char calcPrecision(const int divisor); // @copydoc - virtual bool dump(ostream& output, const unsigned char length) const; + virtual bool dump(ostream& output, const unsigned char length, const bool appendSeparatorDivisor = true) const; /** * Derive a new @a NumberDataType from this. @@ -576,6 +577,17 @@ class DataTypeList { */ DataType* get(const string id, const unsigned char length = 0); + /** + * Returns an iterator pointing to the first ID/@a DataType pair. + * @return an iterator pointing to the first ID/@a DataType pair. + */ + map::const_iterator begin() const { return m_typesById.begin(); } + + /** + * Returns an iterator pointing one past the last ID/@a DataType pair. + * @return an iterator pointing one past the last ID/@a DataType pair. + */ + map::const_iterator end() const { return m_typesById.end(); } private: /** the known @a DataType instances by ID only. */