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 int length = -1, jlength = json_object_array_length(object);
115 if (mStorePtr->exists(name)) {
116 length = mStorePtr->get<int>(name);
118 return length != jlength ? jlength : length;
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