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