e8476fcdc21b9a5581f98a918f4a73ee98cce798
[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(bool value) { add("b", value); };
81     void writeInternal(double value) { add("d", value); };
82     void writeInternal(const std::string& value) { add("s", value.c_str()); };
83
84     template<typename T>
85     void writeInternal(const std::vector<T>& value)
86     {
87         if (!value.empty()) {
88             g_variant_builder_open(mBuilder, G_VARIANT_TYPE_ARRAY);
89             for (const T& v : value) {
90                 writeInternal(v);
91             }
92             g_variant_builder_close(mBuilder);
93         } else {
94             g_variant_builder_add(mBuilder, "as", NULL);
95         }
96     }
97
98     template<typename T>
99     typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value>::type
100     writeInternal(const T& value)
101     {
102         ToGVariantVisitor visitor;
103         value.accept(visitor);
104         g_variant_builder_add_value(mBuilder, visitor.toVariant());
105     }
106
107     template<typename T>
108     typename std::enable_if<isVisitable<T>::value && isUnion<T>::value>::type
109     writeInternal(const T& value)
110     {
111         ToGVariantVisitor visitor;
112         value.accept(visitor);
113         add("v", visitor.toVariant());
114     }
115
116     template<typename Value>
117     void add(const char* type, Value value) {
118         g_variant_builder_add(mBuilder, type, value);
119     }
120 };
121
122 } // namespace config
123
124 #endif // CONFIG_TO_GVARIANT_VISITOR_HPP