2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Mateusz Malicki (m.malicki2@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 Mateusz Malicki (m.malicki2@samsung.com)
22 * @brief GVariant visitor
25 #ifndef CONFIG_FROM_GVARIANT_VISITOR_HPP
26 #define CONFIG_FROM_GVARIANT_VISITOR_HPP
28 #include "config/is-visitable.hpp"
29 #include "config/exception.hpp"
30 #include "config/is-union.hpp"
39 class FromGVariantVisitor {
41 explicit FromGVariantVisitor(GVariant* variant)
43 //Assume that the visited object is not a union
44 checkType(variant, G_VARIANT_TYPE_TUPLE);
45 mIter = g_variant_iter_new(variant);
48 FromGVariantVisitor(const FromGVariantVisitor& visitor)
49 : mIter(g_variant_iter_copy(visitor.mIter))
53 ~FromGVariantVisitor()
55 g_variant_iter_free(mIter);
58 FromGVariantVisitor& operator=(const FromGVariantVisitor&) = delete;
61 void visit(const std::string& name, T& value)
63 GVariant* child = g_variant_iter_next_value(mIter);
65 throw config::ConfigException(
66 "GVariant doesn't match with config. Can't set '" + name + "'");
68 fromGVariant(child, value);
69 g_variant_unref(child);
75 explicit FromGVariantVisitor(GVariant* variant, bool isUnion)
78 checkType(variant, G_VARIANT_TYPE_VARIANT);
79 variant = g_variant_get_variant(variant);
81 checkType(variant, G_VARIANT_TYPE_TUPLE);
82 mIter = g_variant_iter_new(variant);
85 static void checkType(GVariant* object, const GVariantType* type)
87 if (!g_variant_is_of_type(object, type)) {
88 throw ConfigException("Invalid field type");
92 static void fromGVariant(GVariant* object, int& value)
94 checkType(object, G_VARIANT_TYPE_INT32);
95 value = g_variant_get_int32(object);
98 static void fromGVariant(GVariant* object, std::int64_t& value)
100 checkType(object, G_VARIANT_TYPE_INT64);
101 value = g_variant_get_int64(object);
104 static void fromGVariant(GVariant* object, bool& value)
106 checkType(object, G_VARIANT_TYPE_BOOLEAN);
107 value = g_variant_get_boolean(object);
110 static void fromGVariant(GVariant* object, double& value)
112 checkType(object, G_VARIANT_TYPE_DOUBLE);
113 value = g_variant_get_double(object);
116 static void fromGVariant(GVariant* object, std::string& value)
118 checkType(object, G_VARIANT_TYPE_STRING);
119 value = g_variant_get_string(object, NULL);
123 static void fromGVariant(GVariant* object, std::vector<T>& value)
125 checkType(object, G_VARIANT_TYPE_ARRAY);
127 g_variant_iter_init(&iter, object);
128 int length = g_variant_iter_n_children(&iter);
129 value.resize(static_cast<size_t>(length));
130 for (int i = 0; i < length; ++i) {
131 GVariant* child = g_variant_iter_next_value(&iter);
132 assert(child != NULL);
133 fromGVariant(child, value[static_cast<size_t>(i)]);
134 g_variant_unref(child);
139 static typename std::enable_if<isVisitable<T>::value>::type
140 fromGVariant(GVariant* object, T& value)
142 FromGVariantVisitor visitor(object, isUnion<T>::value);
143 value.accept(visitor);
148 } // namespace config
150 #endif // CONFIG_FROM_GVARIANT_VISITOR_HPP