/* * * * INTEL CONFIDENTIAL * Copyright © 2011 Intel * Corporation All Rights Reserved. * * The source code contained or described herein and all documents related to * the source code ("Material") are owned by Intel Corporation or its suppliers * or licensors. Title to the Material remains with Intel Corporation or its * suppliers and licensors. The Material contains trade secrets and proprietary * and confidential information of Intel or its suppliers and licensors. The * Material is protected by worldwide copyright and trade secret laws and * treaty provisions. No part of the Material may be used, copied, reproduced, * modified, published, uploaded, posted, transmitted, distributed, or * disclosed in any way without Intel’s prior express written permission. * * No license under any patent, copyright, trade secret or other intellectual * property right is granted to or conferred upon you by disclosure or delivery * of the Materials, either expressly, by implication, inducement, estoppel or * otherwise. Any license under such intellectual property rights must be * express and approved by Intel in writing. * * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com) * CREATED: 2011-06-01 * UPDATED: 2011-07-27 * * * */ #include "FixedPointParameterType.h" #include #include #include #include #include "Parameter.h" #include "ParameterAccessContext.h" #include "ConfigurationAccessContext.h" #define base CParameterType CFixedPointParameterType::CFixedPointParameterType(const string& strName) : base(strName), _uiIntegral(0), _uiFractional(0) { } string CFixedPointParameterType::getKind() const { return "FixedPointParameter"; } // XML Serialization value space handling // Value space handling for configuration import void CFixedPointParameterType::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const { // Direction? if (!configurationAccessContext.serializeOut()) { // Get Value space from XML if (xmlConfigurableElementSettingsElement.hasAttribute("ValueSpace")) { configurationAccessContext.setValueSpaceRaw(xmlConfigurableElementSettingsElement.getAttributeBoolean("ValueSpace", "Raw")); } else { configurationAccessContext.setValueSpaceRaw(false); } } else { // Provide value space only if not the default one if (configurationAccessContext.valueSpaceIsRaw()) { xmlConfigurableElementSettingsElement.setAttributeString("ValueSpace", "Raw"); } } } bool CFixedPointParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) { // Size uint32_t uiSizeInBits = xmlElement.getAttributeInteger("Size"); // Q notation _uiIntegral = xmlElement.getAttributeInteger("Integral"); _uiFractional = xmlElement.getAttributeInteger("Fractional"); // Size vs. Q notation integrity check if (uiSizeInBits < getUtilSizeInBits()) { serializingContext.setError("Inconsistent Size vs. Q notation for " + getKind() + " " + xmlElement.getPath() + ": Summing (Integral + _uiFractional + 1) should not exceed given Size (" + xmlElement.getAttributeString("Size") + ")"); return false; } // Set the size setSize(uiSizeInBits / 8); return base::fromXml(xmlElement, serializingContext); } bool CFixedPointParameterType::asInteger(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const { // Hexa bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); // Check data integrity if (bValueProvidedAsHexa && !parameterAccessContext.valueSpaceIsRaw()) { parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + " when selected value space is real:"); return false; } int32_t iData; if (parameterAccessContext.valueSpaceIsRaw()) { // Get data in integer form iData = strtol(strValue.c_str(), NULL, 0); if (bValueProvidedAsHexa) { if (!isEncodable(iData)) { // Illegal value provided parameterAccessContext.setError(getOutOfRangeError(strValue, parameterAccessContext.valueSpaceIsRaw(), true)); return false; } else { // Sign extend signExtend(iData); } } } else { double dData = strtod(strValue.c_str(), NULL); // Do the conversion iData = (int32_t)(dData * (1UL << _uiFractional) + 0.5F - (double)(dData < 0)); } // Check integrity if (!isConsistent(iData, true)) { // Illegal value provided parameterAccessContext.setError(getOutOfRangeError(strValue, parameterAccessContext.valueSpaceIsRaw(), bValueProvidedAsHexa)); return false; } uiValue = (uint32_t)iData; return true; } void CFixedPointParameterType::asString(const uint32_t& uiValue, string& strValue, CParameterAccessContext& parameterAccessContext) const { int32_t iData = uiValue; // Check consistency assert(isEncodable(iData)); // Sign extend signExtend(iData); // Format ostringstream strStream; // Raw formatting? if (parameterAccessContext.valueSpaceIsRaw()) { // Hexa formatting? if (parameterAccessContext.outputRawFormatIsHex()) { strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << uiValue; } else { strStream << iData; } } else { double dData = (double)iData / (1UL << _uiFractional); strStream << dData; } strValue = strStream.str(); } // Util size uint32_t CFixedPointParameterType::getUtilSizeInBits() const { return _uiIntegral + _uiFractional + 1; } // Out of range error string CFixedPointParameterType::getOutOfRangeError(const string& strValue, bool bRawValueSpace, bool bHexaValue) const { // Min/Max computation int32_t iMin = ((int32_t)1 << 31) >> (32 - getUtilSizeInBits()); int32_t iMax = -iMin - 1; ostringstream strStream; strStream << "Value " << strValue << " standing out of admitted "; if (!bRawValueSpace) { strStream << "real range [" << (double)iMin / (1UL << _uiFractional) << ", "<< (double)iMax / (1UL << _uiFractional) << "]"; } else { strStream << "raw range ["; if (bHexaValue) { strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(iMin); strStream << ", 0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(iMax); } else { strStream << iMin << ", " << iMax; } strStream << "]"; } strStream << " for " << getKind(); return strStream.str(); }