blob: 2fcde7a8d5c9be4a0d2d77ae26fe8070cda2cc6d [file] [log] [blame]
Patrick Benavoli68a91282011-08-31 11:23:23 +02001/* <auto_header>
2 * <FILENAME>
3 *
4 * INTEL CONFIDENTIAL
5 * Copyright © 2011 Intel
6 * Corporation All Rights Reserved.
7 *
8 * The source code contained or described herein and all documents related to
9 * the source code ("Material") are owned by Intel Corporation or its suppliers
10 * or licensors. Title to the Material remains with Intel Corporation or its
11 * suppliers and licensors. The Material contains trade secrets and proprietary
12 * and confidential information of Intel or its suppliers and licensors. The
13 * Material is protected by worldwide copyright and trade secret laws and
14 * treaty provisions. No part of the Material may be used, copied, reproduced,
15 * modified, published, uploaded, posted, transmitted, distributed, or
16 * disclosed in any way without Intel’s prior express written permission.
17 *
18 * No license under any patent, copyright, trade secret or other intellectual
19 * property right is granted to or conferred upon you by disclosure or delivery
20 * of the Materials, either expressly, by implication, inducement, estoppel or
21 * otherwise. Any license under such intellectual property rights must be
22 * express and approved by Intel in writing.
23 *
24 * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com)
25 * CREATED: 2011-06-01
26 * UPDATED: 2011-07-27
27 *
28 *
29 * </auto_header>
30 */
31#include "ConfigurableElement.h"
32#include "MappingData.h"
33#include "SyncerSet.h"
34#include "ConfigurableDomain.h"
35#include "ConfigurationAccessContext.h"
36#include "ConfigurableElementAggregator.h"
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020037#include <sstream>
Patrick Benavoli68a91282011-08-31 11:23:23 +020038#include <assert.h>
39
40#define base CElement
41
42CConfigurableElement::CConfigurableElement(const string& strName) : base(strName), _uiOffset(0)
43{
44}
45
46CConfigurableElement::~CConfigurableElement()
47{
48}
49
50// XML configuration settings parsing
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020051bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +020052{
53 uint32_t uiIndex;
54 uint32_t uiNbChildren = getNbChildren();
55
56 if (!configurationAccessContext.serializeOut()) {
57 // Just do basic checks and propagate to children
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020058 CXmlElement::CChildIterator it(xmlConfigurationSettingsElementContent);
Patrick Benavoli68a91282011-08-31 11:23:23 +020059
60 CXmlElement xmlChildConfigurableElementSettingsElement;
61
62 // Propagate to children
63 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
64
65 // Get child
66 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
67
68 if (!it.next(xmlChildConfigurableElementSettingsElement)) {
69
70 // Structure error
71 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
72
73 return false;
74 }
75
76 // Check element type matches in type
77 if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
78
79 // Type error
80 configurationAccessContext.setError("Configuration settings parsing: Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
81
82 return false;
83 }
84
85 // Check element type matches in name
86 if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != pChildConfigurableElement->getName()) {
87
88 // Name error
89 configurationAccessContext.setError("Configuration settings parsing: Under configurable elememnt " + getName() + ", expected element name " + pChildConfigurableElement->getName() + " but found " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead");
90
91 return false;
92 }
93
94 // Parse child configurable element's settings
95 if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
96
97 return false;
98 }
99 }
100 // There should remain no configurable element to parse
101 if (it.next(xmlChildConfigurableElementSettingsElement)) {
102
103 // Structure error
104 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
105
106 return false;
107 }
108 } else {
109 // Propagate to children
110 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
111
112 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
113
114 // Create corresponding child element
115 CXmlElement xmlChildConfigurableElementSettingsElement;
116
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200117 xmlConfigurationSettingsElementContent.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200118
119 // Handle element name attribute
120 xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
121
122 // Propagate
123 pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
124 }
125 }
126 // Done
127 return true;
128}
129
Patrick Benavoli68a91282011-08-31 11:23:23 +0200130// Parameter access
131bool CConfigurableElement::setValue(CPathNavigator& pathNavigator, const string& strValue, CErrorContext& errorContext) const
132{
133 string* pStrChildName = pathNavigator.next();
134
135 if (!pStrChildName) {
136
137 errorContext.setError("Non settable element");
138
139 return false;
140 }
141
142 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
143
144 if (!pChild) {
145
146 errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
147
148 return false;
149 }
150
151 return pChild->setValue(pathNavigator, strValue, errorContext);
152}
153
154bool CConfigurableElement::getValue(CPathNavigator& pathNavigator, string& strValue, CErrorContext& errorContext) const
155{
156 string* pStrChildName = pathNavigator.next();
157
158 if (!pStrChildName) {
159
160 errorContext.setError("Non gettable element");
161
162 return false;
163 }
164
165 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
166
167 if (!pChild) {
168
169 errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
170
171 return false;
172 }
173
174 return pChild->getValue(pathNavigator, strValue, errorContext);
175}
176
177// Used for simulation only
178void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
179{
180 // Propagate to children
181 uint32_t uiIndex;
182 uint32_t uiNbChildren = getNbChildren();
183
184 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
185
186 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
187
188 pConfigurableElement->setDefaultValues(parameterAccessContext);
189 }
190}
191
192// Offset
193void CConfigurableElement::setOffset(uint32_t uiOffset)
194{
195 // Assign offset locally
196 _uiOffset = uiOffset;
197
198 // Propagate to children
199 uint32_t uiIndex;
200 uint32_t uiNbChildren = getNbChildren();
201
202 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
203
204 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
205
206 pConfigurableElement->setOffset(uiOffset);
207
208 uiOffset += pConfigurableElement->getFootPrint();
209 }
210}
211
212uint32_t CConfigurableElement::getOffset() const
213{
214 return _uiOffset;
215}
216
217// Memory
218uint32_t CConfigurableElement::getFootPrint() const
219{
220 uint32_t uiSize = 0;
221 uint32_t uiIndex;
222 uint32_t uiNbChildren = getNbChildren();
223
224 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
225
226 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
227
228 uiSize += pConfigurableElement->getFootPrint();
229 }
230
231 return uiSize;
232}
233
234// Browse parent path to find syncer
235ISyncer* CConfigurableElement::getSyncer() const
236{
237 // Check parent
238 const CElement* pParent = getParent();
239
240 if (isOfConfigurableElementType(pParent)) {
241
242 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
243 }
244 return false;
245}
246
247// Syncer set (me, ascendant or descendant ones)
248void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
249{
250 // Try me or ascendants
251 ISyncer* pMineOrAscendantSyncer = getSyncer();
252
253 if (pMineOrAscendantSyncer) {
254
255 // Provide found syncer object
256 syncerSet += pMineOrAscendantSyncer;
257
258 // Done
259 return;
260 }
261 // Fetch descendant ones
262 fillSyncerSetFromDescendant(syncerSet);
263}
264
265// Syncer set (descendant)
266void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
267{
268 // Dig
269 uint32_t uiIndex;
270 uint32_t uiNbChildren = getNbChildren();
271
272 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
273
274 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
275
276 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
277 }
278}
279
280// Configurable domain association
281void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
282{
283 _configurableDomainList.push_back(pConfigurableDomain);
284}
285
286void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
287{
288 _configurableDomainList.remove(pConfigurableDomain);
289}
290
291// Belonging domain
292bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
293{
294 if (containsConfigurableDomain(pConfigurableDomain)) {
295
296 return true;
297 }
298 return belongsToDomainAscending(pConfigurableDomain);
299}
300
301// Belonging domains
302void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
303{
304 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
305
306 // Check parent
307 const CElement* pParent = getParent();
308
309 if (isOfConfigurableElementType(pParent)) {
310
311 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
312 }
313}
314
315void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
316{
317 // Get belonging domain list
318 list<const CConfigurableDomain*> configurableDomainList;
319
320 getBelongingDomains(configurableDomainList);
321
322 // Fill list
323 listDomains(configurableDomainList, strResult, bVertical);
324}
325
326// Elements with no domains
327void CConfigurableElement::listRogueElements(string& strResult) const
328{
329 strResult = "\n";
330
331 // Get rogue element aggregate list (no associated domain)
332 list<const CConfigurableElement*> rogueElementList;
333
334 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
335
336 configurableElementAggregator.aggegate(this);
337
338 // Build list as string
339 list<const CConfigurableElement*>::const_iterator it;
340
341 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
342
343 const CConfigurableElement* pConfigurableElement = *it;
344
345 strResult += pConfigurableElement->getPath() + "\n";
346 }
347}
348
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200349// Footprint as string
350string CConfigurableElement::getFootprintAsString() const
351{
352 // Get size as string
353 ostringstream str;
354
355 str << getFootPrint() << " bytes";
356
357 return str.str();
358}
359
Patrick Benavoli68a91282011-08-31 11:23:23 +0200360// Matching check for no domain association
361bool CConfigurableElement::hasNoDomainAssociated() const
362{
363 return _configurableDomainList.empty();
364}
365
366// Matching check for no valid associated domains
367bool CConfigurableElement::hasNoValidDomainAssociated() const
368{
369 if (_configurableDomainList.empty()) {
370
371 // No domains associated
372 return true;
373 }
374
375 ConfigurableDomainListConstIterator it;
376
377 // Browse all configurable domains for validity checking
378 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
379
380 const CConfigurableDomain* pConfigurableDomain = *it;
381
382 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
383
384 return false;
385 }
386 }
387
388 return true;
389}
390
391// Owning domains
392void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
393{
394 // Fill list
395 listDomains(_configurableDomainList, strResult, bVertical);
396}
397
398uint32_t CConfigurableElement::getBelongingDomainCount() const
399{
400 // Get belonging domain list
401 list<const CConfigurableDomain*> configurableDomainList;
402
403 getBelongingDomains(configurableDomainList);
404
405 return configurableDomainList.size();
406}
407
408void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
409{
410 if (bVertical && configurableDomainList.empty()) {
411
412 strResult = "\n";
413 }
414
415 // Fill list
416 ConfigurableDomainListConstIterator it;
417 bool bFirst = true;
418
419 // Browse all configurable domains for comparison
420 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
421
422 const CConfigurableDomain* pConfigurableDomain = *it;
423
424 if (!bVertical && !bFirst) {
425
426 strResult += ", ";
427 }
428
429 strResult += pConfigurableDomain->getName();
430
431 if (bVertical) {
432
433 strResult += "\n";
434 } else {
435
436 bFirst = false;
437 }
438 }
439}
440
441bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
442{
443 ConfigurableDomainListConstIterator it;
444
445 // Browse all configurable domains for comparison
446 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
447
448 if (pConfigurableDomain == *it) {
449
450 return true;
451 }
452 }
453 return false;
454}
455
456// Belonging domain ascending search
457bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
458{
459 // Check parent
460 const CElement* pParent = getParent();
461
462 if (isOfConfigurableElementType(pParent)) {
463
464 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
465 }
466 return false;
467}
468
469// Belonging subsystem
470const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
471{
472 const CElement* pParent = getParent();
473
474 // Stop at sytem class
475 if (!pParent->getParent()) {
476
477 return NULL;
478 }
479
480 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
481}
482
483// Check parent is still of current type (by structure knowledge)
484bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
485{
486 assert(pParent);
487
488 // Up to system class
489 return !!pParent->getParent();
490}