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) : base(strName, pTypeElement)
41 {
42 }
43 
getType() const44 CInstanceConfigurableElement::Type CParameter::getType() const
45 {
46     return EParameter;
47 }
48 
49 // XML configuration settings parsing/composing
serializeXmlSettings(CXmlElement & xmlConfigurationSettingsElementContent,CConfigurationAccessContext & configurationAccessContext) const50 bool CParameter::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const
51 {
52     // Check for value space
53     handleValueSpaceAttribute(xmlConfigurationSettingsElementContent, configurationAccessContext);
54 
55     // Base
56     return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, configurationAccessContext);
57 }
58 
59 // Value space handling for configuration import
handleValueSpaceAttribute(CXmlElement & xmlConfigurableElementSettingsElement,CConfigurationAccessContext & configurationAccessContext) const60 void CParameter::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const
61 {
62     // Delegate to type
63     static_cast<const CParameterType*>(getTypeElement())->handleValueSpaceAttribute(xmlConfigurableElementSettingsElement, configurationAccessContext);
64 }
65 
getFootPrint() const66 uint32_t CParameter::getFootPrint() const
67 {
68     return getSize();
69 }
70 
getSize() const71 uint32_t CParameter::getSize() const
72 {
73     return static_cast<const CParameterType*>(getTypeElement())->getSize();
74 }
75 
76 // Used for simulation and virtual subsystems
setDefaultValues(CParameterAccessContext & parameterAccessContext) const77 void CParameter::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
78 {
79     // Get default value from type
80     uint32_t uiDefaultValue = static_cast<const CParameterType*>(getTypeElement())->getDefaultValue();
81 
82     // Write blackboard
83     CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard();
84 
85     // Beware this code works on little endian architectures only!
86     pBlackboard->writeInteger(&uiDefaultValue, getSize(), getOffset() - parameterAccessContext.getBaseOffset(), parameterAccessContext.isBigEndianSubsystem());
87 }
88 
89 /// Actual parameter access
90 // String access
doSetValue(const string & strValue,uint32_t uiOffset,CParameterAccessContext & parameterAccessContext) const91 bool CParameter::doSetValue(const string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const
92 {
93     return doSet(strValue, uiOffset, parameterAccessContext);
94 }
95 
doGetValue(string & strValue,uint32_t uiOffset,CParameterAccessContext & parameterAccessContext) const96 void CParameter::doGetValue(string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const
97 {
98     doGet(strValue, uiOffset, parameterAccessContext);
99 }
100 
101 // Boolean access
accessAsBoolean(bool & bValue,bool bSet,CParameterAccessContext & parameterAccessContext) const102 bool CParameter::accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
103 {
104     return doAccess(bValue, bSet, parameterAccessContext);
105 }
106 
107 // Integer Access
accessAsInteger(uint32_t & uiValue,bool bSet,CParameterAccessContext & parameterAccessContext) const108 bool CParameter::accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
109 {
110     return doAccess(uiValue, bSet, parameterAccessContext);
111 }
112 
113 // Signed Integer Access
accessAsSignedInteger(int32_t & iValue,bool bSet,CParameterAccessContext & parameterAccessContext) const114 bool CParameter::accessAsSignedInteger(int32_t& iValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
115 {
116     return doAccess(iValue, bSet, parameterAccessContext);
117 }
118 
119 // Double Access
accessAsDouble(double & dValue,bool bSet,CParameterAccessContext & parameterAccessContext) const120 bool CParameter::accessAsDouble(double& dValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
121 {
122     return doAccess(dValue, bSet, parameterAccessContext);
123 }
124 
125 // Generic Access
126 template <typename type>
doAccess(type & value,bool bSet,CParameterAccessContext & parameterAccessContext) const127 bool CParameter::doAccess(type& value, bool bSet,
128                           CParameterAccessContext& parameterAccessContext) const
129 {
130     if (bSet) {
131         // set value
132         if (!doSet(value, getOffset() - parameterAccessContext.getBaseOffset(),
133                    parameterAccessContext)) {
134 
135             appendParameterPathToError(parameterAccessContext);
136             return false;
137 
138         }
139         // Synchronize
140         if (!sync(parameterAccessContext)){
141 
142             appendParameterPathToError(parameterAccessContext);
143             return false;
144         }
145     } else {
146         // get value
147         if (!doGet(value, getOffset() - parameterAccessContext.getBaseOffset(),
148                    parameterAccessContext)) {
149 
150             appendParameterPathToError(parameterAccessContext);
151             return false;
152         }
153     }
154     return true;
155 }
156 
157 template <typename type>
doSet(type value,uint32_t uiOffset,CParameterAccessContext & parameterAccessContext) const158 bool CParameter::doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const
159 {
160     uint32_t uiData;
161 
162     if (!static_cast<const CParameterType*>(getTypeElement())->toBlackboard(value, uiData, parameterAccessContext)) {
163 
164         return false;
165     }
166     // Write blackboard
167     CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard();
168 
169     // Beware this code works on little endian architectures only!
170     pBlackboard->writeInteger(&uiData, getSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem());
171 
172     return true;
173 }
174 
175 template <typename type>
doGet(type & value,uint32_t uiOffset,CParameterAccessContext & parameterAccessContext) const176 bool CParameter::doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const
177 {
178     uint32_t uiData = 0;
179 
180     // Read blackboard
181     const CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard();
182 
183     // Beware this code works on little endian architectures only!
184     pBlackboard->readInteger(&uiData, getSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem());
185 
186     return static_cast<const CParameterType*>(getTypeElement())->fromBlackboard(value, uiData, parameterAccessContext);
187 }
188