started knx integration
This commit is contained in:
@@ -793,6 +793,70 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS
|
||||
return readFromRawValue(value, outputFormat, output);
|
||||
}
|
||||
|
||||
result_t NumberDataType::getFloatFromRawValue(unsigned int value, float* output) const {
|
||||
int signedValue;
|
||||
if (!hasFlag(REQ) && value == m_replacement) {
|
||||
return RESULT_EMPTY;
|
||||
}
|
||||
|
||||
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 = uintToFloat(value);
|
||||
if (val != val) { // !isnan(val)
|
||||
return RESULT_EMPTY;
|
||||
}
|
||||
if (val != 0.0) {
|
||||
if (m_divisor < 0) {
|
||||
val *= static_cast<float>(-m_divisor);
|
||||
} else if (m_divisor > 1) {
|
||||
val /= static_cast<float>(m_divisor);
|
||||
}
|
||||
}
|
||||
*output = static_cast<float>(val);
|
||||
return RESULT_OK;
|
||||
}
|
||||
// less than 32 bit
|
||||
if (!negative) {
|
||||
if (m_divisor < 0) {
|
||||
*output = static_cast<float>(value) * static_cast<float>(-m_divisor);
|
||||
} else if (m_divisor <= 1) {
|
||||
*output = static_cast<float>(value);
|
||||
} else {
|
||||
*output = static_cast<float>(value) / static_cast<float>(m_divisor);
|
||||
}
|
||||
return RESULT_OK;
|
||||
}
|
||||
signedValue = static_cast<int>(value); // negative signed value
|
||||
} else if (negative) { // negative signed value
|
||||
signedValue = static_cast<int>(value) - (1 << m_bitCount);
|
||||
} else {
|
||||
signedValue = static_cast<int>(value);
|
||||
}
|
||||
if (m_divisor < 0) {
|
||||
*output = static_cast<float>(signedValue) * static_cast<float>(-m_divisor);
|
||||
} else if (m_divisor <= 1) {
|
||||
*output = static_cast<float>(signedValue);
|
||||
} else {
|
||||
*output = static_cast<float>(signedValue) / static_cast<float>(m_divisor);
|
||||
}
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
result_t NumberDataType::readFromRawValue(unsigned int value,
|
||||
OutputFormat outputFormat, ostream* output) const {
|
||||
size_t length = (m_bitCount < 8) ? 1 : (m_bitCount/8);
|
||||
@@ -932,6 +996,75 @@ result_t NumberDataType::writeRawValue(unsigned int value, size_t offset, size_t
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
result_t NumberDataType::getRawValueFromFloat(float val, unsigned int* output) const {
|
||||
unsigned int value;
|
||||
if (hasFlag(EXP)) { // IEEE 754 binary32
|
||||
double dvalue = val;
|
||||
if (m_divisor < 0) {
|
||||
dvalue /= -m_divisor;
|
||||
} else if (m_divisor > 1) {
|
||||
dvalue *= m_divisor;
|
||||
}
|
||||
value = floatToUint(static_cast<float>(dvalue));
|
||||
if (value == 0xffffffff) {
|
||||
return RESULT_ERR_INVALID_NUM;
|
||||
}
|
||||
} else {
|
||||
if (m_divisor == 1) {
|
||||
if (hasFlag(SIG)) {
|
||||
long signedValue = static_cast<long>(val); // TODO static_c?
|
||||
if (signedValue < 0 && m_bitCount != 32) {
|
||||
value = (unsigned int)(signedValue + (1 << m_bitCount));
|
||||
} else {
|
||||
value = (unsigned int)signedValue;
|
||||
}
|
||||
} else if (val < 0) {
|
||||
return RESULT_ERR_INVALID_NUM; // invalid value
|
||||
} else {
|
||||
value = static_cast<unsigned int>(val);
|
||||
}
|
||||
} else {
|
||||
double dvalue = val;
|
||||
if (m_divisor < 0) {
|
||||
dvalue = round(dvalue / -m_divisor);
|
||||
} else {
|
||||
dvalue = round(dvalue * m_divisor);
|
||||
}
|
||||
int length = static_cast<int>(m_bitCount/8);
|
||||
if (hasFlag(SIG)) {
|
||||
if (dvalue < -exp2((8 * static_cast<double>(length)) - 1)
|
||||
|| dvalue >= exp2((8 * static_cast<double>(length)) - 1)) {
|
||||
return RESULT_ERR_OUT_OF_RANGE; // value out of range
|
||||
}
|
||||
if (dvalue < 0 && m_bitCount != 32) {
|
||||
value = static_cast<unsigned int>(dvalue + (1 << m_bitCount));
|
||||
} else {
|
||||
value = static_cast<unsigned int>(dvalue);
|
||||
}
|
||||
} else {
|
||||
if (dvalue < 0.0 || dvalue >= exp2(8 * static_cast<double>(length))) {
|
||||
return RESULT_ERR_OUT_OF_RANGE; // value out of range
|
||||
}
|
||||
value = (unsigned int)dvalue;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFlag(SIG)) { // signed value
|
||||
if ((value & (1 << (m_bitCount - 1))) != 0) { // 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
|
||||
}
|
||||
}
|
||||
*output = value;
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
result_t NumberDataType::writeSymbols(size_t offset, size_t length, istringstream* input,
|
||||
SymbolString* output, size_t* usedLength) const {
|
||||
unsigned int value;
|
||||
|
||||
@@ -539,6 +539,22 @@ class NumberDataType : public DataType {
|
||||
result_t readSymbols(size_t offset, size_t length, const SymbolString& input,
|
||||
const OutputFormat outputFormat, ostream* output) const override;
|
||||
|
||||
/**
|
||||
* Convert the numeric raw value to its float representation (including optional divisor).
|
||||
* @param value the numeric raw value.
|
||||
* @param output the float variable to write the value to.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
*/
|
||||
result_t getFloatFromRawValue(unsigned int value, float* output) const;
|
||||
|
||||
/**
|
||||
* Convert the float value to the numeric raw value (including optional divisor).
|
||||
* @param value the float value.
|
||||
* @param output the variable to write the numeric raw value to.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
*/
|
||||
result_t getRawValueFromFloat(float value, unsigned int* output) const;
|
||||
|
||||
/**
|
||||
* Internal method for interpreting a numeric raw value.
|
||||
* @param value the numeric raw value.
|
||||
|
||||
Reference in New Issue
Block a user