2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
21 * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
25 #ifndef CONFIG_FROM_JSON_VISITOR_HPP
26 #define CONFIG_FROM_JSON_VISITOR_HPP
28 #include "config/is-visitable.hpp"
29 #include "config/exception.hpp"
31 #include <json/json.h>
37 class FromJsonVisitor {
39 explicit FromJsonVisitor(const std::string& jsonString)
42 mObject = json_tokener_parse(jsonString.c_str());
43 if (mObject == nullptr) {
44 throw ConfigException("Json parsing error");
48 FromJsonVisitor(const FromJsonVisitor& visitor)
49 : mObject(json_object_get(visitor.mObject))
55 json_object_put(mObject);
59 void visit(const std::string& name, T& value)
61 json_object* object = nullptr;
62 if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
63 throw ConfigException("Missing field '" + name + "'");
65 fromJsonObject(object, value);
71 FromJsonVisitor& operator=(const FromJsonVisitor&) = delete;
73 explicit FromJsonVisitor(json_object* object)
74 : mObject(json_object_get(object))
78 static void checkType(json_object* object, json_type type)
80 if (type != json_object_get_type(object)) {
81 throw ConfigException("Invalid field type");
85 static void fromJsonObject(json_object* object, int& value)
87 checkType(object, json_type_int);
88 std::int64_t value64 = json_object_get_int64(object);
89 if (value64 > INT32_MAX || value64 < INT32_MIN) {
90 throw ConfigException("Value out of range");
92 value = static_cast<int>(value64);
95 static void fromJsonObject(json_object* object, std::int64_t& value)
97 checkType(object, json_type_int);
98 value = json_object_get_int64(object);
101 static void fromJsonObject(json_object* object, bool& value)
103 checkType(object, json_type_boolean);
104 value = json_object_get_boolean(object);
107 static void fromJsonObject(json_object* object, double& value)
109 checkType(object, json_type_double);
110 value = json_object_get_double(object);
113 static void fromJsonObject(json_object* object, std::string& value)
115 checkType(object, json_type_string);
116 value = json_object_get_string(object);
120 static void fromJsonObject(json_object* object, std::vector<T>& value)
122 checkType(object, json_type_array);
123 int length = json_object_array_length(object);
124 value.resize(static_cast<size_t>(length));
125 for (int i = 0; i < length; ++i) {
126 fromJsonObject(json_object_array_get_idx(object, i), value[static_cast<size_t>(i)]);
130 template<class T, class = typename std::enable_if<isVisitable<T>::value>::type>
131 static void fromJsonObject(json_object* object, T& value)
133 checkType(object, json_type_object);
134 FromJsonVisitor visitor(object);
135 value.accept(visitor);
139 } // namespace config
141 #endif // CONFIG_FROM_JSON_VISITOR_HPP