1 /*
2  * 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.
29  */
30 #include "DomainConfiguration.h"
31 #include "AreaConfiguration.h"
32 #include "ConfigurableElement.h"
33 #include "CompoundRule.h"
34 #include "Subsystem.h"
35 #include "XmlDomainSerializingContext.h"
36 #include "XmlDomainImportContext.h"
37 #include "XmlDomainExportContext.h"
38 #include "ConfigurationAccessContext.h"
39 #include <assert.h>
40 #include "RuleParser.h"
41 
42 #define base CBinarySerializableElement
43 
44 using std::string;
45 
CDomainConfiguration(const string & strName)46 CDomainConfiguration::CDomainConfiguration(const string& strName) : base(strName)
47 {
48 }
49 
~CDomainConfiguration()50 CDomainConfiguration::~CDomainConfiguration()
51 {
52     AreaConfigurationListIterator it;
53 
54     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
55 
56         delete *it;
57     }
58 }
59 
60 // Class kind
getKind() const61 string CDomainConfiguration::getKind() const
62 {
63     return "Configuration";
64 }
65 
66 // Child dynamic creation
childrenAreDynamic() const67 bool CDomainConfiguration::childrenAreDynamic() const
68 {
69     return true;
70 }
71 
72 // XML configuration settings parsing
parseSettings(CXmlElement & xmlConfigurationSettingsElement,CXmlSerializingContext & serializingContext)73 bool CDomainConfiguration::parseSettings(CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext)
74 {
75     // Actual XML context
76     CXmlDomainImportContext& xmlDomainImportContext = static_cast<CXmlDomainImportContext&>(serializingContext);
77 
78     // Take care of configurable elements / area configurations ranks
79     std::list<CAreaConfiguration*> areaConfigurationList;
80 
81     // Parse configurable element's configuration settings
82     CXmlElement::CChildIterator it(xmlConfigurationSettingsElement);
83 
84     CXmlElement xmlConfigurableElementSettingsElement;
85 
86     while (it.next(xmlConfigurableElementSettingsElement)) {
87 
88         // Retrieve area configuration
89         string strConfigurableElementPath = xmlConfigurableElementSettingsElement.getAttributeString("Path");
90 
91         CAreaConfiguration* pAreaConfiguration = findAreaConfiguration(strConfigurableElementPath);
92 
93         if (!pAreaConfiguration) {
94 
95             xmlDomainImportContext.setError("Configurable Element " + strConfigurableElementPath  + " referred to by Configuration " + getPath() + " not associated to Domain");
96 
97             return false;
98         }
99         // Ranks
100         areaConfigurationList.push_back(pAreaConfiguration);
101 
102         // Parse
103         if (!serializeConfigurableElementSettings(pAreaConfiguration, xmlConfigurableElementSettingsElement, xmlDomainImportContext, false)) {
104 
105             return false;
106         }
107     }
108 
109     // Reorder area configurations according to XML content
110     reorderAreaConfigurations(areaConfigurationList);
111 
112     return true;
113 }
114 
115 // XML configuration settings composing
composeSettings(CXmlElement & xmlConfigurationSettingsElement,CXmlSerializingContext & serializingContext) const116 void CDomainConfiguration::composeSettings(CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext) const
117 {
118     // Go through all are configurations
119     AreaConfigurationListIterator it;
120 
121     for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) {
122 
123         const CAreaConfiguration* pAreaConfiguration = *it;
124 
125         // Retrieve configurable element
126         const CConfigurableElement* pConfigurableElement = pAreaConfiguration->getConfigurableElement();
127 
128         // Create configurable element child element
129         CXmlElement xmlConfigurableElementSettingsElement;
130 
131         xmlConfigurationSettingsElement.createChild(xmlConfigurableElementSettingsElement, "ConfigurableElement");
132 
133         // Set Path attribute
134         xmlConfigurableElementSettingsElement.setAttributeString("Path", pConfigurableElement->getPath());
135 
136         // Delegate composing to area configuration
137         ((CDomainConfiguration&)(*this)).serializeConfigurableElementSettings((CAreaConfiguration*)pAreaConfiguration, xmlConfigurableElementSettingsElement, serializingContext, true);
138     }
139 }
140 
141 // Serialize one configuration for one configurable element
serializeConfigurableElementSettings(CAreaConfiguration * pAreaConfiguration,CXmlElement & xmlConfigurableElementSettingsElement,CXmlSerializingContext & serializingContext,bool bSerializeOut)142 bool CDomainConfiguration::serializeConfigurableElementSettings(CAreaConfiguration* pAreaConfiguration, CXmlElement& xmlConfigurableElementSettingsElement, CXmlSerializingContext& serializingContext, bool bSerializeOut)
143 {
144     // Actual XML context
145     CXmlDomainExportContext& xmlDomainExportContext =
146         static_cast<CXmlDomainExportContext&>(serializingContext);
147 
148     // Configurable Element
149     const CConfigurableElement* pConfigurableElement = pAreaConfiguration->getConfigurableElement();
150 
151     // Element content
152     CXmlElement xmlConfigurableElementSettingsElementContent;
153 
154     // Deal with element itself
155     if (!bSerializeOut) {
156 
157         // Check structure
158         if (xmlConfigurableElementSettingsElement.getNbChildElements() != 1) {
159 
160             // Structure error
161             serializingContext.setError("Struture error encountered while parsing settings of " + pConfigurableElement->getKind() + " " + pConfigurableElement->getName() + " in Configuration " + getPath());
162 
163             return false;
164         }
165 
166         // Check name and kind
167         if (!xmlConfigurableElementSettingsElement.getChildElement(pConfigurableElement->getKind(), pConfigurableElement->getName(), xmlConfigurableElementSettingsElementContent)) {
168 
169             serializingContext.setError("Couldn't find settings for " + pConfigurableElement->getKind() + " " + pConfigurableElement->getName() + " for Configuration " + getPath());
170 
171             return false;
172         }
173     } else {
174 
175         // Create child XML element
176         xmlConfigurableElementSettingsElement.createChild(xmlConfigurableElementSettingsElementContent, pConfigurableElement->getKind());
177 
178         // Set Name
179         xmlConfigurableElementSettingsElementContent.setNameAttribute(pConfigurableElement->getName());
180     }
181 
182     // Change context type to parameter settings access
183     string strError;
184 
185     // Create configuration access context
186     CConfigurationAccessContext configurationAccessContext(strError, bSerializeOut);
187 
188     // Provide current value space
189     configurationAccessContext.setValueSpaceRaw(xmlDomainExportContext.valueSpaceIsRaw());
190 
191     // Provide current output raw format
192     configurationAccessContext.setOutputRawFormat(xmlDomainExportContext.outputRawFormatIsHex());
193 
194     // Get subsystem
195     const CSubsystem* pSubsystem = pConfigurableElement->getBelongingSubsystem();
196 
197     if (pSubsystem && pSubsystem != pConfigurableElement) {
198 
199         // Element is a descendant of subsystem
200 
201         // Deal with Endianness
202         configurationAccessContext.setBigEndianSubsystem(pSubsystem->isBigEndian());
203     }
204 
205     // Have domain configuration parse settings for configurable element
206     if (!pAreaConfiguration->serializeXmlSettings(xmlConfigurableElementSettingsElementContent, configurationAccessContext)) {
207 
208         // Forward error
209         xmlDomainExportContext.setError(strError);
210 
211         return false;
212     }
213     return true;
214 }
215 
216 // Configurable Elements association
addConfigurableElement(const CConfigurableElement * pConfigurableElement,const CSyncerSet * pSyncerSet)217 void CDomainConfiguration::addConfigurableElement(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet)
218 {
219     CAreaConfiguration* pAreaConfiguration = pConfigurableElement->createAreaConfiguration(pSyncerSet);
220 
221     _areaConfigurationList.push_back(pAreaConfiguration);
222     _orderedAreaConfigurationList.push_back(pAreaConfiguration);
223 }
224 
removeConfigurableElement(const CConfigurableElement * pConfigurableElement)225 void CDomainConfiguration::removeConfigurableElement(const CConfigurableElement* pConfigurableElement)
226 {
227     CAreaConfiguration* pAreaConfigurationToRemove = getAreaConfiguration(pConfigurableElement);
228 
229     _areaConfigurationList.remove(pAreaConfigurationToRemove);
230     _orderedAreaConfigurationList.remove(pAreaConfigurationToRemove);
231 
232     delete pAreaConfigurationToRemove;
233 }
234 
235 // Sequence management
setElementSequence(const std::vector<string> & astrNewElementSequence,string & strError)236 bool CDomainConfiguration::setElementSequence(const std::vector<string>& astrNewElementSequence, string& strError)
237 {
238     // Build a new list of AreaConfiguration objects
239     std::list<CAreaConfiguration*> areaConfigurationList;
240 
241     uint32_t uiConfigurableElement;
242 
243     for (uiConfigurableElement = 0; uiConfigurableElement < astrNewElementSequence.size(); uiConfigurableElement++) {
244 
245         string strConfigurableElementPath = astrNewElementSequence[uiConfigurableElement];
246 
247         CAreaConfiguration* pAreaConfiguration = findAreaConfiguration(strConfigurableElementPath);
248 
249         if (!pAreaConfiguration) {
250 
251             strError = "Element " + strConfigurableElementPath + " not found in domain";
252 
253             return false;
254         }
255         // Check not already present in the list
256         if (findAreaConfiguration(strConfigurableElementPath, areaConfigurationList)) {
257 
258             strError = "Element " + strConfigurableElementPath + " provided more than once";
259 
260             return false;
261         }
262 
263         // Store new ordered area configuration
264         areaConfigurationList.push_back(pAreaConfiguration);
265     }
266 
267     // Reorder area configurations according to given path list
268     reorderAreaConfigurations(areaConfigurationList);
269 
270     return true;
271 }
272 
getElementSequence(string & strResult) const273 void CDomainConfiguration::getElementSequence(string& strResult) const
274 {
275     strResult = "\n";
276 
277     AreaConfigurationListIterator it;
278 
279     // List configurable element paths out of ordered area configuration list
280     for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) {
281 
282         const CAreaConfiguration* pAreaConfiguration = *it;
283 
284         const CConfigurableElement* pConfigurableElement = pAreaConfiguration->getConfigurableElement();
285 
286         strResult += pConfigurableElement->getPath() + "\n";
287     }
288 }
289 
290 // Application rule
setApplicationRule(const string & strApplicationRule,const CSelectionCriteriaDefinition * pSelectionCriteriaDefinition,string & strError)291 bool CDomainConfiguration::setApplicationRule(const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
292 {
293     // Parser
294     CRuleParser ruleParser(strApplicationRule, pSelectionCriteriaDefinition);
295 
296     // Attempt to parse it
297     if (!ruleParser.parse(NULL, strError)) {
298 
299         return false;
300     }
301     // Replace compound rule
302     setRule(ruleParser.grabRootRule());
303 
304     return true;
305 }
306 
clearApplicationRule()307 void CDomainConfiguration::clearApplicationRule()
308 {
309     // Replace compound rule
310     setRule(NULL);
311 }
312 
getApplicationRule(string & strResult) const313 void CDomainConfiguration::getApplicationRule(string& strResult) const
314 {
315     // Rule
316     const CCompoundRule* pRule = getRule();
317 
318     if (pRule) {
319         // Start clear
320         strResult.clear();
321 
322         // Dump rule
323         pRule->dump(strResult);
324 
325     } else {
326 
327         strResult = "<none>";
328     }
329 }
330 
331 /**
332  * Get the Configuration Blackboard.
333  *
334  * Fetch the Configuration Blackboard related to the ConfigurableElement given in parameter. This
335  * Element is used to retrieve the correct AreaConfiguration where the Blackboard is stored.
336  *
337  * @param[in] pConfigurableElement      A pointer to a ConfigurableElement that is part of the
338  *                                      Domain. This must have been checked previously, as an
339  *                                      assertion is performed.
340  *
341  * return Pointer to the Blackboard of the Configuration.
342  */
getBlackboard(const CConfigurableElement * pConfigurableElement) const343 CParameterBlackboard* CDomainConfiguration::getBlackboard(const CConfigurableElement* pConfigurableElement) const
344 {
345     AreaConfigurationListIterator it;
346 
347     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
348 
349         CAreaConfiguration* pAreaConfiguration = *it;
350 
351         // Check if the Element is associated with the Domain
352         if (pAreaConfiguration->getConfigurableElement() == pConfigurableElement) {
353 
354             return &pAreaConfiguration->getBlackboard();
355         }
356     }
357 
358     assert(0);
359     return NULL;
360 }
361 
362 // Save data from current
save(const CParameterBlackboard * pMainBlackboard)363 void CDomainConfiguration::save(const CParameterBlackboard* pMainBlackboard)
364 {
365     AreaConfigurationListIterator it;
366 
367     // Just propagate to areas
368     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
369 
370         CAreaConfiguration* pAreaConfiguration = *it;
371 
372         pAreaConfiguration->save(pMainBlackboard);
373     }
374 }
375 
376 // Apply data to current
restore(CParameterBlackboard * pMainBlackboard,bool bSync,std::list<string> * plstrError) const377 bool CDomainConfiguration::restore(CParameterBlackboard* pMainBlackboard, bool bSync, std::list<string>* plstrError) const
378 {
379     bool bSuccess = true;
380 
381     AreaConfigurationListIterator it;
382 
383     // Just propagate to areas
384     for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) {
385 
386         const CAreaConfiguration* pAreaConfiguration = *it;
387 
388         bSuccess &= pAreaConfiguration->restore(pMainBlackboard, bSync, plstrError);
389     }
390 
391     return bSuccess;
392 }
393 
394 // Ensure validity for configurable element area configuration
validate(const CConfigurableElement * pConfigurableElement,const CParameterBlackboard * pMainBlackboard)395 void CDomainConfiguration::validate(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
396 {
397     CAreaConfiguration* pAreaConfigurationToValidate = getAreaConfiguration(pConfigurableElement);
398 
399     // Delegate
400     pAreaConfigurationToValidate->validate(pMainBlackboard);
401 }
402 
403 // Ensure validity of all area configurations
validate(const CParameterBlackboard * pMainBlackboard)404 void CDomainConfiguration::validate(const CParameterBlackboard* pMainBlackboard)
405 {
406     AreaConfigurationListIterator it;
407 
408     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
409 
410         CAreaConfiguration* pAreaConfiguration = *it;
411 
412         pAreaConfiguration->validate(pMainBlackboard);
413     }
414 }
415 
416 // Return configuration validity for given configurable element
isValid(const CConfigurableElement * pConfigurableElement) const417 bool CDomainConfiguration::isValid(const CConfigurableElement* pConfigurableElement) const
418 {
419     // Get child configurable elemnt's area configuration
420     CAreaConfiguration* pAreaConfiguration = getAreaConfiguration(pConfigurableElement);
421 
422     assert(pAreaConfiguration);
423 
424     return pAreaConfiguration->isValid();
425 }
426 
427 // Ensure validity of configurable element's area configuration by copying in from a valid one
validateAgainst(const CDomainConfiguration * pValidDomainConfiguration,const CConfigurableElement * pConfigurableElement)428 void CDomainConfiguration::validateAgainst(const CDomainConfiguration* pValidDomainConfiguration, const CConfigurableElement* pConfigurableElement)
429 {
430     // Retrieve related area configurations
431     CAreaConfiguration* pAreaConfigurationToValidate = getAreaConfiguration(pConfigurableElement);
432     const CAreaConfiguration* pAreaConfigurationToValidateAgainst = pValidDomainConfiguration->getAreaConfiguration(pConfigurableElement);
433 
434     // Delegate to area
435     pAreaConfigurationToValidate->validateAgainst(pAreaConfigurationToValidateAgainst);
436 }
437 
438 // Ensure validity of all configurable element's area configuration by copying in from a valid ones
validateAgainst(const CDomainConfiguration * pValidDomainConfiguration)439 void CDomainConfiguration::validateAgainst(const CDomainConfiguration* pValidDomainConfiguration)
440 {
441     // Copy in configuration data from against domain
442     AreaConfigurationListIterator it, itAgainst;
443 
444     for (it = _areaConfigurationList.begin(), itAgainst = pValidDomainConfiguration->_areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it, ++itAgainst) {
445 
446         CAreaConfiguration* pAreaConfigurationToValidate = *it;
447         const CAreaConfiguration* pAreaConfigurationToValidateAgainst = *itAgainst;
448 
449         // Delegate to area
450         pAreaConfigurationToValidate->validateAgainst(pAreaConfigurationToValidateAgainst);
451     }
452 }
453 
454 // Dynamic data application
isApplicable() const455 bool CDomainConfiguration::isApplicable() const
456 {
457     const CCompoundRule* pRule = getRule();
458 
459     return pRule && pRule->matches();
460 }
461 
462 // Merge existing configurations to given configurable element ones
merge(CConfigurableElement * pToConfigurableElement,CConfigurableElement * pFromConfigurableElement)463 void CDomainConfiguration::merge(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
464 {
465     // Retrieve related area configurations
466     CAreaConfiguration* pAreaConfigurationToMergeTo = getAreaConfiguration(pToConfigurableElement);
467     const CAreaConfiguration* pAreaConfigurationToMergeFrom = getAreaConfiguration(pFromConfigurableElement);
468 
469     // Do the merge
470     pAreaConfigurationToMergeFrom->copyToOuter(pAreaConfigurationToMergeTo);
471 }
472 
473 // Domain splitting
split(CConfigurableElement * pFromConfigurableElement)474 void CDomainConfiguration::split(CConfigurableElement* pFromConfigurableElement)
475 {
476     // Retrieve related area configuration
477     const CAreaConfiguration* pAreaConfigurationToSplitFrom = getAreaConfiguration(pFromConfigurableElement);
478 
479     // Go through children areas to copy configuration data to them
480     size_t uiNbConfigurableElementChildren = pFromConfigurableElement->getNbChildren();
481     size_t uiChild;
482 
483     for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
484 
485         CConfigurableElement* pToChildConfigurableElement = static_cast<CConfigurableElement*>(pFromConfigurableElement->getChild(uiChild));
486 
487         // Get child configurable elemnt's area configuration
488         CAreaConfiguration* pChildAreaConfiguration = getAreaConfiguration(pToChildConfigurableElement);
489 
490         // Do the copy
491         pChildAreaConfiguration->copyFromOuter(pAreaConfigurationToSplitFrom);
492     }
493 }
494 
495 // AreaConfiguration retrieval from configurable element
getAreaConfiguration(const CConfigurableElement * pConfigurableElement) const496 CAreaConfiguration* CDomainConfiguration::getAreaConfiguration(const CConfigurableElement* pConfigurableElement) const
497 {
498     AreaConfigurationListIterator it;
499 
500     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
501 
502         CAreaConfiguration* pAreaConfiguration = *it;
503 
504         if (pAreaConfiguration->getConfigurableElement() == pConfigurableElement) {
505 
506             return pAreaConfiguration;
507         }
508     }
509     // Not found?
510     assert(0);
511 
512     return NULL;
513 }
514 
515 // AreaConfiguration retrieval from present area configurations
findAreaConfiguration(const string & strConfigurableElementPath) const516 CAreaConfiguration* CDomainConfiguration::findAreaConfiguration(const string& strConfigurableElementPath) const
517 {
518     return findAreaConfiguration(strConfigurableElementPath, _areaConfigurationList);
519 }
520 
521 // AreaConfiguration retrieval from given area configuration list
findAreaConfiguration(const string & strConfigurableElementPath,const std::list<CAreaConfiguration * > & areaConfigurationList) const522 CAreaConfiguration* CDomainConfiguration::findAreaConfiguration(const string& strConfigurableElementPath, const std::list<CAreaConfiguration*>& areaConfigurationList) const
523 {
524     AreaConfigurationListIterator it;
525 
526     for (it = areaConfigurationList.begin(); it != areaConfigurationList.end(); ++it) {
527 
528         CAreaConfiguration* pAreaConfiguration = *it;
529 
530         if (pAreaConfiguration->getConfigurableElement()->getPath() == strConfigurableElementPath) {
531 
532             return pAreaConfiguration;
533         }
534     }
535 
536     // Not found
537     return NULL;
538 }
539 
540 // Area configuration ordering
reorderAreaConfigurations(const std::list<CAreaConfiguration * > & areaConfigurationList)541 void CDomainConfiguration::reorderAreaConfigurations(const std::list<CAreaConfiguration*>& areaConfigurationList)
542 {
543     // Ensure elements in provided list appear first and ordered the same way in internal one
544 
545     // Remove all elements present in the provided list from the internal one
546     AreaConfigurationListIterator it;
547 
548     for (it = areaConfigurationList.begin(); it != areaConfigurationList.end(); ++it) {
549 
550         _orderedAreaConfigurationList.remove(*it);
551     }
552 
553     // Prepended provided elements into internal list
554     _orderedAreaConfigurationList.insert(_orderedAreaConfigurationList.begin(), areaConfigurationList.begin(), areaConfigurationList.end());
555 }
556 
557 // Find area configuration rank from regular list: for ordered list maintainance
getAreaConfigurationRank(const CAreaConfiguration * pAreaConfiguration) const558 uint32_t CDomainConfiguration::getAreaConfigurationRank(const CAreaConfiguration* pAreaConfiguration) const
559 {
560     uint32_t uiAreaConfigurationRank;
561     AreaConfigurationListIterator it;
562 
563     // Propagate request to areas
564     for (it = _areaConfigurationList.begin(), uiAreaConfigurationRank = 0; it != _areaConfigurationList.end(); ++it, ++uiAreaConfigurationRank) {
565 
566         if (*it == pAreaConfiguration) {
567 
568             return uiAreaConfigurationRank;
569         }
570     }
571 
572     assert(0);
573 
574     return 0;
575 }
576 
577 // Find area configuration from regular list based on rank: for ordered list maintainance
getAreaConfiguration(uint32_t uiAreaConfigurationRank) const578 CAreaConfiguration* CDomainConfiguration::getAreaConfiguration(uint32_t uiAreaConfigurationRank) const
579 {
580     AreaConfigurationListIterator it;
581     uint32_t uiCurrentAreaConfigurationRank;
582 
583     // Propagate request to areas
584     for (it = _areaConfigurationList.begin(), uiCurrentAreaConfigurationRank = 0; it != _areaConfigurationList.end(); ++it, ++uiCurrentAreaConfigurationRank) {
585 
586         if (uiCurrentAreaConfigurationRank == uiAreaConfigurationRank) {
587 
588             return *it;
589         }
590     }
591 
592     assert(0);
593 
594     return NULL;
595 }
596 
597 // Rule
getRule() const598 const CCompoundRule* CDomainConfiguration::getRule() const
599 {
600     if (getNbChildren()) {
601         // Rule created
602         return static_cast<const CCompoundRule*>(getChild(ECompoundRule));
603     }
604     return NULL;
605 }
606 
getRule()607 CCompoundRule* CDomainConfiguration::getRule()
608 {
609     if (getNbChildren()) {
610         // Rule created
611         return static_cast<CCompoundRule*>(getChild(ECompoundRule));
612     }
613     return NULL;
614 }
615 
setRule(CCompoundRule * pRule)616 void CDomainConfiguration::setRule(CCompoundRule* pRule)
617 {
618     CCompoundRule* pOldRule = getRule();
619 
620     if (pOldRule) {
621         // Remove previous rule
622         removeChild(pOldRule);
623 
624         delete pOldRule;
625     }
626 
627     // Set new one
628     if (pRule) {
629         // Chain
630         addChild(pRule);
631     }
632 }
633 
634 // Serialization
binarySerialize(CBinaryStream & binaryStream)635 void CDomainConfiguration::binarySerialize(CBinaryStream& binaryStream)
636 {
637     AreaConfigurationListIterator it;
638 
639     // Area configurations order
640     if (binaryStream.isOut()) {
641 
642         for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) {
643 
644             // Get rank
645             uint32_t uiAreaConfigurationRank = getAreaConfigurationRank(*it);
646 
647             // Store it
648             binaryStream.write((const uint8_t*)&uiAreaConfigurationRank, sizeof(uiAreaConfigurationRank));
649         }
650     } else {
651 
652         // Empty ordered list first
653         _orderedAreaConfigurationList.resize(0);
654 
655         uint32_t uiAreaConfiguration;
656 
657         for (uiAreaConfiguration = 0; uiAreaConfiguration < _areaConfigurationList.size(); uiAreaConfiguration++) {
658 
659             // Get rank
660             uint32_t uiAreaConfigurationRank;
661 
662             binaryStream.read((uint8_t*)&uiAreaConfigurationRank, sizeof(uiAreaConfigurationRank));
663 
664             _orderedAreaConfigurationList.push_back(getAreaConfiguration(uiAreaConfigurationRank));
665         }
666     }
667 
668     // Propagate to areas
669     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
670 
671         CAreaConfiguration* pAreaConfiguration = *it;
672 
673         pAreaConfiguration->serialize(binaryStream);
674     }
675 }
676 
677 // Data size
getDataSize() const678 size_t CDomainConfiguration::getDataSize() const
679 {
680     size_t uiDataSize;
681 
682     // Add necessary size to store area configurations order
683     uiDataSize = _areaConfigurationList.size() * sizeof(uint32_t);
684 
685     // Propagate request to areas
686     AreaConfigurationListIterator it;
687 
688     for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) {
689 
690         const CAreaConfiguration* pAreaConfiguration = *it;
691 
692         uiDataSize += pAreaConfiguration->getSize();
693     }
694     return uiDataSize;
695 }
696