Free memory with dbus_free instead of free. Account for NULL signatures.
[dbus-cxx-async.git] / include / dbus-c++ / types.h
blob98bcf2f404e8568cbb09c5dd7f86b4c30e4bd4ad
1 /*
3 * D-Bus++ - C++ bindings for D-Bus
5 * Copyright (C) 2005-2009 Paolo Durante <shackan@gmail.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifndef __DBUSXX_TYPES_H
26 #define __DBUSXX_TYPES_H
28 #include <stdint.h>
29 #include <string>
30 #include <vector>
31 #include <map>
33 #include "api.h"
34 #include "util.h"
35 #include "message.h"
36 #include "error.h"
38 namespace DBus {
40 struct DBUSXXAPI Path : public std::string
42 Path() {}
43 Path(const std::string &s) : std::string(s) {}
44 Path(const char *c) : std::string(c) {}
45 Path &operator = (std::string &s)
47 std::string::operator = (s);
48 return *this;
52 struct DBUSXXAPI Signature : public std::string
54 Signature() {}
55 Signature(const std::string &s) : std::string(s) {}
56 Signature(const char *c) : std::string(c) {}
57 Signature &operator = (std::string &s)
59 std::string::operator = (s);
60 return *this;
64 struct DBUSXXAPI Invalid {};
66 class DBUSXXAPI Variant
68 public:
70 Variant();
72 Variant(MessageIter &it);
74 Variant &operator = (const Variant &v);
76 const Signature signature() const;
78 void clear();
80 MessageIter reader() const
82 return _msg.reader();
85 MessageIter writer()
87 return _msg.writer();
90 template <typename T>
91 operator T() const
93 T cast;
94 MessageIter ri = _msg.reader();
95 ri >> cast;
96 return cast;
99 private:
101 Message _msg;
104 template <
105 typename T1,
106 typename T2 = Invalid,
107 typename T3 = Invalid,
108 typename T4 = Invalid,
109 typename T5 = Invalid,
110 typename T6 = Invalid,
111 typename T7 = Invalid,
112 typename T8 = Invalid // who needs more than eight?
114 struct Struct
116 T1 _1; T2 _2; T3 _3; T4 _4; T5 _5; T6 _6; T7 _7; T8 _8;
119 template<typename K, typename V>
120 inline bool dict_has_key(const std::map<K,V>& map, const K &key)
122 return map.find(key) != map.end();
125 template <typename T>
126 struct type
128 static std::string sig()
130 throw ErrorInvalidArgs("unknown type");
131 return "";
135 template <> struct type<Variant> { static std::string sig(){ return "v"; } };
136 template <> struct type<uint8_t> { static std::string sig(){ return "y"; } };
137 template <> struct type<bool> { static std::string sig(){ return "b"; } };
138 template <> struct type<int16_t> { static std::string sig(){ return "n"; } };
139 template <> struct type<uint16_t> { static std::string sig(){ return "q"; } };
140 template <> struct type<int32_t> { static std::string sig(){ return "i"; } };
141 template <> struct type<uint32_t> { static std::string sig(){ return "u"; } };
142 template <> struct type<int64_t> { static std::string sig(){ return "x"; } };
143 template <> struct type<uint64_t> { static std::string sig(){ return "t"; } };
144 template <> struct type<double> { static std::string sig(){ return "d"; } };
145 template <> struct type<std::string> { static std::string sig(){ return "s"; } };
146 template <> struct type<Path> { static std::string sig(){ return "o"; } };
147 template <> struct type<Signature> { static std::string sig(){ return "g"; } };
148 template <> struct type<Invalid> { static std::string sig(){ return ""; } };
150 template <typename E>
151 struct type< std::vector<E> >
152 { static std::string sig(){ return "a" + type<E>::sig(); } };
154 template <typename K, typename V>
155 struct type< std::map<K,V> >
156 { static std::string sig(){ return "a{" + type<K>::sig() + type<V>::sig() + "}"; } };
158 template <
159 typename T1,
160 typename T2,
161 typename T3,
162 typename T4,
163 typename T5,
164 typename T6,
165 typename T7,
166 typename T8 // who needs more than eight?
168 struct type< Struct<T1,T2,T3,T4,T5,T6,T7,T8> >
170 static std::string sig()
172 return "("
173 + type<T1>::sig()
174 + type<T2>::sig()
175 + type<T3>::sig()
176 + type<T4>::sig()
177 + type<T5>::sig()
178 + type<T6>::sig()
179 + type<T7>::sig()
180 + type<T8>::sig()
181 + ")";
185 } /* namespace DBus */
187 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Invalid &)
189 return iter;
192 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val)
194 iter.append_byte(val);
195 return iter;
198 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
200 iter.append_bool(val);
201 return iter;
204 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t& val)
206 iter.append_int16(val);
207 return iter;
210 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t& val)
212 iter.append_uint16(val);
213 return iter;
216 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t& val)
218 iter.append_int32(val);
219 return iter;
222 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t& val)
224 iter.append_uint32(val);
225 return iter;
228 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t& val)
230 iter.append_int64(val);
231 return iter;
234 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t& val)
236 iter.append_uint64(val);
237 return iter;
240 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
242 iter.append_double(val);
243 return iter;
246 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
248 iter.append_string(val.c_str());
249 return iter;
252 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val)
254 iter.append_path(val.c_str());
255 return iter;
258 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val)
260 iter.append_signature(val.c_str());
261 return iter;
264 template<typename E>
265 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
267 const std::string sig = DBus::type<E>::sig();
268 DBus::MessageIter ait = iter.new_array(sig.c_str());
270 typename std::vector<E>::const_iterator vit;
271 for (vit = val.begin(); vit != val.end(); ++vit)
273 ait << *vit;
276 iter.close_container(ait);
277 return iter;
280 template<>
281 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
283 DBus::MessageIter ait = iter.new_array("y");
284 ait.append_array('y', &val.front(), val.size());
285 iter.close_container(ait);
286 return iter;
289 template<typename K, typename V>
290 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K,V>& val)
292 const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
293 DBus::MessageIter ait = iter.new_array(sig.c_str());
295 typename std::map<K,V>::const_iterator mit;
296 for (mit = val.begin(); mit != val.end(); ++mit)
298 DBus::MessageIter eit = ait.new_dict_entry();
300 eit << mit->first << mit->second;
302 ait.close_container(eit);
305 iter.close_container(ait);
306 return iter;
309 template <
310 typename T1,
311 typename T2,
312 typename T3,
313 typename T4,
314 typename T5,
315 typename T6,
316 typename T7,
317 typename T8
319 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val)
321 /* const std::string sig =
322 DBus::type<T1>::sig() + DBus::type<T2>::sig() + DBus::type<T3>::sig() + DBus::type<T4>::sig() +
323 DBus::type<T5>::sig() + DBus::type<T6>::sig() + DBus::type<T7>::sig() + DBus::type<T8>::sig();
325 DBus::MessageIter sit = iter.new_struct(/*sig.c_str()*/);
327 sit << val._1 << val._2 << val._3 << val._4 << val._5 << val._6 << val._7 << val._8;
329 iter.close_container(sit);
331 return iter;
334 extern DBUSXXAPI DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Variant &val);
339 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &)
341 return iter;
344 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val)
346 val = iter.get_byte();
347 return ++iter;
350 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val)
352 val = iter.get_bool();
353 return ++iter;
356 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int16_t& val)
358 val = iter.get_int16();
359 return ++iter;
362 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t& val)
364 val = iter.get_uint16();
365 return ++iter;
368 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int32_t& val)
370 val = iter.get_int32();
371 return ++iter;
374 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t& val)
376 val = iter.get_uint32();
377 return ++iter;
380 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int64_t& val)
382 val = iter.get_int64();
383 return ++iter;
386 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t& val)
388 val = iter.get_uint64();
389 return ++iter;
392 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val)
394 val = iter.get_double();
395 return ++iter;
398 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
400 val = iter.get_string();
401 return ++iter;
404 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val)
406 val = iter.get_path();
407 return ++iter;
410 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val)
412 val = iter.get_signature();
413 return ++iter;
416 template<typename E>
417 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
419 if (!iter.is_array())
420 throw DBus::ErrorInvalidArgs("array expected");
422 DBus::MessageIter ait = iter.recurse();
424 while (!ait.at_end())
426 E elem;
428 ait >> elem;
430 val.push_back(elem);
432 return ++iter;
435 template<>
436 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
438 if (!iter.is_array())
439 throw DBus::ErrorInvalidArgs("array expected");
441 if (iter.array_type() != 'y')
442 throw DBus::ErrorInvalidArgs("byte-array expected");
444 DBus::MessageIter ait = iter.recurse();
446 uint8_t *array;
447 size_t length = ait.get_array(&array);
449 val.insert(val.end(), array, array+length);
451 return ++iter;
454 template<typename K, typename V>
455 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K,V>& val)
457 if (!iter.is_dict())
458 throw DBus::ErrorInvalidArgs("dictionary value expected");
460 DBus::MessageIter mit = iter.recurse();
462 while (!mit.at_end())
464 K key; V value;
466 DBus::MessageIter eit = mit.recurse();
468 eit >> key >> value;
470 val[key] = value;
472 ++mit;
475 return ++iter;
478 template <
479 typename T1,
480 typename T2,
481 typename T3,
482 typename T4,
483 typename T5,
484 typename T6,
485 typename T7,
486 typename T8
488 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val)
490 DBus::MessageIter sit = iter.recurse();
492 sit >> val._1 >> val._2 >> val._3 >> val._4 >> val._5 >> val._6 >> val._7 >> val._8;
494 return ++iter;
497 extern DBUSXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);
499 #endif//__DBUSXX_TYPES_H