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, const std::string& prefix)
37 : mStorePtr(new KVStore(db))
40 mObject = json_tokener_parse(json.c_str());
41 if (mObject == nullptr) {
42 throw ConfigException("Json parsing error");
46 ~FromKVJsonVisitor() {
47 json_object_put(mObject);
50 FromKVJsonVisitor(const FromKVJsonVisitor& v) :
51 mObject(json_object_get(v.mObject)),
52 mStorePtr(v.mStorePtr),
53 mKeyPrefix(v.mKeyPrefix)
56 FromKVJsonVisitor& operator=(const FromKVJsonVisitor&) = delete;
59 void visit(const std::string& name, T& value) {
60 getValue(name, value);
64 std::shared_ptr<KVStore> mStorePtr;
65 std::string mKeyPrefix;
68 // create visitor for field object (visitable object)
69 FromKVJsonVisitor(const FromKVJsonVisitor& v, const std::string& name) :
70 mStorePtr(v.mStorePtr)
73 if (!json_object_object_get_ex(v.mObject, name.c_str(), &object)) {
74 throw ConfigException("Missing json field " + key(mKeyPrefix, name));
76 mObject = json_object_get(object);
77 mKeyPrefix = key(v.mKeyPrefix, name);
80 // create visitor for vector i-th element (visitable object)
81 FromKVJsonVisitor(const FromKVJsonVisitor& v, int i) :
82 mStorePtr(v.mStorePtr)
84 json_object* object = json_object_array_get_idx(v.mObject, i);
85 checkType(object, json_type_object);
86 mObject = json_object_get(object);
87 mKeyPrefix = key(v.mKeyPrefix, std::to_string(i));
90 template<typename T, typename std::enable_if<!isVisitable<T>::value, int>::type = 0>
91 void getValue(const std::string& name, T& t)
94 if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
95 throw ConfigException("Missing json field " + key(mKeyPrefix, name));
97 std::string k = key(mKeyPrefix, name);
98 if (mStorePtr->exists(k)) {
99 t = mStorePtr->get<T>(k);
102 fromJsonObject(object, t);
106 template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
107 void getValue(const std::string& name, T& t)
109 FromKVJsonVisitor visitor(*this, name);
113 int getArraySize(std::string& name, json_object* object)
115 if (mStorePtr->exists(name)) {
116 return mStorePtr->get<int>(name);
118 return json_object_array_length(object);
122 void getValue(const std::string& name, std::vector<T>& value)
125 if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
126 throw ConfigException("Missing json field " + key(mKeyPrefix, name));
128 checkType(object, json_type_array);
130 std::string k = key(mKeyPrefix, name);
131 int length = getArraySize(k, object);
132 value.resize(static_cast<size_t>(length));
133 FromKVJsonVisitor visitor(*this, name);
134 for (int i = 0; i < length; ++i) {
135 visitor.getValue(i, value[i]);
139 template<typename T, typename std::enable_if<!isVisitable<T>::value, int>::type = 0>
140 void getValue(int i, T& t)
142 json_object* object = json_object_array_get_idx(mObject, i);
143 std::string k = key(mKeyPrefix, std::to_string(i));
144 if (mStorePtr->exists(k)) {
145 t = mStorePtr->get<T>(k);
148 fromJsonObject(object, t);
152 template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
153 void getValue(int i, T& t)
155 FromKVJsonVisitor visitor(*this, i);
160 void getValue(int i, std::vector<T>& value)
162 std::string k = key(mKeyPrefix, std::to_string(i));
163 int length = getArraySize(k, mObject);
164 value.resize(static_cast<size_t>(length));
165 FromKVJsonVisitor visitor(*this, i);
166 for (int i = 0; i < length; ++i) {
167 visitor.getValue(i, value[i]);
171 static void checkType(json_object* object, json_type type)
173 if (type != json_object_get_type(object)) {
174 throw ConfigException("Invalid field type " + std::to_string(type));
178 static void fromJsonObject(json_object* object, int& value)
180 checkType(object, json_type_int);
181 std::int64_t value64 = json_object_get_int64(object);
182 if (value64 > INT32_MAX || value64 < INT32_MIN) {
183 throw ConfigException("Value out of range");
185 value = static_cast<int>(value64);
188 static void fromJsonObject(json_object* object, std::int64_t& value)
190 checkType(object, json_type_int);
191 value = json_object_get_int64(object);
194 static void fromJsonObject(json_object* object, bool& value)
196 checkType(object, json_type_boolean);
197 value = json_object_get_boolean(object);
200 static void fromJsonObject(json_object* object, double& value)
202 checkType(object, json_type_double);
203 value = json_object_get_double(object);
206 static void fromJsonObject(json_object* object, std::string& value)
208 checkType(object, json_type_string);
209 value = json_object_get_string(object);
213 } // namespace config
215 #endif // CONFIG_FROM_KVJSON_VISITOR_HPP