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