message.cpp
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 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include <dbus-c++/message.h>
29 
30 #include <dbus/dbus.h>
31 #include <cstdlib>
32 
33 #include "internalerror.h"
34 #include "message_p.h"
35 
36 using namespace DBus;
37 
38 /*
39 */
40 
42 {
43  return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
44 }
45 
47 {
48  return type() == DBUS_TYPE_INVALID;
49 }
50 
52 {
53  return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
54 }
55 
57 {
58  dbus_message_iter_next((DBusMessageIter *)&_iter);
59  return (*this);
60 }
61 
63 {
64  MessageIter copy(*this);
65  ++(*this);
66  return copy;
67 }
68 
69 bool MessageIter::append_basic(int type_id, void *value)
70 {
71  return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
72 }
73 
74 void MessageIter::get_basic(int type_id, void *ptr)
75 {
76  if (type() != type_id)
77  throw ErrorInvalidArgs("type mismatch");
78 
79  dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
80 }
81 
82 bool MessageIter::append_byte(unsigned char b)
83 {
84  return append_basic(DBUS_TYPE_BYTE, &b);
85 }
86 
87 unsigned char MessageIter::get_byte()
88 {
89  unsigned char b;
90  get_basic(DBUS_TYPE_BYTE, &b);
91  return b;
92 }
93 
95 {
96  dbus_bool_t db = b;
97  return append_basic(DBUS_TYPE_BOOLEAN, &db);
98 }
99 
101 {
102  dbus_bool_t db;
103  get_basic(DBUS_TYPE_BOOLEAN, &db);
104  return (bool)db;
105 }
106 
107 bool MessageIter::append_int16(signed short i)
108 {
109  return append_basic(DBUS_TYPE_INT16, &i);
110 }
111 
113 {
114  signed short i;
115  get_basic(DBUS_TYPE_INT16, &i);
116  return i;
117 }
118 
119 bool MessageIter::append_uint16(unsigned short u)
120 {
121  return append_basic(DBUS_TYPE_UINT16, &u);
122 }
123 
124 unsigned short MessageIter::get_uint16()
125 {
126  unsigned short u;
127  get_basic(DBUS_TYPE_UINT16, &u);
128  return u;
129 }
130 
131 bool MessageIter::append_int32(signed int i)
132 {
133  return append_basic(DBUS_TYPE_INT32, &i);
134 }
135 
137 {
138  signed int i;
139  get_basic(DBUS_TYPE_INT32, &i);
140  return i;
141 }
142 
143 bool MessageIter::append_uint32(unsigned int u)
144 {
145  return append_basic(DBUS_TYPE_UINT32, &u);
146 }
147 
149 {
150  unsigned int u;
151  get_basic(DBUS_TYPE_UINT32, &u);
152  return u;
153 }
154 
155 signed long long MessageIter::get_int64()
156 {
157  signed long long i;
158  get_basic(DBUS_TYPE_INT64, &i);
159  return i;
160 }
161 
162 bool MessageIter::append_int64(signed long long i)
163 {
164  return append_basic(DBUS_TYPE_INT64, &i);
165 }
166 
167 unsigned long long MessageIter::get_uint64()
168 {
169  unsigned long long u;
170  get_basic(DBUS_TYPE_UINT64, &u);
171  return u;
172 }
173 
174 bool MessageIter::append_uint64(unsigned long long u)
175 {
176  return append_basic(DBUS_TYPE_UINT64, &u);
177 }
178 
180 {
181  double d;
182  get_basic(DBUS_TYPE_DOUBLE, &d);
183  return d;
184 }
185 
187 {
188  return append_basic(DBUS_TYPE_DOUBLE, &d);
189 }
190 
191 bool MessageIter::append_string(const char *chars)
192 {
193  return append_basic(DBUS_TYPE_STRING, &chars);
194 }
195 
197 {
198  char *chars;
199  get_basic(DBUS_TYPE_STRING, &chars);
200  return chars;
201 }
202 
203 bool MessageIter::append_path(const char *chars)
204 {
205  return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
206 }
207 
209 {
210  char *chars;
211  get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
212  return chars;
213 }
214 
215 bool MessageIter::append_signature(const char *chars)
216 {
217  return append_basic(DBUS_TYPE_SIGNATURE, &chars);
218 }
219 
221 {
222  char *chars;
223  get_basic(DBUS_TYPE_SIGNATURE, &chars);
224  return chars;
225 }
226 
228 {
229  MessageIter iter(msg());
230  dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *) & (iter._iter));
231  return iter;
232 }
233 
235 {
236  return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
237 }
238 
239 bool MessageIter::append_array(char type, const void *ptr, size_t length)
240 {
241  return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
242 }
243 
245 {
246  return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
247 }
248 
250 {
251  int length;
252  dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
253  return length;
254 }
255 
257 {
258  return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
259 }
260 
262 {
263  return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
264 }
265 
267 {
268  MessageIter arr(msg());
269  dbus_message_iter_open_container(
270  (DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter)
271  );
272  return arr;
273 }
274 
276 {
277  MessageIter var(msg());
278  dbus_message_iter_open_container(
279  (DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter)
280  );
281  return var;
282 }
283 
285 {
286  MessageIter stu(msg());
287  dbus_message_iter_open_container(
288  (DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter)
289  );
290  return stu;
291 }
292 
294 {
295  MessageIter ent(msg());
296  dbus_message_iter_open_container(
297  (DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter)
298  );
299  return ent;
300 }
301 
303 {
304  dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *) & (container._iter));
305 }
306 
307 static bool is_basic_type(int typecode)
308 {
309  switch (typecode)
310  {
311  case 'y':
312  case 'b':
313  case 'n':
314  case 'q':
315  case 'i':
316  case 'u':
317  case 'x':
318  case 't':
319  case 'd':
320  case 's':
321  case 'o':
322  case 'g':
323  return true;
324  default:
325  return false;
326  }
327 }
328 
330 {
331  for (MessageIter &from = *this; !from.at_end(); ++from)
332  {
333  if (is_basic_type(from.type()))
334  {
335  debug_log("copying basic type: %c", from.type());
336 
337  unsigned char value[8];
338  from.get_basic(from.type(), &value);
339  to.append_basic(from.type(), &value);
340  }
341  else
342  {
343  MessageIter from_container = from.recurse();
344  char *sig = from_container.signature();
345 
346  debug_log("copying compound type: %c[%s]", from.type(), sig);
347 
348  MessageIter to_container(to.msg());
349  dbus_bool_t ret = dbus_message_iter_open_container
350  (
351  (DBusMessageIter *) & (to._iter),
352  from.type(),
353  (from.type() == DBUS_TYPE_VARIANT || from.type() == DBUS_TYPE_ARRAY) ? sig : NULL,
354  (DBusMessageIter *) & (to_container._iter)
355  );
356  if (!ret)
357  {
358  throw ErrorNoMemory("Unable to append container");
359  }
360 
361  from_container.copy_data(to_container);
362  to.close_container(to_container);
363  free(sig);
364  }
365  }
366 }
367 
368 /*
369 */
370 
372  : _pvt(new Private)
373 {
374 }
375 
376 Message::Message(Message::Private *p, bool incref)
377  : _pvt(p)
378 {
379  if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
380 }
381 
383  : _pvt(m._pvt)
384 {
385  dbus_message_ref(_pvt->msg);
386 }
387 
389 {
390  dbus_message_unref(_pvt->msg);
391 }
392 
394 {
395  if (&m != this)
396  {
397  dbus_message_unref(_pvt->msg);
398  _pvt = m._pvt;
399  dbus_message_ref(_pvt->msg);
400  }
401  return *this;
402 }
403 
405 {
406  Private *pvt = new Private(dbus_message_copy(_pvt->msg));
407  return Message(pvt);
408 }
409 
410 bool Message::append(int first_type, ...)
411 {
412  va_list vl;
413  va_start(vl, first_type);
414 
415  bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
416 
417  va_end(vl);
418  return b;
419 }
420 
422 {
423  dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
424 }
425 
426 int Message::type() const
427 {
428  return dbus_message_get_type(_pvt->msg);
429 }
430 
431 int Message::serial() const
432 {
433  return dbus_message_get_serial(_pvt->msg);
434 }
435 
437 {
438  return dbus_message_get_reply_serial(_pvt->msg);
439 }
440 
442 {
443  return dbus_message_set_reply_serial(_pvt->msg, s);
444 }
445 
446 const char *Message::sender() const
447 {
448  return dbus_message_get_sender(_pvt->msg);
449 }
450 
451 bool Message::sender(const char *s)
452 {
453  return dbus_message_set_sender(_pvt->msg, s);
454 }
455 
456 const char *Message::destination() const
457 {
458  return dbus_message_get_destination(_pvt->msg);
459 }
460 
461 bool Message::destination(const char *s)
462 {
463  return dbus_message_set_destination(_pvt->msg, s);
464 }
465 
466 bool Message::is_error() const
467 {
468  return type() == DBUS_MESSAGE_TYPE_ERROR;
469 }
470 
471 bool Message::is_signal(const char *interface, const char *member) const
472 {
473  return dbus_message_is_signal(_pvt->msg, interface, member);
474 }
475 
477 {
478  MessageIter iter(*this);
479  dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
480  return iter;
481 }
482 
484 {
485  MessageIter iter(const_cast<Message &>(*this));
486  dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
487  return iter;
488 }
489 
490 /*
491 */
492 
494 {
495  _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
496 }
497 
498 ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
499 {
500  _pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
501 }
502 
504 {
505  return dbus_message_is_error(_pvt->msg, m.name());
506 }
507 
508 const char *ErrorMessage::name() const
509 {
510  return dbus_message_get_error_name(_pvt->msg);
511 }
512 
513 bool ErrorMessage::name(const char *n)
514 {
515  return dbus_message_set_error_name(_pvt->msg, n);
516 }
517 
518 /*
519 */
520 
522 {
523  _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
524  member(name);
525 }
526 
527 SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
528 {
529  _pvt->msg = dbus_message_new_signal(path, interface, name);
530 }
531 
533 {
534  return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
535 }
536 
537 const char *SignalMessage::interface() const
538 {
539  return dbus_message_get_interface(_pvt->msg);
540 }
541 
542 bool SignalMessage::interface(const char *i)
543 {
544  return dbus_message_set_interface(_pvt->msg, i);
545 }
546 
547 const char *SignalMessage::member() const
548 {
549  return dbus_message_get_member(_pvt->msg);
550 }
551 
552 bool SignalMessage::member(const char *m)
553 {
554  return dbus_message_set_member(_pvt->msg, m);
555 }
556 
557 const char *SignalMessage::path() const
558 {
559  return dbus_message_get_path(_pvt->msg);
560 }
561 
563 {
564  char **p;
565  dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
566  return p;
567 }
568 
569 bool SignalMessage::path(const char *p)
570 {
571  return dbus_message_set_path(_pvt->msg, p);
572 }
573 
574 /*
575 */
576 
578 {
579  _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
580 }
581 
582 CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
583 {
584  _pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
585 }
586 
588 {
589  return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
590 }
591 
592 const char *CallMessage::interface() const
593 {
594  return dbus_message_get_interface(_pvt->msg);
595 }
596 
597 bool CallMessage::interface(const char *i)
598 {
599  return dbus_message_set_interface(_pvt->msg, i);
600 }
601 
602 const char *CallMessage::member() const
603 {
604  return dbus_message_get_member(_pvt->msg);
605 }
606 
607 bool CallMessage::member(const char *m)
608 {
609  return dbus_message_set_member(_pvt->msg, m);
610 }
611 
612 const char *CallMessage::path() const
613 {
614  return dbus_message_get_path(_pvt->msg);
615 }
616 
618 {
619  char **p;
620  dbus_message_get_path_decomposed(_pvt->msg, &p);
621  return p;
622 }
623 
624 bool CallMessage::path(const char *p)
625 {
626  return dbus_message_set_path(_pvt->msg, p);
627 }
628 
629 const char *CallMessage::signature() const
630 {
631  return dbus_message_get_signature(_pvt->msg);
632 }
633 
634 /*
635 */
636 
638 {
639  _pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
640 }
641 
642 const char *ReturnMessage::signature() const
643 {
644  return dbus_message_get_signature(_pvt->msg);
645 }
646 
DXXAPILOCAL bool append_basic(int type_id, void *value)
Definition: message.cpp:69
MessageIter new_array(const char *sig)
Definition: message.cpp:266
MessageIter & operator++()
Definition: message.cpp:56
signed int get_int32()
Definition: message.cpp:136
const char * destination() const
Definition: message.cpp:456
bool append_bool(bool b)
Definition: message.cpp:94
bool append_path(const char *chars)
Definition: message.cpp:203
const char * interface() const
Definition: message.cpp:592
const char * path() const
Definition: message.cpp:612
const char * name() const
Definition: message.cpp:508
bool append_int16(signed short i)
Definition: message.cpp:107
const char * member() const
Definition: message.cpp:547
bool append_double(double d)
Definition: message.cpp:186
bool append_byte(unsigned char byte)
Definition: message.cpp:82
MessageIter new_dict_entry()
Definition: message.cpp:293
bool append(int first_type,...)
Definition: message.cpp:410
void copy_data(MessageIter &to)
Definition: message.cpp:329
MessageIter recurse()
Definition: message.cpp:227
const char * path() const
Definition: message.cpp:557
char ** path_split() const
Definition: message.cpp:562
bool operator==(const CallMessage &) const
Definition: message.cpp:587
SignalMessage(const char *name)
Definition: message.cpp:521
DXXAPI LogFunction debug_log
Definition: debug.cpp:55
MessageIter new_variant(const char *sig)
Definition: message.cpp:275
bool append_signature(const char *chars)
Definition: message.cpp:215
DXXAPILOCAL void get_basic(int type_id, void *ptr)
Definition: message.cpp:74
unsigned char get_byte()
Definition: message.cpp:87
Message copy()
Definition: message.cpp:404
const char * member() const
Definition: message.cpp:602
unsigned long long get_uint64()
Definition: message.cpp:167
char * signature() const
Definition: message.cpp:234
const char * interface() const
Definition: message.cpp:537
bool append_int64(signed long long i)
Definition: message.cpp:162
bool is_signal(const char *interface, const char *member) const
Definition: message.cpp:471
bool append_string(const char *chars)
Definition: message.cpp:191
void terminate()
Definition: message.cpp:421
unsigned int get_uint32()
Definition: message.cpp:148
char ** path_split() const
Definition: message.cpp:617
ReturnMessage(const CallMessage &callee)
Definition: message.cpp:637
const char * get_path()
Definition: message.cpp:208
const char * signature() const
Definition: message.cpp:642
const char * sender() const
Definition: message.cpp:446
signed short get_int16()
Definition: message.cpp:112
bool operator==(const ErrorMessage &) const
Definition: message.cpp:503
void close_container(MessageIter &container)
Definition: message.cpp:302
unsigned char _iter[sizeof(void *) *3+sizeof(int) *11]
Definition: message.h:151
MessageIter reader() const
Definition: message.cpp:483
int serial() const
Definition: message.cpp:431
bool append_int32(signed int i)
Definition: message.cpp:131
Message & operator=(const Message &m)
Definition: message.cpp:393
RefPtrI< Private > _pvt
Definition: message.h:208
static bool is_basic_type(int typecode)
Definition: message.cpp:307
int type() const
Definition: message.cpp:426
const char * signature() const
Definition: message.cpp:629
bool append_uint16(unsigned short u)
Definition: message.cpp:119
bool append_uint64(unsigned long long i)
Definition: message.cpp:174
bool is_error() const
Definition: message.cpp:466
Message & msg() const
Definition: message.h:134
signed long long get_int64()
Definition: message.cpp:155
int get_array(void *ptr)
Definition: message.cpp:249
double get_double()
Definition: message.cpp:179
bool operator==(const SignalMessage &) const
Definition: message.cpp:532
unsigned short get_uint16()
Definition: message.cpp:124
bool append_uint32(unsigned int u)
Definition: message.cpp:143
int reply_serial() const
Definition: message.cpp:436
const char * get_string()
Definition: message.cpp:196
const char * get_signature()
Definition: message.cpp:220
bool append_array(char type, const void *ptr, size_t length)
Definition: message.cpp:239
MessageIter writer()
Definition: message.cpp:476
MessageIter new_struct()
Definition: message.cpp:284