blob: eb66dd879072e738ac02250cfcf8d005e5a11f68 [file] [log] [blame]
Frederic Boisnard6cae0ec2013-05-23 18:48:58 +02001/*
David Wagnerb76c9d62014-02-05 18:30:24 +01002 * 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.
Patrick Benavoli68a91282011-08-31 11:23:23 +020029 */
30#include "ConfigurableElement.h"
31#include "MappingData.h"
32#include "SyncerSet.h"
33#include "ConfigurableDomain.h"
34#include "ConfigurationAccessContext.h"
35#include "ConfigurableElementAggregator.h"
Frédéric Boisnard9620e442012-05-30 16:15:02 +020036#include "AreaConfiguration.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020037#include <assert.h>
38
39#define base CElement
40
Sebastien Gonzalved9526492014-02-20 22:28:03 +010041CConfigurableElement::CConfigurableElement(const std::string& strName) : base(strName), _uiOffset(0)
Patrick Benavoli68a91282011-08-31 11:23:23 +020042{
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
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200129// AreaConfiguration creation
130CAreaConfiguration* CConfigurableElement::createAreaConfiguration(const CSyncerSet* pSyncerSet) const
131{
132 return new CAreaConfiguration(this, pSyncerSet);
133}
134
Patrick Benavoli68a91282011-08-31 11:23:23 +0200135// Parameter access
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100136bool CConfigurableElement::accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200137{
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100138 std::string* pStrChildName = pathNavigator.next();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200139
140 if (!pStrChildName) {
141
David Wagner78052ff2014-10-31 18:04:33 +0100142 parameterAccessContext.setError((bSet ? "Can't set " : "Can't get ") + pathNavigator.getCurrentPath() + " because it is not a parameter");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200143
144 return false;
145 }
146
147 const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName));
148
149 if (!pChild) {
150
Patrick Benavoli065264a2011-11-20 15:46:41 +0100151 parameterAccessContext.setError("Path not found: " + pathNavigator.getCurrentPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200152
153 return false;
154 }
155
Patrick Benavoli065264a2011-11-20 15:46:41 +0100156 return pChild->accessValue(pathNavigator, strValue, bSet, parameterAccessContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200157}
158
Frederic Boisnard6cae0ec2013-05-23 18:48:58 +0200159void CConfigurableElement::getListOfElementsWithMapping(
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100160 std::list<const CConfigurableElement*>& configurableElementPath) const
Frederic Boisnard6cae0ec2013-05-23 18:48:58 +0200161{
162 // Check parent
163 const CElement* pParent = getParent();
164 if (isOfConfigurableElementType(pParent)) {
165
166 const CConfigurableElement* pConfigurableElement =
167 static_cast<const CConfigurableElement*>(pParent);
168
169 pConfigurableElement->getListOfElementsWithMapping(configurableElementPath);
170 }
171}
172
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +0100173// Used for simulation and virtual subsystems
Patrick Benavoli68a91282011-08-31 11:23:23 +0200174void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const
175{
176 // Propagate to children
177 uint32_t uiIndex;
178 uint32_t uiNbChildren = getNbChildren();
179
180 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
181
182 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
183
184 pConfigurableElement->setDefaultValues(parameterAccessContext);
185 }
186}
187
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200188// Element properties
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100189void CConfigurableElement::showProperties(std::string& strResult) const
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200190{
191 base::showProperties(strResult);
192
193 strResult += "Total size: " + getFootprintAsString() + "\n";
194}
195
Patrick Benavoli68a91282011-08-31 11:23:23 +0200196// Offset
197void CConfigurableElement::setOffset(uint32_t uiOffset)
198{
199 // Assign offset locally
200 _uiOffset = uiOffset;
201
202 // Propagate to children
203 uint32_t uiIndex;
204 uint32_t uiNbChildren = getNbChildren();
205
206 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
207
208 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex));
209
210 pConfigurableElement->setOffset(uiOffset);
211
212 uiOffset += pConfigurableElement->getFootPrint();
213 }
214}
215
216uint32_t CConfigurableElement::getOffset() const
217{
218 return _uiOffset;
219}
220
221// Memory
222uint32_t CConfigurableElement::getFootPrint() const
223{
224 uint32_t uiSize = 0;
225 uint32_t uiIndex;
226 uint32_t uiNbChildren = getNbChildren();
227
228 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
229
230 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
231
232 uiSize += pConfigurableElement->getFootPrint();
233 }
234
235 return uiSize;
236}
237
238// Browse parent path to find syncer
239ISyncer* CConfigurableElement::getSyncer() const
240{
241 // Check parent
242 const CElement* pParent = getParent();
243
244 if (isOfConfigurableElementType(pParent)) {
245
246 return static_cast<const CConfigurableElement*>(pParent)->getSyncer();
247 }
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200248 return NULL;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200249}
250
251// Syncer set (me, ascendant or descendant ones)
252void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const
253{
254 // Try me or ascendants
255 ISyncer* pMineOrAscendantSyncer = getSyncer();
256
257 if (pMineOrAscendantSyncer) {
258
259 // Provide found syncer object
260 syncerSet += pMineOrAscendantSyncer;
261
262 // Done
263 return;
264 }
265 // Fetch descendant ones
266 fillSyncerSetFromDescendant(syncerSet);
267}
268
269// Syncer set (descendant)
270void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const
271{
272 // Dig
273 uint32_t uiIndex;
274 uint32_t uiNbChildren = getNbChildren();
275
276 for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) {
277
278 const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex));
279
280 pConfigurableElement->fillSyncerSetFromDescendant(syncerSet);
281 }
282}
283
284// Configurable domain association
285void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
286{
287 _configurableDomainList.push_back(pConfigurableDomain);
288}
289
290void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain)
291{
292 _configurableDomainList.remove(pConfigurableDomain);
293}
294
295// Belonging domain
296bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const
297{
298 if (containsConfigurableDomain(pConfigurableDomain)) {
299
300 return true;
301 }
302 return belongsToDomainAscending(pConfigurableDomain);
303}
304
305// Belonging domains
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100306void CConfigurableElement::getBelongingDomains(std::list<const CConfigurableDomain*>& configurableDomainList) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200307{
308 configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end());
309
310 // Check parent
311 const CElement* pParent = getParent();
312
313 if (isOfConfigurableElementType(pParent)) {
314
315 static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList);
316 }
317}
318
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100319void CConfigurableElement::listBelongingDomains(std::string& strResult, bool bVertical) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200320{
321 // Get belonging domain list
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100322 std::list<const CConfigurableDomain*> configurableDomainList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200323
324 getBelongingDomains(configurableDomainList);
325
326 // Fill list
327 listDomains(configurableDomainList, strResult, bVertical);
328}
329
330// Elements with no domains
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100331void CConfigurableElement::listRogueElements(std::string& strResult) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200332{
333 strResult = "\n";
334
335 // Get rogue element aggregate list (no associated domain)
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100336 std::list<const CConfigurableElement*> rogueElementList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200337
338 CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated);
339
340 configurableElementAggregator.aggegate(this);
341
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100342 // Build list as std::string
343 std::list<const CConfigurableElement*>::const_iterator it;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200344
345 for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) {
346
347 const CConfigurableElement* pConfigurableElement = *it;
348
349 strResult += pConfigurableElement->getPath() + "\n";
350 }
351}
352
Patrick Benavoli4bed9212011-10-27 14:18:00 +0200353// Belonging to no domains
354bool CConfigurableElement::isRogue() const
355{
356 return !getBelongingDomainCount();
357}
358
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200359// Footprint as string
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100360std::string CConfigurableElement::getFootprintAsString() const
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200361{
362 // Get size as string
Patrick Benavoli2ecf9002011-08-31 11:23:24 +0200363 return toString(getFootPrint()) + " byte(s)";
Patrick Benavoli6ba361d2011-08-31 11:23:24 +0200364}
365
Patrick Benavoli68a91282011-08-31 11:23:23 +0200366// Matching check for no domain association
367bool CConfigurableElement::hasNoDomainAssociated() const
368{
369 return _configurableDomainList.empty();
370}
371
372// Matching check for no valid associated domains
373bool CConfigurableElement::hasNoValidDomainAssociated() const
374{
375 if (_configurableDomainList.empty()) {
376
377 // No domains associated
378 return true;
379 }
380
381 ConfigurableDomainListConstIterator it;
382
383 // Browse all configurable domains for validity checking
384 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
385
386 const CConfigurableDomain* pConfigurableDomain = *it;
387
388 if (pConfigurableDomain->isApplicableConfigurationValid(this)) {
389
390 return false;
391 }
392 }
393
394 return true;
395}
396
397// Owning domains
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100398void CConfigurableElement::listAssociatedDomains(std::string& strResult, bool bVertical) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200399{
400 // Fill list
401 listDomains(_configurableDomainList, strResult, bVertical);
402}
403
404uint32_t CConfigurableElement::getBelongingDomainCount() const
405{
406 // Get belonging domain list
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100407 std::list<const CConfigurableDomain*> configurableDomainList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200408
409 getBelongingDomains(configurableDomainList);
410
411 return configurableDomainList.size();
412}
413
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100414void CConfigurableElement::listDomains(const std::list<const CConfigurableDomain*>& configurableDomainList, std::string& strResult, bool bVertical) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200415{
416 if (bVertical && configurableDomainList.empty()) {
417
418 strResult = "\n";
419 }
420
421 // Fill list
422 ConfigurableDomainListConstIterator it;
423 bool bFirst = true;
424
425 // Browse all configurable domains for comparison
426 for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) {
427
428 const CConfigurableDomain* pConfigurableDomain = *it;
429
430 if (!bVertical && !bFirst) {
431
432 strResult += ", ";
433 }
434
435 strResult += pConfigurableDomain->getName();
436
437 if (bVertical) {
438
439 strResult += "\n";
440 } else {
441
442 bFirst = false;
443 }
444 }
445}
446
447bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const
448{
449 ConfigurableDomainListConstIterator it;
450
451 // Browse all configurable domains for comparison
452 for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) {
453
454 if (pConfigurableDomain == *it) {
455
456 return true;
457 }
458 }
459 return false;
460}
461
462// Belonging domain ascending search
463bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const
464{
465 // Check parent
466 const CElement* pParent = getParent();
467
468 if (isOfConfigurableElementType(pParent)) {
469
470 return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain);
471 }
472 return false;
473}
474
475// Belonging subsystem
476const CSubsystem* CConfigurableElement::getBelongingSubsystem() const
477{
478 const CElement* pParent = getParent();
479
Kevin Rocardace81f82012-12-11 16:19:17 +0100480 // Stop at system class
Patrick Benavoli68a91282011-08-31 11:23:23 +0200481 if (!pParent->getParent()) {
482
483 return NULL;
484 }
485
486 return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem();
487}
488
Patrick Benavoli065264a2011-11-20 15:46:41 +0100489// Check element is a parameter
490bool CConfigurableElement::isParameter() const
491{
492 return false;
493}
494
495
Patrick Benavoli68a91282011-08-31 11:23:23 +0200496// Check parent is still of current type (by structure knowledge)
497bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const
498{
499 assert(pParent);
500
501 // Up to system class
502 return !!pParent->getParent();
503}