1b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner/* 2a9be2d378b7ad84e679a48efa81f42fb54f85d9aJean-Michel Trivi * Copyright (c) 2011-2015, 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" 39a9be2d378b7ad84e679a48efa81f42fb54f85d9aJean-Michel Trivi#include "Utility.h" 408b01852701d50869318663f568270f977d93dbdfFrederic Boisnard#include <errno.h> 418ef87a1fe5d2f05557856efa6faf070bb9b03337David Wagner#include <convert.hpp> 4268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 4368a912857707864bbaaff9808717813105072a6ePatrick Benavoli#define base CParameterType 4468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 45d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalveusing std::string; 46d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalve 479368eea42a1afb01dd44110582f997115b50e742François GaffieCFixedPointParameterType::CFixedPointParameterType(const string &strName) : base(strName) 4868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 4968a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 5068a912857707864bbaaff9808717813105072a6ePatrick Benavoli 5168a912857707864bbaaff9808717813105072a6ePatrick Benavolistring CFixedPointParameterType::getKind() const 5268a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 5368a912857707864bbaaff9808717813105072a6ePatrick Benavoli return "FixedPointParameter"; 5468a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 5568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 562ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli// Element properties 579368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CFixedPointParameterType::showProperties(string &strResult) const 582ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli{ 592ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli base::showProperties(strResult); 602ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli 612ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli // Notation 622ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += "Notation: Q"; 639368eea42a1afb01dd44110582f997115b50e742François Gaffie strResult += std::to_string(_uiIntegral); 642ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += "."; 659368eea42a1afb01dd44110582f997115b50e742François Gaffie strResult += std::to_string(_uiFractional); 662ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli strResult += "\n"; 672ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli} 682ecf900ad8c30ce9f8e81f57977a1a80a6f6d8afPatrick Benavoli 6968a912857707864bbaaff9808717813105072a6ePatrick Benavoli// XML Serialization value space handling 7068a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Value space handling for configuration import 719368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CFixedPointParameterType::handleValueSpaceAttribute( 729368eea42a1afb01dd44110582f997115b50e742François Gaffie CXmlElement &xmlConfigurableElementSettingsElement, 739368eea42a1afb01dd44110582f997115b50e742François Gaffie CConfigurationAccessContext &configurationAccessContext) const 7468a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 7568a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Direction? 7668a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (!configurationAccessContext.serializeOut()) { 7768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 789368eea42a1afb01dd44110582f997115b50e742François Gaffie string strValueSpace; 799368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlConfigurableElementSettingsElement.getAttribute("ValueSpace", strValueSpace); 809368eea42a1afb01dd44110582f997115b50e742François Gaffie configurationAccessContext.setValueSpaceRaw(strValueSpace == "Raw"); 8168a912857707864bbaaff9808717813105072a6ePatrick Benavoli } else { 8268a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Provide value space only if not the default one 8368a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (configurationAccessContext.valueSpaceIsRaw()) { 8468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 859368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlConfigurableElementSettingsElement.setAttribute("ValueSpace", "Raw"); 8668a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 8768a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 8868a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 8968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 909368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::fromXml(const CXmlElement &xmlElement, 919368eea42a1afb01dd44110582f997115b50e742François Gaffie CXmlSerializingContext &serializingContext) 9268a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 9368a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Size 949368eea42a1afb01dd44110582f997115b50e742François Gaffie size_t sizeInBits = 0; 959368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.getAttribute("Size", sizeInBits); 9668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 9768a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Q notation 989368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.getAttribute("Integral", _uiIntegral); 999368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.getAttribute("Fractional", _uiFractional); 10068a912857707864bbaaff9808717813105072a6ePatrick Benavoli 10168a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Size vs. Q notation integrity check 1029368eea42a1afb01dd44110582f997115b50e742François Gaffie if (sizeInBits < getUtilSizeInBits()) { 10368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1049368eea42a1afb01dd44110582f997115b50e742François Gaffie std::string size; 1059368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.getAttribute("Size", size); 1069368eea42a1afb01dd44110582f997115b50e742François Gaffie serializingContext.setError( 1079368eea42a1afb01dd44110582f997115b50e742François Gaffie "Inconsistent Size vs. Q notation for " + getKind() + " " + xmlElement.getPath() + 1089368eea42a1afb01dd44110582f997115b50e742François Gaffie ": Summing (Integral + _uiFractional + 1) should not exceed given Size (" + size + ")"); 10968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 11068a912857707864bbaaff9808717813105072a6ePatrick Benavoli return false; 11168a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 11268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 11368a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Set the size 1149368eea42a1afb01dd44110582f997115b50e742François Gaffie setSize(sizeInBits / 8); 11568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 11668a912857707864bbaaff9808717813105072a6ePatrick Benavoli return base::fromXml(xmlElement, serializingContext); 11768a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 11868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1199368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::toBlackboard(const string &strValue, uint32_t &uiValue, 1209368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext ¶meterAccessContext) const 12168a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 1229368eea42a1afb01dd44110582f997115b50e742François Gaffie bool bValueProvidedAsHexa = utility::isHexadecimal(strValue); 12368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1246ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli // Check data integrity 1256ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli if (bValueProvidedAsHexa && !parameterAccessContext.valueSpaceIsRaw()) { 12668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1279368eea42a1afb01dd44110582f997115b50e742François Gaffie parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + 1289368eea42a1afb01dd44110582f997115b50e742François Gaffie " when selected value space is real:"); 12968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1306ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli return false; 13168a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 13268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1336ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli if (parameterAccessContext.valueSpaceIsRaw()) { 13468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 135a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (bValueProvidedAsHexa) { 1368b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 137a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return convertFromHexadecimal(strValue, uiValue, parameterAccessContext); 1388b01852701d50869318663f568270f977d93dbdfFrederic Boisnard } 139a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return convertFromDecimal(strValue, uiValue, parameterAccessContext); 140a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 141a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek return convertFromQnm(strValue, uiValue, parameterAccessContext); 142a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 14368a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1449368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CFixedPointParameterType::setOutOfRangeError( 1459368eea42a1afb01dd44110582f997115b50e742François Gaffie const string &strValue, CParameterAccessContext ¶meterAccessContext) const 146a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 1479368eea42a1afb01dd44110582f997115b50e742François Gaffie std::ostringstream stream; 148a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 1499368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << "Value " << strValue << " standing out of admitted "; 150a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 151a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (!parameterAccessContext.valueSpaceIsRaw()) { 152a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 153a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Min/Max computation 154a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie double dMin = 0; 155a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie double dMax = 0; 156a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie getRange(dMin, dMax); 15768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1589368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << std::fixed << std::setprecision(_uiFractional) << "real range [" << dMin << ", " 1599368eea42a1afb01dd44110582f997115b50e742François Gaffie << dMax << "]"; 1606ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } else { 1616ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 162a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Min/Max computation 163a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie int32_t iMax = getMaxValue<uint32_t>(); 164a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie int32_t iMin = -iMax - 1; 16568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1669368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << "raw range ["; 1678b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 1689368eea42a1afb01dd44110582f997115b50e742François Gaffie if (utility::isHexadecimal(strValue)) { 1699368eea42a1afb01dd44110582f997115b50e742François Gaffie 1709368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << std::hex << std::uppercase << std::setw(static_cast<int>(getSize()) * 2) 1719368eea42a1afb01dd44110582f997115b50e742François Gaffie << std::setfill('0'); 1728b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 173a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Format Min 1749368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << "0x" << makeEncodable(iMin); 175a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // Format Max 1769368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << ", 0x" << makeEncodable(iMax); 17768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 178a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } else { 1798b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 1809368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << iMin << ", " << iMax; 181a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 18268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1839368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << "]"; 184a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 1859368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << " for " << getKind(); 186a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 1879368eea42a1afb01dd44110582f997115b50e742François Gaffie parameterAccessContext.setError(stream.str()); 18868a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 18968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1909368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::fromBlackboard(string &strValue, const uint32_t &value, 1919368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext ¶meterAccessContext) const 19268a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 1938b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check encodability 1949368eea42a1afb01dd44110582f997115b50e742François Gaffie assert(isEncodable(value, false)); 19568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 19668a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Format 1979368eea42a1afb01dd44110582f997115b50e742François Gaffie std::ostringstream stream; 19868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1996ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli // Raw formatting? 20068a912857707864bbaaff9808717813105072a6ePatrick Benavoli if (parameterAccessContext.valueSpaceIsRaw()) { 2016ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli // Hexa formatting? 2026ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli if (parameterAccessContext.outputRawFormatIsHex()) { 2039368eea42a1afb01dd44110582f997115b50e742François Gaffie uint32_t data = static_cast<uint32_t>(value); 2046ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 2059368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << "0x" << std::hex << std::uppercase 2069368eea42a1afb01dd44110582f997115b50e742François Gaffie << std::setw(static_cast<int>(getSize() * 2)) << std::setfill('0') << data; 2076ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } else { 2089368eea42a1afb01dd44110582f997115b50e742François Gaffie int32_t data = value; 2096ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 2105901c1d3f448af5d0506d889b0543d9e0de0c2ceGuillaume Denneulin // Sign extend 2119368eea42a1afb01dd44110582f997115b50e742François Gaffie signExtend(data); 2125901c1d3f448af5d0506d889b0543d9e0de0c2ceGuillaume Denneulin 2139368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << data; 2146ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } 21568a912857707864bbaaff9808717813105072a6ePatrick Benavoli } else { 2169368eea42a1afb01dd44110582f997115b50e742François Gaffie int32_t data = value; 21768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 218258c6f5ae24de2e96ac0a0a842483bdc60b6b063Frederic Boisnard // Sign extend 2199368eea42a1afb01dd44110582f997115b50e742François Gaffie signExtend(data); 220258c6f5ae24de2e96ac0a0a842483bdc60b6b063Frederic Boisnard 221065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Conversion 2229368eea42a1afb01dd44110582f997115b50e742François Gaffie stream << std::fixed << std::setprecision(_uiFractional) << binaryQnmToDouble(data); 22368a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 22468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 2259368eea42a1afb01dd44110582f997115b50e742François Gaffie strValue = stream.str(); 226065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 227065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return true; 228065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 229065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 230065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli// Value access 2319368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::toBlackboard(double dUserValue, uint32_t &uiValue, 2329368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext ¶meterAccessContext) const 233065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 2348b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check that the value is within the allowed range for this type 2358b01852701d50869318663f568270f977d93dbdfFrederic Boisnard if (!checkValueAgainstRange(dUserValue)) { 236065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 237065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Illegal value provided 238065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli parameterAccessContext.setError("Value out of range"); 239065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 240065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return false; 241065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli } 242065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 2438b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Do the conversion 244a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek int32_t iData = doubleToBinaryQnm(dUserValue); 2458b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 2468b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check integrity 2478b01852701d50869318663f568270f977d93dbdfFrederic Boisnard assert(isEncodable((uint32_t)iData, true)); 2488b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 249065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli uiValue = iData; 250065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 251065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return true; 252065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 253065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 2549368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::fromBlackboard(double &dUserValue, uint32_t uiValue, 2559368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext & /*ctx*/) const 256065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 257065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli int32_t iData = uiValue; 258065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 2598b01852701d50869318663f568270f977d93dbdfFrederic Boisnard // Check unsigned value is encodable 2608b01852701d50869318663f568270f977d93dbdfFrederic Boisnard assert(isEncodable(uiValue, false)); 261065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 262065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Sign extend 263065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli signExtend(iData); 264065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 265a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek dUserValue = binaryQnmToDouble(iData); 266065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 267065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return true; 26868a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 26968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 27068a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Util size 2719368eea42a1afb01dd44110582f997115b50e742François Gaffiesize_t CFixedPointParameterType::getUtilSizeInBits() const 27268a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 27368a912857707864bbaaff9808717813105072a6ePatrick Benavoli return _uiIntegral + _uiFractional + 1; 27468a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 2756ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 2768b01852701d50869318663f568270f977d93dbdfFrederic Boisnard// Compute the range for the type (minimum and maximum values) 2779368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CFixedPointParameterType::getRange(double &dMin, double &dMax) const 2786ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli{ 2799368eea42a1afb01dd44110582f997115b50e742François Gaffie dMax = ((1U << (_uiIntegral + _uiFractional)) - 1) / double(1U << _uiFractional); 2809368eea42a1afb01dd44110582f997115b50e742François Gaffie dMin = -((1U << (_uiIntegral + _uiFractional)) / double(1U << _uiFractional)); 281a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 2826ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 2839368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::convertFromHexadecimal( 2849368eea42a1afb01dd44110582f997115b50e742François Gaffie const string &strValue, uint32_t &uiValue, 2859368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext ¶meterAccessContext) const 286a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 287a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // For hexadecimal representation, we need full 32 bit range conversion. 2889368eea42a1afb01dd44110582f997115b50e742François Gaffie if (!convertTo(strValue, uiValue) || !isEncodable(uiValue, false)) { 2896ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 290a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setOutOfRangeError(strValue, parameterAccessContext); 291a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return false; 292a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 2939368eea42a1afb01dd44110582f997115b50e742François Gaffie signExtend(reinterpret_cast<int32_t &>(uiValue)); 2946ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 295a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // check that the data is encodable and can been safely written to the blackboard 2969368eea42a1afb01dd44110582f997115b50e742François Gaffie assert(isEncodable(uiValue, true)); 2978b01852701d50869318663f568270f977d93dbdfFrederic Boisnard 298a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return true; 299a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 3006ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 3019368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::convertFromDecimal( 3029368eea42a1afb01dd44110582f997115b50e742François Gaffie const string &strValue, uint32_t &uiValue, 3039368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext ¶meterAccessContext) const 304a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 3059368eea42a1afb01dd44110582f997115b50e742François Gaffie if (!convertTo(strValue, reinterpret_cast<int32_t &>(uiValue)) || !isEncodable(uiValue, true)) { 3066ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 307a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setOutOfRangeError(strValue, parameterAccessContext); 308a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return false; 309a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie } 310a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return true; 311a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie} 3126ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 3139368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CFixedPointParameterType::convertFromQnm(const string &strValue, uint32_t &uiValue, 3149368eea42a1afb01dd44110582f997115b50e742François Gaffie CParameterAccessContext ¶meterAccessContext) const 315a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie{ 3169368eea42a1afb01dd44110582f997115b50e742François Gaffie double dData = 0; 3176ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 318a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie if (!convertTo(strValue, dData) || !checkValueAgainstRange(dData)) { 3196ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 320a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie setOutOfRangeError(strValue, parameterAccessContext); 321a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return false; 3226ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli } 323a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoek uiValue = static_cast<uint32_t>(doubleToBinaryQnm(dData)); 3246ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli 325a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie // check that the data is encodable and has been safely written to the blackboard 326a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie assert(isEncodable(uiValue, true)); 327a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie 328a17d5a584a9b681e2eb48465815d275eb5fccb8fFrancois Gaffie return true; 3296ba361d96bc2581667b3400f87ff89fae6449e1fPatrick Benavoli} 3301387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli 3318b01852701d50869318663f568270f977d93dbdfFrederic Boisnard// Check that the value is within available range for this type 3328b01852701d50869318663f568270f977d93dbdfFrederic Boisnardbool CFixedPointParameterType::checkValueAgainstRange(double dValue) const 3331387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli{ 3348b01852701d50869318663f568270f977d93dbdfFrederic Boisnard double dMin = 0; 3358b01852701d50869318663f568270f977d93dbdfFrederic Boisnard double dMax = 0; 3368b01852701d50869318663f568270f977d93dbdfFrederic Boisnard getRange(dMin, dMax); 33711e6498a4fa3b27ca34d2fcb76bd6365da9d5c1bPatrick Benavoli 338d9406eea67ae1d88b36e356d10d491f3bf0dfe1bMattijs Korpershoek return (dValue <= dMax) && (dValue >= dMin); 3391387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli} 3401387bda01b089d8e8df06339d9c15d53b3de6725Patrick Benavoli 341065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli// Data conversion 342a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoekint32_t CFixedPointParameterType::doubleToBinaryQnm(double dValue) const 343065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 34459cc1e33810c55e6fa1e3bd320e1cf29e24d23beDavid Wagner // For Qn.m number, multiply by 2^n and round to the nearest integer 3459368eea42a1afb01dd44110582f997115b50e742François Gaffie int32_t iData = static_cast<int32_t>(round(dValue * double(1UL << _uiFractional))); 346065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Left justify 34759cc1e33810c55e6fa1e3bd320e1cf29e24d23beDavid Wagner // For a Qn.m number, shift 32 - (n + m + 1) bits to the left (the rest of 34859cc1e33810c55e6fa1e3bd320e1cf29e24d23beDavid Wagner // the bits aren't used) 349065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli iData <<= getSize() * 8 - getUtilSizeInBits(); 350065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 351065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli return iData; 352065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 353065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli 354a24e61fddaf09d2989fff25785e329454c842d7fMattijs Korpershoekdouble CFixedPointParameterType::binaryQnmToDouble(int32_t iValue) const 355065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli{ 356065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli // Unjustify 357065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli iValue >>= getSize() * 8 - getUtilSizeInBits(); 3589368eea42a1afb01dd44110582f997115b50e742François Gaffie return static_cast<double>(iValue) / double(1UL << _uiFractional); 359065264a93ce9c63b6a5c95e985188ee33ba587d3Patrick Benavoli} 360326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 361326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron// From IXmlSource 3629368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CFixedPointParameterType::toXml(CXmlElement &xmlElement, 3639368eea42a1afb01dd44110582f997115b50e742François Gaffie CXmlSerializingContext &serializingContext) const 364326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron{ 365326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron // Size 3669368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.setAttribute("Size", getSize() * 8); 367326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 368326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron // Integral 3699368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.setAttribute("Integral", _uiIntegral); 370326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 371326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron // Fractional 3729368eea42a1afb01dd44110582f997115b50e742François Gaffie xmlElement.setAttribute("Fractional", _uiFractional); 373326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron 374326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron base::toXml(xmlElement, serializingContext); 375326a31df0dd401283de6170ed09bcf605f61ef7dGeorges-Henri Baron} 376