00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 struct DXXAPI Path : public std::string
00041 {
00042 Path() {}
00043 Path(const std::string &s) : std::string(s) {}
00044 Path(const char *c) : std::string(c) {}
00045 Path &operator = (std::string &s)
00046 {
00047 std::string::operator = (s);
00048 return *this;
00049 }
00050 };
00051
00052 struct DXXAPI Signature : public std::string
00053 {
00054 Signature() {}
00055 Signature(const std::string &s) : std::string(s) {}
00056 Signature(const char *c) : std::string(c) {}
00057 Signature &operator = (std::string &s)
00058 {
00059 std::string::operator = (s);
00060 return *this;
00061 }
00062 };
00063
00064 struct DXXAPI Invalid {};
00065
00066 class DXXAPI Variant
00067 {
00068 public:
00069
00070 Variant();
00071
00072 Variant(MessageIter &it);
00073
00074 Variant &operator = (const Variant &v);
00075
00076 const Signature signature() const;
00077
00078 void clear();
00079
00080 MessageIter reader() const
00081 {
00082 return _msg.reader();
00083 }
00084
00085 MessageIter writer()
00086 {
00087 return _msg.writer();
00088 }
00089
00090 template <typename T>
00091 operator T() const
00092 {
00093 T cast;
00094 MessageIter ri = _msg.reader();
00095 ri >> cast;
00096 return cast;
00097 }
00098
00099 private:
00100
00101 Message _msg;
00102 };
00103
00104 template <
00105 typename T1,
00106 typename T2 = Invalid,
00107 typename T3 = Invalid,
00108 typename T4 = Invalid,
00109 typename T5 = Invalid,
00110 typename T6 = Invalid,
00111 typename T7 = Invalid,
00112 typename T8 = Invalid
00113 >
00114 struct Struct
00115 {
00116 T1 _1; T2 _2; T3 _3; T4 _4; T5 _5; T6 _6; T7 _7; T8 _8;
00117 };
00118
00119 template<typename K, typename V>
00120 inline bool dict_has_key(const std::map<K,V>& map, const K &key)
00121 {
00122 return map.find(key) != map.end();
00123 }
00124
00125 template <typename T>
00126 struct type
00127 {
00128 static std::string sig()
00129 {
00130 throw ErrorInvalidArgs("unknown type");
00131 return "";
00132 }
00133 };
00134
00135 template <> struct type<Variant> { static std::string sig(){ return "v"; } };
00136 template <> struct type<uint8_t> { static std::string sig(){ return "y"; } };
00137 template <> struct type<bool> { static std::string sig(){ return "b"; } };
00138 template <> struct type<int16_t> { static std::string sig(){ return "n"; } };
00139 template <> struct type<uint16_t> { static std::string sig(){ return "q"; } };
00140 template <> struct type<int32_t> { static std::string sig(){ return "i"; } };
00141 template <> struct type<uint32_t> { static std::string sig(){ return "u"; } };
00142 template <> struct type<int64_t> { static std::string sig(){ return "x"; } };
00143 template <> struct type<uint64_t> { static std::string sig(){ return "t"; } };
00144 template <> struct type<double> { static std::string sig(){ return "d"; } };
00145 template <> struct type<std::string> { static std::string sig(){ return "s"; } };
00146 template <> struct type<Path> { static std::string sig(){ return "o"; } };
00147 template <> struct type<Signature> { static std::string sig(){ return "g"; } };
00148 template <> struct type<Invalid> { static std::string sig(){ return ""; } };
00149
00150 template <typename E>
00151 struct type< std::vector<E> >
00152 { static std::string sig(){ return "a" + type<E>::sig(); } };
00153
00154 template <typename K, typename V>
00155 struct type< std::map<K,V> >
00156 { static std::string sig(){ return "a{" + type<K>::sig() + type<V>::sig() + "}"; } };
00157
00158 template <
00159 typename T1,
00160 typename T2,
00161 typename T3,
00162 typename T4,
00163 typename T5,
00164 typename T6,
00165 typename T7,
00166 typename T8
00167 >
00168 struct type< Struct<T1,T2,T3,T4,T5,T6,T7,T8> >
00169 {
00170 static std::string sig()
00171 {
00172 return "("
00173 + type<T1>::sig()
00174 + type<T2>::sig()
00175 + type<T3>::sig()
00176 + type<T4>::sig()
00177 + type<T5>::sig()
00178 + type<T6>::sig()
00179 + type<T7>::sig()
00180 + type<T8>::sig()
00181 + ")";
00182 }
00183 };
00184
00185 }
00186
00187 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Invalid &)
00188 {
00189 return iter;
00190 }
00191
00192 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val)
00193 {
00194 iter.append_byte(val);
00195 return iter;
00196 }
00197
00198 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
00199 {
00200 iter.append_bool(val);
00201 return iter;
00202 }
00203
00204 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t& val)
00205 {
00206 iter.append_int16(val);
00207 return iter;
00208 }
00209
00210 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t& val)
00211 {
00212 iter.append_uint16(val);
00213 return iter;
00214 }
00215
00216 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t& val)
00217 {
00218 iter.append_int32(val);
00219 return iter;
00220 }
00221
00222 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t& val)
00223 {
00224 iter.append_uint32(val);
00225 return iter;
00226 }
00227
00228 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t& val)
00229 {
00230 iter.append_int64(val);
00231 return iter;
00232 }
00233
00234 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t& val)
00235 {
00236 iter.append_uint64(val);
00237 return iter;
00238 }
00239
00240 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
00241 {
00242 iter.append_double(val);
00243 return iter;
00244 }
00245
00246 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
00247 {
00248 iter.append_string(val.c_str());
00249 return iter;
00250 }
00251
00252 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val)
00253 {
00254 iter.append_path(val.c_str());
00255 return iter;
00256 }
00257
00258 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val)
00259 {
00260 iter.append_signature(val.c_str());
00261 return iter;
00262 }
00263
00264 template<typename E>
00265 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
00266 {
00267 const std::string sig = DBus::type<E>::sig();
00268 DBus::MessageIter ait = iter.new_array(sig.c_str());
00269
00270 typename std::vector<E>::const_iterator vit;
00271 for (vit = val.begin(); vit != val.end(); ++vit)
00272 {
00273 ait << *vit;
00274 }
00275
00276 iter.close_container(ait);
00277 return iter;
00278 }
00279
00280 template<>
00281 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
00282 {
00283 DBus::MessageIter ait = iter.new_array("y");
00284 ait.append_array('y', &val.front(), val.size());
00285 iter.close_container(ait);
00286 return iter;
00287 }
00288
00289 template<typename K, typename V>
00290 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K,V>& val)
00291 {
00292 const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
00293 DBus::MessageIter ait = iter.new_array(sig.c_str());
00294
00295 typename std::map<K,V>::const_iterator mit;
00296 for (mit = val.begin(); mit != val.end(); ++mit)
00297 {
00298 DBus::MessageIter eit = ait.new_dict_entry();
00299
00300 eit << mit->first << mit->second;
00301
00302 ait.close_container(eit);
00303 }
00304
00305 iter.close_container(ait);
00306 return iter;
00307 }
00308
00309 template <
00310 typename T1,
00311 typename T2,
00312 typename T3,
00313 typename T4,
00314 typename T5,
00315 typename T6,
00316 typename T7,
00317 typename T8
00318 >
00319 inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val)
00320 {
00321
00322
00323
00324
00325 DBus::MessageIter sit = iter.new_struct();
00326
00327 sit << val._1 << val._2 << val._3 << val._4 << val._5 << val._6 << val._7 << val._8;
00328
00329 iter.close_container(sit);
00330
00331 return iter;
00332 }
00333
00334 extern DXXAPI DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Variant &val);
00335
00336
00337
00338
00339 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &)
00340 {
00341 return iter;
00342 }
00343
00344 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val)
00345 {
00346 val = iter.get_byte();
00347 return ++iter;
00348 }
00349
00350 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val)
00351 {
00352 val = iter.get_bool();
00353 return ++iter;
00354 }
00355
00356 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int16_t& val)
00357 {
00358 val = iter.get_int16();
00359 return ++iter;
00360 }
00361
00362 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t& val)
00363 {
00364 val = iter.get_uint16();
00365 return ++iter;
00366 }
00367
00368 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int32_t& val)
00369 {
00370 val = iter.get_int32();
00371 return ++iter;
00372 }
00373
00374 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t& val)
00375 {
00376 val = iter.get_uint32();
00377 return ++iter;
00378 }
00379
00380 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int64_t& val)
00381 {
00382 val = iter.get_int64();
00383 return ++iter;
00384 }
00385
00386 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t& val)
00387 {
00388 val = iter.get_uint64();
00389 return ++iter;
00390 }
00391
00392 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val)
00393 {
00394 val = iter.get_double();
00395 return ++iter;
00396 }
00397
00398 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
00399 {
00400 val = iter.get_string();
00401 return ++iter;
00402 }
00403
00404 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val)
00405 {
00406 val = iter.get_path();
00407 return ++iter;
00408 }
00409
00410 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val)
00411 {
00412 val = iter.get_signature();
00413 return ++iter;
00414 }
00415
00416 template<typename E>
00417 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
00418 {
00419 if (!iter.is_array())
00420 throw DBus::ErrorInvalidArgs("array expected");
00421
00422 DBus::MessageIter ait = iter.recurse();
00423
00424 while (!ait.at_end())
00425 {
00426 E elem;
00427
00428 ait >> elem;
00429
00430 val.push_back(elem);
00431 }
00432 return ++iter;
00433 }
00434
00435 template<>
00436 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
00437 {
00438 if (!iter.is_array())
00439 throw DBus::ErrorInvalidArgs("array expected");
00440
00441 if (iter.array_type() != 'y')
00442 throw DBus::ErrorInvalidArgs("byte-array expected");
00443
00444 DBus::MessageIter ait = iter.recurse();
00445
00446 uint8_t *array;
00447 size_t length = ait.get_array(&array);
00448
00449 val.insert(val.end(), array, array+length);
00450
00451 return ++iter;
00452 }
00453
00454 template<typename K, typename V>
00455 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K,V>& val)
00456 {
00457 if (!iter.is_dict())
00458 throw DBus::ErrorInvalidArgs("dictionary value expected");
00459
00460 DBus::MessageIter mit = iter.recurse();
00461
00462 while (!mit.at_end())
00463 {
00464 K key; V value;
00465
00466 DBus::MessageIter eit = mit.recurse();
00467
00468 eit >> key >> value;
00469
00470 val[key] = value;
00471
00472 ++mit;
00473 }
00474
00475 return ++iter;
00476 }
00477
00478 template <
00479 typename T1,
00480 typename T2,
00481 typename T3,
00482 typename T4,
00483 typename T5,
00484 typename T6,
00485 typename T7,
00486 typename T8
00487 >
00488 inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val)
00489 {
00490 DBus::MessageIter sit = iter.recurse();
00491
00492 sit >> val._1 >> val._2 >> val._3 >> val._4 >> val._5 >> val._6 >> val._7 >> val._8;
00493
00494 return ++iter;
00495 }
00496
00497 extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);
00498
00499 #endif//__DBUSXX_TYPES_H
00500