1 #ifndef CONFIG_FROM_KVJSON_VISITOR_HPP
2 #define CONFIG_FROM_KVJSON_VISITOR_HPP
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
7 * Contact: Krzysztof Dynowski (k.dynowski@samsumg.com)
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License
25 * @author Krzysztof Dynowski (k.dynowski@samsumg.com)
26 * @brief KVStore visitor with defaults values from json
29 #include "config/manager.hpp"
34 class FromKVJsonVisitor {
36 FromKVJsonVisitor(const std::string& db, const std::string& json) :
37 mStorePtr(new KVStore(db))
39 mObject = json_tokener_parse(json.c_str());
40 if (mObject == nullptr) {
41 throw ConfigException("Json parsing error");
45 ~FromKVJsonVisitor() {
46 json_object_put(mObject);
49 FromKVJsonVisitor(const FromKVJsonVisitor& v) :
50 mObject(json_object_get(v.mObject)),
51 mStorePtr(v.mStorePtr),
52 mKeyPrefix(v.mKeyPrefix)
55 FromKVJsonVisitor& operator=(const FromKVJsonVisitor&) = delete;
58 void visit(const std::string& name, T& value) {
59 getValue(name, value);
63 std::shared_ptr<KVStore> mStorePtr;
64 std::string mKeyPrefix;
67 // create visitor for field object (visitable object)
68 FromKVJsonVisitor(const FromKVJsonVisitor& v, const std::string& name) :
69 mStorePtr(v.mStorePtr)
72 if (!json_object_object_get_ex(v.mObject, name.c_str(), &object)) {
73 throw ConfigException("Missing json field " + key(mKeyPrefix, name));
75 mObject = json_object_get(object);
76 mKeyPrefix = key(v.mKeyPrefix, name);
79 // create visitor for vector i-th element (visitable object)
80 FromKVJsonVisitor(const FromKVJsonVisitor& v, int i) :
81 mStorePtr(v.mStorePtr)
83 json_object* object = json_object_array_get_idx(v.mObject, i);
84 checkType(object, json_type_object);
85 mObject = json_object_get(object);
86 mKeyPrefix = key(v.mKeyPrefix, std::to_string(i));
89 template<typename T, typename std::enable_if<!isVisitable<T>::value, int>::type = 0>
90 void getValue(const std::string& name, T& t)
93 if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
94 throw ConfigException("Missing json field " + key(mKeyPrefix, name));
96 std::string k = key(mKeyPrefix, name);
97 if (mStorePtr->exists(k)) {
98 t = mStorePtr->get<T>(k);
101 fromJsonObject(object, t);
105 template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
106 void getValue(const std::string& name, T& t)
108 FromKVJsonVisitor visitor(*this, name);
112 int getArraySize(std::string& name, json_object* object)
114 if (mStorePtr->exists(name)) {
115 return mStorePtr->get<int>(name);
117 return json_object_array_length(object);
121 void getValue(const std::string& name, std::vector<T>& value)
124 if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
125 throw ConfigException("Missing json field " + key(mKeyPrefix, name));
127 checkType(object, json_type_array);
129 std::string k = key(mKeyPrefix, name);
130 int length = getArraySize(k, object);
131 value.resize(static_cast<size_t>(length));
132 FromKVJsonVisitor visitor(*this, name);
133 for (int i = 0; i < length; ++i) {
134 visitor.getValue(i, value[i]);
138 template<typename T, typename std::enable_if<!isVisitable<T>::value, int>::type = 0>
139 void getValue(int i, T& t)
141 json_object* object = json_object_array_get_idx(mObject, i);
142 std::string k = key(mKeyPrefix, std::to_string(i));
143 if (mStorePtr->exists(k)) {
144 t = mStorePtr->get<T>(k);
147 fromJsonObject(object, t);
151 template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
152 void getValue(int i, T& t)
154 FromKVJsonVisitor visitor(*this, i);
159 void getValue(int i, std::vector<T>& value)
161 std::string k = key(mKeyPrefix, std::to_string(i));
162 int length = getArraySize(k, mObject);
163 value.resize(static_cast<size_t>(length));
164 FromKVJsonVisitor visitor(*this, i);
165 for (int i = 0; i < length; ++i) {
166 visitor.getValue(i, value[i]);
170 static void checkType(json_object* object, json_type type)
172 if (type != json_object_get_type(object)) {
173 throw ConfigException("Invalid field type " + std::to_string(type));
177 static void fromJsonObject(json_object* object, int& value)
179 checkType(object, json_type_int);
180 std::int64_t value64 = json_object_get_int64(object);
181 if (value64 > INT32_MAX || value64 < INT32_MIN) {
182 throw ConfigException("Value out of range");
184 value = static_cast<int>(value64);
187 static void fromJsonObject(json_object* object, std::int64_t& value)
189 checkType(object, json_type_int);
190 value = json_object_get_int64(object);
193 static void fromJsonObject(json_object* object, bool& value)
195 checkType(object, json_type_boolean);
196 value = json_object_get_boolean(object);
199 static void fromJsonObject(json_object* object, double& value)
201 checkType(object, json_type_double);
202 value = json_object_get_double(object);
205 static void fromJsonObject(json_object* object, std::string& value)
207 checkType(object, json_type_string);
208 value = json_object_get_string(object);
212 } // namespace config
214 #endif // CONFIG_FROM_KVJSON_VISITOR_HPP