blob: f439ebf0b862654ea8c6b1485fb4664ab70cba1e [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"
37#include <assert.h>
38
39#define base CElement
40
41CConfigurableElement::CConfigurableElement(const string& strName) : base(strName), _uiOffset(0)
42{
43}
44
45CConfigurableElement::~CConfigurableElement()
46{
47}
48
49// XML configuration settings parsing
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020050bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +020051{
52 uint32_t uiIndex;
53 uint32_t uiNbChildren = getNbChildren();
54
55 if (!configurationAccessContext.serializeOut()) {
56 // Just do basic checks and propagate to children
Patrick Benavoli6ba361d2011-08-31 11:23:24 +020057 CXmlElement::CChildIterator it(xmlConfigurationSettingsElementContent);
Patrick Benavoli68a91282011-08-31 11:23:23 +020058
59 CXmlElement xmlChildConfigurableElementSettingsElement;
60
61 // Propagate to children
62 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
63
64 // Get child
65 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
66
67 if (!it.next(xmlChildConfigurableElementSettingsElement)) {
68
69 // Structure error
70 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
71
72 return false;
73 }
74
75 // Check element type matches in type
76 if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
77
78 // Type error
79 configurationAccessContext.setError("Configuration settings parsing: Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
80
81 return false;
82 }
83
84 // Check element type matches in name
85 if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != pChildConfigurableElement->getName()) {
86
87 // Name error
88 configurationAccessContext.setError("Configuration settings parsing: Under configurable elememnt " + getName() + ", expected element name " + pChildConfigurableElement->getName() + " but found " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead");
89
90 return false;
91 }
92
93 // Parse child configurable element's settings
94 if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
95
96 return false;
97 }
98 }
99 // There should remain no configurable element to parse
100 if (it.next(xmlChildConfigurableElementSettingsElement)) {
101
102 // Structure error
103 configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName());
104
105 return false;
106 }
107 } else {
108 // Propagate to children
109 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
110
111 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
112
113 // Create corresponding child element
114 CXmlElement xmlChildConfigurableElementSettingsElement;
115
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200116 xmlConfigurationSettingsElementContent.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200117
118 // Handle element name attribute
119 xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
120
121 // Propagate
122 pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
123 }
124 }
125 // Done
126 return true;
127}
128
Patrick Benavoli68a91282011-08-31 11:23:23 +0200129// Parameter access
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200130bool CConfigurableElement::setValue(CPathNavigator& pathNavigator, const string& strValue, CParameterAccessContext& parameterContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200131{
132 string* pStrChildName = pathNavigator.next();
133
134 if (!pStrChildName) {
135
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200136 parameterContext.setError("Non settable element");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200137
138 return false;
139 }
140
141 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
142
143 if (!pChild) {
144
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200145 parameterContext.setError("Path not found: " + pathNavigator.getCurrentPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200146
147 return false;
148 }
149
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200150 return pChild->setValue(pathNavigator, strValue, parameterContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200151}
152
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200153bool CConfigurableElement::getValue(CPathNavigator& pathNavigator, string& strValue, CParameterAccessContext& parameterContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200154{
155 string* pStrChildName = pathNavigator.next();
156
157 if (!pStrChildName) {
158
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200159 parameterContext.setError("Non gettable element");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200160
161 return false;
162 }
163
164 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
165
166 if (!pChild) {
167
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200168 parameterContext.setError("Path not found: " + pathNavigator.getCurrentPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200169
170 return false;
171 }
172
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200173 return pChild->getValue(pathNavigator, strValue, parameterContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200174}
175
176// Used for simulation only
177void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
178{
179 // Propagate to children
180 uint32_t uiIndex;
181 uint32_t uiNbChildren = getNbChildren();
182
183 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
184
185 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
186
187 pConfigurableElement->setDefaultValues(parameterAccessContext);
188 }
189}
190
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200191// Element properties
192void CConfigurableElement::showProperties(string& strResult) const
193{
194 base::showProperties(strResult);
195
196 strResult += "Total size: " + getFootprintAsString() + "\n";
197}
198
Patrick Benavoli68a91282011-08-31 11:23:23 +0200199// Offset
200void CConfigurableElement::setOffset(uint32_t uiOffset)
201{
202 // Assign offset locally
203 _uiOffset = uiOffset;
204
205 // Propagate to children
206 uint32_t uiIndex;
207 uint32_t uiNbChildren = getNbChildren();
208
209 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
210
211 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
212
213 pConfigurableElement->setOffset(uiOffset);
214
215 uiOffset += pConfigurableElement->getFootPrint();
216 }
217}
218
219uint32_t CConfigurableElement::getOffset() const
220{
221 return _uiOffset;
222}
223
224// Memory
225uint32_t CConfigurableElement::getFootPrint() const
226{
227 uint32_t uiSize = 0;
228 uint32_t uiIndex;
229 uint32_t uiNbChildren = getNbChildren();
230
231 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
232
233 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
234
235 uiSize += pConfigurableElement->getFootPrint();
236 }
237
238 return uiSize;
239}
240
241// Browse parent path to find syncer
242ISyncer* CConfigurableElement::getSyncer() const
243{
244 // Check parent
245 const CElement* pParent = getParent();
246
247 if (isOfConfigurableElementType(pParent)) {
248
249 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
250 }
251 return false;
252}
253
254// Syncer set (me, ascendant or descendant ones)
255void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
256{
257 // Try me or ascendants
258 ISyncer* pMineOrAscendantSyncer = getSyncer();
259
260 if (pMineOrAscendantSyncer) {
261
262 // Provide found syncer object
263 syncerSet += pMineOrAscendantSyncer;
264
265 // Done
266 return;
267 }
268 // Fetch descendant ones
269 fillSyncerSetFromDescendant(syncerSet);
270}
271
272// Syncer set (descendant)
273void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
274{
275 // Dig
276 uint32_t uiIndex;
277 uint32_t uiNbChildren = getNbChildren();
278
279 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
280
281 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
282
283 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
284 }
285}
286
287// Configurable domain association
288void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
289{
290 _configurableDomainList.push_back(pConfigurableDomain);
291}
292
293void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
294{
295 _configurableDomainList.remove(pConfigurableDomain);
296}
297
298// Belonging domain
299bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
300{
301 if (containsConfigurableDomain(pConfigurableDomain)) {
302
303 return true;
304 }
305 return belongsToDomainAscending(pConfigurableDomain);
306}
307
308// Belonging domains
309void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
310{
311 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
312
313 // Check parent
314 const CElement* pParent = getParent();
315
316 if (isOfConfigurableElementType(pParent)) {
317
318 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
319 }
320}
321
322void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
323{
324 // Get belonging domain list
325 list<const CConfigurableDomain*> configurableDomainList;
326
327 getBelongingDomains(configurableDomainList);
328
329 // Fill list
330 listDomains(configurableDomainList, strResult, bVertical);
331}
332
333// Elements with no domains
334void CConfigurableElement::listRogueElements(string& strResult) const
335{
336 strResult = "\n";
337
338 // Get rogue element aggregate list (no associated domain)
339 list<const CConfigurableElement*> rogueElementList;
340
341 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
342
343 configurableElementAggregator.aggegate(this);
344
345 // Build list as string
346 list<const CConfigurableElement*>::const_iterator it;
347
348 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
349
350 const CConfigurableElement* pConfigurableElement = *it;
351
352 strResult += pConfigurableElement->getPath() + "\n";
353 }
354}
355
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200356// Footprint as string
357string CConfigurableElement::getFootprintAsString() const
358{
359 // Get size as string
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200360 return toString(getFootPrint()) + " byte(s)";
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200361}
362
Patrick Benavoli68a91282011-08-31 11:23:23 +0200363// Matching check for no domain association
364bool CConfigurableElement::hasNoDomainAssociated() const
365{
366 return _configurableDomainList.empty();
367}
368
369// Matching check for no valid associated domains
370bool CConfigurableElement::hasNoValidDomainAssociated() const
371{
372 if (_configurableDomainList.empty()) {
373
374 // No domains associated
375 return true;
376 }
377
378 ConfigurableDomainListConstIterator it;
379
380 // Browse all configurable domains for validity checking
381 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
382
383 const CConfigurableDomain* pConfigurableDomain = *it;
384
385 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
386
387 return false;
388 }
389 }
390
391 return true;
392}
393
394// Owning domains
395void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
396{
397 // Fill list
398 listDomains(_configurableDomainList, strResult, bVertical);
399}
400
401uint32_t CConfigurableElement::getBelongingDomainCount() const
402{
403 // Get belonging domain list
404 list<const CConfigurableDomain*> configurableDomainList;
405
406 getBelongingDomains(configurableDomainList);
407
408 return configurableDomainList.size();
409}
410
411void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
412{
413 if (bVertical && configurableDomainList.empty()) {
414
415 strResult = "\n";
416 }
417
418 // Fill list
419 ConfigurableDomainListConstIterator it;
420 bool bFirst = true;
421
422 // Browse all configurable domains for comparison
423 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
424
425 const CConfigurableDomain* pConfigurableDomain = *it;
426
427 if (!bVertical && !bFirst) {
428
429 strResult += ", ";
430 }
431
432 strResult += pConfigurableDomain->getName();
433
434 if (bVertical) {
435
436 strResult += "\n";
437 } else {
438
439 bFirst = false;
440 }
441 }
442}
443
444bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
445{
446 ConfigurableDomainListConstIterator it;
447
448 // Browse all configurable domains for comparison
449 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
450
451 if (pConfigurableDomain == *it) {
452
453 return true;
454 }
455 }
456 return false;
457}
458
459// Belonging domain ascending search
460bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
461{
462 // Check parent
463 const CElement* pParent = getParent();
464
465 if (isOfConfigurableElementType(pParent)) {
466
467 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
468 }
469 return false;
470}
471
472// Belonging subsystem
473const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
474{
475 const CElement* pParent = getParent();
476
477 // Stop at sytem class
478 if (!pParent->getParent()) {
479
480 return NULL;
481 }
482
483 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
484}
485
486// Check parent is still of current type (by structure knowledge)
487bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
488{
489 assert(pParent);
490
491 // Up to system class
492 return !!pParent->getParent();
493}