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_message_iter_open_container
350  (
351  (DBusMessageIter *) & (to._iter),
352  from.type(),
353  from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
354  (DBusMessageIter *) & (to_container._iter)
355  );
356 
357  from_container.copy_data(to_container);
358  to.close_container(to_container);
359  free(sig);
360  }
361  }
362 }
363 
364 /*
365 */
366 
368  : _pvt(new Private)
369 {
370 }
371 
372 Message::Message(Message::Private *p, bool incref)
373  : _pvt(p)
374 {
375  if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
376 }
377 
379  : _pvt(m._pvt)
380 {
381  dbus_message_ref(_pvt->msg);
382 }
383 
385 {
386  dbus_message_unref(_pvt->msg);
387 }
388 
390 {
391  if (&m != this)
392  {
393  dbus_message_unref(_pvt->msg);
394  _pvt = m._pvt;
395  dbus_message_ref(_pvt->msg);
396  }
397  return *this;
398 }
399 
401 {
402  Private *pvt = new Private(dbus_message_copy(_pvt->msg));
403  return Message(pvt);
404 }
405 
406 bool Message::append(int first_type, ...)
407 {
408  va_list vl;
409  va_start(vl, first_type);
410 
411  bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
412 
413  va_end(vl);
414  return b;
415 }
416 
418 {
419  dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
420 }
421 
422 int Message::type() const
423 {
424  return dbus_message_get_type(_pvt->msg);
425 }
426 
427 int Message::serial() const
428 {
429  return dbus_message_get_serial(_pvt->msg);
430 }
431 
433 {
434  return dbus_message_get_reply_serial(_pvt->msg);
435 }
436 
438 {
439  return dbus_message_set_reply_serial(_pvt->msg, s);
440 }
441 
442 const char *Message::sender() const
443 {
444  return dbus_message_get_sender(_pvt->msg);
445 }
446 
447 bool Message::sender(const char *s)
448 {
449  return dbus_message_set_sender(_pvt->msg, s);
450 }
451 
452 const char *Message::destination() const
453 {
454  return dbus_message_get_destination(_pvt->msg);
455 }
456 
457 bool Message::destination(const char *s)
458 {
459  return dbus_message_set_destination(_pvt->msg, s);
460 }
461 
462 bool Message::is_error() const
463 {
464  return type() == DBUS_MESSAGE_TYPE_ERROR;
465 }
466 
467 bool Message::is_signal(const char *interface, const char *member) const
468 {
469  return dbus_message_is_signal(_pvt->msg, interface, member);
470 }
471 
473 {
474  MessageIter iter(*this);
475  dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
476  return iter;
477 }
478 
480 {
481  MessageIter iter(const_cast<Message &>(*this));
482  dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
483  return iter;
484 }
485 
486 /*
487 */
488 
490 {
491  _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
492 }
493 
494 ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
495 {
496  _pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
497 }
498 
500 {
501  return dbus_message_is_error(_pvt->msg, m.name());
502 }
503 
504 const char *ErrorMessage::name() const
505 {
506  return dbus_message_get_error_name(_pvt->msg);
507 }
508 
509 bool ErrorMessage::name(const char *n)
510 {
511  return dbus_message_set_error_name(_pvt->msg, n);
512 }
513 
514 /*
515 */
516 
518 {
519  _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
520  member(name);
521 }
522 
523 SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
524 {
525  _pvt->msg = dbus_message_new_signal(path, interface, name);
526 }
527 
529 {
530  return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
531 }
532 
533 const char *SignalMessage::interface() const
534 {
535  return dbus_message_get_interface(_pvt->msg);
536 }
537 
538 bool SignalMessage::interface(const char *i)
539 {
540  return dbus_message_set_interface(_pvt->msg, i);
541 }
542 
543 const char *SignalMessage::member() const
544 {
545  return dbus_message_get_member(_pvt->msg);
546 }
547 
548 bool SignalMessage::member(const char *m)
549 {
550  return dbus_message_set_member(_pvt->msg, m);
551 }
552 
553 const char *SignalMessage::path() const
554 {
555  return dbus_message_get_path(_pvt->msg);
556 }
557 
559 {
560  char **p;
561  dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
562  return p;
563 }
564 
565 bool SignalMessage::path(const char *p)
566 {
567  return dbus_message_set_path(_pvt->msg, p);
568 }
569 
570 /*
571 */
572 
574 {
575  _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
576 }
577 
578 CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
579 {
580  _pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
581 }
582 
584 {
585  return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
586 }
587 
588 const char *CallMessage::interface() const
589 {
590  return dbus_message_get_interface(_pvt->msg);
591 }
592 
593 bool CallMessage::interface(const char *i)
594 {
595  return dbus_message_set_interface(_pvt->msg, i);
596 }
597 
598 const char *CallMessage::member() const
599 {
600  return dbus_message_get_member(_pvt->msg);
601 }
602 
603 bool CallMessage::member(const char *m)
604 {
605  return dbus_message_set_member(_pvt->msg, m);
606 }
607 
608 const char *CallMessage::path() const
609 {
610  return dbus_message_get_path(_pvt->msg);
611 }
612 
614 {
615  char **p;
616  dbus_message_get_path_decomposed(_pvt->msg, &p);
617  return p;
618 }
619 
620 bool CallMessage::path(const char *p)
621 {
622  return dbus_message_set_path(_pvt->msg, p);
623 }
624 
625 const char *CallMessage::signature() const
626 {
627  return dbus_message_get_signature(_pvt->msg);
628 }
629 
630 /*
631 */
632 
634 {
635  _pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
636 }
637 
638 const char *ReturnMessage::signature() const
639 {
640  return dbus_message_get_signature(_pvt->msg);
641 }
642 
const char * destination() const
Definition: message.cpp:452
bool append_array(char type, const void *ptr, size_t length)
Definition: message.cpp:239
const char * sender() const
Definition: message.cpp:442
const char * get_string()
Definition: message.cpp:196
bool operator==(const SignalMessage &) const
Definition: message.cpp:528
const char * get_signature()
Definition: message.cpp:220
signed long long get_int64()
Definition: message.cpp:155
friend class ReturnMessage
Definition: message.h:213
DXXAPILOCAL bool append_basic(int type_id, void *value)
Definition: message.cpp:69
bool append_signature(const char *chars)
Definition: message.cpp:215
DXXAPILOCAL void get_basic(int type_id, void *ptr)
Definition: message.cpp:74
signed int get_int32()
Definition: message.cpp:136
bool append_bool(bool b)
Definition: message.cpp:94
bool operator==(const ErrorMessage &) const
Definition: message.cpp:499
Message copy()
Definition: message.cpp:400
bool append_string(const char *chars)
Definition: message.cpp:191
bool append_int16(signed short i)
Definition: message.cpp:107
const char * path() const
Definition: message.cpp:608
MessageIter & operator++()
Definition: message.cpp:56
unsigned char get_byte()
Definition: message.cpp:87
static bool is_basic_type(int typecode)
Definition: message.cpp:307
char * signature() const
Definition: message.cpp:234
bool append_path(const char *chars)
Definition: message.cpp:203
unsigned long long get_uint64()
Definition: message.cpp:167
bool append_int64(signed long long i)
Definition: message.cpp:162
bool append_uint64(unsigned long long i)
Definition: message.cpp:174
bool append_double(double d)
Definition: message.cpp:186
int type() const
Definition: message.cpp:422
const char * get_path()
Definition: message.cpp:208
bool append_uint32(unsigned int u)
Definition: message.cpp:143
signed short get_int16()
Definition: message.cpp:112
const char * signature() const
Definition: message.cpp:638
char ** path_split() const
Definition: message.cpp:558
void copy_data(MessageIter &to)
Definition: message.cpp:329
MessageIter new_struct()
Definition: message.cpp:284
int serial() const
Definition: message.cpp:427
MessageIter recurse()
Definition: message.cpp:227
int reply_serial() const
Definition: message.cpp:432
bool is_error() const
Definition: message.cpp:462
const char * signature() const
Definition: message.cpp:625
bool is_signal(const char *interface, const char *member) const
Definition: message.cpp:467
char ** path_split() const
Definition: message.cpp:613
unsigned short get_uint16()
Definition: message.cpp:124
bool operator==(const CallMessage &) const
Definition: message.cpp:583
unsigned int get_uint32()
Definition: message.cpp:148
unsigned char _iter[sizeof(void *) *3+sizeof(int) *11]
Definition: message.h:151
MessageIter reader() const
Definition: message.cpp:479
bool append_byte(unsigned char byte)
Definition: message.cpp:82
void close_container(MessageIter &container)
Definition: message.cpp:302
const char * member() const
Definition: message.cpp:598
int get_array(void *ptr)
Definition: message.cpp:249
DXXAPI LogFunction debug_log
Definition: debug.cpp:55
SignalMessage(const char *name)
Definition: message.cpp:517
double get_double()
Definition: message.cpp:179
RefPtrI< Private > _pvt
Definition: message.h:208
const char * member() const
Definition: message.cpp:543
bool append_int32(signed int i)
Definition: message.cpp:131
Message & operator=(const Message &m)
Definition: message.cpp:389
bool append_uint16(unsigned short u)
Definition: message.cpp:119
MessageIter writer()
Definition: message.cpp:472
const char * name() const
Definition: message.cpp:504
const char * interface() const
Definition: message.cpp:533
Message & msg() const
Definition: message.h:134
MessageIter new_dict_entry()
Definition: message.cpp:293
MessageIter new_variant(const char *sig)
Definition: message.cpp:275
bool append(int first_type,...)
Definition: message.cpp:406
MessageIter new_array(const char *sig)
Definition: message.cpp:266
const char * path() const
Definition: message.cpp:553
void terminate()
Definition: message.cpp:417
const char * interface() const
Definition: message.cpp:588