diff options
author | Francois Gaffie <francois.gaffie@intel.com> | 2014-04-08 14:56:08 +0200 |
---|---|---|
committer | Mattijs Korpershoek <mattijsx.korpershoek@intel.com> | 2014-06-25 10:52:26 +0200 |
commit | a17d5a584a9b681e2eb48465815d275eb5fccb8f (patch) | |
tree | eb311ae15fdf461e1d8f3d568d4fb5eb65ed92cf /parameter | |
parent | 59cc1e33810c55e6fa1e3bd320e1cf29e24d23be (diff) | |
download | external_parameter-framework-a17d5a584a9b681e2eb48465815d275eb5fccb8f.zip external_parameter-framework-a17d5a584a9b681e2eb48465815d275eb5fccb8f.tar.gz external_parameter-framework-a17d5a584a9b681e2eb48465815d275eb5fccb8f.tar.bz2 |
Fix Fixed Point convert issue.
BZ: 185336
Convert is failing when trying to convert the string value
to integer value within FixedPointParameterType class.
This patch fixes the issue by requesting to convert the string
into a signed type.
Change-Id: I77987eb1564292bd6dcdd0da4db52c4b4f92818f
Signed-off-by: Francois Gaffie <francois.gaffie@intel.com>
Signed-off-by: Mattijs Korpershoek <mattijsx.korpershoek@intel.com>
Diffstat (limited to 'parameter')
-rw-r--r-- | parameter/FixedPointParameterType.cpp | 137 | ||||
-rw-r--r-- | parameter/FixedPointParameterType.h | 65 |
2 files changed, 147 insertions, 55 deletions
diff --git a/parameter/FixedPointParameterType.cpp b/parameter/FixedPointParameterType.cpp index 0f9369d..067f311 100644 --- a/parameter/FixedPointParameterType.cpp +++ b/parameter/FixedPointParameterType.cpp @@ -112,8 +112,7 @@ bool CFixedPointParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerial bool CFixedPointParameterType::toBlackboard(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const { - // Hexa - bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); + bool bValueProvidedAsHexa = isHexadecimal(strValue); // Check data integrity if (bValueProvidedAsHexa && !parameterAccessContext.valueSpaceIsRaw()) { @@ -123,45 +122,59 @@ bool CFixedPointParameterType::toBlackboard(const string& strValue, uint32_t& ui return false; } - uint32_t uiData; - if (parameterAccessContext.valueSpaceIsRaw()) { - if (!convertTo(strValue, uiData) || !isEncodable(uiData, !bValueProvidedAsHexa)) { + if (bValueProvidedAsHexa) { - // Illegal value provided - parameterAccessContext.setError(getOutOfRangeError(strValue, parameterAccessContext.valueSpaceIsRaw(), bValueProvidedAsHexa)); + return convertFromHexadecimal(strValue, uiValue, parameterAccessContext); - return false; } - if (bValueProvidedAsHexa) { + return convertFromDecimal(strValue, uiValue, parameterAccessContext); + } + return convertFromQiQf(strValue, uiValue, parameterAccessContext); +} - // Sign extend - signExtend((int32_t&)uiData); - } +void CFixedPointParameterType::setOutOfRangeError(const string& strValue, CParameterAccessContext& parameterAccessContext) const +{ + ostringstream strStream; + + strStream << "Value " << strValue << " standing out of admitted "; + + if (!parameterAccessContext.valueSpaceIsRaw()) { + + // Min/Max computation + double dMin = 0; + double dMax = 0; + getRange(dMin, dMax); + strStream << "real range [" << dMin << ", " << dMax << "]"; } else { - double dData; - // Check encodability - if (!convertTo(strValue, dData) || !checkValueAgainstRange(dData)) { + // Min/Max computation + int32_t iMax = getMaxValue<uint32_t>(); + int32_t iMin = -iMax - 1; - // Illegal value provided - parameterAccessContext.setError(getOutOfRangeError(strValue, parameterAccessContext.valueSpaceIsRaw(), bValueProvidedAsHexa)); + strStream << "raw range ["; - return false; - } + if (isHexadecimal(strValue)) { - // Do the conversion - uiData = (uint32_t)asInteger(dData); - } + // Format Min + strStream << "0x" << hex << uppercase << + setw(getSize() * 2) << setfill('0') << makeEncodable(iMin); + // Format Max + strStream << ", 0x" << hex << uppercase << + setw(getSize() * 2) << setfill('0') << makeEncodable(iMax); - // check that the data is encodable and can be safely written to the blackboard - assert(isEncodable(uiData, true)); + } else { - uiValue = uiData; + strStream << iMin << ", " << iMax; + } - return true; + strStream << "]"; + } + strStream << " for " << getKind(); + + parameterAccessContext.setError(strStream.str()); } bool CFixedPointParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const @@ -278,46 +291,58 @@ void CFixedPointParameterType::getRange(double& dMin, double& dMax) const dMin = -(double)(1UL << (_uiIntegral + _uiFractional)) / (1UL << _uiFractional); } -// Out of range error -string CFixedPointParameterType::getOutOfRangeError(const string& strValue, bool bRawValueSpace, bool bHexaValue) const +bool CFixedPointParameterType::isHexadecimal(const string& strValue) const { - ostringstream strStream; + return !strValue.compare(0, 2, "0x"); +} - strStream << "Value " << strValue << " standing out of admitted "; +bool CFixedPointParameterType::convertFromHexadecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +{ + // For hexadecimal representation, we need full 32 bit range conversion. + uint32_t uiData; + if (!convertTo(strValue, uiData) || !isEncodable(uiData, false)) { - if (!bRawValueSpace) { + setOutOfRangeError(strValue, parameterAccessContext); + return false; + } + signExtend((int32_t&)uiData); - // Min/Max computation - double dMin = 0; - double dMax = 0; - getRange(dMin, dMax); + // check that the data is encodable and can been safely written to the blackboard + assert(isEncodable(uiData, true)); + uiValue = uiData; - strStream << "real range [" << dMin << ", "<< dMax << "]"; - } else { + return true; +} - // Min/Max computation - int32_t iMax = getMaxValue<uint32_t>(); - int32_t iMin = -iMax - 1; +bool CFixedPointParameterType::convertFromDecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +{ + int32_t iData; - strStream << "raw range ["; + if (!convertTo(strValue, iData) || !isEncodable((uint32_t)iData, true)) { - if (bHexaValue) { + setOutOfRangeError(strValue, parameterAccessContext); + return false; + } + uiValue = static_cast<uint32_t>(iData); - // Format Min - strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(iMin); - // Format Max - strStream << ", 0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(iMax); + return true; +} - } else { +bool CFixedPointParameterType::convertFromQiQf(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +{ + double dData; - strStream << iMin << ", " << iMax; - } + if (!convertTo(strValue, dData) || !checkValueAgainstRange(dData)) { - strStream << "]"; + setOutOfRangeError(strValue, parameterAccessContext); + return false; } - strStream << " for " << getKind(); + uiValue = static_cast<uint32_t>(asInteger(dData)); - return strStream.str(); + // check that the data is encodable and has been safely written to the blackboard + assert(isEncodable(uiValue, true)); + + return true; } // Check that the value is within available range for this type @@ -327,7 +352,13 @@ bool CFixedPointParameterType::checkValueAgainstRange(double dValue) const double dMax = 0; getRange(dMin, dMax); - return (dValue <= dMax) && (dValue >= dMin); + /** + * Bijective transformation is only ensured in raw format. + * So, as the double stored in the XML may be significant, and as the std::setprecision used + * may round up, double representation may go outside the range. + */ + int32_t rawValue = asInteger(dValue); + return (rawValue <= asInteger(dMax)) && (rawValue >= asInteger(dMin)); } // Data conversion diff --git a/parameter/FixedPointParameterType.h b/parameter/FixedPointParameterType.h index 7f204ff..acb638a 100644 --- a/parameter/FixedPointParameterType.h +++ b/parameter/FixedPointParameterType.h @@ -64,8 +64,69 @@ private: uint32_t getUtilSizeInBits() const; // Range computation void getRange(double& dMin, double& dMax) const; - // Out of range error - string getOutOfRangeError(const string& strValue, bool bRawValueSpace, bool bHexaValue) const; + + /** + * Checks if a string has the written representation of an hexadecimal number (Which is + * the prefix "Ox" in C++). + * + * @param[in] strValue Parameter read from the XML file representated as a string. + * + * @return true if the string is written as hexa, false otherwise. + */ + bool isHexadecimal(const string& strValue) const; + + /** + * Convert a decimal raw represented string into an unsigned long integer. + * In case of a failing conversion or encodability, this function set the error to + * illegal value provided and gives the range allowed for the parameter. + * + * @param[in] strValue Parameter read from the XML file representated as a string in decimal + * raw format + * @param[out] uiValue Parameter representated as a long unsigned integer. + * @param[in:out] parameterAccessContext Parameter access context. + * + * @return true if the string was successfully converted, false otherwise. + */ + bool convertFromDecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + + /** + * Convert an hexadecimal raw represented string into an unsigned long integer. + * In case of a failing conversion or encodability, this function set the error to + * illegal value provided and gives the range allowed for the parameter. + * + * @param[in] strValue Parameter read from the XML file representated as a string in hexadecimal + * raw format + * @param[out] uiValue Parameter representated as a long unsigned integer. + * @param[in:out] parameterAccessContext Parameter access context. + * + * @return true if the string was successfully converted, false otherwise. + */ + bool convertFromHexadecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + + /** + * Convert a QI QF represented string into an unsigned long integer. + * In case of a failing conversion or encodability, this function set the error to + * illegal value provided and gives the range allowed for the parameter. + * + * @param[in] strValue Parameter read from the XML file representated as a string in QIQF + * representation. + * @param[out] uiValue Parameter representated as a long unsigned integer. + * @param[in:out] parameterAccessContext Parameter access context. + * + * @return true if the string was successfully converted, false otherwise. + */ + bool convertFromQiQf(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + + /** + * Set the out of range error. + * In case of a failing conversion or encodability, this function set the error to + * illegal value provided and gives the range allowed for the parameter. + * + * @param[in] strValue Parameter read from the XML file representated as a string + * @param[in:out] parameterAccessContext Parameter Access Context + */ + void setOutOfRangeError(const string& strValue, CParameterAccessContext& parameterAccessContext) const; + // Check if data is encodable bool checkValueAgainstRange(double dValue) const; // Data conversion |