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
CParameterType(const string & strName)43 CParameterType::CParameterType(const string &strName) : base(strName)
44 {
45 }
46
47 // Object creation
populate(CElement *) const48 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
setSize(size_t size)54 void CParameterType::setSize(size_t size)
55 {
56 _size = size;
57 }
58
getSize() const59 size_t CParameterType::getSize() const
60 {
61 return _size;
62 }
63
64 // Unit
getUnit() const65 string CParameterType::getUnit() const
66 {
67 return _strUnit;
68 }
69
setUnit(const std::string & strUnit)70 void CParameterType::setUnit(const std::string &strUnit)
71 {
72 _strUnit = strUnit;
73 }
74
75 // From IXmlSink
fromXml(const CXmlElement & xmlElement,CXmlSerializingContext & serializingContext)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
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const84 void CParameterType::toXml(CXmlElement &xmlElement,
85 CXmlSerializingContext &serializingContext) const
86 {
87 base::toXml(xmlElement, serializingContext);
88 setXmlUnitAttribute(xmlElement);
89 }
90
setXmlUnitAttribute(CXmlElement & xmlElement) const91 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
handleValueSpaceAttribute(CXmlElement &,CConfigurationAccessContext &) const101 void CParameterType::handleValueSpaceAttribute(
102 CXmlElement & /*xmlConfigurableElementSettingsElement*/,
103 CConfigurationAccessContext & /*ctx*/) const
104 {
105 // Do nothing by default
106 }
107
108 // Element properties
showProperties(string & strResult) const109 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)
getDefaultValue() const123 uint32_t CParameterType::getDefaultValue() const
124 {
125 return 0;
126 }
127
128 // Parameter instantiation
doInstantiate() const129 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
signExtend(int32_t & iData) const140 void CParameterType::signExtend(int32_t &iData) const
141 {
142 doSignExtend(iData);
143 }
144
signExtend(int64_t & iData) const145 void CParameterType::signExtend(int64_t &iData) const
146 {
147 doSignExtend(iData);
148 }
149
150 // Generic sign extension
151 template <typename type>
doSignExtend(type & data) const152 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 undefined**.
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)
isEncodable(uint32_t uiData,bool bIsSigned) const164 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)
isEncodable(uint64_t uiData,bool bIsSigned) const170 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>
doIsEncodable(type data,bool bIsSigned) const177 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
makeEncodable(uint32_t uiData) const202 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
toBlackboard(bool,uint32_t &,CParameterAccessContext & parameterAccessContext) const214 bool CParameterType::toBlackboard(bool /*bUserValue*/, uint32_t & /*uiValue*/,
215 CParameterAccessContext ¶meterAccessContext) const
216 {
217 parameterAccessContext.setError("Unsupported conversion");
218 return false;
219 }
220
fromBlackboard(bool &,uint32_t,CParameterAccessContext & parameterAccessContext) const221 bool CParameterType::fromBlackboard(bool & /*bUserValue*/, uint32_t /*uiValue*/,
222 CParameterAccessContext ¶meterAccessContext) const
223 {
224 parameterAccessContext.setError("Unsupported conversion");
225 return false;
226 }
227
228 // Integer
toBlackboard(uint32_t,uint32_t &,CParameterAccessContext & parameterAccessContext) const229 bool CParameterType::toBlackboard(uint32_t /*uiUserValue*/, uint32_t & /*uiValue*/,
230 CParameterAccessContext ¶meterAccessContext) const
231 {
232 parameterAccessContext.setError("Unsupported conversion");
233 return false;
234 }
235
fromBlackboard(uint32_t &,uint32_t,CParameterAccessContext & parameterAccessContext) const236 bool CParameterType::fromBlackboard(uint32_t & /*uiUserValue*/, uint32_t /*uiValue*/,
237 CParameterAccessContext ¶meterAccessContext) const
238 {
239 parameterAccessContext.setError("Unsupported conversion");
240 return false;
241 }
242
243 // Signed Integer
toBlackboard(int32_t,uint32_t &,CParameterAccessContext & parameterAccessContext) const244 bool CParameterType::toBlackboard(int32_t /*iUserValue*/, uint32_t & /*uiValue*/,
245 CParameterAccessContext ¶meterAccessContext) const
246 {
247 parameterAccessContext.setError("Unsupported conversion");
248
249 return false;
250 }
251
fromBlackboard(int32_t &,uint32_t,CParameterAccessContext & parameterAccessContext) const252 bool CParameterType::fromBlackboard(int32_t & /*iUserValue*/, uint32_t /*uiValue*/,
253 CParameterAccessContext ¶meterAccessContext) const
254 {
255 parameterAccessContext.setError("Unsupported conversion");
256
257 return false;
258 }
259
260 // Double
toBlackboard(double,uint32_t &,CParameterAccessContext & parameterAccessContext) const261 bool CParameterType::toBlackboard(double /*dUserValue*/, uint32_t & /*uiValue*/,
262 CParameterAccessContext ¶meterAccessContext) const
263 {
264 parameterAccessContext.setError("Unsupported conversion");
265
266 return false;
267 }
268
fromBlackboard(double &,uint32_t,CParameterAccessContext & parameterAccessContext) const269 bool CParameterType::fromBlackboard(double & /*dUserValue*/, uint32_t /*uiValue*/,
270 CParameterAccessContext ¶meterAccessContext) const
271 {
272 parameterAccessContext.setError("Unsupported conversion");
273
274 return false;
275 }
276