blob: 9707fb2d5504b3044cb9363c408b4b2d326dbbbe [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
50bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const
51{
52 uint32_t uiIndex;
53 uint32_t uiNbChildren = getNbChildren();
54
55 if (!configurationAccessContext.serializeOut()) {
56 // Just do basic checks and propagate to children
57 CXmlElement::CChildIterator it(xmlConfigurableElementSettingsElement);
58
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
116 xmlConfigurableElementSettingsElement.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
117
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
129#if 0
130bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const
131{
132 if (!configurationAccessContext.serializeOut()) {
133 // Just do basic checks and propagate to children
134 CXmlElement::CChildIterator it(xmlConfigurableElementSettingsElement);
135
136 CXmlElement xmlChildConfigurableElementSettingsElement;
137
138 while (it.next(xmlChildConfigurableElementSettingsElement)) {
139
140 // Find child configurable element
141 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(findChild(xmlChildConfigurableElementSettingsElement.getNameAttribute()));
142
143 if (!pChildConfigurableElement) {
144
145 configurationAccessContext.setError("Configuration settings parsing: Unable to find configurable element " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " under configurable element " + getName());
146
147 return false;
148 }
149
150 // Check element type matches
151 if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) {
152
153 configurationAccessContext.setError("Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind());
154
155 return false;
156 }
157
158 // Parse child configurable element's settings
159 if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) {
160
161 return false;
162 }
163 }
164 } else {
165 // Propagate to children
166 uint32_t uiIndex;
167 uint32_t uiNbChildren = getNbChildren();
168
169 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
170
171 const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
172
173 // Create corresponding child element
174 CXmlElement xmlChildConfigurableElementSettingsElement;
175
176 xmlConfigurableElementSettingsElement.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind());
177
178 // Handle element name attribute
179 xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName());
180
181 // Propagate
182 pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext);
183 }
184 }
185 // Done
186 return true;
187}
188#endif
189
190// Parameter access
191bool CConfigurableElement::setValue(CPathNavigator& pathNavigator, const string& strValue, CErrorContext& errorContext) const
192{
193 string* pStrChildName = pathNavigator.next();
194
195 if (!pStrChildName) {
196
197 errorContext.setError("Non settable element");
198
199 return false;
200 }
201
202 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
203
204 if (!pChild) {
205
206 errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
207
208 return false;
209 }
210
211 return pChild->setValue(pathNavigator, strValue, errorContext);
212}
213
214bool CConfigurableElement::getValue(CPathNavigator& pathNavigator, string& strValue, CErrorContext& errorContext) const
215{
216 string* pStrChildName = pathNavigator.next();
217
218 if (!pStrChildName) {
219
220 errorContext.setError("Non gettable element");
221
222 return false;
223 }
224
225 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
226
227 if (!pChild) {
228
229 errorContext.setError("Path not found: " + pathNavigator.getCurrentPath());
230
231 return false;
232 }
233
234 return pChild->getValue(pathNavigator, strValue, errorContext);
235}
236
237// Used for simulation only
238void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
239{
240 // Propagate to children
241 uint32_t uiIndex;
242 uint32_t uiNbChildren = getNbChildren();
243
244 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
245
246 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
247
248 pConfigurableElement->setDefaultValues(parameterAccessContext);
249 }
250}
251
252// Offset
253void CConfigurableElement::setOffset(uint32_t uiOffset)
254{
255 // Assign offset locally
256 _uiOffset = uiOffset;
257
258 // Propagate to children
259 uint32_t uiIndex;
260 uint32_t uiNbChildren = getNbChildren();
261
262 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
263
264 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
265
266 pConfigurableElement->setOffset(uiOffset);
267
268 uiOffset += pConfigurableElement->getFootPrint();
269 }
270}
271
272uint32_t CConfigurableElement::getOffset() const
273{
274 return _uiOffset;
275}
276
277// Memory
278uint32_t CConfigurableElement::getFootPrint() const
279{
280 uint32_t uiSize = 0;
281 uint32_t uiIndex;
282 uint32_t uiNbChildren = getNbChildren();
283
284 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
285
286 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
287
288 uiSize += pConfigurableElement->getFootPrint();
289 }
290
291 return uiSize;
292}
293
294// Browse parent path to find syncer
295ISyncer* CConfigurableElement::getSyncer() const
296{
297 // Check parent
298 const CElement* pParent = getParent();
299
300 if (isOfConfigurableElementType(pParent)) {
301
302 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
303 }
304 return false;
305}
306
307// Syncer set (me, ascendant or descendant ones)
308void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
309{
310 // Try me or ascendants
311 ISyncer* pMineOrAscendantSyncer = getSyncer();
312
313 if (pMineOrAscendantSyncer) {
314
315 // Provide found syncer object
316 syncerSet += pMineOrAscendantSyncer;
317
318 // Done
319 return;
320 }
321 // Fetch descendant ones
322 fillSyncerSetFromDescendant(syncerSet);
323}
324
325// Syncer set (descendant)
326void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
327{
328 // Dig
329 uint32_t uiIndex;
330 uint32_t uiNbChildren = getNbChildren();
331
332 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
333
334 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
335
336 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
337 }
338}
339
340// Configurable domain association
341void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
342{
343 _configurableDomainList.push_back(pConfigurableDomain);
344}
345
346void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
347{
348 _configurableDomainList.remove(pConfigurableDomain);
349}
350
351// Belonging domain
352bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
353{
354 if (containsConfigurableDomain(pConfigurableDomain)) {
355
356 return true;
357 }
358 return belongsToDomainAscending(pConfigurableDomain);
359}
360
361// Belonging domains
362void CConfigurableElement::getBelongingDomains(list<const CConfigurableDomain*>& configurableDomainList) const
363{
364 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
365
366 // Check parent
367 const CElement* pParent = getParent();
368
369 if (isOfConfigurableElementType(pParent)) {
370
371 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
372 }
373}
374
375void CConfigurableElement::listBelongingDomains(string& strResult, bool bVertical) const
376{
377 // Get belonging domain list
378 list<const CConfigurableDomain*> configurableDomainList;
379
380 getBelongingDomains(configurableDomainList);
381
382 // Fill list
383 listDomains(configurableDomainList, strResult, bVertical);
384}
385
386// Elements with no domains
387void CConfigurableElement::listRogueElements(string& strResult) const
388{
389 strResult = "\n";
390
391 // Get rogue element aggregate list (no associated domain)
392 list<const CConfigurableElement*> rogueElementList;
393
394 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
395
396 configurableElementAggregator.aggegate(this);
397
398 // Build list as string
399 list<const CConfigurableElement*>::const_iterator it;
400
401 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
402
403 const CConfigurableElement* pConfigurableElement = *it;
404
405 strResult += pConfigurableElement->getPath() + "\n";
406 }
407}
408
409// Matching check for no domain association
410bool CConfigurableElement::hasNoDomainAssociated() const
411{
412 return _configurableDomainList.empty();
413}
414
415// Matching check for no valid associated domains
416bool CConfigurableElement::hasNoValidDomainAssociated() const
417{
418 if (_configurableDomainList.empty()) {
419
420 // No domains associated
421 return true;
422 }
423
424 ConfigurableDomainListConstIterator it;
425
426 // Browse all configurable domains for validity checking
427 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
428
429 const CConfigurableDomain* pConfigurableDomain = *it;
430
431 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
432
433 return false;
434 }
435 }
436
437 return true;
438}
439
440// Owning domains
441void CConfigurableElement::listAssociatedDomains(string& strResult, bool bVertical) const
442{
443 // Fill list
444 listDomains(_configurableDomainList, strResult, bVertical);
445}
446
447uint32_t CConfigurableElement::getBelongingDomainCount() const
448{
449 // Get belonging domain list
450 list<const CConfigurableDomain*> configurableDomainList;
451
452 getBelongingDomains(configurableDomainList);
453
454 return configurableDomainList.size();
455}
456
457void CConfigurableElement::listDomains(const list<const CConfigurableDomain*>& configurableDomainList, string& strResult, bool bVertical) const
458{
459 if (bVertical && configurableDomainList.empty()) {
460
461 strResult = "\n";
462 }
463
464 // Fill list
465 ConfigurableDomainListConstIterator it;
466 bool bFirst = true;
467
468 // Browse all configurable domains for comparison
469 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
470
471 const CConfigurableDomain* pConfigurableDomain = *it;
472
473 if (!bVertical && !bFirst) {
474
475 strResult += ", ";
476 }
477
478 strResult += pConfigurableDomain->getName();
479
480 if (bVertical) {
481
482 strResult += "\n";
483 } else {
484
485 bFirst = false;
486 }
487 }
488}
489
490bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
491{
492 ConfigurableDomainListConstIterator it;
493
494 // Browse all configurable domains for comparison
495 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
496
497 if (pConfigurableDomain == *it) {
498
499 return true;
500 }
501 }
502 return false;
503}
504
505// Belonging domain ascending search
506bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
507{
508 // Check parent
509 const CElement* pParent = getParent();
510
511 if (isOfConfigurableElementType(pParent)) {
512
513 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
514 }
515 return false;
516}
517
518// Belonging subsystem
519const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
520{
521 const CElement* pParent = getParent();
522
523 // Stop at sytem class
524 if (!pParent->getParent()) {
525
526 return NULL;
527 }
528
529 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
530}
531
532// Check parent is still of current type (by structure knowledge)
533bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
534{
535 assert(pParent);
536
537 // Up to system class
538 return !!pParent->getParent();
539}