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