Fork Vasum on GitHub Official Vasum Wiki on Tizen.org
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
from-gvariant-visitor.hpp
Go to the documentation of this file.
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 
25 #ifndef CARGO_GVARIANT_FROM_GVARIANT_VISITOR_HPP
26 #define CARGO_GVARIANT_FROM_GVARIANT_VISITOR_HPP
27 
28 #include "cargo/is-visitable.hpp"
29 #include "cargo/is-like-tuple.hpp"
30 #include "cargo/exception.hpp"
31 #include "cargo/is-union.hpp"
32 #include "cargo/types.hpp"
33 #include "cargo/visit-fields.hpp"
34 
35 #include <string>
36 #include <vector>
37 #include <array>
38 #include <utility>
39 #include <memory>
40 #include <cstring>
41 #include <cassert>
42 
43 #include <glib.h>
44 
45 namespace cargo {
46 
48 public:
49  explicit FromGVariantVisitor(GVariant* variant)
50  {
51  //Assume that the visited object is not a union
52  checkType(variant, G_VARIANT_TYPE_TUPLE);
53  mIter = g_variant_iter_new(variant);
54  }
55 
57  : mIter(g_variant_iter_copy(visitor.mIter))
58  {
59  }
60 
62  {
63  g_variant_iter_free(mIter);
64  }
65 
67 
68  template<typename T>
69  void visit(const std::string& name, T& value)
70  {
71  auto child = makeUnique(g_variant_iter_next_value(mIter));
72  if (!child) {
74  "GVariant doesn't match with Cargo. Can't set '" + name + "'");
75  }
76  fromGVariant(child.get(), value);
77  }
78 
79 private:
80  GVariantIter* mIter;
81 
82  static std::unique_ptr<GVariant, decltype(&g_variant_unref)> makeUnique(GVariant* variant)
83  {
84  return std::unique_ptr<GVariant, decltype(&g_variant_unref)>(variant, g_variant_unref);
85  }
86 
87  static void checkType(GVariant* object, const GVariantType* type)
88  {
89  if (!g_variant_is_of_type(object, type)) {
90  throw CargoException("Invalid field type");
91  }
92  }
93 
94  static void fromGVariant(GVariant* object, std::int8_t& value)
95  {
96  checkType(object, G_VARIANT_TYPE_BYTE);
97  value = static_cast<std::int8_t>(g_variant_get_byte(object));
98  }
99 
100  static void fromGVariant(GVariant* object, std::int16_t& value)
101  {
102  checkType(object, G_VARIANT_TYPE_INT16);
103  value = g_variant_get_int16(object);
104  }
105 
106  static void fromGVariant(GVariant* object, std::int32_t& value)
107  {
108  checkType(object, G_VARIANT_TYPE_INT32);
109  value = g_variant_get_int32(object);
110  }
111 
112  static void fromGVariant(GVariant* object, std::int64_t& value)
113  {
114  checkType(object, G_VARIANT_TYPE_INT64);
115  value = g_variant_get_int64(object);
116  }
117 
118  static void fromGVariant(GVariant* object, std::uint8_t& value)
119  {
120  checkType(object, G_VARIANT_TYPE_BYTE);
121  value = g_variant_get_byte(object);
122  }
123 
124  static void fromGVariant(GVariant* object, std::uint16_t& value)
125  {
126  checkType(object, G_VARIANT_TYPE_UINT16);
127  value = g_variant_get_uint16(object);
128  }
129 
130  static void fromGVariant(GVariant* object, std::uint32_t& value)
131  {
132  checkType(object, G_VARIANT_TYPE_UINT32);
133  value = g_variant_get_uint32(object);
134  }
135 
136  static void fromGVariant(GVariant* object, std::uint64_t& value)
137  {
138  checkType(object, G_VARIANT_TYPE_UINT64);
139  value = g_variant_get_uint64(object);
140  }
141 
142  static void fromGVariant(GVariant* object, bool& value)
143  {
144  checkType(object, G_VARIANT_TYPE_BOOLEAN);
145  value = g_variant_get_boolean(object);
146  }
147 
148  static void fromGVariant(GVariant* object, double& value)
149  {
150  checkType(object, G_VARIANT_TYPE_DOUBLE);
151  value = g_variant_get_double(object);
152  }
153 
154  static void fromGVariant(GVariant* object, std::string& value)
155  {
156  checkType(object, G_VARIANT_TYPE_STRING);
157  value = g_variant_get_string(object, NULL);
158  }
159 
160  static void fromGVariant(GVariant* object, char* &value)
161  {
162  checkType(object, G_VARIANT_TYPE_STRING);
163 
164  const char* source = g_variant_get_string(object, NULL);
165  size_t len = std::strlen(source);
166 
167  value = new char[len + 1];
168  std::strncpy(value, source, len);
169  value[len] = '\0';
170  }
171 
172  static void fromGVariant(GVariant* object, cargo::FileDescriptor& value)
173  {
174  checkType(object, G_VARIANT_TYPE_HANDLE);
175  value.value = g_variant_get_handle(object);
176  }
177 
178  template<typename T>
179  static void fromGVariant(GVariant* object, std::vector<T>& value)
180  {
181  checkType(object, G_VARIANT_TYPE_ARRAY);
182  GVariantIter iter;
183  g_variant_iter_init(&iter, object);
184  int length = g_variant_iter_n_children(&iter);
185  value.resize(static_cast<size_t>(length));
186  for (int i = 0; i < length; ++i) {
187  auto child = makeUnique(g_variant_iter_next_value(&iter));
188  assert(child);
189  fromGVariant(child.get(), value[static_cast<size_t>(i)]);
190  }
191  }
192 
193  template<typename T, std::size_t N>
194  static void fromGVariant(GVariant* object, std::array<T, N>& values)
195  {
196  checkType(object, G_VARIANT_TYPE_ARRAY);
197 
198  GVariantIter iter;
199  g_variant_iter_init(&iter, object);
200 
201  for (T& value: values) {
202  auto child = makeUnique(g_variant_iter_next_value(&iter));
203  fromGVariant(child.get(), value);
204  }
205  }
206 
207  template<typename V>
208  static void fromGVariant(GVariant* object, std::map<std::string, V>& values)
209  {
210  checkType(object, G_VARIANT_TYPE_TUPLE);
211  GVariantIter iter;
212  g_variant_iter_init(&iter, object);
213  const int length = g_variant_iter_n_children(&iter);
214  for (int i = 0; i < length; ++i) {
215  auto child = makeUnique(g_variant_iter_next_value(&iter));
216  assert(child);
217  std::pair<std::string, V> val;
218  fromGVariant(child.get(), val);
219  values.insert(std::move(val));
220  }
221  }
222 
224  {
225  template<typename T>
226  static void visit(GVariantIter* iter, T&& value)
227  {
228  auto child = makeUnique(g_variant_iter_next_value(iter));
229  fromGVariant(child.get(), value);
230  }
231  };
232 
233  template<typename T, typename std::enable_if<isLikeTuple<T>::value, int>::type = 0>
234  static void fromGVariant(GVariant* object, T& values)
235  {
236  checkType(object, G_VARIANT_TYPE_TUPLE);
237 
238  GVariantIter iter;
239  g_variant_iter_init(&iter, object);
240 
241  HelperVisitor visitor;
242  visitFields(values, &visitor, &iter);
243  }
244 
245  template<typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
246  static void fromGVariant(GVariant* object, T& value)
247  {
248  fromGVariant(object,
249  *reinterpret_cast<typename std::underlying_type<T>::type*>(&value));
250  }
251 
252  template<typename T>
253  static typename std::enable_if<isUnion<T>::value>::type
254  fromGVariant(GVariant* object, T& value)
255  {
256  checkType(object, G_VARIANT_TYPE_VARIANT);
257  auto inner = makeUnique(g_variant_get_variant(object));
258 
259  FromGVariantVisitor visitor(inner.get());
260  value.accept(visitor);
261  }
262 
263  template<typename T>
264  static typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value>::type
265  fromGVariant(GVariant* object, T& value)
266  {
267  FromGVariantVisitor visitor(object);
268  value.accept(visitor);
269  }
270 
271 };
272 
273 } // namespace cargo
274 
275 #endif // CARGO_GVARIANT_FROM_GVARIANT_VISITOR_HPP
Definition: is-union.hpp:60
Internal configuration helper.
static void fromGVariant(GVariant *object, bool &value)
Definition: from-gvariant-visitor.hpp:142
static void fromGVariant(GVariant *object, cargo::FileDescriptor &value)
Definition: from-gvariant-visitor.hpp:172
GVariantIter * mIter
Definition: from-gvariant-visitor.hpp:80
void visit(const std::string &name, T &value)
Definition: from-gvariant-visitor.hpp:69
static void fromGVariant(GVariant *object, std::int64_t &value)
Definition: from-gvariant-visitor.hpp:112
static void fromGVariant(GVariant *object, std::vector< T > &value)
Definition: from-gvariant-visitor.hpp:179
static void fromGVariant(GVariant *object, std::int16_t &value)
Definition: from-gvariant-visitor.hpp:100
Whenever possible, this type will be serialized using Linux file descriptor passing.
Definition: types.hpp:33
Helper function for iterating tuples, pairs and arrays.
Tuple or pair checker.
Definition: from-gvariant-visitor.hpp:223
~FromGVariantVisitor()
Definition: from-gvariant-visitor.hpp:61
Types declarations.
static std::enable_if< isUnion< T >::value >::type fromGVariant(GVariant *object, T &value)
Definition: from-gvariant-visitor.hpp:254
FromGVariantVisitor & operator=(const FromGVariantVisitor &)=delete
static void fromGVariant(GVariant *object, char *&value)
Definition: from-gvariant-visitor.hpp:160
static std::enable_if< isVisitable< T >::value &&!isUnion< T >::value >::type fromGVariant(GVariant *object, T &value)
Definition: from-gvariant-visitor.hpp:265
Internal configuration helper.
Definition: from-gvariant-visitor.hpp:47
static void fromGVariant(GVariant *object, std::uint8_t &value)
Definition: from-gvariant-visitor.hpp:118
static void visit(GVariantIter *iter, T &&value)
Definition: from-gvariant-visitor.hpp:226
Exceptions for libcargo.
static void fromGVariant(GVariant *object, T &value)
Definition: from-gvariant-visitor.hpp:246
static std::unique_ptr< GVariant, decltype(&g_variant_unref)> makeUnique(GVariant *variant)
Definition: from-gvariant-visitor.hpp:82
static void fromGVariant(GVariant *object, T &values)
Definition: from-gvariant-visitor.hpp:234
static void fromGVariant(GVariant *object, double &value)
Definition: from-gvariant-visitor.hpp:148
static void checkType(GVariant *object, const GVariantType *type)
Definition: from-gvariant-visitor.hpp:87
Base class for exceptions in libcargo.
Definition: exception.hpp:35
int value
Definition: types.hpp:34
static void fromGVariant(GVariant *object, std::string &value)
Definition: from-gvariant-visitor.hpp:154
static void fromGVariant(GVariant *object, std::uint32_t &value)
Definition: from-gvariant-visitor.hpp:130
static void fromGVariant(GVariant *object, std::array< T, N > &values)
Definition: from-gvariant-visitor.hpp:194
FromGVariantVisitor(GVariant *variant)
Definition: from-gvariant-visitor.hpp:49
static void fromGVariant(GVariant *object, std::map< std::string, V > &values)
Definition: from-gvariant-visitor.hpp:208
static void fromGVariant(GVariant *object, std::int8_t &value)
Definition: from-gvariant-visitor.hpp:94
FromGVariantVisitor(const FromGVariantVisitor &visitor)
Definition: from-gvariant-visitor.hpp:56
static void fromGVariant(GVariant *object, std::uint64_t &value)
Definition: from-gvariant-visitor.hpp:136
static void fromGVariant(GVariant *object, std::int32_t &value)
Definition: from-gvariant-visitor.hpp:106
void visitFields(T &t, F f, A...args)
Definition: visit-fields.hpp:58
static void fromGVariant(GVariant *object, std::uint16_t &value)
Definition: from-gvariant-visitor.hpp:124