• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "ElementHandle.h"
31 #include "ParameterAccessContext.h"
32 #include "BaseParameter.h"
33 #include "XmlParameterSerializingContext.h"
34 #include "Subsystem.h"
35 #include <assert.h>
36 #include "ParameterMgr.h"
37 
38 #include <mutex>
39 
40 using std::string;
41 using std::mutex;
42 using std::lock_guard;
43 
44 /** @return 0 by default, ie for non overloaded types. */
45 template <class T>
getUserInputSize(const T &)46 static size_t getUserInputSize(const T & /*scalar*/)
47 {
48     return 0;
49 }
50 
51 /** @return the vector's size. */
52 template <class T>
getUserInputSize(const std::vector<T> & vector)53 static size_t getUserInputSize(const std::vector<T> &vector)
54 {
55     return vector.size();
56 }
57 
ElementHandle(CConfigurableElement & element,CParameterMgr & parameterMgr)58 ElementHandle::ElementHandle(CConfigurableElement &element, CParameterMgr &parameterMgr)
59     : mElement(element), mParameterMgr(parameterMgr)
60 {
61 }
62 
getName() const63 string ElementHandle::getName() const
64 {
65     return mElement.getName();
66 }
67 
getSize() const68 size_t ElementHandle::getSize() const
69 {
70     return mElement.getFootPrint();
71 }
72 
isParameter() const73 bool ElementHandle::isParameter() const
74 {
75     return mElement.isParameter();
76 }
77 
getDescription() const78 string ElementHandle::getDescription() const
79 {
80     return mElement.getDescription();
81 }
82 
83 // Parameter features
isRogue() const84 bool ElementHandle::isRogue() const
85 {
86     return mElement.isRogue();
87 }
88 
isArray() const89 bool ElementHandle::isArray() const
90 {
91     return getArrayLength() != 0;
92 }
93 
getArrayLength() const94 size_t ElementHandle::getArrayLength() const
95 {
96     // Only instances can be arrays, SystemClass can not, nor subsystems
97     auto *instance = dynamic_cast<CInstanceConfigurableElement *>(&mElement);
98     if (instance == nullptr) {
99         return 0;
100     }
101     return instance->getArrayLength();
102 }
103 
getPath() const104 string ElementHandle::getPath() const
105 {
106     return mElement.getPath();
107 }
108 
getKind() const109 string ElementHandle::getKind() const
110 {
111     return mElement.getKind();
112 }
113 
getChildren()114 std::vector<ElementHandle> ElementHandle::getChildren()
115 {
116     size_t nbChildren = mElement.getNbChildren();
117 
118     std::vector<ElementHandle> children;
119     children.reserve(nbChildren);
120 
121     for (size_t childIndex = 0; childIndex < nbChildren; ++childIndex) {
122         auto *child = static_cast<CConfigurableElement *>(mElement.getChild(childIndex));
123         // Can not use emplace back as the constructor is private
124         children.push_back({*child, mParameterMgr});
125     }
126     return children;
127 }
128 
getMappingData(const string & strKey,string & strValue) const129 bool ElementHandle::getMappingData(const string &strKey, string &strValue) const
130 {
131     const std::string *pStrValue;
132 
133     // Seach for the key in self and ancestors
134     auto elements = mElement.getConfigurableElementContext();
135 
136     for (auto *element : elements)
137         if (element->getMappingData(strKey, pStrValue)) {
138             strValue = *pStrValue;
139             return true;
140         }
141 
142     return false;
143 }
144 
getStructureAsXML(std::string & xmlSettings,std::string & error) const145 bool ElementHandle::getStructureAsXML(std::string &xmlSettings, std::string &error) const
146 {
147     // Use default access context for structure export
148     CParameterAccessContext accessContext(error);
149     return mParameterMgr.exportElementToXMLString(
150         &mElement, mElement.getXmlElementName(),
151         CXmlParameterSerializingContext{accessContext, error}, xmlSettings);
152 }
153 
154 template <class T>
155 struct isVector : std::false_type
156 {
157 };
158 template <class T>
159 struct isVector<std::vector<T>> : std::true_type
160 {
161 };
162 
getAsXML(std::string & xmlValue,std::string & error) const163 bool ElementHandle::getAsXML(std::string &xmlValue, std::string &error) const
164 {
165     std::string result;
166     if (not mParameterMgr.getSettingsAsXML(&mElement, result)) {
167         error = result;
168         return false;
169     }
170 
171     xmlValue = result;
172     return true;
173 }
174 
setAsXML(const std::string & xmlValue,std::string & error)175 bool ElementHandle::setAsXML(const std::string &xmlValue, std::string &error)
176 {
177     return mParameterMgr.setSettingsAsXML(&mElement, xmlValue, error);
178 }
179 
getAsBytes(std::vector<uint8_t> & bytesValue,std::string &) const180 bool ElementHandle::getAsBytes(std::vector<uint8_t> &bytesValue, std::string & /*error*/) const
181 {
182     mParameterMgr.getSettingsAsBytes(mElement, bytesValue);
183 
184     // Currently this operation can not fail.
185     // Nevertheless this is more a design than intrinsic property.
186     // Use the same error reporting pattern to avoid breaking the api in future
187     // release if an error need to be reported (and be consistent with all other getAs*).
188     return true;
189 }
190 
setAsBytes(const std::vector<uint8_t> & bytesValue,std::string & error)191 bool ElementHandle::setAsBytes(const std::vector<uint8_t> &bytesValue, std::string &error)
192 {
193     return mParameterMgr.setSettingsAsBytes(mElement, bytesValue, error);
194 }
195 
196 template <class T>
setAs(const T value,string & error) const197 bool ElementHandle::setAs(const T value, string &error) const
198 {
199     if (not checkSetValidity(getUserInputSize(value), error)) {
200         return false;
201     }
202     // Safe downcast thanks to isParameter check in checkSetValidity
203     auto &parameter = static_cast<CBaseParameter &>(mElement);
204 
205     // When in tuning mode, silently skip "set" requests
206     if (mParameterMgr.tuningModeOn()) {
207 
208         return true;
209     }
210 
211     CParameterAccessContext parameterAccessContext(error, mParameterMgr.getParameterBlackboard());
212 
213     // BaseParamere::access takes a non-const argument - therefore we need to
214     // copy the value
215     T copy = value;
216 
217     // Ensure we're safe against blackboard foreign access
218     lock_guard<mutex> autoLock(mParameterMgr.getBlackboardMutex());
219 
220     return parameter.access(copy, true, parameterAccessContext);
221 }
222 
223 template <class T>
getAs(T & value,string & error) const224 bool ElementHandle::getAs(T &value, string &error) const
225 {
226     if (not checkGetValidity(isVector<T>::value, error)) {
227         return false;
228     }
229     // Safe downcast thanks to isParameter check in checkGetValidity
230     auto &parameter = static_cast<const CBaseParameter &>(mElement);
231 
232     // Ensure we're safe against blackboard foreign access
233     lock_guard<mutex> autoLock(mParameterMgr.getBlackboardMutex());
234 
235     CParameterAccessContext parameterAccessContext(error, mParameterMgr.getParameterBlackboard());
236 
237     return parameter.access(value, false, parameterAccessContext);
238 }
239 
240 // Boolean access
setAsBoolean(bool value,string & error)241 bool ElementHandle::setAsBoolean(bool value, string &error)
242 {
243     return setAs(value, error);
244 }
245 
getAsBoolean(bool & value,string & error) const246 bool ElementHandle::getAsBoolean(bool &value, string &error) const
247 {
248     return getAs(value, error);
249 }
250 
setAsBooleanArray(const std::vector<bool> & value,string & error)251 bool ElementHandle::setAsBooleanArray(const std::vector<bool> &value, string &error)
252 {
253     return setAs(value, error);
254 }
255 
getAsBooleanArray(std::vector<bool> & value,string & error) const256 bool ElementHandle::getAsBooleanArray(std::vector<bool> &value, string &error) const
257 {
258     return getAs(value, error);
259 }
260 
261 // Integer Access
setAsInteger(uint32_t value,string & error)262 bool ElementHandle::setAsInteger(uint32_t value, string &error)
263 {
264     return setAs(value, error);
265 }
266 
getAsInteger(uint32_t & value,string & error) const267 bool ElementHandle::getAsInteger(uint32_t &value, string &error) const
268 {
269     return getAs(value, error);
270 }
271 
setAsIntegerArray(const std::vector<uint32_t> & value,string & error)272 bool ElementHandle::setAsIntegerArray(const std::vector<uint32_t> &value, string &error)
273 {
274     return setAs(value, error);
275 }
276 
getAsIntegerArray(std::vector<uint32_t> & value,string & error) const277 bool ElementHandle::getAsIntegerArray(std::vector<uint32_t> &value, string &error) const
278 {
279     return getAs(value, error);
280 }
281 
282 // Signed Integer Access
setAsSignedInteger(int32_t value,string & error)283 bool ElementHandle::setAsSignedInteger(int32_t value, string &error)
284 {
285     return setAs(value, error);
286 }
287 
getAsSignedInteger(int32_t & value,string & error) const288 bool ElementHandle::getAsSignedInteger(int32_t &value, string &error) const
289 {
290     return getAs(value, error);
291 }
292 
setAsSignedIntegerArray(const std::vector<int32_t> & value,string & error)293 bool ElementHandle::setAsSignedIntegerArray(const std::vector<int32_t> &value, string &error)
294 {
295     return setAs(value, error);
296 }
297 
getAsSignedIntegerArray(std::vector<int32_t> & value,string & error) const298 bool ElementHandle::getAsSignedIntegerArray(std::vector<int32_t> &value, string &error) const
299 {
300     return getAs(value, error);
301 }
302 
303 // Double Access
setAsDouble(double value,string & error)304 bool ElementHandle::setAsDouble(double value, string &error)
305 {
306     return setAs(value, error);
307 }
308 
getAsDouble(double & value,string & error) const309 bool ElementHandle::getAsDouble(double &value, string &error) const
310 {
311     return getAs(value, error);
312 }
313 
setAsDoubleArray(const std::vector<double> & value,string & error)314 bool ElementHandle::setAsDoubleArray(const std::vector<double> &value, string &error)
315 {
316     return setAs(value, error);
317 }
318 
getAsDoubleArray(std::vector<double> & value,string & error) const319 bool ElementHandle::getAsDoubleArray(std::vector<double> &value, string &error) const
320 {
321     return getAs(value, error);
322 }
323 
324 // String Access
setAsString(const string & value,string & error)325 bool ElementHandle::setAsString(const string &value, string &error)
326 {
327     return setAs(value, error);
328 }
329 
getAsString(string & value,string & error) const330 bool ElementHandle::getAsString(string &value, string &error) const
331 {
332     return getAs(value, error);
333 }
334 
setAsStringArray(const std::vector<string> & value,string & error)335 bool ElementHandle::setAsStringArray(const std::vector<string> &value, string &error)
336 {
337     return setAs(value, error);
338 }
339 
getAsStringArray(std::vector<string> & value,string & error) const340 bool ElementHandle::getAsStringArray(std::vector<string> &value, string &error) const
341 {
342     return getAs(value, error);
343 }
344 
checkGetValidity(bool asArray,string & error) const345 bool ElementHandle::checkGetValidity(bool asArray, string &error) const
346 {
347     if (not isParameter()) {
348         error = "Can not set element " + getPath() + " as it is not a parameter.";
349         return false;
350     }
351 
352     if (asArray != isArray()) {
353 
354         auto toStr = [](bool array) { return array ? "an array" : "a scalar"; };
355         error = "Can not get \"" + getPath() + "\" as " + toStr(asArray) + " because it is " +
356                 toStr(isArray());
357         return false;
358     }
359 
360     return true;
361 }
362 
363 // Access validity
checkSetValidity(size_t arrayLength,string & error) const364 bool ElementHandle::checkSetValidity(size_t arrayLength, string &error) const
365 {
366     // Settings a parameter necessitates the right to get it
367     if (not checkGetValidity(arrayLength != 0, error)) {
368         return false;
369     }
370 
371     if (!isRogue()) {
372 
373         error = "Can not set parameter \"" + getPath() + "\" as it is not rogue.";
374         return false;
375     }
376 
377     if (arrayLength && (arrayLength != getArrayLength())) {
378 
379         using std::to_string;
380         error = "Array length mismatch for \"" + getPath() + "\", expected: " +
381                 to_string(getArrayLength()) + ", got: " + to_string(arrayLength);
382         return false;
383     }
384 
385     return true;
386 }
387