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 #include "Utility.h"
35 
36 #define base CTypeElement
37 
38 using std::string;
39 
40 const std::string CParameterType::gUnitPropertyName = "Unit";
41 
CParameterType(const string & strName)42 CParameterType::CParameterType(const string& strName) : base(strName), _uiSize(0)
43 {
44 }
45 
~CParameterType()46 CParameterType::~CParameterType()
47 {
48 }
49 
50 // Object creation
populate(CElement * pElement) const51 void CParameterType::populate(CElement* pElement) const
52 {
53     (void)pElement;
54     // Prevent further digging for instantiaton since we're leaf on the strcture tree
55 }
56 
57 // Size
setSize(uint32_t uiSize)58 void CParameterType::setSize(uint32_t uiSize)
59 {
60     _uiSize = uiSize;
61 }
62 
getSize() const63 uint32_t CParameterType::getSize() const
64 {
65     return _uiSize;
66 }
67 
68 // Unit
getUnit() const69 string CParameterType::getUnit() const
70 {
71     return _strUnit;
72 }
73 
setUnit(const std::string & strUnit)74 void CParameterType::setUnit(const std::string& strUnit)
75 {
76     _strUnit = strUnit;
77 }
78 
79 // From IXmlSink
fromXml(const CXmlElement & xmlElement,CXmlSerializingContext & serializingContext)80 bool CParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
81 {
82     setUnit(xmlElement.getAttributeString(gUnitPropertyName));
83     return base::fromXml(xmlElement, serializingContext);
84 }
85 
86 // From IXmlSource
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const87 void CParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
88 {
89     base::toXml(xmlElement, serializingContext);
90     setXmlUnitAttribute(xmlElement);
91 }
92 
setXmlUnitAttribute(CXmlElement & xmlElement) const93 void CParameterType::setXmlUnitAttribute(CXmlElement& xmlElement) const
94 {
95     const string& unit = getUnit();
96     if (!unit.empty()) {
97         xmlElement.setAttributeString(gUnitPropertyName, unit);
98     }
99 }
100 
101 // XML Serialization value space handling
102 // Value space handling for configuration import/export
handleValueSpaceAttribute(CXmlElement & xmlConfigurableElementSettingsElement,CConfigurationAccessContext & configurationAccessContext) const103 void CParameterType::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const
104 {
105     (void)xmlConfigurableElementSettingsElement;
106     (void)configurationAccessContext;
107     // Do nothing by default
108 }
109 
110 // Element properties
showProperties(string & strResult) const111 void CParameterType::showProperties(string& strResult) const
112 {
113     base::showProperties(strResult);
114 
115     // Add Unit property if found
116     if (!getUnit().empty()) {
117         strResult += gUnitPropertyName + ": " + getUnit() + "\n";
118     }
119 
120     // Scalar size
121     strResult += "Scalar size: " + CUtility::toString(getSize()) + " byte(s) \n";
122 }
123 
124 // Default value handling (simulation only)
getDefaultValue() const125 uint32_t CParameterType::getDefaultValue() const
126 {
127     return 0;
128 }
129 
130 // Parameter instantiation
doInstantiate() const131 CInstanceConfigurableElement* CParameterType::doInstantiate() const
132 {
133     if (isScalar()) {
134         // Scalar parameter
135         return new CParameter(getName(), this);
136     } else {
137         // Array Parameter
138         return new CArrayParameter(getName(), this);
139     }
140 }
141 
signExtend(int32_t & iData) const142 void CParameterType::signExtend(int32_t& iData) const
143 {
144     doSignExtend(iData);
145 }
146 
signExtend(int64_t & iData) const147 void CParameterType::signExtend(int64_t& iData) const
148 {
149     doSignExtend(iData);
150 }
151 
152 // Generic sign extension
153 template <typename type>
doSignExtend(type & data) const154 void CParameterType::doSignExtend(type& data) const
155 {
156     uint32_t uiSizeInBits = getSize() * 8;
157     uint32_t uiShift = 8 * sizeof(data) - uiSizeInBits;
158 
159     if (uiShift) {
160 
161         data = (data << uiShift) >> uiShift;
162     }
163 }
164 
165 // Check data has no bit set outside available range (32 bits)
isEncodable(uint32_t uiData,bool bIsSigned) const166 bool CParameterType::isEncodable(uint32_t uiData, bool bIsSigned) const
167 {
168     return doIsEncodable(uiData, bIsSigned);
169 }
170 
171 // Check data has no bit set outside available range (64 bits)
isEncodable(uint64_t uiData,bool bIsSigned) const172 bool CParameterType::isEncodable(uint64_t uiData, bool bIsSigned) const
173 {
174     return doIsEncodable(uiData, bIsSigned);
175 }
176 
177 // Generic encodability check
178 template <typename type>
doIsEncodable(type data,bool bIsSigned) const179 bool CParameterType::doIsEncodable(type data, bool bIsSigned) const
180 {
181     if (getSize() == sizeof(data)) {
182         // Prevent inappropriate shifts
183         return true;
184     }
185 
186     uint32_t uiShift = getSize() * 8;
187 
188     if (!bIsSigned) {
189 
190         // Check high bits are clean
191         return !(data >> uiShift);
192 
193     } else {
194 
195         // Negative value?
196         bool bIsValueExpectedNegative = (data & (1 << (uiShift - 1))) != 0;
197 
198         // Check high bits are clean
199         return bIsValueExpectedNegative ? !(~data >> uiShift) : !(data >> uiShift);
200     }
201 }
202 
203 // Remove all bits set outside available range
makeEncodable(uint32_t uiData) const204 uint32_t CParameterType::makeEncodable(uint32_t uiData) const
205 {
206     if (getSize() == sizeof(uint32_t)) {
207 
208         return uiData;
209     }
210     uint32_t uiSizeInBits = getSize() * 8;
211 
212     uint32_t uiMask = (1 << uiSizeInBits) - 1;
213 
214     return uiData & uiMask;
215 }
216 
217 // Conversions (dynamic access)
218 // Value access
219 // Boolean
toBlackboard(bool bUserValue,uint32_t & uiValue,CParameterAccessContext & parameterAccessContext) const220 bool CParameterType::toBlackboard(bool bUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const
221 {
222     (void)bUserValue;
223     (void)uiValue;
224     (void)parameterAccessContext;
225 
226     parameterAccessContext.setError("Unsupported conversion");
227 
228     return false;
229 }
230 
fromBlackboard(bool & bUserValue,uint32_t uiValue,CParameterAccessContext & parameterAccessContext) const231 bool CParameterType::fromBlackboard(bool& bUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const
232 {
233     (void)bUserValue;
234     (void)uiValue;
235     (void)parameterAccessContext;
236 
237     parameterAccessContext.setError("Unsupported conversion");
238 
239     return false;
240 }
241 
242 // Integer
toBlackboard(uint32_t uiUserValue,uint32_t & uiValue,CParameterAccessContext & parameterAccessContext) const243 bool CParameterType::toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const
244 {
245     (void)uiUserValue;
246     (void)uiValue;
247     (void)parameterAccessContext;
248 
249     parameterAccessContext.setError("Unsupported conversion");
250 
251     return false;
252 }
253 
fromBlackboard(uint32_t & uiUserValue,uint32_t uiValue,CParameterAccessContext & parameterAccessContext) const254 bool CParameterType::fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const
255 {
256     (void)uiUserValue;
257     (void)uiValue;
258     (void)parameterAccessContext;
259 
260     parameterAccessContext.setError("Unsupported conversion");
261 
262     return false;
263 }
264 
265 // Signed Integer
toBlackboard(int32_t iUserValue,uint32_t & uiValue,CParameterAccessContext & parameterAccessContext) const266 bool CParameterType::toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const
267 {
268     (void)iUserValue;
269     (void)uiValue;
270     (void)parameterAccessContext;
271 
272     parameterAccessContext.setError("Unsupported conversion");
273 
274     return false;
275 }
276 
fromBlackboard(int32_t & iUserValue,uint32_t uiValue,CParameterAccessContext & parameterAccessContext) const277 bool CParameterType::fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const
278 {
279     (void)iUserValue;
280     (void)uiValue;
281     (void)parameterAccessContext;
282 
283     parameterAccessContext.setError("Unsupported conversion");
284 
285     return false;
286 }
287 
288 // Double
toBlackboard(double dUserValue,uint32_t & uiValue,CParameterAccessContext & parameterAccessContext) const289 bool CParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const
290 {
291     (void)dUserValue;
292     (void)uiValue;
293     (void)parameterAccessContext;
294 
295     parameterAccessContext.setError("Unsupported conversion");
296 
297     return false;
298 }
299 
fromBlackboard(double & dUserValue,uint32_t uiValue,CParameterAccessContext & parameterAccessContext) const300 bool CParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const
301 {
302     (void)dUserValue;
303     (void)uiValue;
304     (void)parameterAccessContext;
305 
306     parameterAccessContext.setError("Unsupported conversion");
307 
308     return false;
309 }
310 
311 
312