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 "InstanceConfigurableElement.h"
31 #include "Mapper.h"
32 #include "SyncerSet.h"
33 #include "Syncer.h"
34 #include "TypeElement.h"
35 #include "ParameterAccessContext.h"
36 #include <assert.h>
37 
38 #define base CConfigurableElementWithMapping
39 
CInstanceConfigurableElement(const std::string & strName,const CTypeElement * pTypeElement)40 CInstanceConfigurableElement::CInstanceConfigurableElement(const std::string& strName, const CTypeElement* pTypeElement) : base(strName), _pTypeElement(pTypeElement), _pSyncer(NULL)
41 {
42 }
43 
getKind() const44 std::string CInstanceConfigurableElement::getKind() const
45 {
46     // Delegate
47     return _pTypeElement->getKind();
48 }
49 
50 // Type element
getTypeElement() const51 const CTypeElement* CInstanceConfigurableElement::getTypeElement() const
52 {
53     return _pTypeElement;
54 }
55 
56 // Mapping
getMappingData(const std::string & strKey,const std::string * & pStrValue) const57 bool CInstanceConfigurableElement::getMappingData(const std::string& strKey, const std::string*& pStrValue) const
58 {
59     // Delegate
60     return getTypeElement()->getMappingData(strKey, pStrValue);
61 }
62 
63 // Returns the formatted mapping
getFormattedMapping() const64 std::string CInstanceConfigurableElement::getFormattedMapping() const
65 {
66     // Delegate
67     return getTypeElement()->getFormattedMapping();
68 }
69 
map(IMapper & mapper,std::string & strError)70 bool CInstanceConfigurableElement::map(IMapper& mapper, std::string& strError)
71 {
72     bool bHasMappingData = getTypeElement()->hasMappingData();
73     bool bKeepDiving = true;
74 
75     // Begin
76     if (bHasMappingData && !mapper.mapBegin(this, bKeepDiving, strError)) {
77 
78         return false;
79     }
80 
81     // Go on through children?
82     if (bKeepDiving) {
83 
84         // Map children
85         size_t uiNbChildren = getNbChildren();
86         size_t uiChild;
87 
88         for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
89 
90             CInstanceConfigurableElement* pInstanceConfigurableChildElement =
91                     static_cast<CInstanceConfigurableElement*>(getChild(uiChild));
92 
93             if (!pInstanceConfigurableChildElement->map(mapper, strError)) {
94 
95                 return false;
96             }
97         }
98     }
99 
100     // End
101     if (bHasMappingData) {
102 
103         mapper.mapEnd();
104     }
105     return true;
106 }
107 
getListOfElementsWithMapping(std::list<const CConfigurableElement * > & configurableElementPath) const108 void CInstanceConfigurableElement::getListOfElementsWithMapping(
109         std::list<const CConfigurableElement*>& configurableElementPath) const
110 {
111     const CTypeElement* pTypeElement = getTypeElement();
112 
113     if (pTypeElement && pTypeElement->hasMappingData()) {
114 
115         configurableElementPath.push_back(this);
116     }
117 
118     base::getListOfElementsWithMapping(configurableElementPath);
119 }
120 
121 // Element properties
showProperties(std::string & strResult) const122 void CInstanceConfigurableElement::showProperties(std::string& strResult) const
123 {
124     base::showProperties(strResult);
125 
126     // Delegate to type element
127     _pTypeElement->showProperties(strResult);
128 }
129 
130 // Scalar or Array?
isScalar() const131 bool CInstanceConfigurableElement::isScalar() const
132 {
133     return _pTypeElement->isScalar();
134 }
135 
136 // Array Length
getArrayLength() const137 uint32_t CInstanceConfigurableElement::getArrayLength() const
138 {
139     return _pTypeElement->getArrayLength();
140 }
141 
142 // Sync to HW
setSyncer(ISyncer * pSyncer)143 void CInstanceConfigurableElement::setSyncer(ISyncer* pSyncer)
144 {
145     assert(!_pSyncer);
146 
147     _pSyncer = pSyncer;
148 }
149 
unsetSyncer()150 void CInstanceConfigurableElement::unsetSyncer()
151 {
152     _pSyncer = NULL;
153 }
154 
155 // Syncer
getSyncer() const156 ISyncer* CInstanceConfigurableElement::getSyncer() const
157 {
158     if (_pSyncer) {
159 
160         return _pSyncer;
161     }
162     // Check parent
163     return base::getSyncer();
164 }
165 
166 // Syncer set (descendant)
fillSyncerSetFromDescendant(CSyncerSet & syncerSet) const167 void CInstanceConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
168 {
169     if (_pSyncer) {
170 
171         syncerSet += _pSyncer;
172     } else {
173         // Continue digging
174         base::fillSyncerSetFromDescendant(syncerSet);
175     }
176 }
177 
sync(CParameterAccessContext & parameterAccessContext) const178 bool CInstanceConfigurableElement::sync(CParameterAccessContext& parameterAccessContext) const
179 {
180     if (!parameterAccessContext.getAutoSync()) {
181 
182         // AutoSync is disabled, do not perform the sync.
183         // This is not an error, but the expected behavior so return true anyway.
184         return true;
185     }
186     ISyncer* pSyncer = getSyncer();
187 
188     if (!pSyncer) {
189 
190         parameterAccessContext.setError("Unable to synchronize modification. No Syncer object associated to configurable element:");
191 
192         return false;
193     }
194     std::string strError;
195 
196     if (!pSyncer->sync(*parameterAccessContext.getParameterBlackboard(), false, strError)) {
197 
198         parameterAccessContext.setError(strError);
199 
200         return false;
201     }
202     return true;
203 }
204 
205 // Check parameter access path well formed for leaf elements
checkPathExhausted(CPathNavigator & pathNavigator,CErrorContext & errorContext)206 bool CInstanceConfigurableElement::checkPathExhausted(CPathNavigator& pathNavigator, CErrorContext& errorContext)
207 {
208     std::string* pStrChildName = pathNavigator.next();
209 
210     if (pStrChildName) {
211 
212         // Should be leaf element
213         errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
214 
215         return false;
216     }
217     return true;
218 }
219 
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const220 void CInstanceConfigurableElement::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const
221 {
222     base::toXml(xmlElement, serializingContext);
223     // Since Description belongs to the Type of Element, delegate it to the type element.
224     getTypeElement()->setXmlDescriptionAttribute(xmlElement);
225 }
226