Home | History | Annotate | Download | only in parameter
      1 /*
      2  * Copyright (c) 2011-2015, 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 "BitParameterType.h"
     31 #include "BitParameter.h"
     32 #include <stdlib.h>
     33 #include <sstream>
     34 #include "ParameterAccessContext.h"
     35 #include "BitParameterBlockType.h"
     36 #include "Utility.h"
     37 
     38 #define base CTypeElement
     39 
     40 using std::string;
     41 
     42 CBitParameterType::CBitParameterType(const string &strName) : base(strName)
     43 {
     44 }
     45 
     46 // CElement
     47 string CBitParameterType::getKind() const
     48 {
     49     return "BitParameter";
     50 }
     51 
     52 // Element properties
     53 void CBitParameterType::showProperties(string &strResult) const
     54 {
     55     base::showProperties(strResult);
     56 
     57     // Bit Pos
     58     strResult += "Bit pos: ";
     59     strResult += std::to_string(_bitPos);
     60     strResult += "\n";
     61 
     62     // Bit size
     63     strResult += "Bit size: ";
     64     strResult += std::to_string(_uiBitSize);
     65     strResult += "\n";
     66 
     67     // Max
     68     strResult += "Max: ";
     69     strResult += std::to_string(_uiMax);
     70     strResult += "\n";
     71 }
     72 
     73 // From IXmlSink
     74 bool CBitParameterType::fromXml(const CXmlElement &xmlElement,
     75                                 CXmlSerializingContext &serializingContext)
     76 {
     77     // Pos
     78     xmlElement.getAttribute("Pos", _bitPos);
     79 
     80     // Size
     81     xmlElement.getAttribute("Size", _uiBitSize);
     82 
     83     // Validate bit pos and size still fit into parent type
     84     const CBitParameterBlockType *pBitParameterBlockType =
     85         static_cast<const CBitParameterBlockType *>(getParent());
     86 
     87     size_t uiParentBlockBitSize = pBitParameterBlockType->getSize() * 8;
     88 
     89     if (_bitPos + _uiBitSize > uiParentBlockBitSize) {
     90 
     91         // Range exceeded
     92         std::ostringstream strStream;
     93 
     94         strStream << "Pos and Size attributes inconsistent with maximum container element size ("
     95                   << uiParentBlockBitSize << " bits) for " + getKind();
     96 
     97         serializingContext.setError(strStream.str());
     98 
     99         return false;
    100     }
    101 
    102     // Max
    103     _uiMax = getMaxEncodableValue();
    104     if (xmlElement.getAttribute("Max", _uiMax) && (_uiMax > getMaxEncodableValue())) {
    105 
    106         // Max value exceeded
    107         std::ostringstream strStream;
    108 
    109         strStream << "Max attribute inconsistent with maximum encodable size ("
    110                   << getMaxEncodableValue() << ") for " + getKind();
    111 
    112         serializingContext.setError(strStream.str());
    113 
    114         return false;
    115     }
    116 
    117     // Base
    118     return base::fromXml(xmlElement, serializingContext);
    119 }
    120 
    121 // Conversion
    122 bool CBitParameterType::toBlackboard(const string &strValue, uint64_t &uiValue,
    123                                      CParameterAccessContext &parameterAccessContext) const
    124 {
    125     // Get value
    126     uint64_t uiConvertedValue = strtoull(strValue.c_str(), NULL, 0);
    127 
    128     if (uiConvertedValue > _uiMax) {
    129 
    130         // Range exceeded
    131         std::ostringstream strStream;
    132 
    133         strStream << "Value " << strValue << " standing out of admitted range [";
    134 
    135         if (utility::isHexadecimal(strValue)) {
    136 
    137             strStream << "0x0, "
    138                       << "0x" << std::hex << std::uppercase;
    139         } else {
    140 
    141             strStream << "0, ";
    142         }
    143         strStream << _uiMax << "] for " + getKind();
    144 
    145         parameterAccessContext.setError(strStream.str());
    146 
    147         return false;
    148     }
    149 
    150     // Do bitwise RMW operation
    151     uiValue = (uiValue & ~getMask()) | (uiConvertedValue << _bitPos);
    152 
    153     return true;
    154 }
    155 
    156 void CBitParameterType::fromBlackboard(string &strValue, const uint64_t &uiValue,
    157                                        CParameterAccessContext &parameterAccessContext) const
    158 {
    159     uint64_t uiConvertedValue = (uiValue & getMask()) >> _bitPos;
    160 
    161     // Format
    162     std::ostringstream strStream;
    163 
    164     // Take care of format
    165     if (parameterAccessContext.valueSpaceIsRaw() && parameterAccessContext.outputRawFormatIsHex()) {
    166 
    167         strStream << "0x" << std::hex << std::uppercase;
    168     }
    169 
    170     strStream << uiConvertedValue;
    171 
    172     strValue = strStream.str();
    173 }
    174 
    175 // Value access
    176 // Integer
    177 bool CBitParameterType::toBlackboard(uint64_t uiUserValue, uint64_t &uiValue,
    178                                      CParameterAccessContext &parameterAccessContext) const
    179 {
    180     if (uiUserValue > _uiMax) {
    181 
    182         parameterAccessContext.setError("Value out of range");
    183 
    184         return false;
    185     }
    186 
    187     // Do bitwise RMW operation
    188     uiValue = (uiValue & ~getMask()) | (uiUserValue << _bitPos);
    189 
    190     return true;
    191 }
    192 
    193 void CBitParameterType::fromBlackboard(uint32_t &userValue, uint64_t value,
    194                                        CParameterAccessContext & /*ctx*/) const
    195 {
    196     userValue = static_cast<uint32_t>((value & getMask()) >> _bitPos);
    197 }
    198 
    199 // Access from area configuration
    200 uint64_t CBitParameterType::merge(uint64_t uiOriginData, uint64_t uiNewData) const
    201 {
    202     return (uiOriginData & ~getMask()) | (uiNewData & getMask());
    203 }
    204 
    205 // Bit Size
    206 size_t CBitParameterType::getBitSize() const
    207 {
    208     return _uiBitSize;
    209 }
    210 
    211 CInstanceConfigurableElement *CBitParameterType::doInstantiate() const
    212 {
    213     return new CBitParameter(getName(), this);
    214 }
    215 
    216 // Max value
    217 uint64_t CBitParameterType::getMaxEncodableValue() const
    218 {
    219     return (uint64_t)-1L >> (8 * sizeof(uint64_t) - _uiBitSize);
    220 }
    221 
    222 // Biwise mask
    223 uint64_t CBitParameterType::getMask() const
    224 {
    225     return getMaxEncodableValue() << _bitPos;
    226 }
    227 
    228 // Check data has no bit set outside available range
    229 bool CBitParameterType::isEncodable(uint64_t uiData) const
    230 {
    231     size_t uiShift = 8 * sizeof(uiData) - _uiBitSize;
    232 
    233     if (uiShift) {
    234 
    235         // Check high bits are clean
    236         return !(uiData >> uiShift);
    237     }
    238 
    239     return true;
    240 }
    241 
    242 // From IXmlSource
    243 void CBitParameterType::toXml(CXmlElement &xmlElement,
    244                               CXmlSerializingContext &serializingContext) const
    245 {
    246     // Position
    247     xmlElement.setAttribute("Pos", _bitPos);
    248 
    249     // Size
    250     xmlElement.setAttribute("Size", _uiBitSize);
    251 
    252     // Maximum
    253     xmlElement.setAttribute("Max", _uiMax);
    254 
    255     base::toXml(xmlElement, serializingContext);
    256 }
    257