types.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *  D-Bus++ - C++ bindings for D-Bus
00004  *
00005  *  Copyright (C) 2005-2007  Paolo Durante <shackan@gmail.com>
00006  *
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Lesser General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2.1 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 
00025 #ifndef __DBUSXX_TYPES_H
00026 #define __DBUSXX_TYPES_H
00027 
00028 #include <stdint.h>
00029 #include <string>
00030 #include <vector>
00031 #include <map>
00032 
00033 #include "api.h"
00034 #include "util.h"
00035 #include "message.h"
00036 #include "error.h"
00037 
00038 namespace DBus
00039 {
00040 
00041 struct DXXAPI Path : public std::string
00042 {
00043   Path() {}
00044   Path(const std::string &s) : std::string(s) {}
00045   Path(const char *c) : std::string(c) {}
00046   Path &operator = (std::string &s)
00047   {
00048     std::string::operator = (s);
00049     return *this;
00050   }
00051 };
00052 
00053 struct DXXAPI Signature : public std::string
00054 {
00055   Signature() {}
00056   Signature(const std::string &s) : std::string(s) {}
00057   Signature(const char *c) : std::string(c) {}
00058   Signature &operator = (std::string &s)
00059   {
00060     std::string::operator = (s);
00061     return *this;
00062   }
00063 };
00064 
00065 struct DXXAPI Invalid {};
00066 
00067 class DXXAPI Variant
00068 {
00069 public:
00070 
00071   Variant();
00072 
00073   Variant(MessageIter &it);
00074 
00075   Variant &operator = (const Variant &v);
00076 
00077   const Signature signature() const;
00078 
00079   void clear();
00080 
00081   MessageIter reader() const
00082   {
00083     return _msg.reader();
00084   }
00085 
00086   MessageIter writer()
00087   {
00088     return _msg.writer();
00089   }
00090 
00091   template <typename T>
00092   operator T() const
00093   {
00094     T cast;
00095     MessageIter ri = _msg.reader();
00096     ri >> cast;
00097     return cast;
00098   }
00099 
00100 private:
00101 
00102   Message _msg;
00103 };
00104 
00105 template <
00106 typename T1,
00107          typename T2 = Invalid,
00108          typename T3 = Invalid,
00109          typename T4 = Invalid,
00110          typename T5 = Invalid,
00111          typename T6 = Invalid,
00112          typename T7 = Invalid,
00113          typename T8 = Invalid,
00114          typename T9 = Invalid,
00115          typename T10 = Invalid,
00116          typename T11 = Invalid,
00117          typename T12 = Invalid,
00118          typename T13 = Invalid,
00119          typename T14 = Invalid,
00120          typename T15 = Invalid,
00121          typename T16 = Invalid // nobody needs more than 16
00122          >
00123 struct Struct
00124 {
00125   T1 _1;
00126   T2 _2;
00127   T3 _3;
00128   T4 _4;
00129   T5 _5;
00130   T6 _6;
00131   T7 _7;
00132   T8 _8;
00133   T9 _9;
00134   T10 _10;
00135   T11 _11;
00136   T12 _12;
00137   T13 _13;
00138   T14 _14;
00139   T15 _15;
00140   T16 _16;
00141 };
00142 
00143 template<typename K, typename V>
00144 inline bool dict_has_key(const std::map<K, V>& map, const K &key)
00145 {
00146   return map.find(key) != map.end();
00147 }
00148 
00149 template <typename T>
00150 struct type
00151 {
00152   static std::string sig()
00153   {
00154     throw ErrorInvalidArgs("unknown type");
00155     return "";
00156   }
00157 };
00158 
00159 template <> struct type<Variant>
00160 {
00161   static std::string sig()
00162   {
00163     return "v";
00164   }
00165 };
00166 template <> struct type<uint8_t>
00167 {
00168   static std::string sig()
00169   {
00170     return "y";
00171   }
00172 };
00173 template <> struct type<bool>
00174 {
00175   static std::string sig()
00176   {
00177     return "b";
00178   }
00179 };
00180 template <> struct type<int16_t>
00181 {
00182   static std::string sig()
00183   {
00184     return "n";
00185   }
00186 };
00187 template <> struct type<uint16_t>
00188 {
00189   static std::string sig()
00190   {
00191     return "q";
00192   }
00193 };
00194 template <> struct type<int32_t>
00195 {
00196   static std::string sig()
00197   {
00198     return "i";
00199   }
00200 };
00201 template <> struct type<uint32_t>
00202 {
00203   static std::string sig()
00204   {
00205     return "u";
00206   }
00207 };
00208 template <> struct type<int64_t>
00209 {
00210   static std::string sig()
00211   {
00212     return "x";
00213   }
00214 };
00215 template <> struct type<uint64_t>
00216 {
00217   static std::string sig()
00218   {
00219     return "t";
00220   }
00221 };
00222 template <> struct type<double>
00223 {
00224   static std::string sig()
00225   {
00226     return "d";
00227   }
00228 };
00229 template <> struct type<std::string>
00230 {
00231   static std::string sig()
00232   {
00233     return "s";
00234   }
00235 };
00236 template <> struct type<Path>
00237 {
00238   static std::string sig()
00239   {
00240     return "o";
00241   }
00242 };
00243 template <> struct type<Signature>
00244 {
00245   static std::string sig()
00246   {
00247     return "g";
00248   }
00249 };
00250 template <> struct type<Invalid>
00251 {
00252   static std::string sig()
00253   {
00254     return "";
00255   }
00256 };
00257 
00258 template <typename E>
00259 struct type< std::vector<E> >
00260 {
00261   static std::string sig()
00262   {
00263     return "a" + type<E>::sig();
00264   }
00265 };
00266 
00267 template <typename K, typename V>
00268 struct type< std::map<K, V> >
00269 {
00270   static std::string sig()
00271   {
00272     return "a{" + type<K>::sig() + type<V>::sig() + "}";
00273   }
00274 };
00275 
00276 template <
00277 typename T1,
00278          typename T2,
00279          typename T3,
00280          typename T4,
00281          typename T5,
00282          typename T6,
00283          typename T7,
00284          typename T8,
00285          typename T9,
00286          typename T10,
00287          typename T11,
00288          typename T12,
00289          typename T13,
00290          typename T14,
00291          typename T15,
00292          typename T16 // nobody needs more than 16
00293          >
00294 struct type< Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> >
00295 {
00296   static std::string sig()
00297   {
00298     return "("
00299            + type<T1>::sig()
00300            + type<T2>::sig()
00301            + type<T3>::sig()
00302            + type<T4>::sig()
00303            + type<T5>::sig()
00304            + type<T6>::sig()
00305            + type<T7>::sig()
00306            + type<T8>::sig()
00307            + type<T9>::sig()
00308            + type<T10>::sig()
00309            + type<T11>::sig()
00310            + type<T12>::sig()
00311            + type<T13>::sig()
00312            + type<T14>::sig()
00313            + type<T15>::sig()
00314            + type<T16>::sig()
00315            + ")";
00316   }
00317 };
00318 
00319 } /* namespace DBus */
00320 
00321 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Invalid &)
00322 {
00323   return iter;
00324 }
00325 
00326 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val)
00327 {
00328   iter.append_byte(val);
00329   return iter;
00330 }
00331 
00332 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
00333 {
00334   iter.append_bool(val);
00335   return iter;
00336 }
00337 
00338 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t &val)
00339 {
00340   iter.append_int16(val);
00341   return iter;
00342 }
00343 
00344 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t &val)
00345 {
00346   iter.append_uint16(val);
00347   return iter;
00348 }
00349 
00350 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t &val)
00351 {
00352   iter.append_int32(val);
00353   return iter;
00354 }
00355 
00356 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t &val)
00357 {
00358   iter.append_uint32(val);
00359   return iter;
00360 }
00361 
00362 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t &val)
00363 {
00364   iter.append_int64(val);
00365   return iter;
00366 }
00367 
00368 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t &val)
00369 {
00370   iter.append_uint64(val);
00371   return iter;
00372 }
00373 
00374 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
00375 {
00376   iter.append_double(val);
00377   return iter;
00378 }
00379 
00380 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
00381 {
00382   iter.append_string(val.c_str());
00383   return iter;
00384 }
00385 
00386 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val)
00387 {
00388   iter.append_path(val.c_str());
00389   return iter;
00390 }
00391 
00392 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val)
00393 {
00394   iter.append_signature(val.c_str());
00395   return iter;
00396 }
00397 
00398 template<typename E>
00399 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
00400 {
00401   const std::string sig = DBus::type<E>::sig();
00402   DBus::MessageIter ait = iter.new_array(sig.c_str());
00403 
00404   typename std::vector<E>::const_iterator vit;
00405   for (vit = val.begin(); vit != val.end(); ++vit)
00406   {
00407     ait << *vit;
00408   }
00409 
00410   iter.close_container(ait);
00411   return iter;
00412 }
00413 
00414 template<>
00415 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
00416 {
00417   DBus::MessageIter ait = iter.new_array("y");
00418   ait.append_array('y', &val.front(), val.size());
00419   iter.close_container(ait);
00420   return iter;
00421 }
00422 
00423 template<typename K, typename V>
00424 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K, V>& val)
00425 {
00426   const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
00427   DBus::MessageIter ait = iter.new_array(sig.c_str());
00428 
00429   typename std::map<K, V>::const_iterator mit;
00430   for (mit = val.begin(); mit != val.end(); ++mit)
00431   {
00432     DBus::MessageIter eit = ait.new_dict_entry();
00433 
00434     eit << mit->first << mit->second;
00435 
00436     ait.close_container(eit);
00437   }
00438 
00439   iter.close_container(ait);
00440   return iter;
00441 }
00442 
00443 template <
00444 typename T1,
00445          typename T2,
00446          typename T3,
00447          typename T4,
00448          typename T5,
00449          typename T6,
00450          typename T7,
00451          typename T8,
00452          typename T9,
00453          typename T10,
00454          typename T11,
00455          typename T12,
00456          typename T13,
00457          typename T14,
00458          typename T15,
00459          typename T16
00460          >
00461 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)
00462 {
00463   DBus::MessageIter sit = iter.new_struct();
00464 
00465   sit << val._1 << val._2 << val._3 << val._4
00466       << val._5 << val._6 << val._7 << val._8
00467       << val._9 << val._10 << val._11 << val._12
00468       << val._13 << val._14 << val._15 << val._16;
00469 
00470   iter.close_container(sit);
00471 
00472   return iter;
00473 }
00474 
00475 extern DXXAPI DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Variant &val);
00476 
00477 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &)
00478 {
00479   return iter;
00480 }
00481 
00482 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val)
00483 {
00484   val = iter.get_byte();
00485   return ++iter;
00486 }
00487 
00488 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val)
00489 {
00490   val = iter.get_bool();
00491   return ++iter;
00492 }
00493 
00494 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int16_t &val)
00495 {
00496   val = iter.get_int16();
00497   return ++iter;
00498 }
00499 
00500 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t &val)
00501 {
00502   val = iter.get_uint16();
00503   return ++iter;
00504 }
00505 
00506 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int32_t &val)
00507 {
00508   val = iter.get_int32();
00509   return ++iter;
00510 }
00511 
00512 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t &val)
00513 {
00514   val = iter.get_uint32();
00515   return ++iter;
00516 }
00517 
00518 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int64_t &val)
00519 {
00520   val = iter.get_int64();
00521   return ++iter;
00522 }
00523 
00524 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t &val)
00525 {
00526   val = iter.get_uint64();
00527   return ++iter;
00528 }
00529 
00530 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val)
00531 {
00532   val = iter.get_double();
00533   return ++iter;
00534 }
00535 
00536 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
00537 {
00538   val = iter.get_string();
00539   return ++iter;
00540 }
00541 
00542 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val)
00543 {
00544   val = iter.get_path();
00545   return ++iter;
00546 }
00547 
00548 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val)
00549 {
00550   val = iter.get_signature();
00551   return ++iter;
00552 }
00553 
00554 template<typename E>
00555 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
00556 {
00557   if (!iter.is_array())
00558     throw DBus::ErrorInvalidArgs("array expected");
00559 
00560   DBus::MessageIter ait = iter.recurse();
00561 
00562   while (!ait.at_end())
00563   {
00564     E elem;
00565 
00566     ait >> elem;
00567 
00568     val.push_back(elem);
00569   }
00570   return ++iter;
00571 }
00572 
00573 template<>
00574 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
00575 {
00576   if (!iter.is_array())
00577     throw DBus::ErrorInvalidArgs("array expected");
00578 
00579   if (iter.array_type() != 'y')
00580     throw DBus::ErrorInvalidArgs("byte-array expected");
00581 
00582   DBus::MessageIter ait = iter.recurse();
00583 
00584   uint8_t *array;
00585   size_t length = ait.get_array(&array);
00586 
00587   val.insert(val.end(), array, array + length);
00588 
00589   return ++iter;
00590 }
00591 
00592 template<typename K, typename V>
00593 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K, V>& val)
00594 {
00595   if (!iter.is_dict())
00596     throw DBus::ErrorInvalidArgs("dictionary value expected");
00597 
00598   DBus::MessageIter mit = iter.recurse();
00599 
00600   while (!mit.at_end())
00601   {
00602     K key;
00603     V value;
00604 
00605     DBus::MessageIter eit = mit.recurse();
00606 
00607     eit >> key >> value;
00608 
00609     val[key] = value;
00610 
00611     ++mit;
00612   }
00613 
00614   return ++iter;
00615 }
00616 
00617 template <
00618 typename T1,
00619          typename T2,
00620          typename T3,
00621          typename T4,
00622          typename T5,
00623          typename T6,
00624          typename T7,
00625          typename T8,
00626          typename T9,
00627          typename T10,
00628          typename T11,
00629          typename T12,
00630          typename T13,
00631          typename T14,
00632          typename T15,
00633          typename T16
00634          >
00635 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>& val)
00636 {
00637   DBus::MessageIter sit = iter.recurse();
00638 
00639   sit >> val._1 >> val._2 >> val._3 >> val._4
00640       >> val._5 >> val._6 >> val._7 >> val._8
00641       >> val._9 >> val._10 >> val._11 >> val._12
00642       >> val._13 >> val._14 >> val._15 >> val._16;
00643 
00644   return ++iter;
00645 }
00646 
00647 extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);
00648 
00649 #endif//__DBUSXX_TYPES_H
00650