added isNumeric() to DataType and use this instead of checking typeid(NumberDataType), added isMaster argument to readSymbols() and writeSymbols()

This commit is contained in:
john30
2016-10-03 15:22:19 +02:00
parent 639e4e7858
commit e116cadf3f
4 changed files with 63 additions and 55 deletions
+17 -21
View File
@@ -225,7 +225,6 @@ result_t SingleDataField::create(const string id, const unsigned char length,
const PartType partType, int divisor, map<unsigned int, string> values, const PartType partType, int divisor, map<unsigned int, string> values,
SingleDataField* &returnField) SingleDataField* &returnField)
{ {
DataType* dataType = DataTypeList::getInstance()->get(id, length==REMAIN_LEN ? 0 : length); DataType* dataType = DataTypeList::getInstance()->get(id, length==REMAIN_LEN ? 0 : length);
if (!dataType) { if (!dataType) {
return RESULT_ERR_NOTFOUND; 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 return RESULT_ERR_OUT_OF_RANGE; // invalid length
} }
} }
if (typeid(*dataType)==typeid(StringDataType) if (dataType->isNumeric()) {
|| 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)) {
NumberDataType* numType = (NumberDataType*)dataType; NumberDataType* numType = (NumberDataType*)dataType;
if (values.empty() && numType->hasFlag(DAY)) { if (values.empty() && numType->hasFlag(DAY)) {
for (unsigned int i = 0; i < sizeof(dayNames) / sizeof(dayNames[0]); i++) 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); returnField = new ValueListDataField(name, comment, unit, numType, partType, byteCount, values);
return RESULT_OK; 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) void SingleDataField::dump(ostream& output)
@@ -366,7 +362,7 @@ result_t SingleDataField::read(const PartType partType,
output << m_name << "="; 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) if (result != RESULT_OK)
return result; return result;
@@ -407,21 +403,21 @@ result_t SingleDataField::write(istringstream& input,
default: default:
return RESULT_ERR_INVALID_PART; 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, const unsigned char offset,
ostringstream& output, OutputFormat outputFormat) 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, result_t SingleDataField::writeSymbols(istringstream& input,
const unsigned char offset, 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() SingleDataField* SingleDataField::clone()
@@ -436,7 +432,7 @@ result_t SingleDataField::derive(string name, string comment,
{ {
if (m_partType != pt_any && partType == pt_any) if (m_partType != pt_any && partType == pt_any)
return RESULT_ERR_INVALID_PART; // cannot create a template from a concrete instance 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())) if (!numeric && (divisor != 0 || !values.empty()))
return RESULT_ERR_INVALID_ARG; // cannot set divisor or values for non-numeric field return RESULT_ERR_INVALID_ARG; // cannot set divisor or values for non-numeric field
if (name.empty()) if (name.empty())
@@ -463,7 +459,7 @@ result_t SingleDataField::derive(string name, string comment,
bool SingleDataField::hasField(const char* fieldName, bool numeric) 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); 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) bool SingleDataField::hasFullByteOffset(bool after)
{ {
if (m_length > 1 || typeid(*m_dataType) != typeid(NumberDataType)) { if (m_length > 1 || !m_dataType->isNumeric()) {
return true; return true;
} }
NumberDataType* num = (NumberDataType*)m_dataType; NumberDataType* num = (NumberDataType*)m_dataType;
@@ -540,7 +536,7 @@ void ValueListDataField::dump(ostream& output)
dumpString(output, m_comment); dumpString(output, m_comment);
} }
result_t ValueListDataField::readSymbols(SymbolString& input, result_t ValueListDataField::readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset, const unsigned char offset,
ostringstream& output, OutputFormat outputFormat) ostringstream& output, OutputFormat outputFormat)
{ {
@@ -571,7 +567,7 @@ result_t ValueListDataField::readSymbols(SymbolString& input,
result_t ValueListDataField::writeSymbols(istringstream& input, result_t ValueListDataField::writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char offset,
SymbolString& output, unsigned char* usedLength) SymbolString& output, const bool isMaster, unsigned char* usedLength)
{ {
NumberDataType* numType = (NumberDataType*)m_dataType; NumberDataType* numType = (NumberDataType*)m_dataType;
if (isIgnored()) if (isIgnored())
+15 -13
View File
@@ -261,9 +261,9 @@ public:
* Note: the caller needs to free the created instance. * Note: the caller needs to free the created instance.
*/ */
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); SingleDataField* &returnField);
/** /**
* Get the value unit. * Get the value unit.
@@ -288,9 +288,9 @@ public:
// @copydoc // @copydoc
virtual result_t derive(string name, string comment, virtual result_t derive(string name, string comment,
string unit, const PartType partType, string unit, const PartType partType,
int divisor, map<unsigned int, string> values, int divisor, map<unsigned int, string> values,
vector<SingleDataField*>& fields); vector<SingleDataField*>& fields);
/** /**
* Get whether this field uses a full byte offset. * Get whether this field uses a full byte offset.
@@ -327,26 +327,28 @@ protected:
/** /**
* Internal method for reading the field from a @a SymbolString. * Internal method for reading the field from a @a SymbolString.
* @param input the unescaped @a SymbolString to read the binary value from. * @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 offset the offset in the @a SymbolString.
* @param output the ostringstream to append the formatted value to. * @param output the ostringstream to append the formatted value to.
* @param outputFormat the @a OutputFormat options to use. * @param outputFormat the @a OutputFormat options to use.
* @return @a RESULT_OK on success, or an error code. * @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 offset,
ostringstream& output, OutputFormat outputFormat); ostringstream& output, OutputFormat outputFormat);
/** /**
* Internal method for writing the field to a @a SymbolString. * Internal method for writing the field to a @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 offset the offset in the @a SymbolString. * @param offset the offset in the @a SymbolString.
* @param output the unescaped @a SymbolString to write the binary value to. * @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. * @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. * @return @a RESULT_OK on success, or an error code.
*/ */
virtual result_t writeSymbols(istringstream& input, virtual result_t writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char offset,
SymbolString& output, unsigned char* usedLength); SymbolString& output, const bool isMaster, unsigned char* usedLength);
protected: protected:
@@ -408,14 +410,14 @@ public:
protected: protected:
// @copydoc // @copydoc
virtual result_t readSymbols(SymbolString& input, virtual result_t readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset, const unsigned char offset,
ostringstream& output, OutputFormat outputFormat); ostringstream& output, OutputFormat outputFormat);
// @copydoc // @copydoc
virtual result_t writeSymbols(istringstream& input, virtual result_t writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char offset,
SymbolString& output, unsigned char* usedLength); SymbolString& output, const bool isMaster, unsigned char* usedLength);
private: private:
+10 -8
View File
@@ -140,8 +140,9 @@ result_t StringDataType::readRawValue(SymbolString& input, const unsigned char o
return RESULT_EMPTY; return RESULT_EMPTY;
} }
result_t StringDataType::readSymbols(SymbolString& input, const unsigned char baseOffset, result_t StringDataType::readSymbols(SymbolString& input, const bool isMaster,
const unsigned char length, ostringstream& output, OutputFormat outputFormat) const unsigned char baseOffset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat)
{ {
size_t start = 0, count = length; size_t start = 0, count = length;
int incr = 1; int incr = 1;
@@ -182,7 +183,7 @@ result_t StringDataType::readSymbols(SymbolString& input, const unsigned char ba
result_t StringDataType::writeSymbols(istringstream& input, result_t StringDataType::writeSymbols(istringstream& input,
unsigned char baseOffset, const unsigned char length, 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; size_t start = 0, count = length;
bool remainder = count==REMAIN_LEN && hasFlag(ADJ); bool remainder = count==REMAIN_LEN && hasFlag(ADJ);
@@ -261,8 +262,9 @@ result_t DateTimeDataType::readRawValue(SymbolString& input, const unsigned char
return RESULT_EMPTY; return RESULT_EMPTY;
} }
result_t DateTimeDataType::readSymbols(SymbolString& input, const unsigned char baseOffset, result_t DateTimeDataType::readSymbols(SymbolString& input, const bool isMaster,
const unsigned char length, ostringstream& output, OutputFormat outputFormat) const unsigned char baseOffset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat)
{ {
size_t start = 0, count = length; size_t start = 0, count = length;
int incr = 1; int incr = 1;
@@ -365,7 +367,7 @@ result_t DateTimeDataType::readSymbols(SymbolString& input, const unsigned char
result_t DateTimeDataType::writeSymbols(istringstream& input, result_t DateTimeDataType::writeSymbols(istringstream& input,
unsigned char baseOffset, const unsigned char length, 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; size_t start = 0, count = length;
bool remainder = count==REMAIN_LEN && hasFlag(ADJ); bool remainder = count==REMAIN_LEN && hasFlag(ADJ);
@@ -625,7 +627,7 @@ result_t NumberDataType::readRawValue(SymbolString& input,
return RESULT_OK; 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, const unsigned char baseOffset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat) ostringstream& output, OutputFormat outputFormat)
{ {
@@ -769,7 +771,7 @@ result_t NumberDataType::writeRawValue(unsigned int value,
result_t NumberDataType::writeSymbols(istringstream& input, result_t NumberDataType::writeSymbols(istringstream& input,
const unsigned char baseOffset, const unsigned char length, const unsigned char baseOffset, const unsigned char length,
SymbolString& output, unsigned char* usedLength) SymbolString& output, const bool isMaster, unsigned char* usedLength)
{ {
unsigned int value; unsigned int value;
+21 -13
View File
@@ -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 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 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
/** /**
@@ -178,15 +179,20 @@ public:
bool hasFlag(const unsigned int flag) const { return (m_flags & flag) != 0; } 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); } 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); } 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). * @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. * Internal method for reading the field from a @a SymbolString.
* @param input the unescaped @a SymbolString to read the binary value from. * @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 offset the offset in the @a SymbolString.
* @param length the number of symbols to read. * @param length the number of symbols to read.
* @param output the ostringstream to append the formatted value to. * @param output the ostringstream to append the formatted value to.
* @param outputFormat the @a OutputFormat options to use. * @param outputFormat the @a OutputFormat options to use.
* @return @a RESULT_OK on success, or an error code. * @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, const unsigned char offset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat) = 0; ostringstream& output, OutputFormat outputFormat) = 0;
@@ -232,12 +239,13 @@ public:
* @param offset the offset in the @a SymbolString. * @param offset the offset in the @a SymbolString.
* @param length the number of symbols to write, or @a REMAIN_LEN. * @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 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. * @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. * @return @a RESULT_OK on success, or an error code.
*/ */
virtual result_t writeSymbols(istringstream& input, virtual result_t writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
SymbolString& output, unsigned char* usedLength) = 0; SymbolString& output, const bool isMaster, unsigned char* usedLength) = 0;
protected: protected:
@@ -286,14 +294,14 @@ public:
unsigned int& value); unsigned int& value);
// @copydoc // @copydoc
virtual result_t readSymbols(SymbolString& input, virtual result_t readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat); ostringstream& output, OutputFormat outputFormat);
// @copydoc // @copydoc
virtual result_t writeSymbols(istringstream& input, virtual result_t writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
SymbolString& output, unsigned char* usedLength); SymbolString& output, const bool isMaster, unsigned char* usedLength);
private: private:
@@ -344,14 +352,14 @@ public:
unsigned int& value); unsigned int& value);
// @copydoc // @copydoc
virtual result_t readSymbols(SymbolString& input, virtual result_t readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat); ostringstream& output, OutputFormat outputFormat);
// @copydoc // @copydoc
virtual result_t writeSymbols(istringstream& input, virtual result_t writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
SymbolString& output, unsigned char* usedLength); SymbolString& output, const bool isMaster, unsigned char* usedLength);
private: private:
@@ -383,7 +391,7 @@ public:
*/ */
NumberDataType(const string id, const unsigned char bitCount, const unsigned short flags, const unsigned int replacement, 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) 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. * 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, NumberDataType(const string id, const unsigned char bitCount, const unsigned short flags, const unsigned int replacement,
const short firstBit, const int divisor) const short firstBit, const int divisor)
: DataType(id, bitCount, flags, replacement), m_minValue(0), m_maxValue((1<<bitCount)-1), m_divisor(divisor), m_precision(0), m_firstBit(firstBit), m_baseType(NULL) {} : DataType(id, bitCount, flags|NUM, replacement), m_minValue(0), m_maxValue((1<<bitCount)-1), m_divisor(divisor), m_precision(0), m_firstBit(firstBit), m_baseType(NULL) {}
/** /**
* Destructor. * Destructor.
@@ -424,7 +432,7 @@ public:
* not necessary. * not necessary.
* @return @a RESULT_OK on success, or an error code. * @return @a RESULT_OK on success, or an error code.
*/ */
result_t derive(int divisor, unsigned char bitCount, NumberDataType* &derived); virtual result_t derive(int divisor, unsigned char bitCount, NumberDataType* &derived);
/** /**
* @return the minimum raw value. * @return the minimum raw value.
@@ -457,7 +465,7 @@ public:
unsigned int& value); unsigned int& value);
// @copydoc // @copydoc
virtual result_t readSymbols(SymbolString& input, virtual result_t readSymbols(SymbolString& input, const bool isMaster,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
ostringstream& output, OutputFormat outputFormat); ostringstream& output, OutputFormat outputFormat);
@@ -478,7 +486,7 @@ public:
// @copydoc // @copydoc
virtual result_t writeSymbols(istringstream& input, virtual result_t writeSymbols(istringstream& input,
const unsigned char offset, const unsigned char length, const unsigned char offset, const unsigned char length,
SymbolString& output, unsigned char* usedLength); SymbolString& output, const bool isMaster, unsigned char* usedLength);
private: private: