Home | History | Annotate | Download | only in parameter
      1 /*
      2  * Copyright (c) 2011-2014, Intel Corporation
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without modification,
      6  * are permitted provided that the following conditions are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright notice, this
      9  * list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above copyright notice,
     12  * this list of conditions and the following disclaimer in the documentation and/or
     13  * other materials provided with the distribution.
     14  *
     15  * 3. Neither the name of the copyright holder nor the names of its contributors
     16  * may be used to endorse or promote products derived from this software without
     17  * specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
     23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 #include "ParameterType.h"
     31 #include "Parameter.h"
     32 #include "ArrayParameter.h"
     33 #include "ParameterAccessContext.h"
     34 
     35 #include <climits>
     36 
     37 #define base CTypeElement
     38 
     39 using std::string;
     40 
     41 const std::string CParameterType::gUnitPropertyName = "Unit";
     42 
     43 CParameterType::CParameterType(const string &strName) : base(strName)
     44 {
     45 }
     46 
     47 // Object creation
     48 void CParameterType::populate(CElement * /*elem*/) const
     49 {
     50     // Prevent further digging for instantiaton since we're leaf on the strcture tree
     51 }
     52 
     53 // Size
     54 void CParameterType::setSize(size_t size)
     55 {
     56     _size = size;
     57 }
     58 
     59 size_t CParameterType::getSize() const
     60 {
     61     return _size;
     62 }
     63 
     64 // Unit
     65 string CParameterType::getUnit() const
     66 {
     67     return _strUnit;
     68 }
     69 
     70 void CParameterType::setUnit(const std::string &strUnit)
     71 {
     72     _strUnit = strUnit;
     73 }
     74 
     75 // From IXmlSink
     76 bool CParameterType::fromXml(const CXmlElement &xmlElement,
     77                              CXmlSerializingContext &serializingContext)
     78 {
     79     xmlElement.getAttribute(gUnitPropertyName, _strUnit);
     80     return base::fromXml(xmlElement, serializingContext);
     81 }
     82 
     83 // From IXmlSource
     84 void CParameterType::toXml(CXmlElement &xmlElement,
     85                            CXmlSerializingContext &serializingContext) const
     86 {
     87     base::toXml(xmlElement, serializingContext);
     88     setXmlUnitAttribute(xmlElement);
     89 }
     90 
     91 void CParameterType::setXmlUnitAttribute(CXmlElement &xmlElement) const
     92 {
     93     const string &unit = getUnit();
     94     if (!unit.empty()) {
     95         xmlElement.setAttribute(gUnitPropertyName, unit);
     96     }
     97 }
     98 
     99 // XML Serialization value space handling
    100 // Value space handling for configuration import/export
    101 void CParameterType::handleValueSpaceAttribute(
    102     CXmlElement & /*xmlConfigurableElementSettingsElement*/,
    103     CConfigurationAccessContext & /*ctx*/) const
    104 {
    105     // Do nothing by default
    106 }
    107 
    108 // Element properties
    109 void CParameterType::showProperties(string &strResult) const
    110 {
    111     base::showProperties(strResult);
    112 
    113     // Add Unit property if found
    114     if (!getUnit().empty()) {
    115         strResult += gUnitPropertyName + ": " + getUnit() + "\n";
    116     }
    117 
    118     // Scalar size
    119     strResult += "Scalar size: " + std::to_string(getSize()) + " byte(s) \n";
    120 }
    121 
    122 // Default value handling (simulation only)
    123 uint32_t CParameterType::getDefaultValue() const
    124 {
    125     return 0;
    126 }
    127 
    128 // Parameter instantiation
    129 CInstanceConfigurableElement *CParameterType::doInstantiate() const
    130 {
    131     if (isScalar()) {
    132         // Scalar parameter
    133         return new CParameter(getName(), this);
    134     } else {
    135         // Array Parameter
    136         return new CArrayParameter(getName(), this);
    137     }
    138 }
    139 
    140 void CParameterType::signExtend(int32_t &iData) const
    141 {
    142     doSignExtend(iData);
    143 }
    144 
    145 void CParameterType::signExtend(int64_t &iData) const
    146 {
    147     doSignExtend(iData);
    148 }
    149 
    150 // Generic sign extension
    151 template <typename type>
    152 void CParameterType::doSignExtend(type &data) const
    153 {
    154     size_t shift = CHAR_BIT * (sizeof(data) - getSize());
    155     // FIXME: If `data` has a signed type and nonnegative value,
    156     //        and `data  2^shift` is representable in the result type,
    157     //        then that is the resulting value;
    158     //        otherwise, **the behavior is undened**.
    159     //        ISO C99 (6.5.7/4) & ISO C++11 [expr.shift]
    160     data = (data << shift) >> shift;
    161 }
    162 
    163 // Check data has no bit set outside available range (32 bits)
    164 bool CParameterType::isEncodable(uint32_t uiData, bool bIsSigned) const
    165 {
    166     return doIsEncodable(uiData, bIsSigned);
    167 }
    168 
    169 // Check data has no bit set outside available range (64 bits)
    170 bool CParameterType::isEncodable(uint64_t uiData, bool bIsSigned) const
    171 {
    172     return doIsEncodable(uiData, bIsSigned);
    173 }
    174 
    175 // Generic encodability check
    176 template <typename type>
    177 bool CParameterType::doIsEncodable(type data, bool bIsSigned) const
    178 {
    179     if (getSize() == sizeof(data)) {
    180         // Prevent inappropriate shifts
    181         return true;
    182     }
    183 
    184     size_t shift = getSize() * 8;
    185 
    186     if (!bIsSigned) {
    187 
    188         // Check high bits are clean
    189         return !(data >> shift);
    190 
    191     } else {
    192 
    193         // Negative value?
    194         bool bIsValueExpectedNegative = (data & (type(1) << (shift - 1))) != 0;
    195 
    196         // Check high bits are clean
    197         return bIsValueExpectedNegative ? !(~data >> shift) : !(data >> shift);
    198     }
    199 }
    200 
    201 // Remove all bits set outside available range
    202 uint32_t CParameterType::makeEncodable(uint32_t uiData) const
    203 {
    204     size_t sizeInBits = getSize() * 8;
    205 
    206     uint32_t uiMask = (1 << sizeInBits) - 1;
    207 
    208     return uiData & uiMask;
    209 }
    210 
    211 // Conversions (dynamic access)
    212 // Value access
    213 // Boolean
    214 bool CParameterType::toBlackboard(bool /*bUserValue*/, uint32_t & /*uiValue*/,
    215                                   CParameterAccessContext &parameterAccessContext) const
    216 {
    217     parameterAccessContext.setError("Unsupported conversion");
    218     return false;
    219 }
    220 
    221 bool CParameterType::fromBlackboard(bool & /*bUserValue*/, uint32_t /*uiValue*/,
    222                                     CParameterAccessContext &parameterAccessContext) const
    223 {
    224     parameterAccessContext.setError("Unsupported conversion");
    225     return false;
    226 }
    227 
    228 // Integer
    229 bool CParameterType::toBlackboard(uint32_t /*uiUserValue*/, uint32_t & /*uiValue*/,
    230                                   CParameterAccessContext &parameterAccessContext) const
    231 {
    232     parameterAccessContext.setError("Unsupported conversion");
    233     return false;
    234 }
    235 
    236 bool CParameterType::fromBlackboard(uint32_t & /*uiUserValue*/, uint32_t /*uiValue*/,
    237                                     CParameterAccessContext &parameterAccessContext) const
    238 {
    239     parameterAccessContext.setError("Unsupported conversion");
    240     return false;
    241 }
    242 
    243 // Signed Integer
    244 bool CParameterType::toBlackboard(int32_t /*iUserValue*/, uint32_t & /*uiValue*/,
    245                                   CParameterAccessContext &parameterAccessContext) const
    246 {
    247     parameterAccessContext.setError("Unsupported conversion");
    248 
    249     return false;
    250 }
    251 
    252 bool CParameterType::fromBlackboard(int32_t & /*iUserValue*/, uint32_t /*uiValue*/,
    253                                     CParameterAccessContext &parameterAccessContext) const
    254 {
    255     parameterAccessContext.setError("Unsupported conversion");
    256 
    257     return false;
    258 }
    259 
    260 // Double
    261 bool CParameterType::toBlackboard(double /*dUserValue*/, uint32_t & /*uiValue*/,
    262                                   CParameterAccessContext &parameterAccessContext) const
    263 {
    264     parameterAccessContext.setError("Unsupported conversion");
    265 
    266     return false;
    267 }
    268 
    269 bool CParameterType::fromBlackboard(double & /*dUserValue*/, uint32_t /*uiValue*/,
    270                                     CParameterAccessContext &parameterAccessContext) const
    271 {
    272     parameterAccessContext.setError("Unsupported conversion");
    273 
    274     return false;
    275 }
    276