1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_ROSEN_XML_CONFIG_BASE_H
17 #define OHOS_ROSEN_XML_CONFIG_BASE_H
18 
19 #include <map>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23 
24 namespace OHOS {
25 namespace Rosen {
26 class XmlConfigBase {
27 public:
28     enum class ValueType {
29         UNDIFINED,
30         MAP,
31         BOOL,
32         STRING,
33         STRINGS,
34         INTS,
35         FLOATS,
36         POSITIVE_FLOATS,
37     };
38     struct ConfigItem {
39         std::map<std::string, ConfigItem>* property_ = nullptr;
40         ValueType type_ = ValueType::UNDIFINED;
41         union {
42             std::map<std::string, ConfigItem>* mapValue_ = nullptr;
43             bool boolValue_;
44             std::string stringValue_;
45             std::vector<int>* intsValue_;
46             std::vector<float>* floatsValue_;
47             std::vector<std::string>* stringsValue_;
48         };
ConfigItemConfigItem49         ConfigItem() {}
~ConfigItemConfigItem50         ~ConfigItem()
51         {
52             Destroy();
53         };
DestroyConfigItem54         void Destroy()
55         {
56             ClearValue();
57             if (property_) {
58                 delete property_;
59                 property_ = nullptr;
60             }
61         }
ClearValueConfigItem62         void ClearValue()
63         {
64             switch (type_) {
65                 case ValueType::MAP:
66                     delete mapValue_;
67                     mapValue_ = nullptr;
68                     break;
69                 case ValueType::STRING:
70                     stringValue_.~basic_string();
71                     break;
72                 case ValueType::INTS:
73                     delete intsValue_;
74                     intsValue_ = nullptr;
75                     break;
76                 case ValueType::FLOATS:
77                     delete floatsValue_;
78                     floatsValue_ = nullptr;
79                     break;
80                 case ValueType::STRINGS:
81                     delete stringsValue_;
82                     stringsValue_ = nullptr;
83                     break;
84                 default:
85                     break;
86             }
87         }
ConfigItemConfigItem88         ConfigItem(const ConfigItem& value)
89         {
90             *this = value;
91         }
92         ConfigItem& operator=(const ConfigItem& value)
93         {
94             Destroy();
95             switch (value.type_) {
96                 case ValueType::MAP:
97                     mapValue_ = new std::map<std::string, ConfigItem>(*value.mapValue_);
98                     break;
99                 case ValueType::BOOL:
100                     boolValue_ = value.boolValue_;
101                     break;
102                 case ValueType::STRING:
103                     new(&stringValue_)std::string(value.stringValue_);
104                     break;
105                 case ValueType::INTS:
106                     intsValue_ = new std::vector<int>(*value.intsValue_);
107                     break;
108                 case ValueType::FLOATS:
109                     floatsValue_ = new std::vector<float>(*value.floatsValue_);
110                     break;
111                 case ValueType::STRINGS:
112                     stringsValue_ = new std::vector<std::string>(*value.stringsValue_);
113                     break;
114                 default:
115                     break;
116             }
117             type_ = value.type_;
118             if (value.property_) {
119                 property_ = new std::map<std::string, ConfigItem>(*value.property_);
120             }
121             return *this;
122         }
ConfigItemConfigItem123         ConfigItem(ConfigItem&& value) noexcept
124         {
125             *this = std::move(value);
126         }
127         ConfigItem& operator=(ConfigItem&& value) noexcept
128         {
129             Destroy();
130             switch (value.type_) {
131                 case ValueType::MAP:
132                     mapValue_ = value.mapValue_;
133                     value.mapValue_ = nullptr;
134                     break;
135                 case ValueType::BOOL:
136                     boolValue_ = value.boolValue_;
137                     break;
138                 case ValueType::STRING:
139                     new(&stringValue_)std::string(std::move(value.stringValue_));
140                     break;
141                 case ValueType::INTS:
142                     intsValue_ = value.intsValue_;
143                     value.intsValue_ = nullptr;
144                     break;
145                 case ValueType::FLOATS:
146                     floatsValue_ = value.floatsValue_;
147                     value.floatsValue_ = nullptr;
148                     break;
149                 case ValueType::STRINGS:
150                     stringsValue_ = value.stringsValue_;
151                     value.stringsValue_ = nullptr;
152                     break;
153                 default:
154                     break;
155             }
156             type_ = value.type_;
157             property_ = value.property_;
158             value.type_ = ValueType::UNDIFINED;
159             value.property_ = nullptr;
160             return *this;
161         }
SetPropertyConfigItem162         void SetProperty(const std::map<std::string, ConfigItem>& prop)
163         {
164             if (property_) {
165                 delete property_;
166             }
167             property_ = new std::map<std::string, ConfigItem>(prop);
168         }
169         // set map value
SetValueConfigItem170         void SetValue(const std::map<std::string, ConfigItem>& value)
171         {
172             ClearValue();
173             type_ = ValueType::MAP;
174             mapValue_ = new std::map<std::string, ConfigItem>(value);
175         }
176         // set bool value
SetValueConfigItem177         void SetValue(bool value)
178         {
179             ClearValue();
180             type_ = ValueType::BOOL;
181             boolValue_ = value;
182         }
183         // set string value
SetValueConfigItem184         void SetValue(const std::string& value)
185         {
186             ClearValue();
187             type_ = ValueType::STRING;
188             new(&stringValue_)std::string(value);
189         }
190         // set ints value
SetValueConfigItem191         void SetValue(const std::vector<int>& value)
192         {
193             ClearValue();
194             type_ = ValueType::INTS;
195             intsValue_ = new std::vector<int>(value);
196         }
197         // set floats value
SetValueConfigItem198         void SetValue(const std::vector<float>& value)
199         {
200             ClearValue();
201             type_ = ValueType::FLOATS;
202             floatsValue_ = new std::vector<float>(value);
203         }
204         // set strings value
SetValueConfigItem205         void SetValue(const std::vector<std::string>& value)
206         {
207             ClearValue();
208             type_ = ValueType::STRINGS;
209             stringsValue_ = new std::vector<std::string>(value);
210         }
IsIntsConfigItem211         bool IsInts() const
212         {
213             return type_ == ValueType::INTS;
214         }
IsFloatsConfigItem215         bool IsFloats() const
216         {
217             return type_ == ValueType::FLOATS;
218         }
IsStringConfigItem219         bool IsString() const
220         {
221             return type_ == ValueType::STRING;
222         }
IsStringsConfigItem223         bool IsStrings() const
224         {
225             return type_ == ValueType::STRINGS;
226         }
IsBoolConfigItem227         bool IsBool() const
228         {
229             return type_ == ValueType::BOOL;
230         }
IsMapConfigItem231         bool IsMap() const
232         {
233             return type_ == ValueType::MAP;
234         }
235         const ConfigItem& operator[](const std::string& key) const
236         {
237             if (type_ != ValueType::MAP) {
238                 return DEFAULT;
239             }
240             if (mapValue_->count(key) == 0) {
241                 return DEFAULT;
242             }
243             return mapValue_->at(key);
244         }
GetPropConfigItem245         const ConfigItem& GetProp(const std::string& key) const
246         {
247             if (!property_) {
248                 return DEFAULT;
249             }
250             if (property_->count(key) == 0) {
251                 return DEFAULT;
252             }
253             return property_->at(key);
254         }
255         static const ConfigItem DEFAULT;
256     };
257     static std::recursive_mutex mutex_;
258 };
259 } // namespace Rosen
260 } // namespace OHOS
261 
262 #endif // OHOS_ROSEN_XML_CONFIG_BASE_H