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 "EnumParameterType.h"
     31 #include "EnumValuePair.h"
     32 #include "ParameterAccessContext.h"
     33 #include "convert.hpp"
     34 
     35 #define base CParameterType
     36 
     37 using std::string;
     38 
     39 CEnumParameterType::CEnumParameterType(const string &strName) : base(strName)
     40 {
     41 }
     42 
     43 string CEnumParameterType::getKind() const
     44 {
     45     return "EnumParameter";
     46 }
     47 
     48 bool CEnumParameterType::childrenAreDynamic() const
     49 {
     50     return true;
     51 }
     52 
     53 // Element properties
     54 void CEnumParameterType::showProperties(string &strResult) const
     55 {
     56     base::showProperties(strResult);
     57 
     58     strResult += "Value Pairs:\n";
     59 
     60     // Show all value pairs
     61     size_t uiChild;
     62     size_t uiNbChildren = getNbChildren();
     63 
     64     for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
     65 
     66         const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild));
     67 
     68         strResult += "\tLiteral: \"";
     69         strResult += pValuePair->getName();
     70         strResult += "\", Numerical: ";
     71         strResult += pValuePair->getNumericalAsString();
     72         strResult += "\n";
     73     }
     74 }
     75 
     76 bool CEnumParameterType::fromXml(const CXmlElement &xmlElement,
     77                                  CXmlSerializingContext &serializingContext)
     78 {
     79     // Size in bits
     80     size_t sizeInBits = 0;
     81     if (not xmlElement.getAttribute("Size", sizeInBits)) {
     82         return false;
     83     }
     84 
     85     // Size
     86     setSize(sizeInBits / 8);
     87 
     88     // Base
     89     return base::fromXml(xmlElement, serializingContext);
     90 }
     91 
     92 // Conversion (tuning)
     93 bool CEnumParameterType::toBlackboard(const string &strValue, uint32_t &uiValue,
     94                                       CParameterAccessContext &parameterAccessContext) const
     95 {
     96     int32_t iParsedUserValue = 0;
     97 
     98     // Try to read the user-provided string as an integer
     99     if (not convertTo(strValue, iParsedUserValue)) {
    100         // If it fails to parse as an integer, first try to convert it from
    101         // lexical to numerical space.
    102         int32_t iNumerical;
    103         if (not getNumerical(strValue, iNumerical)) {
    104 
    105             parameterAccessContext.setError("Provided value '" + strValue +
    106                                             "' is not part of the lexical space"
    107                                             " or not within the numerical range.");
    108 
    109             return false;
    110         }
    111         iParsedUserValue = iNumerical;
    112     }
    113 
    114     // Once it has been converted to a number (either through parsing or
    115     // through lexical->numerical conversion), call the numerical overload of
    116     // toBlackboard.
    117     return toBlackboard(iParsedUserValue, uiValue, parameterAccessContext);
    118 }
    119 
    120 int32_t CEnumParameterType::getMin() const
    121 {
    122     // Enums are always signed, it means we have one less util bit
    123     return -getMax() - 1;
    124 }
    125 
    126 int32_t CEnumParameterType::getMax() const
    127 {
    128     return getMaxValue<int32_t>();
    129 }
    130 
    131 bool CEnumParameterType::fromBlackboard(string &userValue, const uint32_t &value,
    132                                         CParameterAccessContext & /*ctx*/) const
    133 {
    134     // Convert the raw value from the blackboard
    135     int32_t signedValue = static_cast<int32_t>(value);
    136     signExtend(signedValue);
    137 
    138     // Convert from numerical space to literal space
    139     return getLiteral(signedValue, userValue);
    140 }
    141 
    142 // Value access
    143 bool CEnumParameterType::toBlackboard(int32_t userValue, uint32_t &value,
    144                                       CParameterAccessContext &parameterAccessContext) const
    145 {
    146     if (!checkValueAgainstSpace(userValue)) {
    147 
    148         parameterAccessContext.setError(std::to_string(userValue) +
    149                                         " is not part of numerical space.");
    150 
    151         return false;
    152     }
    153 
    154     if (userValue < getMin() or userValue > getMax()) {
    155 
    156         // FIXME: values provided as hexa (either on command line or in a config
    157         // file will appear in decimal base instead of hexa base...
    158         parameterAccessContext.setError(
    159             "Value " + std::to_string(userValue) + " standing out of admitted range [" +
    160             std::to_string(getMin()) + ", " + std::to_string(getMax()) + "] for " + getKind());
    161         return false;
    162     }
    163 
    164     value = static_cast<uint32_t>(userValue);
    165 
    166     return true;
    167 }
    168 
    169 bool CEnumParameterType::fromBlackboard(int32_t &userValue, uint32_t value,
    170                                         CParameterAccessContext & /*ctx*/) const
    171 {
    172     int32_t signedValue = static_cast<int32_t>(value);
    173 
    174     // Sign extend
    175     signExtend(signedValue);
    176 
    177     userValue = signedValue;
    178 
    179     return true;
    180 }
    181 
    182 // Default value handling (simulation only)
    183 uint32_t CEnumParameterType::getDefaultValue() const
    184 {
    185     if (!getNbChildren()) {
    186 
    187         return 0;
    188     }
    189 
    190     // Return first available numerical
    191     return static_cast<const CEnumValuePair *>(getChild(0))->getNumerical();
    192 }
    193 
    194 // Literal - numerical conversions
    195 bool CEnumParameterType::getLiteral(int32_t iNumerical, string &strLiteral) const
    196 {
    197     size_t uiChild;
    198     size_t uiNbChildren = getNbChildren();
    199 
    200     for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
    201 
    202         const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild));
    203 
    204         if (pValuePair->getNumerical() == iNumerical) {
    205 
    206             strLiteral = pValuePair->getName();
    207 
    208             return true;
    209         }
    210     }
    211 
    212     return false;
    213 }
    214 
    215 bool CEnumParameterType::getNumerical(const string &strLiteral, int32_t &iNumerical) const
    216 {
    217     size_t uiChild;
    218     size_t uiNbChildren = getNbChildren();
    219 
    220     for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
    221 
    222         const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild));
    223 
    224         if (pValuePair->getName() == strLiteral) {
    225 
    226             iNumerical = pValuePair->getNumerical();
    227 
    228             return true;
    229         }
    230     }
    231 
    232     return false;
    233 }
    234 
    235 // Numerical validity of the enum value
    236 bool CEnumParameterType::checkValueAgainstSpace(int32_t iNumerical) const
    237 {
    238     // Check that the value is part of the allowed values for this kind of enum
    239     size_t uiChild;
    240     size_t uiNbChildren = getNbChildren();
    241 
    242     for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
    243 
    244         const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild));
    245 
    246         if (pValuePair->getNumerical() == iNumerical) {
    247 
    248             return true;
    249         }
    250     }
    251 
    252     return false;
    253 }
    254 
    255 // From IXmlSource
    256 void CEnumParameterType::toXml(CXmlElement &xmlElement,
    257                                CXmlSerializingContext &serializingContext) const
    258 {
    259     // Size
    260     xmlElement.setAttribute("Size", getSize() * 8);
    261 
    262     base::toXml(xmlElement, serializingContext);
    263 }
    264