message.cpp
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 #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); //todo: return as a std::vector ? 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