Added GVariant visitor
[archive/platform/core/system/libConfig.git] / src / config / manager.hpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file
21  * @author  Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
22  * @brief   Configuration management functions
23  */
24
25 #ifndef CONFIG_MANAGER_HPP
26 #define CONFIG_MANAGER_HPP
27
28 #include "config/to-gvariant-visitor.hpp"
29 #include "config/to-json-visitor.hpp"
30 #include "config/to-kvstore-visitor.hpp"
31 #include "config/to-fdstore-visitor.hpp"
32 #include "config/from-gvariant-visitor.hpp"
33 #include "config/from-json-visitor.hpp"
34 #include "config/from-kvstore-visitor.hpp"
35 #include "config/from-fdstore-visitor.hpp"
36 #include "config/from-kvjson-visitor.hpp"
37 #include "config/fs-utils.hpp"
38 #include "config/is-union.hpp"
39
40 namespace config {
41
42 /**
43  * Fills the configuration with data stored in the GVariant
44  *
45  * @param gvariant   configuration in GVariant type
46  * @param config     visitable structure to fill
47  */
48 template <class Config>
49 void loadFromGVariant(GVariant* gvariant, Config& config)
50 {
51     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
52     static_assert(!isUnion<Config>::value, "Don't use CONFIG_DECLARE_UNION in top level config");
53
54     FromGVariantVisitor visitor(gvariant);
55     config.accept(visitor);
56 }
57
58 /**
59  * Saves the config in a GVariant
60  *
61  * @param config   visitable structure to convert
62  */
63 template <class Config>
64 GVariant* saveToGVariant(const Config& config)
65 {
66     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
67     static_assert(!isUnion<Config>::value, "Don't use CONFIG_DECLARE_UNION in top level config");
68
69     ToGVariantVisitor visitor;
70     config.accept(visitor);
71     return visitor.toVariant();
72 }
73
74 /**
75  * Fills the configuration with data stored in the json string
76  *
77  * @param jsonString configuration in a json format
78  * @param config     visitable structure to fill
79  */
80 template <class Config>
81 void loadFromJsonString(const std::string& jsonString, Config& config)
82 {
83     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
84
85     FromJsonVisitor visitor(jsonString);
86     config.accept(visitor);
87 }
88
89 /**
90  * Creates a string representation of the configuration in json format
91  *
92  * @param config   visitable structure to convert
93  */
94 template <class Config>
95 std::string saveToJsonString(const Config& config)
96 {
97     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
98
99     ToJsonVisitor visitor;
100     config.accept(visitor);
101     return visitor.toString();
102 }
103
104 /**
105  * Loads the config from a json file
106  *
107  * @param filename path to the file
108  * @param config   visitable structure to load
109  */
110 template <class Config>
111 void loadFromJsonFile(const std::string& filename, Config& config)
112 {
113     std::string content;
114     if (!fsutils::readFileContent(filename, content)) {
115         throw ConfigException("Could not load " + filename);
116     }
117     try {
118         loadFromJsonString(content, config);
119     } catch (ConfigException& e) {
120         throw ConfigException("Error in " + filename + ": " + e.what());
121     }
122 }
123
124 /**
125  * Saves the config in a json file
126  *
127  * @param filename path to the file
128  * @param config   visitable structure to save
129  */
130 template <class Config>
131 void saveToJsonFile(const std::string& filename, const Config& config)
132 {
133     const std::string content = saveToJsonString(config);
134     if (!fsutils::saveFileContent(filename, content)) {
135         throw ConfigException("Could not save " + filename);
136     }
137 }
138
139 /**
140  * Loads a visitable configuration from KVStore.
141  *
142  * @param filename   path to the KVStore db
143  * @param config     visitable structure to load
144  * @param configName name of the configuration inside the KVStore db
145  */
146 template <class Config>
147 void loadFromKVStore(const std::string& filename, Config& config, const std::string& configName)
148 {
149     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
150
151     KVStore store(filename);
152     KVStore::Transaction transaction(store);
153     FromKVStoreVisitor visitor(store, configName);
154     config.accept(visitor);
155     transaction.commit();
156 }
157
158 /**
159  * Saves the config to a KVStore.
160  *
161  * @param filename   path to the KVStore db
162  * @param config     visitable structure to save
163  * @param configName name of the config inside the KVStore db
164  */
165 template <class Config>
166 void saveToKVStore(const std::string& filename, const Config& config, const std::string& configName)
167 {
168     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
169
170     KVStore store(filename);
171     KVStore::Transaction transaction(store);
172     ToKVStoreVisitor visitor(store, configName);
173     config.accept(visitor);
174     transaction.commit();
175 }
176
177 /**
178  * Load the config from KVStore with defaults given in json
179  *
180  * @param kvfile    path to the KVStore db
181  * @param jsonfile  path to json file with defaults
182  * @param config    visitable structure to save
183  * @param kvConfigName name of the config inside the KVStore db
184  */
185 template <class Config>
186 void loadFromKVStoreWithJson(const std::string& kvfile,
187                              const std::string& json,
188                              Config& config,
189                              const std::string& kvConfigName)
190 {
191     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
192
193     KVStore store(kvfile);
194     KVStore::Transaction transaction(store);
195     FromKVJsonVisitor visitor(store, json, kvConfigName);
196     config.accept(visitor);
197     transaction.commit();
198 }
199
200 /**
201  * Load the config from KVStore with defaults given in json file
202  *
203  * @param kvfile    path to the KVStore db
204  * @param jsonfile  path to json file with defaults
205  * @param config    visitable structure to save
206  * @param kvConfigName name of the config inside the KVStore db
207  */
208 template <class Config>
209 void loadFromKVStoreWithJsonFile(const std::string& kvfile,
210                                  const std::string& jsonfile,
211                                  Config& config,
212                                  const std::string& kvConfigName)
213 {
214     std::string content;
215     if (!fsutils::readFileContent(jsonfile, content)) {
216         throw ConfigException("Could not load " + jsonfile);
217     }
218     try {
219         loadFromKVStoreWithJson(kvfile, content, config, kvConfigName);
220     } catch (ConfigException& e) {
221         throw ConfigException("Error in " + jsonfile + ": " + e.what());
222     }
223 }
224
225 /**
226  * Load binary data from a file/socket/pipe represented by the fd
227  *
228  * @param fd file descriptor
229  * @param config visitable structure to load
230  */
231 template <class Config>
232 void loadFromFD(const int fd, Config& config)
233 {
234     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
235
236     FromFDStoreVisitor visitor(fd);
237     config.accept(visitor);
238 }
239
240 /**
241  * Save binary data to a file/socket/pipe represented by the fd
242  *
243  * @param fd file descriptor
244  * @param config visitable structure to save
245  */
246 template <class Config>
247 void saveToFD(const int fd, const Config& config)
248 {
249     static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
250
251     ToFDStoreVisitor visitor(fd);
252     config.accept(visitor);
253 }
254
255 } // namespace config
256
257 #endif // CONFIG_MANAGER_HPP