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);
58 FromJsonVisitor& operator=(const FromJsonVisitor&) = delete;
61 void visit(const std::string& name, T& value)
63 json_object* object = nullptr;
64 if (!json_object_object_get_ex(mObject, name.c_str(), &object)) {
65 throw ConfigException("Missing field '" + name + "'");
67 fromJsonObject(object, value);
74 explicit FromJsonVisitor(json_object* object)
75 : mObject(json_object_get(object))
79 static void checkType(json_object* object, json_type type)
81 if (type != json_object_get_type(object)) {
82 throw ConfigException("Invalid field type");
86 static void fromJsonObject(json_object* object, std::int32_t& value)
88 checkType(object, json_type_int);
89 std::int64_t value64 = json_object_get_int64(object);
90 if (value64 > INT32_MAX || value64 < INT32_MIN) {
91 throw ConfigException("Value out of range");
93 value = static_cast<std::int32_t>(value64);
96 static void fromJsonObject(json_object* object, std::uint32_t& value)
98 checkType(object, json_type_int);
99 std::int64_t value64 = json_object_get_int64(object);
100 if (value64 > UINT32_MAX || value64 < 0) {
101 throw ConfigException("Value out of range");
103 value = static_cast<std::uint32_t>(value64);
106 static void fromJsonObject(json_object* object, std::int64_t& value)
108 checkType(object, json_type_int);
109 value = json_object_get_int64(object);
112 static void fromJsonObject(json_object* object, std::uint64_t& value)
114 checkType(object, json_type_int);
115 std::int64_t value64 = json_object_get_int64(object);
117 throw ConfigException("Value out of range");
119 value = static_cast<std::uint64_t>(value64);
122 static void fromJsonObject(json_object* object, bool& value)
124 checkType(object, json_type_boolean);
125 value = json_object_get_boolean(object);
128 static void fromJsonObject(json_object* object, double& value)
130 checkType(object, json_type_double);
131 value = json_object_get_double(object);
134 static void fromJsonObject(json_object* object, std::string& value)
136 checkType(object, json_type_string);
137 value = json_object_get_string(object);
141 static void fromJsonObject(json_object* object, std::vector<T>& value)
143 checkType(object, json_type_array);
144 int length = json_object_array_length(object);
145 value.resize(static_cast<size_t>(length));
146 for (int i = 0; i < length; ++i) {
147 fromJsonObject(json_object_array_get_idx(object, i), value[static_cast<size_t>(i)]);
151 template<typename T, class = typename std::enable_if<isVisitable<T>::value>::type>
152 static void fromJsonObject(json_object* object, T& value)
154 checkType(object, json_type_object);
155 FromJsonVisitor visitor(object);
156 value.accept(visitor);
160 } // namespace config
162 #endif // CONFIG_FROM_JSON_VISITOR_HPP