blob: b11b84f187b6a23d5d7b95f9fe0e8fc7db25e623 [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 Benavoli4bed9212011-10-27 14:18:00 +0200356// Belonging to no domains
357bool CConfigurableElement::isRogue() const
358{
359 return !getBelongingDomainCount();
360}
361
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200362// Footprint as string
363string CConfigurableElement::getFootprintAsString() const
364{
365 // Get size as string
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200366 return toString(getFootPrint()) + " byte(s)";
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200367}
368
Patrick Benavoli68a91282011-08-31 11:23:23 +0200369// Matching check for no domain association
370bool CConfigurableElement::hasNoDomainAssociated() const
371{
372 return _configurableDomainList.empty();
373}
374
375// Matching check for no valid associated domains
376bool CConfigurableElement::hasNoValidDomainAssociated() const
377{
378 if (_configurableDomainList.empty()) {
379
380 // No domains associated
381 return true;
382 }
383
384 ConfigurableDomainListConstIterator it;
385
386 // Browse all configurable domains for validity checking
387 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
388
389 const CConfigurableDomain* pConfigurableDomain = *it;
390
391 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
392
393 return false;
394 }
395 }
396
397 return true;
398}
399
400// Owning domains
401void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
402{
403 // Fill list
404 listDomains(_configurableDomainList, strResult, bVertical);
405}
406
407uint32_t CConfigurableElement::getBelongingDomainCount() const
408{
409 // Get belonging domain list
410 list<const CConfigurableDomain*> configurableDomainList;
411
412 getBelongingDomains(configurableDomainList);
413
414 return configurableDomainList.size();
415}
416
417void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
418{
419 if (bVertical && configurableDomainList.empty()) {
420
421 strResult = "\n";
422 }
423
424 // Fill list
425 ConfigurableDomainListConstIterator it;
426 bool bFirst = true;
427
428 // Browse all configurable domains for comparison
429 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
430
431 const CConfigurableDomain* pConfigurableDomain = *it;
432
433 if (!bVertical && !bFirst) {
434
435 strResult += ", ";
436 }
437
438 strResult += pConfigurableDomain->getName();
439
440 if (bVertical) {
441
442 strResult += "\n";
443 } else {
444
445 bFirst = false;
446 }
447 }
448}
449
450bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
451{
452 ConfigurableDomainListConstIterator it;
453
454 // Browse all configurable domains for comparison
455 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
456
457 if (pConfigurableDomain == *it) {
458
459 return true;
460 }
461 }
462 return false;
463}
464
465// Belonging domain ascending search
466bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
467{
468 // Check parent
469 const CElement* pParent = getParent();
470
471 if (isOfConfigurableElementType(pParent)) {
472
473 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
474 }
475 return false;
476}
477
478// Belonging subsystem
479const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
480{
481 const CElement* pParent = getParent();
482
483 // Stop at sytem class
484 if (!pParent->getParent()) {
485
486 return NULL;
487 }
488
489 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
490}
491
492// Check parent is still of current type (by structure knowledge)
493bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
494{
495 assert(pParent);
496
497 // Up to system class
498 return !!pParent->getParent();
499}