Skip to content

Commit

Permalink
add value range and step support, fix value list validation
Browse files Browse the repository at this point in the history
  • Loading branch information
john30 committed Jan 6, 2025
1 parent 88b039e commit e795ce6
Show file tree
Hide file tree
Showing 5 changed files with 417 additions and 138 deletions.
5 changes: 3 additions & 2 deletions src/lib/ebus/contrib/tem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ result_t TemParamDataType::writeSymbols(const size_t offset, const size_t length
value = (grp << 7) | num; // grp in bits 7...11, num in bits 0...6
}
}
if (value < getMinValue() || value > getMaxValue()) {
return RESULT_ERR_OUT_OF_RANGE; // value out of range
result_t ret = checkValueRange(value);
if (ret != RESULT_OK) {
return ret;
}
return writeRawValue(value, offset, length, output, usedLength);
}
Expand Down
70 changes: 64 additions & 6 deletions src/lib/ebus/data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ result_t DataField::create(bool isWriteMessage, bool isTemplate, bool isBroadcas

string divisorStr = pluck("divisor", &row);
string valuesStr = pluck("values", &row);
string rangeStr = pluck("range", &row);
if (divisorStr.empty() && valuesStr.empty()) {
divisorStr = pluck("divisor/values", &row); // [divisor|values]
if (divisorStr.find('=') != string::npos) {
Expand Down Expand Up @@ -365,6 +366,57 @@ result_t DataField::create(bool isWriteMessage, bool isTemplate, bool isBroadcas
}
transform(typeName.begin(), typeName.end(), typeName.begin(), ::toupper);
const DataType* dataType = DataTypeList::getInstance()->get(typeName, length == REMAIN_LEN ? 0 : length);
if (dataType && dataType->isNumeric() && !rangeStr.empty()) {
const NumberDataType* numType = reinterpret_cast<const NumberDataType*>(dataType);
if (divisor != 1 && divisor != 0) {
result = numType->derive(divisor, numType->getBitCount(), &numType);
divisor = 1;
}
// either from-to or from-to:step
size_t sepPos = rangeStr.find('-', 1);
string part = rangeStr.substr(0, sepPos);
FileReader::trim(&part);
unsigned int from;
if (result == RESULT_OK) {
result = numType->parseInput(part, &from);
}
unsigned int to = from;
unsigned int inc = 0;
if (result == RESULT_OK) {
part = rangeStr.substr(sepPos+1);
FileReader::trim(&part);
sepPos = part.find(':');
if (sepPos != string::npos) {
string incStr = part.substr(sepPos + 1);
FileReader::trim(&incStr);
part = part.substr(0, sepPos);
FileReader::trim(&part);
result = numType->parseInput(incStr, &inc);
}
if (result == RESULT_OK) {
result = numType->parseInput(part, &to);
}
}
float ffrom = 0, fto = 0;
if (result == RESULT_OK) {
result = numType->getFloatFromRawValue(from, &ffrom);
}
if (result == RESULT_OK) {
result = numType->getFloatFromRawValue(to, &fto);
}
if (result == RESULT_OK && ffrom > fto) {
result = RESULT_ERR_INVALID_LIST;
}
if (result == RESULT_OK) {
result = numType->derive(from, to, inc, &numType);
};
if (result != RESULT_OK) {
*errorDescription = "\""+rangeStr+"\" in field "+formatInt(fieldIndex);
result = RESULT_ERR_OUT_OF_RANGE;
break;
}
dataType = numType;
}
if (!dataType) {
result = RESULT_ERR_NOTFOUND;
*errorDescription = "field type "+typeName+" in field "+formatInt(fieldIndex);
Expand Down Expand Up @@ -512,8 +564,11 @@ result_t SingleDataField::create(const string& name, const map<string, string>&
*returnField = new SingleDataField(name, attributes, numType, partType, byteCount);
return RESULT_OK;
}
if (values->begin()->first < numType->getMinValue() || values->rbegin()->first > numType->getMaxValue()) {
return RESULT_ERR_OUT_OF_RANGE;
for (auto& it : *values) {
result_t ret = numType->checkValueRange(it.first);
if (ret != RESULT_OK) {
return ret;
}
}
*returnField = new ValueListDataField(name, attributes, numType, partType, byteCount, *values);
return RESULT_OK;
Expand Down Expand Up @@ -775,8 +830,11 @@ result_t ValueListDataField::derive(const string& name, PartType partType, int d
}
const NumberDataType* num = reinterpret_cast<const NumberDataType*>(m_dataType);
if (!values.empty()) {
if (values.begin()->first < num->getMinValue() || values.rbegin()->first > num->getMaxValue()) {
return RESULT_ERR_INVALID_ARG; // cannot use divisor != 1 for value list field
for (auto& it : values) {
result_t ret = num->checkValueRange(it.first);
if (ret != RESULT_OK) {
return RESULT_ERR_INVALID_ARG;
}
}
fields->push_back(new ValueListDataField(useName, *attributes,
num, partType, m_length, values));
Expand Down Expand Up @@ -922,8 +980,8 @@ result_t ConstantDataField::readSymbols(const SymbolString& input, size_t offset
if (result != RESULT_OK) {
return result;
}
string value = coutput.str();
FileReader::trim(&value);
string value = coutput.str();
FileReader::trim(&value);
if (m_verify) {
if (value != m_value) {
return RESULT_ERR_OUT_OF_RANGE;
Expand Down
Loading

0 comments on commit e795ce6

Please sign in to comment.