FixedPointParameterType.cpp revision 258c6f5ae24de2e96ac0a0a842483bdc60b6b063
1/* <auto_header> 2 * <FILENAME> 3 * 4 * INTEL CONFIDENTIAL 5 * Copyright © 2011 Intel 6 * Corporation All Rights Reserved. 7 * 8 * The source code contained or described herein and all documents related to 9 * the source code ("Material") are owned by Intel Corporation or its suppliers 10 * or licensors. Title to the Material remains with Intel Corporation or its 11 * suppliers and licensors. The Material contains trade secrets and proprietary 12 * and confidential information of Intel or its suppliers and licensors. The 13 * Material is protected by worldwide copyright and trade secret laws and 14 * treaty provisions. No part of the Material may be used, copied, reproduced, 15 * modified, published, uploaded, posted, transmitted, distributed, or 16 * disclosed in any way without Intel’s prior express written permission. 17 * 18 * No license under any patent, copyright, trade secret or other intellectual 19 * property right is granted to or conferred upon you by disclosure or delivery 20 * of the Materials, either expressly, by implication, inducement, estoppel or 21 * otherwise. Any license under such intellectual property rights must be 22 * express and approved by Intel in writing. 23 * 24 * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com) 25 * CREATED: 2011-06-01 26 * UPDATED: 2011-07-27 27 * 28 * 29 * </auto_header> 30 */ 31#include "FixedPointParameterType.h" 32#include <stdlib.h> 33#include <sstream> 34#include <iomanip> 35#include <assert.h> 36#include <math.h> 37#include "Parameter.h" 38#include "ParameterAccessContext.h" 39#include "ConfigurationAccessContext.h" 40 41#define base CParameterType 42 43CFixedPointParameterType::CFixedPointParameterType(const string& strName) : base(strName), _uiIntegral(0), _uiFractional(0) 44{ 45} 46 47string CFixedPointParameterType::getKind() const 48{ 49 return "FixedPointParameter"; 50} 51 52// Element properties 53void CFixedPointParameterType::showProperties(string& strResult) const 54{ 55 base::showProperties(strResult); 56 57 // Notation 58 strResult += "Notation: Q"; 59 strResult += toString(_uiIntegral); 60 strResult += "."; 61 strResult += toString(_uiFractional); 62 strResult += "\n"; 63} 64 65// XML Serialization value space handling 66// Value space handling for configuration import 67void CFixedPointParameterType::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const 68{ 69 // Direction? 70 if (!configurationAccessContext.serializeOut()) { 71 72 // Get Value space from XML 73 if (xmlConfigurableElementSettingsElement.hasAttribute("ValueSpace")) { 74 75 configurationAccessContext.setValueSpaceRaw(xmlConfigurableElementSettingsElement.getAttributeBoolean("ValueSpace", "Raw")); 76 } else { 77 78 configurationAccessContext.setValueSpaceRaw(false); 79 } 80 } else { 81 // Provide value space only if not the default one 82 if (configurationAccessContext.valueSpaceIsRaw()) { 83 84 xmlConfigurableElementSettingsElement.setAttributeString("ValueSpace", "Raw"); 85 } 86 } 87} 88 89bool CFixedPointParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) 90{ 91 // Size 92 uint32_t uiSizeInBits = xmlElement.getAttributeInteger("Size"); 93 94 // Q notation 95 _uiIntegral = xmlElement.getAttributeInteger("Integral"); 96 _uiFractional = xmlElement.getAttributeInteger("Fractional"); 97 98 // Size vs. Q notation integrity check 99 if (uiSizeInBits < getUtilSizeInBits()) { 100 101 serializingContext.setError("Inconsistent Size vs. Q notation for " + getKind() + " " + xmlElement.getPath() + ": Summing (Integral + _uiFractional + 1) should not exceed given Size (" + xmlElement.getAttributeString("Size") + ")"); 102 103 return false; 104 } 105 106 // Set the size 107 setSize(uiSizeInBits / 8); 108 109 return base::fromXml(xmlElement, serializingContext); 110} 111 112bool CFixedPointParameterType::toBlackboard(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 113{ 114 // Hexa 115 bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); 116 117 // Check data integrity 118 if (bValueProvidedAsHexa && !parameterAccessContext.valueSpaceIsRaw()) { 119 120 parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + " when selected value space is real:"); 121 122 return false; 123 } 124 125 int32_t iData; 126 127 if (parameterAccessContext.valueSpaceIsRaw()) { 128 129 // Get data in integer form 130 iData = strtol(strValue.c_str(), NULL, 0); 131 132 if (bValueProvidedAsHexa && isEncodable(iData)) { 133 134 // Sign extend 135 signExtend(iData); 136 } 137 138 } else { 139 double dData = strtod(strValue.c_str(), NULL); 140 141 // Do the conversion 142 iData = asInteger(dData); 143 } 144 145 // Check integrity 146 if (!isConsistent(iData)) { 147 148 // Illegal value provided 149 parameterAccessContext.setError(getOutOfRangeError(strValue, parameterAccessContext.valueSpaceIsRaw(), bValueProvidedAsHexa)); 150 151 return false; 152 } 153 154 uiValue = iData; 155 156 return true; 157} 158 159bool CFixedPointParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 160{ 161 int32_t iData = uiValue; 162 163 // Check consistency 164 assert(isEncodable(iData)); 165 166 // Format 167 ostringstream strStream; 168 169 // Raw formatting? 170 if (parameterAccessContext.valueSpaceIsRaw()) { 171 172 // Hexa formatting? 173 if (parameterAccessContext.outputRawFormatIsHex()) { 174 175 strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << (uint32_t)iData; 176 } else { 177 178 // Sign extend 179 signExtend(iData); 180 181 strStream << iData; 182 } 183 } else { 184 185 // Sign extend 186 signExtend(iData); 187 188 // Conversion 189 double dData = asDouble(iData); 190 191 // Set up the precision of the display and notation type 192 strStream << fixed << setprecision((_uiFractional + 1) * log10(2.0)) << dData; 193 } 194 195 strValue = strStream.str(); 196 197 return true; 198} 199 200// Value access 201bool CFixedPointParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 202{ 203 // Do the conversion 204 int32_t iData = asInteger(dUserValue); 205 206 // Check integrity 207 if (!isConsistent(iData)) { 208 209 // Illegal value provided 210 parameterAccessContext.setError("Value out of range"); 211 212 return false; 213 } 214 215 uiValue = iData; 216 217 return true; 218} 219 220bool CFixedPointParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const 221{ 222 (void)parameterAccessContext; 223 224 int32_t iData = uiValue; 225 226 // Check consistency 227 assert(isEncodable(iData)); 228 229 // Sign extend 230 signExtend(iData); 231 232 dUserValue = asDouble(iData); 233 234 return true; 235} 236 237// Util size 238uint32_t CFixedPointParameterType::getUtilSizeInBits() const 239{ 240 return _uiIntegral + _uiFractional + 1; 241} 242 243// Out of range error 244string CFixedPointParameterType::getOutOfRangeError(const string& strValue, bool bRawValueSpace, bool bHexaValue) const 245{ 246 // Min/Max computation 247 int32_t iMax = (1L << (getSize() * 8 - 1)) - 1; 248 int32_t iMin = -iMax - 1; 249 250 ostringstream strStream; 251 252 strStream << "Value " << strValue << " standing out of admitted "; 253 254 if (!bRawValueSpace) { 255 256 strStream << "real range [" << (double)iMin / (1UL << _uiFractional) << ", "<< (double)iMax / (1UL << _uiFractional) << "]"; 257 } else { 258 259 strStream << "raw range ["; 260 261 if (bHexaValue) { 262 263 // Format Min 264 strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(iMin); 265 // Format Max 266 strStream << ", 0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(iMax); 267 268 } else { 269 270 strStream << iMin << ", " << iMax; 271 } 272 273 strStream << "]"; 274 } 275 strStream << " for " << getKind(); 276 277 return strStream.str(); 278} 279 280// Check data is consistent with available range, with respect to its sign 281bool CFixedPointParameterType::isConsistent(uint32_t uiData) const 282{ 283 uint32_t uiShift = getSize() * 8; 284 285 if (uiShift == 8 * sizeof(uiData)) { 286 // Prevent inappropriate shifts 287 return true; 288 } 289 290 // Negative value? 291 bool bIsValueExpectedNegative = (uiData & (1 << (uiShift - 1))) != 0; 292 293 // Check high bits are clean 294 return bIsValueExpectedNegative ? !(~uiData >> uiShift) : !(uiData >> uiShift); 295} 296 297// Data conversion 298int32_t CFixedPointParameterType::asInteger(double dValue) const 299{ 300 // Do the conversion 301 int32_t iData = (int32_t)(dValue * (1UL << _uiFractional) + 0.5F - (double)(dValue < 0)); 302 // Left justify 303 iData <<= getSize() * 8 - getUtilSizeInBits(); 304 305 return iData; 306} 307 308double CFixedPointParameterType::asDouble(int32_t iValue) const 309{ 310 // Unjustify 311 iValue >>= getSize() * 8 - getUtilSizeInBits(); 312 // Convert 313 return (double)iValue / (1UL << _uiFractional); 314} 315