Support for uints
[archive/platform/core/system/libConfig.git] / src / config / to-gvariant-visitor.hpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Mateusz Malicki (m.malicki2@samsung.com)
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  */
18
19 /**
20  * @file
21  * @author  Mateusz Malicki (m.malicki2@samsung.com)
22  * @brief   GVariant visitor
23  */
24
25 #ifndef CONFIG_TO_GVARIANT_VISITOR_HPP
26 #define CONFIG_TO_GVARIANT_VISITOR_HPP
27
28 #include "config/is-visitable.hpp"
29 #include "config/is-union.hpp"
30
31 #include <string>
32 #include <vector>
33 #include <glib.h>
34
35 namespace config {
36
37 class ToGVariantVisitor {
38
39 public:
40     ToGVariantVisitor()
41         : mBuilder(g_variant_builder_new(G_VARIANT_TYPE_TUPLE))
42     {
43     }
44
45     ToGVariantVisitor(const ToGVariantVisitor& visitor)
46         : mBuilder(visitor.mBuilder ? g_variant_builder_ref(visitor.mBuilder) : nullptr)
47     {
48     }
49
50     ~ToGVariantVisitor()
51     {
52         if (mBuilder) {
53             g_variant_builder_unref(mBuilder);
54         }
55     }
56
57     ToGVariantVisitor& operator=(const ToGVariantVisitor&) = delete;
58
59     GVariant* toVariant()
60     {
61         if (mBuilder) {
62             GVariant* ret = g_variant_builder_end(mBuilder);
63             g_variant_builder_unref(mBuilder);
64             mBuilder = nullptr;
65             return ret;
66         }
67         return nullptr;
68     }
69
70     template<typename T>
71     void visit(const std::string& /* name */, const T& value)
72     {
73         writeInternal(value);
74     }
75 private:
76     GVariantBuilder* mBuilder;
77
78     void writeInternal(std::int32_t value) { add("i", value); };
79     void writeInternal(std::int64_t value) { add("x", value); };
80     void writeInternal(std::uint32_t value) { add("u", value); };
81     void writeInternal(std::uint64_t value) { add("t", value); };
82     void writeInternal(bool value) { add("b", value); };
83     void writeInternal(double value) { add("d", value); };
84     void writeInternal(const std::string& value) { add("s", value.c_str()); };
85
86     template<typename T>
87     void writeInternal(const std::vector<T>& value)
88     {
89         if (!value.empty()) {
90             g_variant_builder_open(mBuilder, G_VARIANT_TYPE_ARRAY);
91             for (const T& v : value) {
92                 writeInternal(v);
93             }
94             g_variant_builder_close(mBuilder);
95         } else {
96             g_variant_builder_add(mBuilder, "as", NULL);
97         }
98     }
99
100     template<typename T>
101     typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value>::type
102     writeInternal(const T& value)
103     {
104         ToGVariantVisitor visitor;
105         value.accept(visitor);
106         g_variant_builder_add_value(mBuilder, visitor.toVariant());
107     }
108
109     template<typename T>
110     typename std::enable_if<isVisitable<T>::value && isUnion<T>::value>::type
111     writeInternal(const T& value)
112     {
113         ToGVariantVisitor visitor;
114         value.accept(visitor);
115         add("v", visitor.toVariant());
116     }
117
118     template<typename Value>
119     void add(const char* type, Value value) {
120         g_variant_builder_add(mBuilder, type, value);
121     }
122 };
123
124 } // namespace config
125
126 #endif // CONFIG_TO_GVARIANT_VISITOR_HPP