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 "Parameter.h"
31 #include "ParameterType.h"
32 #include "ParameterAccessContext.h"
33 #include "ConfigurationAccessContext.h"
34 #include "ParameterBlackboard.h"
35 
36 #define base CBaseParameter
37 
38 using std::string;
39 
CParameter(const string & strName,const CTypeElement * pTypeElement)40 CParameter::CParameter(const string &strName, const CTypeElement *pTypeElement)
41     : base(strName, pTypeElement)
42 {
43 }
44 
getType() const45 CInstanceConfigurableElement::Type CParameter::getType() const
46 {
47     return EParameter;
48 }
49 
50 // XML configuration settings parsing/composing
serializeXmlSettings(CXmlElement & xmlConfigurationSettingsElementContent,CConfigurationAccessContext & configurationAccessContext) const51 bool CParameter::serializeXmlSettings(CXmlElement &xmlConfigurationSettingsElementContent,
52                                       CConfigurationAccessContext &configurationAccessContext) const
53 {
54     // Check for value space
55     handleValueSpaceAttribute(xmlConfigurationSettingsElementContent, configurationAccessContext);
56 
57     // Base
58     return base::serializeXmlSettings(xmlConfigurationSettingsElementContent,
59                                       configurationAccessContext);
60 }
61 
62 // Value space handling for configuration import
handleValueSpaceAttribute(CXmlElement & xmlConfigurableElementSettingsElement,CConfigurationAccessContext & configurationAccessContext) const63 void CParameter::handleValueSpaceAttribute(
64     CXmlElement &xmlConfigurableElementSettingsElement,
65     CConfigurationAccessContext &configurationAccessContext) const
66 {
67     // Delegate to type
68     static_cast<const CParameterType *>(getTypeElement())
69         ->handleValueSpaceAttribute(xmlConfigurableElementSettingsElement,
70                                     configurationAccessContext);
71 }
72 
getFootPrint() const73 size_t CParameter::getFootPrint() const
74 {
75     return getSize();
76 }
77 
getSize() const78 size_t CParameter::getSize() const
79 {
80     return static_cast<const CParameterType *>(getTypeElement())->getSize();
81 }
82 
83 // Used for simulation and virtual subsystems
setDefaultValues(CParameterAccessContext & parameterAccessContext) const84 void CParameter::setDefaultValues(CParameterAccessContext &parameterAccessContext) const
85 {
86     // Get default value from type
87     uint32_t uiDefaultValue =
88         static_cast<const CParameterType *>(getTypeElement())->getDefaultValue();
89 
90     // Write blackboard
91     CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard();
92 
93     // Beware this code works on little endian architectures only!
94     pBlackboard->writeInteger(&uiDefaultValue, getSize(),
95                               getOffset() - parameterAccessContext.getBaseOffset());
96 }
97 
98 /// Actual parameter access
99 // String access
doSetValue(const string & strValue,size_t offset,CParameterAccessContext & parameterAccessContext) const100 bool CParameter::doSetValue(const string &strValue, size_t offset,
101                             CParameterAccessContext &parameterAccessContext) const
102 {
103     return doSet(strValue, offset, parameterAccessContext);
104 }
105 
doGetValue(string & strValue,size_t offset,CParameterAccessContext & parameterAccessContext) const106 void CParameter::doGetValue(string &strValue, size_t offset,
107                             CParameterAccessContext &parameterAccessContext) const
108 {
109     doGet(strValue, offset, parameterAccessContext);
110 }
111 
112 // Boolean access
access(bool & bValue,bool bSet,CParameterAccessContext & parameterAccessContext) const113 bool CParameter::access(bool &bValue, bool bSet,
114                         CParameterAccessContext &parameterAccessContext) const
115 {
116     return doAccess(bValue, bSet, parameterAccessContext);
117 }
118 
119 // Integer Access
access(uint32_t & uiValue,bool bSet,CParameterAccessContext & parameterAccessContext) const120 bool CParameter::access(uint32_t &uiValue, bool bSet,
121                         CParameterAccessContext &parameterAccessContext) const
122 {
123     return doAccess(uiValue, bSet, parameterAccessContext);
124 }
125 
126 // Signed Integer Access
access(int32_t & iValue,bool bSet,CParameterAccessContext & parameterAccessContext) const127 bool CParameter::access(int32_t &iValue, bool bSet,
128                         CParameterAccessContext &parameterAccessContext) const
129 {
130     return doAccess(iValue, bSet, parameterAccessContext);
131 }
132 
133 // Double Access
access(double & dValue,bool bSet,CParameterAccessContext & parameterAccessContext) const134 bool CParameter::access(double &dValue, bool bSet,
135                         CParameterAccessContext &parameterAccessContext) const
136 {
137     return doAccess(dValue, bSet, parameterAccessContext);
138 }
139 
140 // Generic Access
141 template <typename type>
doAccess(type & value,bool bSet,CParameterAccessContext & parameterAccessContext) const142 bool CParameter::doAccess(type &value, bool bSet,
143                           CParameterAccessContext &parameterAccessContext) const
144 {
145     if (bSet) {
146         // set value
147         if (!doSet(value, getOffset() - parameterAccessContext.getBaseOffset(),
148                    parameterAccessContext)) {
149 
150             appendParameterPathToError(parameterAccessContext);
151             return false;
152         }
153         // Synchronize
154         if (!sync(parameterAccessContext)) {
155 
156             appendParameterPathToError(parameterAccessContext);
157             return false;
158         }
159     } else {
160         // get value
161         if (!doGet(value, getOffset() - parameterAccessContext.getBaseOffset(),
162                    parameterAccessContext)) {
163 
164             appendParameterPathToError(parameterAccessContext);
165             return false;
166         }
167     }
168     return true;
169 }
170 
171 template <typename type>
doSet(type value,size_t offset,CParameterAccessContext & parameterAccessContext) const172 bool CParameter::doSet(type value, size_t offset,
173                        CParameterAccessContext &parameterAccessContext) const
174 {
175     uint32_t uiData;
176 
177     if (!static_cast<const CParameterType *>(getTypeElement())
178              ->toBlackboard(value, uiData, parameterAccessContext)) {
179 
180         return false;
181     }
182     // Write blackboard
183     CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard();
184 
185     // Beware this code works on little endian architectures only!
186     pBlackboard->writeInteger(&uiData, getSize(), offset);
187 
188     return true;
189 }
190 
191 template <typename type>
doGet(type & value,size_t offset,CParameterAccessContext & parameterAccessContext) const192 bool CParameter::doGet(type &value, size_t offset,
193                        CParameterAccessContext &parameterAccessContext) const
194 {
195     uint32_t uiData = 0;
196 
197     // Read blackboard
198     const CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard();
199 
200     // Beware this code works on little endian architectures only!
201     pBlackboard->readInteger(&uiData, getSize(), offset);
202 
203     return static_cast<const CParameterType *>(getTypeElement())
204         ->fromBlackboard(value, uiData, parameterAccessContext);
205 }
206