FixedPointParameterType.cpp revision a24e61fddaf09d2989fff25785e329454c842d7f
1b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner/* 2b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Copyright (c) 2011-2014, Intel Corporation 3b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * All rights reserved. 4b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 5b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Redistribution and use in source and binary forms, with or without modification, 6b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * are permitted provided that the following conditions are met: 7b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 8b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 1. Redistributions of source code must retain the above copyright notice, this 9b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * list of conditions and the following disclaimer. 10b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 11b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 2. Redistributions in binary form must reproduce the above copyright notice, 12b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * this list of conditions and the following disclaimer in the documentation and/or 13b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * other materials provided with the distribution. 14b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 15b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 3. Neither the name of the copyright holder nor the names of its contributors 16b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * may be used to endorse or promote products derived from this software without 17b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * specific prior written permission. 18b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 19b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2968a912857707864bbaaff9808717813105072a6ePatrick Benavoli */ 3068a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "FixedPointParameterType.h" 3168a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include <stdlib.h> 3268a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include <sstream> 336ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli#include <iomanip> 346ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli#include <assert.h> 35258c6f5ae24de2e96ac0a0a842483bdc60b6b063Frederic Boisnard#include <math.h> 3668a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "Parameter.h" 3768a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "ParameterAccessContext.h" 3868a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "ConfigurationAccessContext.h" 398b01852701d50869318663f568270f977d93dbdfFrederic Boisnard#include <errno.h> 408ef87a1fe5d2f05557856efa6faf070bb9b03337David Wagner#include <convert.hpp> 4168a912857707864bbaaff9808717813105072a6ePatrick Benavoli 4268a912857707864bbaaff9808717813105072a6ePatrick Benavoli#define base CParameterType 4368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 4468a912857707864bbaaff9808717813105072a6ePatrick BenavoliCFixedPointParameterType::CFixedPointParameterType(const string& strName) : base(strName), _uiIntegral(0), _uiFractional(0) 4568a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 4668a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 4768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 4868a912857707864bbaaff9808717813105072a6ePatrick Benavolistring CFixedPointParameterType::getKind() const 4968a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 5068a912857707864bbaaff9808717813105072a6ePatrick Benavoli return "FixedPointParameter"; 5168a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 5268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 532ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli// Element properties 542ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavolivoid CFixedPointParameterType::showProperties(string& strResult) const 552ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli{ 562ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli base::showProperties(strResult); 572ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli 582ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli // Notation 592ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += "Notation: Q"; 602ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += toString(_uiIntegral); 612ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += "."; 622ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += toString(_uiFractional); 632ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += "\n"; 642ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli} 652ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli 6668a912857707864bbaaff9808717813105072a6ePatrick Benavoli// XML Serialization value space handling 6768a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Value space handling for configuration import 6868a912857707864bbaaff9808717813105072a6ePatrick Benavolivoid CFixedPointParameterType::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const 6968a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 7068a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Direction? 7168a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (!configurationAccessContext.serializeOut()) { 7268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 7368a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Get Value space from XML 7468a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (xmlConfigurableElementSettingsElement.hasAttribute("ValueSpace")) { 7568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 7668a912857707864bbaaff9808717813105072a6ePatrick Benavoli configurationAccessContext.setValueSpaceRaw(xmlConfigurableElementSettingsElement.getAttributeBoolean("ValueSpace", "Raw")); 7768a912857707864bbaaff9808717813105072a6ePatrick Benavoli } else { 7868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 7968a912857707864bbaaff9808717813105072a6ePatrick Benavoli configurationAccessContext.setValueSpaceRaw(false); 8068a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 8168a912857707864bbaaff9808717813105072a6ePatrick Benavoli } else { 8268a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Provide value space only if not the default one 8368a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (configurationAccessContext.valueSpaceIsRaw()) { 8468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 8568a912857707864bbaaff9808717813105072a6ePatrick Benavoli xmlConfigurableElementSettingsElement.setAttributeString("ValueSpace", "Raw"); 8668a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 8768a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 8868a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 8968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 9068a912857707864bbaaff9808717813105072a6ePatrick Benavolibool CFixedPointParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) 9168a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 9268a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Size 9368a912857707864bbaaff9808717813105072a6ePatrick Benavoli uint32_t uiSizeInBits = xmlElement.getAttributeInteger("Size"); 9468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 9568a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Q notation 9668a912857707864bbaaff9808717813105072a6ePatrick Benavoli _uiIntegral = xmlElement.getAttributeInteger("Integral"); 9768a912857707864bbaaff9808717813105072a6ePatrick Benavoli _uiFractional = xmlElement.getAttributeInteger("Fractional"); 9868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 9968a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Size vs. Q notation integrity check 10068a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (uiSizeInBits < getUtilSizeInBits()) { 10168a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1026ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli serializingContext.setError("Inconsistent Size vs. Q notation for " + getKind() + " " + xmlElement.getPath() + ": Summing (Integral + _uiFractional + 1) should not exceed given Size (" + xmlElement.getAttributeString("Size") + ")"); 10368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 10468a912857707864bbaaff9808717813105072a6ePatrick Benavoli return false; 10568a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 10668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 10768a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Set the size 10868a912857707864bbaaff9808717813105072a6ePatrick Benavoli setSize(uiSizeInBits / 8); 10968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 11068a912857707864bbaaff9808717813105072a6ePatrick Benavoli return base::fromXml(xmlElement, serializingContext); 11168a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 11268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 113065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavolibool CFixedPointParameterType::toBlackboard(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 11468a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 115a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie bool bValueProvidedAsHexa = isHexadecimal(strValue); 11668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1176ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli // Check data integrity 1186ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli if (bValueProvidedAsHexa && !parameterAccessContext.valueSpaceIsRaw()) { 11968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1206ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + " when selected value space is real:"); 12168a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1226ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli return false; 12368a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 12468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1256ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli if (parameterAccessContext.valueSpaceIsRaw()) { 12668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 127a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (bValueProvidedAsHexa) { 1288b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 129a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return convertFromHexadecimal(strValue, uiValue, parameterAccessContext); 1308b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 1318b01852701d50869318663f568270f977d93dbdfFrederic Boisnard } 132a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return convertFromDecimal(strValue, uiValue, parameterAccessContext); 133a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 134a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek return convertFromQnm(strValue, uiValue, parameterAccessContext); 135a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 13668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 137a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffievoid CFixedPointParameterType::setOutOfRangeError(const string& strValue, CParameterAccessContext& parameterAccessContext) const 138a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 139a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie ostringstream strStream; 140a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 141a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << "Value " << strValue << " standing out of admitted "; 142a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 143a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (!parameterAccessContext.valueSpaceIsRaw()) { 144a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 145a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Min/Max computation 146a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie double dMin = 0; 147a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie double dMax = 0; 148a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie getRange(dMin, dMax); 14968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 150d299108157ee4d0eadb7683b2fa6a6635bc63d95David Wagner strStream << fixed << setprecision(_uiFractional) 151d299108157ee4d0eadb7683b2fa6a6635bc63d95David Wagner << "real range [" << dMin << ", " << dMax << "]"; 1526ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } else { 1536ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 154a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Min/Max computation 155a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie int32_t iMax = getMaxValue<uint32_t>(); 156a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie int32_t iMin = -iMax - 1; 15768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 158a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << "raw range ["; 1598b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 160a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (isHexadecimal(strValue)) { 1618b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 162a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Format Min 163a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << "0x" << hex << uppercase << 164a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setw(getSize() * 2) << setfill('0') << makeEncodable(iMin); 165a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Format Max 166a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << ", 0x" << hex << uppercase << 167a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setw(getSize() * 2) << setfill('0') << makeEncodable(iMax); 16868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 169a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } else { 1708b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 171a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << iMin << ", " << iMax; 172a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 17368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 174a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << "]"; 175a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 176a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie strStream << " for " << getKind(); 177a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 178a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie parameterAccessContext.setError(strStream.str()); 17968a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 18068a912857707864bbaaff9808717813105072a6ePatrick Benavoli 181065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavolibool CFixedPointParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 18268a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 1836ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli int32_t iData = uiValue; 18468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1858b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check encodability 1868b01852701d50869318663f568270f977d93dbdfFrederic Boisnard assert(isEncodable((uint32_t)iData, false)); 18768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 18868a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Format 18968a912857707864bbaaff9808717813105072a6ePatrick Benavoli ostringstream strStream; 19068a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1916ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli // Raw formatting? 19268a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (parameterAccessContext.valueSpaceIsRaw()) { 19368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1946ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli // Hexa formatting? 1956ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli if (parameterAccessContext.outputRawFormatIsHex()) { 1966ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 19711e6498a4fa3b27ca34d2fcb76bd6365da9d5c1bPatrick Benavoli strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << (uint32_t)iData; 1986ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } else { 1996ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 2005901c1d3f448af5d0506d889b0543d9e0de0c2ceGuillaume Denneulin // Sign extend 2015901c1d3f448af5d0506d889b0543d9e0de0c2ceGuillaume Denneulin signExtend(iData); 2025901c1d3f448af5d0506d889b0543d9e0de0c2ceGuillaume Denneulin 2036ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli strStream << iData; 2046ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } 20568a912857707864bbaaff9808717813105072a6ePatrick Benavoli } else { 20668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 207258c6f5ae24de2e96ac0a0a842483bdc60b6b063Frederic Boisnard // Sign extend 208258c6f5ae24de2e96ac0a0a842483bdc60b6b063Frederic Boisnard signExtend(iData); 209258c6f5ae24de2e96ac0a0a842483bdc60b6b063Frederic Boisnard 210065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Conversion 211a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek double dData = binaryQnmToDouble(iData); 21268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 213d299108157ee4d0eadb7683b2fa6a6635bc63d95David Wagner strStream << fixed << setprecision(_uiFractional) << dData; 21468a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 21568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 21668a912857707864bbaaff9808717813105072a6ePatrick Benavoli strValue = strStream.str(); 217065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 218065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return true; 219065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 220065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 221065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli// Value access 222065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavolibool CFixedPointParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 223065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 2248b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check that the value is within the allowed range for this type 2258b01852701d50869318663f568270f977d93dbdfFrederic Boisnard if (!checkValueAgainstRange(dUserValue)) { 226065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 227065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Illegal value provided 228065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli parameterAccessContext.setError("Value out of range"); 229065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 230065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return false; 231065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli } 232065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 2338b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Do the conversion 234a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek int32_t iData = doubleToBinaryQnm(dUserValue); 2358b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 2368b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check integrity 2378b01852701d50869318663f568270f977d93dbdfFrederic Boisnard assert(isEncodable((uint32_t)iData, true)); 2388b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 239065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli uiValue = iData; 240065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 241065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return true; 242065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 243065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 244065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavolibool CFixedPointParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const 245065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 246065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli (void)parameterAccessContext; 247065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 248065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli int32_t iData = uiValue; 249065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 2508b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check unsigned value is encodable 2518b01852701d50869318663f568270f977d93dbdfFrederic Boisnard assert(isEncodable(uiValue, false)); 252065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 253065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Sign extend 254065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli signExtend(iData); 255065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 256a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek dUserValue = binaryQnmToDouble(iData); 257065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 258065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return true; 25968a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 26068a912857707864bbaaff9808717813105072a6ePatrick Benavoli 26168a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Util size 26268a912857707864bbaaff9808717813105072a6ePatrick Benavoliuint32_t CFixedPointParameterType::getUtilSizeInBits() const 26368a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 26468a912857707864bbaaff9808717813105072a6ePatrick Benavoli return _uiIntegral + _uiFractional + 1; 26568a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 2666ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 2678b01852701d50869318663f568270f977d93dbdfFrederic Boisnard// Compute the range for the type (minimum and maximum values) 2688b01852701d50869318663f568270f977d93dbdfFrederic Boisnardvoid CFixedPointParameterType::getRange(double& dMin, double& dMax) const 2698b01852701d50869318663f568270f977d93dbdfFrederic Boisnard{ 2708b01852701d50869318663f568270f977d93dbdfFrederic Boisnard dMax = (double)((1UL << (_uiIntegral + _uiFractional)) - 1) / (1UL << _uiFractional); 2718b01852701d50869318663f568270f977d93dbdfFrederic Boisnard dMin = -(double)(1UL << (_uiIntegral + _uiFractional)) / (1UL << _uiFractional); 2728b01852701d50869318663f568270f977d93dbdfFrederic Boisnard} 2738b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 274a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffiebool CFixedPointParameterType::isHexadecimal(const string& strValue) const 2756ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli{ 276a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return !strValue.compare(0, 2, "0x"); 277a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 2786ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 279a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffiebool CFixedPointParameterType::convertFromHexadecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 280a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 281a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // For hexadecimal representation, we need full 32 bit range conversion. 282a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie uint32_t uiData; 283a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (!convertTo(strValue, uiData) || !isEncodable(uiData, false)) { 2846ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 285a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setOutOfRangeError(strValue, parameterAccessContext); 286a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return false; 287a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 288a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie signExtend((int32_t&)uiData); 2896ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 290a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // check that the data is encodable and can been safely written to the blackboard 291a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie assert(isEncodable(uiData, true)); 292a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie uiValue = uiData; 2938b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 294a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return true; 295a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 2966ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 297a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffiebool CFixedPointParameterType::convertFromDecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const 298a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 299a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie int32_t iData; 3008b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 301a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (!convertTo(strValue, iData) || !isEncodable((uint32_t)iData, true)) { 3026ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 303a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setOutOfRangeError(strValue, parameterAccessContext); 304a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return false; 305a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 306a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie uiValue = static_cast<uint32_t>(iData); 3076ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 308a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return true; 309a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 3106ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 311a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoekbool CFixedPointParameterType::convertFromQnm(const string& strValue, uint32_t& uiValue, 312a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek CParameterAccessContext& parameterAccessContext) const 313a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 314a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie double dData; 3156ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 316a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (!convertTo(strValue, dData) || !checkValueAgainstRange(dData)) { 3176ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 318a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setOutOfRangeError(strValue, parameterAccessContext); 319a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return false; 3206ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } 321a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek uiValue = static_cast<uint32_t>(doubleToBinaryQnm(dData)); 3226ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 323a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // check that the data is encodable and has been safely written to the blackboard 324a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie assert(isEncodable(uiValue, true)); 325a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 326a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return true; 3276ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli} 3281387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli 3298b01852701d50869318663f568270f977d93dbdfFrederic Boisnard// Check that the value is within available range for this type 3308b01852701d50869318663f568270f977d93dbdfFrederic Boisnardbool CFixedPointParameterType::checkValueAgainstRange(double dValue) const 3311387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli{ 3328b01852701d50869318663f568270f977d93dbdfFrederic Boisnard double dMin = 0; 3338b01852701d50869318663f568270f977d93dbdfFrederic Boisnard double dMax = 0; 3348b01852701d50869318663f568270f977d93dbdfFrederic Boisnard getRange(dMin, dMax); 33511e6498a4fa3b27ca34d2fcb76bd6365da9d5c1bPatrick Benavoli 336d9406eea67ae1d88b36e356d10d491f3bf0dfe1bMattijs Korpershoek return (dValue <= dMax) && (dValue >= dMin); 3371387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli} 3381387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli 339065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli// Data conversion 340a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoekint32_t CFixedPointParameterType::doubleToBinaryQnm(double dValue) const 341065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 34259cc1e33810c55e6fa1e3bd320e1cf29e24d23beDavid Wagner // For Qn.m number, multiply by 2^n and round to the nearest integer 343a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek int32_t iData = static_cast<int32_t>(round(dValue * (1UL << _uiFractional))); 344065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Left justify 34559cc1e33810c55e6fa1e3bd320e1cf29e24d23beDavid Wagner // For a Qn.m number, shift 32 - (n + m + 1) bits to the left (the rest of 34659cc1e33810c55e6fa1e3bd320e1cf29e24d23beDavid Wagner // the bits aren't used) 347065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli iData <<= getSize() * 8 - getUtilSizeInBits(); 348065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 349065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return iData; 350065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 351065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 352a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek 353a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoekdouble CFixedPointParameterType::binaryQnmToDouble(int32_t iValue) const 354065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 355065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Unjustify 356065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli iValue >>= getSize() * 8 - getUtilSizeInBits(); 357a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek return static_cast<double>(iValue) / (1UL << _uiFractional); 358065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 359326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 360326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron// From IXmlSource 361326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baronvoid CFixedPointParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const 362326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron{ 363326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron // Size 364326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron xmlElement.setAttributeString("Size", toString(getSize() * 8)); 365326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 366326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron // Integral 367326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron xmlElement.setAttributeString("Integral", toString(_uiIntegral)); 368326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 369326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron // Fractional 370326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron xmlElement.setAttributeString("Fractional", toString(_uiFractional)); 371326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 372326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron base::toXml(xmlElement, serializingContext); 373326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron} 374