types.h
Go to the documentation of this file.
1 /*
2  *
3  * D-Bus++ - C++ bindings for D-Bus
4  *
5  * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
6  *
7  *
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.
12  *
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.
17  *
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
21  *
22  */
23 
24 
25 #ifndef __DBUSXX_TYPES_H
26 #define __DBUSXX_TYPES_H
27 
28 #include <stdint.h>
29 #include <string>
30 #include <vector>
31 #include <map>
32 
33 #include "api.h"
34 #include "util.h"
35 #include "message.h"
36 #include "error.h"
37 
38 namespace DBus
39 {
40 
41 struct DXXAPI Path : public std::string
42 {
43  Path() {}
44  Path(const std::string &s) : std::string(s) {}
45  Path(const char *c) : std::string(c) {}
46  Path &operator = (std::string &s)
47  {
48  std::string::operator = (s);
49  return *this;
50  }
51 };
52 
53 struct DXXAPI Signature : public std::string
54 {
55  Signature() {}
56  Signature(const std::string &s) : std::string(s) {}
57  Signature(const char *c) : std::string(c) {}
58  Signature &operator = (std::string &s)
59  {
60  std::string::operator = (s);
61  return *this;
62  }
63 };
64 
65 struct DXXAPI Invalid {};
66 
68 {
69 public:
70 
71  Variant();
72 
73  Variant(MessageIter &it);
74 
75  Variant &operator = (const Variant &v);
76 
77  const Signature signature() const;
78 
79  void clear();
80 
81  MessageIter reader() const
82  {
83  return _msg.reader();
84  }
85 
86  MessageIter writer()
87  {
88  return _msg.writer();
89  }
90 
91  template <typename T>
92  operator T() const
93  {
94  T cast;
95  MessageIter ri = _msg.reader();
96  ri >> cast;
97  return cast;
98  }
99 
100 private:
101 
103 };
104 
105 template <
106 typename T1,
107  typename T2 = Invalid,
108  typename T3 = Invalid,
109  typename T4 = Invalid,
110  typename T5 = Invalid,
111  typename T6 = Invalid,
112  typename T7 = Invalid,
113  typename T8 = Invalid,
114  typename T9 = Invalid,
115  typename T10 = Invalid,
116  typename T11 = Invalid,
117  typename T12 = Invalid,
118  typename T13 = Invalid,
119  typename T14 = Invalid,
120  typename T15 = Invalid,
121  typename T16 = Invalid // nobody needs more than 16
122  >
123 struct Struct
124 {
125  T1 _1;
126  T2 _2;
127  T3 _3;
128  T4 _4;
129  T5 _5;
130  T6 _6;
131  T7 _7;
132  T8 _8;
133  T9 _9;
134  T10 _10;
135  T11 _11;
136  T12 _12;
137  T13 _13;
138  T14 _14;
139  T15 _15;
140  T16 _16;
141 };
142 
143 template<typename K, typename V>
144 inline bool dict_has_key(const std::map<K, V>& map, const K &key)
145 {
146  return map.find(key) != map.end();
147 }
148 
149 template <typename T>
150 struct type
151 {
152  static std::string sig()
153  {
154  throw ErrorInvalidArgs("unknown type");
155  return "";
156  }
157 };
158 
159 template <> struct type<Variant>
160 {
161  static std::string sig()
162  {
163  return "v";
164  }
165 };
166 template <> struct type<uint8_t>
167 {
168  static std::string sig()
169  {
170  return "y";
171  }
172 };
173 template <> struct type<bool>
174 {
175  static std::string sig()
176  {
177  return "b";
178  }
179 };
180 template <> struct type<int16_t>
181 {
182  static std::string sig()
183  {
184  return "n";
185  }
186 };
187 template <> struct type<uint16_t>
188 {
189  static std::string sig()
190  {
191  return "q";
192  }
193 };
194 template <> struct type<int32_t>
195 {
196  static std::string sig()
197  {
198  return "i";
199  }
200 };
201 template <> struct type<uint32_t>
202 {
203  static std::string sig()
204  {
205  return "u";
206  }
207 };
208 template <> struct type<int64_t>
209 {
210  static std::string sig()
211  {
212  return "x";
213  }
214 };
215 template <> struct type<uint64_t>
216 {
217  static std::string sig()
218  {
219  return "t";
220  }
221 };
222 template <> struct type<double>
223 {
224  static std::string sig()
225  {
226  return "d";
227  }
228 };
229 template <> struct type<std::string>
230 {
231  static std::string sig()
232  {
233  return "s";
234  }
235 };
236 template <> struct type<Path>
237 {
238  static std::string sig()
239  {
240  return "o";
241  }
242 };
243 template <> struct type<Signature>
244 {
245  static std::string sig()
246  {
247  return "g";
248  }
249 };
250 template <> struct type<Invalid>
251 {
252  static std::string sig()
253  {
254  return "";
255  }
256 };
257 
258 template <typename E>
259 struct type< std::vector<E> >
260 {
261  static std::string sig()
262  {
263  return "a" + type<E>::sig();
264  }
265 };
266 
267 template <typename K, typename V>
268 struct type< std::map<K, V> >
269 {
270  static std::string sig()
271  {
272  return "a{" + type<K>::sig() + type<V>::sig() + "}";
273  }
274 };
275 
276 template <
277 typename T1,
278  typename T2,
279  typename T3,
280  typename T4,
281  typename T5,
282  typename T6,
283  typename T7,
284  typename T8,
285  typename T9,
286  typename T10,
287  typename T11,
288  typename T12,
289  typename T13,
290  typename T14,
291  typename T15,
292  typename T16 // nobody needs more than 16
293  >
294 struct type< Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> >
295 {
296  static std::string sig()
297  {
298  return "("
299  + type<T1>::sig()
300  + type<T2>::sig()
301  + type<T3>::sig()
302  + type<T4>::sig()
303  + type<T5>::sig()
304  + type<T6>::sig()
305  + type<T7>::sig()
306  + type<T8>::sig()
307  + type<T9>::sig()
308  + type<T10>::sig()
309  + type<T11>::sig()
310  + type<T12>::sig()
311  + type<T13>::sig()
312  + type<T14>::sig()
313  + type<T15>::sig()
314  + type<T16>::sig()
315  + ")";
316  }
317 };
318 
319 } /* namespace DBus */
320 
322 {
323  return iter;
324 }
325 
326 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val)
327 {
328  iter.append_byte(val);
329  return iter;
330 }
331 
332 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
333 {
334  iter.append_bool(val);
335  return iter;
336 }
337 
338 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t &val)
339 {
340  iter.append_int16(val);
341  return iter;
342 }
343 
344 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t &val)
345 {
346  iter.append_uint16(val);
347  return iter;
348 }
349 
350 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t &val)
351 {
352  iter.append_int32(val);
353  return iter;
354 }
355 
356 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t &val)
357 {
358  iter.append_uint32(val);
359  return iter;
360 }
361 
362 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t &val)
363 {
364  iter.append_int64(val);
365  return iter;
366 }
367 
368 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t &val)
369 {
370  iter.append_uint64(val);
371  return iter;
372 }
373 
374 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
375 {
376  iter.append_double(val);
377  return iter;
378 }
379 
380 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
381 {
382  iter.append_string(val.c_str());
383  return iter;
384 }
385 
387 {
388  iter.append_path(val.c_str());
389  return iter;
390 }
391 
393 {
394  iter.append_signature(val.c_str());
395  return iter;
396 }
397 
398 template<typename E>
399 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
400 {
401  const std::string sig = DBus::type<E>::sig();
402  DBus::MessageIter ait = iter.new_array(sig.c_str());
403 
404  typename std::vector<E>::const_iterator vit;
405  for (vit = val.begin(); vit != val.end(); ++vit)
406  {
407  ait << *vit;
408  }
409 
410  iter.close_container(ait);
411  return iter;
412 }
413 
414 template<>
415 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
416 {
417  DBus::MessageIter ait = iter.new_array("y");
418  ait.append_array('y', &val.front(), val.size());
419  iter.close_container(ait);
420  return iter;
421 }
422 
423 template<typename K, typename V>
424 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K, V>& val)
425 {
426  const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
427  DBus::MessageIter ait = iter.new_array(sig.c_str());
428 
429  typename std::map<K, V>::const_iterator mit;
430  for (mit = val.begin(); mit != val.end(); ++mit)
431  {
432  DBus::MessageIter eit = ait.new_dict_entry();
433 
434  eit << mit->first << mit->second;
435 
436  ait.close_container(eit);
437  }
438 
439  iter.close_container(ait);
440  return iter;
441 }
442 
443 template <
444 typename T1,
445  typename T2,
446  typename T3,
447  typename T4,
448  typename T5,
449  typename T6,
450  typename T7,
451  typename T8,
452  typename T9,
453  typename T10,
454  typename T11,
455  typename T12,
456  typename T13,
457  typename T14,
458  typename T15,
459  typename T16
460  >
461 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>& val)
462 {
463  DBus::MessageIter sit = iter.new_struct();
464 
465  sit << val._1 << val._2 << val._3 << val._4
466  << val._5 << val._6 << val._7 << val._8
467  << val._9 << val._10 << val._11 << val._12
468  << val._13 << val._14 << val._15 << val._16;
469 
470  iter.close_container(sit);
471 
472  return iter;
473 }
474 
476 
478 {
479  return iter;
480 }
481 
483 {
484  val = iter.get_byte();
485  return ++iter;
486 }
487 
489 {
490  val = iter.get_bool();
491  return ++iter;
492 }
493 
495 {
496  val = iter.get_int16();
497  return ++iter;
498 }
499 
500 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t &val)
501 {
502  val = iter.get_uint16();
503  return ++iter;
504 }
505 
507 {
508  val = iter.get_int32();
509  return ++iter;
510 }
511 
512 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t &val)
513 {
514  val = iter.get_uint32();
515  return ++iter;
516 }
517 
519 {
520  val = iter.get_int64();
521  return ++iter;
522 }
523 
524 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t &val)
525 {
526  val = iter.get_uint64();
527  return ++iter;
528 }
529 
531 {
532  val = iter.get_double();
533  return ++iter;
534 }
535 
536 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
537 {
538  val = iter.get_string();
539  return ++iter;
540 }
541 
543 {
544  val = iter.get_path();
545  return ++iter;
546 }
547 
549 {
550  val = iter.get_signature();
551  return ++iter;
552 }
553 
554 template<typename E>
555 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
556 {
557  if (!iter.is_array())
558  throw DBus::ErrorInvalidArgs("array expected");
559 
560  DBus::MessageIter ait = iter.recurse();
561 
562  while (!ait.at_end())
563  {
564  E elem;
565 
566  ait >> elem;
567 
568  val.push_back(elem);
569  }
570  return ++iter;
571 }
572 
573 template<>
574 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
575 {
576  if (!iter.is_array())
577  throw DBus::ErrorInvalidArgs("array expected");
578 
579  if (iter.array_type() != 'y')
580  throw DBus::ErrorInvalidArgs("byte-array expected");
581 
582  DBus::MessageIter ait = iter.recurse();
583 
584  uint8_t *array;
585  size_t length = ait.get_array(&array);
586 
587  val.insert(val.end(), array, array + length);
588 
589  return ++iter;
590 }
591 
592 template<typename K, typename V>
593 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K, V>& val)
594 {
595  if (!iter.is_dict())
596  throw DBus::ErrorInvalidArgs("dictionary value expected");
597 
598  DBus::MessageIter mit = iter.recurse();
599 
600  while (!mit.at_end())
601  {
602  K key;
603  V value;
604 
605  DBus::MessageIter eit = mit.recurse();
606 
607  eit >> key >> value;
608 
609  val[key] = value;
610 
611  ++mit;
612  }
613 
614  return ++iter;
615 }
616 
617 template <
618 typename T1,
619  typename T2,
620  typename T3,
621  typename T4,
622  typename T5,
623  typename T6,
624  typename T7,
625  typename T8,
626  typename T9,
627  typename T10,
628  typename T11,
629  typename T12,
630  typename T13,
631  typename T14,
632  typename T15,
633  typename T16
634  >
636 {
637  DBus::MessageIter sit = iter.recurse();
638 
639  sit >> val._1 >> val._2 >> val._3 >> val._4
640  >> val._5 >> val._6 >> val._7 >> val._8
641  >> val._9 >> val._10 >> val._11 >> val._12
642  >> val._13 >> val._14 >> val._15 >> val._16;
643 
644  return ++iter;
645 }
646 
648 
649 #endif//__DBUSXX_TYPES_H
650