00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <dbus-c++/message.h>
00029
00030 #include <dbus/dbus.h>
00031 #include <cstdlib>
00032
00033 #include "internalerror.h"
00034 #include "message_p.h"
00035
00036 using namespace DBus;
00037
00038
00039
00040
00041 int MessageIter::type()
00042 {
00043 return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
00044 }
00045
00046 bool MessageIter::at_end()
00047 {
00048 return type() == DBUS_TYPE_INVALID;
00049 }
00050
00051 bool MessageIter::has_next()
00052 {
00053 return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
00054 }
00055
00056 MessageIter &MessageIter::operator ++()
00057 {
00058 dbus_message_iter_next((DBusMessageIter *)&_iter);
00059 return (*this);
00060 }
00061
00062 MessageIter MessageIter::operator ++(int)
00063 {
00064 MessageIter copy(*this);
00065 ++(*this);
00066 return copy;
00067 }
00068
00069 bool MessageIter::append_basic(int type_id, void *value)
00070 {
00071 return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
00072 }
00073
00074 void MessageIter::get_basic(int type_id, void *ptr)
00075 {
00076 if (type() != type_id)
00077 throw ErrorInvalidArgs("type mismatch");
00078
00079 dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
00080 }
00081
00082 bool MessageIter::append_byte(unsigned char b)
00083 {
00084 return append_basic(DBUS_TYPE_BYTE, &b);
00085 }
00086
00087 unsigned char MessageIter::get_byte()
00088 {
00089 unsigned char b;
00090 get_basic(DBUS_TYPE_BYTE, &b);
00091 return b;
00092 }
00093
00094 bool MessageIter::append_bool(bool b)
00095 {
00096 dbus_bool_t db = b;
00097 return append_basic(DBUS_TYPE_BOOLEAN, &db);
00098 }
00099
00100 bool MessageIter::get_bool()
00101 {
00102 dbus_bool_t db;
00103 get_basic(DBUS_TYPE_BOOLEAN, &db);
00104 return (bool)db;
00105 }
00106
00107 bool MessageIter::append_int16(signed short i)
00108 {
00109 return append_basic(DBUS_TYPE_INT16, &i);
00110 }
00111
00112 signed short MessageIter::get_int16()
00113 {
00114 signed short i;
00115 get_basic(DBUS_TYPE_INT16, &i);
00116 return i;
00117 }
00118
00119 bool MessageIter::append_uint16(unsigned short u)
00120 {
00121 return append_basic(DBUS_TYPE_UINT16, &u);
00122 }
00123
00124 unsigned short MessageIter::get_uint16()
00125 {
00126 unsigned short u;
00127 get_basic(DBUS_TYPE_UINT16, &u);
00128 return u;
00129 }
00130
00131 bool MessageIter::append_int32(signed int i)
00132 {
00133 return append_basic(DBUS_TYPE_INT32, &i);
00134 }
00135
00136 signed int MessageIter::get_int32()
00137 {
00138 signed int i;
00139 get_basic(DBUS_TYPE_INT32, &i);
00140 return i;
00141 }
00142
00143 bool MessageIter::append_uint32(unsigned int u)
00144 {
00145 return append_basic(DBUS_TYPE_UINT32, &u);
00146 }
00147
00148 unsigned int MessageIter::get_uint32()
00149 {
00150 unsigned int u;
00151 get_basic(DBUS_TYPE_UINT32, &u);
00152 return u;
00153 }
00154
00155 signed long long MessageIter::get_int64()
00156 {
00157 signed long long i;
00158 get_basic(DBUS_TYPE_INT64, &i);
00159 return i;
00160 }
00161
00162 bool MessageIter::append_int64(signed long long i)
00163 {
00164 return append_basic(DBUS_TYPE_INT64, &i);
00165 }
00166
00167 unsigned long long MessageIter::get_uint64()
00168 {
00169 unsigned long long u;
00170 get_basic(DBUS_TYPE_UINT64, &u);
00171 return u;
00172 }
00173
00174 bool MessageIter::append_uint64(unsigned long long u)
00175 {
00176 return append_basic(DBUS_TYPE_UINT64, &u);
00177 }
00178
00179 double MessageIter::get_double()
00180 {
00181 double d;
00182 get_basic(DBUS_TYPE_DOUBLE, &d);
00183 return d;
00184 }
00185
00186 bool MessageIter::append_double(double d)
00187 {
00188 return append_basic(DBUS_TYPE_DOUBLE, &d);
00189 }
00190
00191 bool MessageIter::append_string(const char *chars)
00192 {
00193 return append_basic(DBUS_TYPE_STRING, &chars);
00194 }
00195
00196 const char *MessageIter::get_string()
00197 {
00198 char *chars;
00199 get_basic(DBUS_TYPE_STRING, &chars);
00200 return chars;
00201 }
00202
00203 bool MessageIter::append_path(const char *chars)
00204 {
00205 return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
00206 }
00207
00208 const char *MessageIter::get_path()
00209 {
00210 char *chars;
00211 get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
00212 return chars;
00213 }
00214
00215 bool MessageIter::append_signature(const char *chars)
00216 {
00217 return append_basic(DBUS_TYPE_SIGNATURE, &chars);
00218 }
00219
00220 const char *MessageIter::get_signature()
00221 {
00222 char *chars;
00223 get_basic(DBUS_TYPE_SIGNATURE, &chars);
00224 return chars;
00225 }
00226
00227 MessageIter MessageIter::recurse()
00228 {
00229 MessageIter iter(msg());
00230 dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *) & (iter._iter));
00231 return iter;
00232 }
00233
00234 char *MessageIter::signature() const
00235 {
00236 return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
00237 }
00238
00239 bool MessageIter::append_array(char type, const void *ptr, size_t length)
00240 {
00241 return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
00242 }
00243
00244 int MessageIter::array_type()
00245 {
00246 return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
00247 }
00248
00249 int MessageIter::get_array(void *ptr)
00250 {
00251 int length;
00252 dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
00253 return length;
00254 }
00255
00256 bool MessageIter::is_array()
00257 {
00258 return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
00259 }
00260
00261 bool MessageIter::is_dict()
00262 {
00263 return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
00264 }
00265
00266 MessageIter MessageIter::new_array(const char *sig)
00267 {
00268 MessageIter arr(msg());
00269 dbus_message_iter_open_container(
00270 (DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter)
00271 );
00272 return arr;
00273 }
00274
00275 MessageIter MessageIter::new_variant(const char *sig)
00276 {
00277 MessageIter var(msg());
00278 dbus_message_iter_open_container(
00279 (DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter)
00280 );
00281 return var;
00282 }
00283
00284 MessageIter MessageIter::new_struct()
00285 {
00286 MessageIter stu(msg());
00287 dbus_message_iter_open_container(
00288 (DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter)
00289 );
00290 return stu;
00291 }
00292
00293 MessageIter MessageIter::new_dict_entry()
00294 {
00295 MessageIter ent(msg());
00296 dbus_message_iter_open_container(
00297 (DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter)
00298 );
00299 return ent;
00300 }
00301
00302 void MessageIter::close_container(MessageIter &container)
00303 {
00304 dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *) & (container._iter));
00305 }
00306
00307 static bool is_basic_type(int typecode)
00308 {
00309 switch (typecode)
00310 {
00311 case 'y':
00312 case 'b':
00313 case 'n':
00314 case 'q':
00315 case 'i':
00316 case 'u':
00317 case 'x':
00318 case 't':
00319 case 'd':
00320 case 's':
00321 case 'o':
00322 case 'g':
00323 return true;
00324 default:
00325 return false;
00326 }
00327 }
00328
00329 void MessageIter::copy_data(MessageIter &to)
00330 {
00331 for (MessageIter &from = *this; !from.at_end(); ++from)
00332 {
00333 if (is_basic_type(from.type()))
00334 {
00335 debug_log("copying basic type: %c", from.type());
00336
00337 unsigned char value[8];
00338 from.get_basic(from.type(), &value);
00339 to.append_basic(from.type(), &value);
00340 }
00341 else
00342 {
00343 MessageIter from_container = from.recurse();
00344 char *sig = from_container.signature();
00345
00346 debug_log("copying compound type: %c[%s]", from.type(), sig);
00347
00348 MessageIter to_container(to.msg());
00349 dbus_message_iter_open_container
00350 (
00351 (DBusMessageIter *) & (to._iter),
00352 from.type(),
00353 from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
00354 (DBusMessageIter *) & (to_container._iter)
00355 );
00356
00357 from_container.copy_data(to_container);
00358 to.close_container(to_container);
00359 free(sig);
00360 }
00361 }
00362 }
00363
00364
00365
00366
00367 Message::Message()
00368 : _pvt(new Private)
00369 {
00370 }
00371
00372 Message::Message(Message::Private *p, bool incref)
00373 : _pvt(p)
00374 {
00375 if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
00376 }
00377
00378 Message::Message(const Message &m)
00379 : _pvt(m._pvt)
00380 {
00381 dbus_message_ref(_pvt->msg);
00382 }
00383
00384 Message::~Message()
00385 {
00386 dbus_message_unref(_pvt->msg);
00387 }
00388
00389 Message &Message::operator = (const Message &m)
00390 {
00391 if (&m != this)
00392 {
00393 dbus_message_unref(_pvt->msg);
00394 _pvt = m._pvt;
00395 dbus_message_ref(_pvt->msg);
00396 }
00397 return *this;
00398 }
00399
00400 Message Message::copy()
00401 {
00402 Private *pvt = new Private(dbus_message_copy(_pvt->msg));
00403 return Message(pvt);
00404 }
00405
00406 bool Message::append(int first_type, ...)
00407 {
00408 va_list vl;
00409 va_start(vl, first_type);
00410
00411 bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
00412
00413 va_end(vl);
00414 return b;
00415 }
00416
00417 void Message::terminate()
00418 {
00419 dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
00420 }
00421
00422 int Message::type() const
00423 {
00424 return dbus_message_get_type(_pvt->msg);
00425 }
00426
00427 int Message::serial() const
00428 {
00429 return dbus_message_get_serial(_pvt->msg);
00430 }
00431
00432 int Message::reply_serial() const
00433 {
00434 return dbus_message_get_reply_serial(_pvt->msg);
00435 }
00436
00437 bool Message::reply_serial(int s)
00438 {
00439 return dbus_message_set_reply_serial(_pvt->msg, s);
00440 }
00441
00442 const char *Message::sender() const
00443 {
00444 return dbus_message_get_sender(_pvt->msg);
00445 }
00446
00447 bool Message::sender(const char *s)
00448 {
00449 return dbus_message_set_sender(_pvt->msg, s);
00450 }
00451
00452 const char *Message::destination() const
00453 {
00454 return dbus_message_get_destination(_pvt->msg);
00455 }
00456
00457 bool Message::destination(const char *s)
00458 {
00459 return dbus_message_set_destination(_pvt->msg, s);
00460 }
00461
00462 bool Message::is_error() const
00463 {
00464 return type() == DBUS_MESSAGE_TYPE_ERROR;
00465 }
00466
00467 bool Message::is_signal(const char *interface, const char *member) const
00468 {
00469 return dbus_message_is_signal(_pvt->msg, interface, member);
00470 }
00471
00472 MessageIter Message::writer()
00473 {
00474 MessageIter iter(*this);
00475 dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
00476 return iter;
00477 }
00478
00479 MessageIter Message::reader() const
00480 {
00481 MessageIter iter(const_cast<Message &>(*this));
00482 dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
00483 return iter;
00484 }
00485
00486
00487
00488
00489 ErrorMessage::ErrorMessage()
00490 {
00491 _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
00492 }
00493
00494 ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
00495 {
00496 _pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
00497 }
00498
00499 bool ErrorMessage::operator == (const ErrorMessage &m) const
00500 {
00501 return dbus_message_is_error(_pvt->msg, m.name());
00502 }
00503
00504 const char *ErrorMessage::name() const
00505 {
00506 return dbus_message_get_error_name(_pvt->msg);
00507 }
00508
00509 bool ErrorMessage::name(const char *n)
00510 {
00511 return dbus_message_set_error_name(_pvt->msg, n);
00512 }
00513
00514
00515
00516
00517 SignalMessage::SignalMessage(const char *name)
00518 {
00519 _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
00520 member(name);
00521 }
00522
00523 SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
00524 {
00525 _pvt->msg = dbus_message_new_signal(path, interface, name);
00526 }
00527
00528 bool SignalMessage::operator == (const SignalMessage &m) const
00529 {
00530 return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
00531 }
00532
00533 const char *SignalMessage::interface() const
00534 {
00535 return dbus_message_get_interface(_pvt->msg);
00536 }
00537
00538 bool SignalMessage::interface(const char *i)
00539 {
00540 return dbus_message_set_interface(_pvt->msg, i);
00541 }
00542
00543 const char *SignalMessage::member() const
00544 {
00545 return dbus_message_get_member(_pvt->msg);
00546 }
00547
00548 bool SignalMessage::member(const char *m)
00549 {
00550 return dbus_message_set_member(_pvt->msg, m);
00551 }
00552
00553 const char *SignalMessage::path() const
00554 {
00555 return dbus_message_get_path(_pvt->msg);
00556 }
00557
00558 char **SignalMessage::path_split() const
00559 {
00560 char **p;
00561 dbus_message_get_path_decomposed(_pvt->msg, &p);
00562 return p;
00563 }
00564
00565 bool SignalMessage::path(const char *p)
00566 {
00567 return dbus_message_set_path(_pvt->msg, p);
00568 }
00569
00570
00571
00572
00573 CallMessage::CallMessage()
00574 {
00575 _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
00576 }
00577
00578 CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
00579 {
00580 _pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
00581 }
00582
00583 bool CallMessage::operator == (const CallMessage &m) const
00584 {
00585 return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
00586 }
00587
00588 const char *CallMessage::interface() const
00589 {
00590 return dbus_message_get_interface(_pvt->msg);
00591 }
00592
00593 bool CallMessage::interface(const char *i)
00594 {
00595 return dbus_message_set_interface(_pvt->msg, i);
00596 }
00597
00598 const char *CallMessage::member() const
00599 {
00600 return dbus_message_get_member(_pvt->msg);
00601 }
00602
00603 bool CallMessage::member(const char *m)
00604 {
00605 return dbus_message_set_member(_pvt->msg, m);
00606 }
00607
00608 const char *CallMessage::path() const
00609 {
00610 return dbus_message_get_path(_pvt->msg);
00611 }
00612
00613 char **CallMessage::path_split() const
00614 {
00615 char **p;
00616 dbus_message_get_path_decomposed(_pvt->msg, &p);
00617 return p;
00618 }
00619
00620 bool CallMessage::path(const char *p)
00621 {
00622 return dbus_message_set_path(_pvt->msg, p);
00623 }
00624
00625 const char *CallMessage::signature() const
00626 {
00627 return dbus_message_get_signature(_pvt->msg);
00628 }
00629
00630
00631
00632
00633 ReturnMessage::ReturnMessage(const CallMessage &callee)
00634 {
00635 _pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
00636 }
00637
00638 const char *ReturnMessage::signature() const
00639 {
00640 return dbus_message_get_signature(_pvt->msg);
00641 }
00642