introduced DataFieldTemplates,a dded missing type HTI

This commit is contained in:
john30
2014-11-23 14:40:18 +01:00
parent d19d89a0b0
commit 42ee567e63
2 changed files with 95 additions and 9 deletions
+44 -5
View File
@@ -38,6 +38,7 @@ static const dataType_t dataTypes[] = {
{"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 Mon=0x01 - Sun=0x07)) {"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 Mon=0x01 - Sun=0x07))
{"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 {"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) {"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)
{"HTI", 24, bt_tim, 0, 0, 5, 5, 0, 0}, // time, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x17,0x3b,0x3b)
{"HTM", 16, bt_tim, 0, 0, 5, 5, 0, 0}, // time as hh:mm, 00:00 - 23:59 (0x00,0x00 - 0x17,0x3b) {"HTM", 16, bt_tim, 0, 0, 5, 5, 0, 0}, // time as hh:mm, 00:00 - 23:59 (0x00,0x00 - 0x17,0x3b)
{"TTM", 8, bt_tim, 0, 0x90, 5, 5, 0, 0}, // truncated time (only multiple of 10 minutes), 00:00 - 24:00 (minutes div 10 + hour * 6 as integer) {"TTM", 8, bt_tim, 0, 0x90, 5, 5, 0, 0}, // truncated time (only multiple of 10 minutes), 00:00 - 24:00 (minutes div 10 + hour * 6 as integer)
{"BDY", 8, bt_num, DAY|LST, 0x07, 0, 6, 1, 0}, // weekday, "Mon" - "Sun" (0x00 - 0x06) [ebus type] {"BDY", 8, bt_num, DAY|LST, 0x07, 0, 6, 1, 0}, // weekday, "Mon" - "Sun" (0x00 - 0x06) [ebus type]
@@ -97,7 +98,7 @@ unsigned int parseInt(const char* str, int base, const unsigned int minValue, co
result_t DataField::create(vector<string>::iterator& it, result_t DataField::create(vector<string>::iterator& it,
const vector<string>::iterator end, const vector<string>::iterator end,
const map< string, DataField*> templates, DataFieldTemplates* templates,
DataField*& returnField, const bool isSetMessage, DataField*& returnField, const bool isSetMessage,
const unsigned char dstAddress) const unsigned char dstAddress)
{ {
@@ -199,20 +200,20 @@ result_t DataField::create(vector<string>::iterator& it,
if (pos == string::npos) { if (pos == string::npos) {
length = 0; length = 0;
// check for reference(s) to templates // check for reference(s) to templates
if (templates.empty() == false) { if (templates != NULL) {
istringstream stream(typeStr); istringstream stream(typeStr);
bool found = false; bool found = false;
string lengthStr; string lengthStr;
while (getline(stream, token, VALUE_SEPARATOR) != 0) { while (getline(stream, token, VALUE_SEPARATOR) != 0) {
map<string, DataField*>::const_iterator ref = templates.find(token); DataField* templ = templates->get(token);
if (ref == templates.end()) { if (templ == NULL) {
if (found == false) if (found == false)
break; // fallback to direct definition break; // fallback to direct definition
result = RESULT_ERR_INVALID_ARG; // cannot mix reference and direct definition result = RESULT_ERR_INVALID_ARG; // cannot mix reference and direct definition
break; break;
} }
found = true; found = true;
result = ref->second->derive(name, comment, unit, partType, divisor, values, fields); result = templ->derive(name, comment, unit, partType, divisor, values, fields);
if (result != RESULT_OK) if (result != RESULT_OK)
break; break;
} }
@@ -1030,3 +1031,41 @@ result_t DataFieldSet::write(istringstream& input,
return RESULT_OK; return RESULT_OK;
} }
void DataFieldTemplates::clear()
{
for (map<string, DataField*>::iterator it=m_fieldsByName.begin(); it!=m_fieldsByName.end(); it++) {
delete it->second;
it->second = NULL;
}
m_fieldsByName.clear();
}
result_t DataFieldTemplates::add(DataField* field, bool replace)
{
string name = field->getName();
map<string, DataField*>::iterator it = m_fieldsByName.find(name);
if (it != m_fieldsByName.end()) {
if (replace == false)
return RESULT_ERR_INVALID_ARG; // duplicate key
delete it->second;
it->second = field;
return RESULT_OK;
}
m_fieldsByName[name] = field;
return RESULT_OK;
}
DataField* DataFieldTemplates::get(const string name)
{
map<string, DataField*>::const_iterator ref = m_fieldsByName.find(name);
if (ref == m_fieldsByName.end())
return NULL;
return ref->second;
}
+51 -4
View File
@@ -79,6 +79,7 @@ typedef struct {
unsigned int parseInt(const char* str, int base, const unsigned int minValue, const unsigned int maxValue, result_t& result, unsigned int* length=NULL); unsigned int parseInt(const char* str, int base, const unsigned int minValue, const unsigned int maxValue, result_t& result, unsigned int* length=NULL);
class DataFieldTemplates;
class SingleDataField; class SingleDataField;
/** /**
@@ -103,7 +104,7 @@ public:
* @brief Factory method for creating new instances. * @brief Factory method for creating new instances.
* @param it the iterator to traverse for the definition parts. * @param it the iterator to traverse for the definition parts.
* @param end the iterator pointing to the end of the definition parts. * @param end the iterator pointing to the end of the definition parts.
* @param templates a map of @a DataField templates to be referenced by name. * @param templates the @a DataFieldTemplates to be referenced by name, or NULL.
* @param returnField the variable in which to store the created instance. * @param returnField the variable in which to store the created instance.
* @param isSetMessage whether the field is part of a set message (default false). * @param isSetMessage whether the field is part of a set message (default false).
* @param dstAddress the destination bus address (default @a SYN for creating a template @a DataField). * @param dstAddress the destination bus address (default @a SYN for creating a template @a DataField).
@@ -111,7 +112,7 @@ public:
* Note: the caller needs to free the created instance. * Note: the caller needs to free the created instance.
*/ */
static result_t create(vector<string>::iterator& it, const vector<string>::iterator end, static result_t create(vector<string>::iterator& it, const vector<string>::iterator end,
const map<string, DataField*> templates, DataField*& returnField, DataFieldTemplates* templates, DataField*& returnField,
const bool isSetMessage=false, const unsigned char dstAddress=SYN); const bool isSetMessage=false, const unsigned char dstAddress=SYN);
/** /**
* @brief Returns the length of this field (or contained fields) in bytes. * @brief Returns the length of this field (or contained fields) in bytes.
@@ -279,6 +280,8 @@ protected:
*/ */
virtual result_t writeSymbols(istringstream& input, const unsigned char offset, SymbolString& output) = 0; virtual result_t writeSymbols(istringstream& input, const unsigned char offset, SymbolString& output) = 0;
protected:
/** the value unit. */ /** the value unit. */
const string m_unit; const string m_unit;
/** the data type definition. */ /** the data type definition. */
@@ -386,7 +389,6 @@ protected:
/** the offset to the first bit in the binary value. */ /** the offset to the first bit in the binary value. */
const unsigned char m_bitOffset; const unsigned char m_bitOffset;
}; };
@@ -431,6 +433,8 @@ protected:
// @copydoc // @copydoc
virtual result_t writeSymbols(istringstream& input, const unsigned char offset, SymbolString& output); virtual result_t writeSymbols(istringstream& input, const unsigned char offset, SymbolString& output);
private:
/** the combined divisor to apply on the value, or 1 for none. */ /** the combined divisor to apply on the value, or 1 for none. */
const unsigned int m_divisor; const unsigned int m_divisor;
@@ -478,6 +482,8 @@ protected:
// @copydoc // @copydoc
virtual result_t writeSymbols(istringstream& input, const unsigned char offset, SymbolString& output); virtual result_t writeSymbols(istringstream& input, const unsigned char offset, SymbolString& output);
private:
/** the value=text assignments. */ /** the value=text assignments. */
map<unsigned int, string> m_values; map<unsigned int, string> m_values;
@@ -540,7 +546,7 @@ public:
SymbolString& slaveData, unsigned char slaveOffset, SymbolString& slaveData, unsigned char slaveOffset,
char separator); char separator);
protected: private:
/** the @a vector of @a SingleDataField instances part of this set. */ /** the @a vector of @a SingleDataField instances part of this set. */
vector<SingleDataField*> m_fields; vector<SingleDataField*> m_fields;
@@ -548,4 +554,45 @@ protected:
}; };
/**
* @brief A map of template @a DataField instances.
*/
class DataFieldTemplates
{
public:
/**
* @brief Constructs a new instance.
*/
DataFieldTemplates() {}
/**
* @brief Destructor.
*/
virtual ~DataFieldTemplates() { clear(); }
/**
* @brief Removes all @a DataField instances.
*/
void clear();
/**
* @brief Adds a template @a DataField instance to this map.
* @param field the @a DataField instance to add.
* @param replace whether replacing an already stored instance is allowed.
* @return @a RESULT_OK on success, or an error code.
* Note: the caller may not free the added instance on success.
*/
result_t add(DataField* message, bool replace=false);
/**
* @brief Gets the template @a DataField instance with the specified name.
* @return the template @a DataField instance, or NULL.
* Note: the caller may not free the returned instance.
*/
DataField* get(string name);
private:
/** the known template @a DataField instances by name. */
map<string, DataField*> m_fieldsByName;
};
#endif // LIBEBUS_DATA_H_ #endif // LIBEBUS_DATA_H_