1 /*
2  * Copyright (c) 2011-2015, 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 #pragma once
31 
32 #include "parameter_export.h"
33 
34 #include "Element.h"
35 
36 #include <list>
37 #include <vector>
38 
39 class CConfigurableDomain;
40 class CSyncerSet;
41 class ISyncer;
42 class CSubsystem;
43 class CConfigurationAccessContext;
44 class CParameterAccessContext;
45 class CAreaConfiguration;
46 
47 class PARAMETER_EXPORT CConfigurableElement : public CElement
48 {
49     friend class CConfigurableDomain;
50     friend class CDomainConfiguration;
51     typedef std::list<const CConfigurableDomain *>::const_iterator
52         ConfigurableDomainListConstIterator;
53 
54 public:
55     CConfigurableElement(const std::string &strName = "");
56     virtual ~CConfigurableElement() = default;
57 
58     // Offset in main blackboard
59     void setOffset(size_t offset);
60     size_t getOffset() const;
61 
62     // Allocation
63     virtual size_t getFootPrint() const;
64 
65     // Syncer set (me, ascendant or descendant ones)
66     void fillSyncerSet(CSyncerSet &syncerSet) const;
67 
68     // Belonging domain
69     bool belongsTo(const CConfigurableDomain *pConfigurableDomain) const;
70 
71     // Belonging domains
72     void listBelongingDomains(std::string &strResult, bool bVertical = true) const;
73 
74     // Matching check for domain association
75     bool hasNoDomainAssociated() const;
76 
77     // Matching check for no valid associated domains
78     bool hasNoValidDomainAssociated() const;
79 
80     // Owning domains
81     void listAssociatedDomains(std::string &strResult, bool bVertical = true) const;
82     size_t getBelongingDomainCount() const;
83 
84     // Elements with no domains
85     void listRogueElements(std::string &strResult) const;
86 
87     /** @return true if element is rogue, false otherwise
88      *
89      * An element is rogue if it is disjoint with all domains.
90      *
91      * Ie: An element is rogue if neither its descendants, ascendants
92      *     nor itself are associated with any domain.
93      *
94      * Ie: An element is *not* rogue if any of its descendants, ascendants
95      *     or itself are associated with at least one domain.
96      */
97     bool isRogue() const;
98 
99     // Footprint as string
100     std::string getFootprintAsString() const;
101 
102     // Belonging subsystem
103     virtual const CSubsystem *getBelongingSubsystem() const;
104 
105     // Check element is a parameter
106     virtual bool isParameter() const;
107 
108     // AreaConfiguration creation
109     virtual CAreaConfiguration *createAreaConfiguration(const CSyncerSet *pSyncerSet) const;
110 
111     // Parameter access
112     virtual bool accessValue(CPathNavigator &pathNavigator, std::string &strValue, bool bSet,
113                              CParameterAccessContext &parameterAccessContext) const;
114 
115     /** Gets the element as an array of bytes.
116      *
117      * This is like having a direct access to the blackboard.
118      *
119      * @param[out] bytes Where to store the result.
120      * @param[in] parameterAccessContext Context containing the blackboard to
121      *            read from.
122      */
123     void getSettingsAsBytes(std::vector<uint8_t> &bytes,
124                             CParameterAccessContext &parameterAccessContext) const;
125     /** Sets the element as if it was an array of bytes.
126      *
127      * This is like having a direct access to the blackboard.
128      *
129      * @param[out] bytes The content to be set.
130      * @param[in] parameterAccessContext Context containing the blackboard to
131      *            write to.
132      */
133     bool setSettingsAsBytes(const std::vector<uint8_t> &bytes,
134                             CParameterAccessContext &parameterAccessContext) const;
135 
136     /** @return List of all ConfigurableElements that have a mapping relevant in this context.
137      *          Ie: return self and CConfigurableElement ancestor of this node.
138      *
139      */
140     std::list<const CConfigurableElement *> getConfigurableElementContext() const;
141 
142     // Used for simulation and virtual subsystems
143     virtual void setDefaultValues(CParameterAccessContext &parameterAccessContext) const;
144 
145     // Element properties
146     virtual void showProperties(std::string &strResult) const;
147 
148     /**
149      * Get the value associated to a mapping key in the object's mapping
150      *
151      * @param[in] strKey the mapping key
152      * @param[out] pStrValue the associated value
153      *
154      * @return true if @p strKey is found in the object's mapping, false if not
155      */
156     virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const = 0;
157     /** Get the string representation of the mapping
158      *
159      * If applicable, amend values are applied to the leaf element.
160      */
161     virtual std::string getFormattedMapping() const = 0;
162 
163     // XML configuration settings parsing
164     virtual bool serializeXmlSettings(
165         CXmlElement &xmlConfigurationSettingsElementContent,
166         CConfigurationAccessContext &configurationAccessContext) const;
167 
168     bool fromXml(const CXmlElement &xmlElement,
169                  CXmlSerializingContext &serializingContext) override final;
170 
171     void toXml(CXmlElement &xmlElement,
172                CXmlSerializingContext &serializingContext) const override final;
173 
174     /** Deserialize the structure from xml. */
structureFromXml(const CXmlElement & xmlElement,CXmlSerializingContext & serializingContext)175     virtual bool structureFromXml(const CXmlElement &xmlElement,
176                                   CXmlSerializingContext &serializingContext)
177     {
178         // Forward to Element::fromXml.
179         // This is unfortunate as Element::fromXml will call back
180         // fromXml on each children.
181         // Thus on each non leaf node of the tree, the code will test if
182         // the setting or the structure are to be serialized.
183         // This test could be avoided by several ways including:
184         //  - split 2 roles fromXml in two function
185         //    1) construct the elements
186         //    2) recursive call on children
187         //  - dispatch in with a virtual method. This would not not remove
188         //    the branching rather hide it behind a virtual method override.
189         return CElement::fromXml(xmlElement, serializingContext);
190     }
191 
192     /** Serialize the structure to xml. */
structureToXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext)193     virtual void structureToXml(CXmlElement &xmlElement,
194                                 CXmlSerializingContext &serializingContext) const
195     {
196         // See structureFromXml implementation comment.
197         CElement::toXml(xmlElement, serializingContext);
198     }
199 
200 protected:
201     // Syncer (me or ascendant)
202     virtual ISyncer *getSyncer() const;
203     // Syncer set (descendant)
204     virtual void fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const;
205     // Configuration Domain local search
206     bool containsConfigurableDomain(const CConfigurableDomain *pConfigurableDomain) const;
207 
208 private:
209     // Content dumping. Override and stop further deriving: Configurable
210     // Elements should be called with the overloaded version taking a
211     // "Parameter Access Context" (The name is misleading as it is actually
212     // used to access any Configurable Element).
213     std::string logValue(utility::ErrorContext &errorContext) const override final;
214     virtual std::string logValue(CParameterAccessContext &context) const;
215 
216     // Configurable domain association
217     void addAttachedConfigurableDomain(const CConfigurableDomain *pConfigurableDomain);
218     void removeAttachedConfigurableDomain(const CConfigurableDomain *pConfigurableDomain);
219 
220     // Belonging domain ascending search
221     bool belongsToDomainAscending(const CConfigurableDomain *pConfigurableDomain) const;
222 
223     // Belonging domains
224     void getBelongingDomains(std::list<const CConfigurableDomain *> &configurableDomainList) const;
225     void listDomains(const std::list<const CConfigurableDomain *> &configurableDomainList,
226                      std::string &strResult, bool bVertical) const;
227 
228     // Check parent is still of current type (by structure knowledge)
229     bool isOfConfigurableElementType(const CElement *pParent) const;
230 
231     // Offset in main blackboard
232     size_t _offset{0};
233 
234     // Associated configurable domains
235     std::list<const CConfigurableDomain *> _configurableDomainList;
236 };
237