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
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_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
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
410bool 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
426int Message::type() const
427{
428 return dbus_message_get_type(_pvt->msg);
429}
430
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
446const char *Message::sender() const
447{
448 return dbus_message_get_sender(_pvt->msg);
449}
450
451bool Message::sender(const char *s)
452{
453 return dbus_message_set_sender(_pvt->msg, s);
454}
455
456const char *Message::destination() const
457{
458 return dbus_message_get_destination(_pvt->msg);
459}
460
461bool Message::destination(const char *s)
462{
463 return dbus_message_set_destination(_pvt->msg, s);
464}
465
467{
468 return type() == DBUS_MESSAGE_TYPE_ERROR;
469}
470
471bool 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
498ErrorMessage::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
508const char *ErrorMessage::name() const
509{
510 return dbus_message_get_error_name(_pvt->msg);
511}
512
513bool 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
527SignalMessage::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
537const char *SignalMessage::interface() const
538{
539 return dbus_message_get_interface(_pvt->msg);
540}
541
542bool SignalMessage::interface(const char *i)
543{
544 return dbus_message_set_interface(_pvt->msg, i);
545}
546
547const char *SignalMessage::member() const
548{
549 return dbus_message_get_member(_pvt->msg);
550}
551
552bool SignalMessage::member(const char *m)
553{
554 return dbus_message_set_member(_pvt->msg, m);
555}
556
557const 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
569bool 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
582CallMessage::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
592const char *CallMessage::interface() const
593{
594 return dbus_message_get_interface(_pvt->msg);
595}
596
597bool CallMessage::interface(const char *i)
598{
599 return dbus_message_set_interface(_pvt->msg, i);
600}
601
602const char *CallMessage::member() const
603{
604 return dbus_message_get_member(_pvt->msg);
605}
606
607bool CallMessage::member(const char *m)
608{
609 return dbus_message_set_member(_pvt->msg, m);
610}
611
612const 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
624bool CallMessage::path(const char *p)
625{
626 return dbus_message_set_path(_pvt->msg, p);
627}
628
629const 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
642const char *ReturnMessage::signature() const
643{
644 return dbus_message_get_signature(_pvt->msg);
645}
646
char ** path_split() const
Definition message.cpp:617
bool operator==(const CallMessage &) const
Definition message.cpp:587
const char * member() const
Definition message.cpp:602
const char * signature() const
Definition message.cpp:629
const char * path() const
Definition message.cpp:612
const char * interface() const
Definition message.cpp:592
const char * name() const
Definition message.cpp:508
bool operator==(const ErrorMessage &) const
Definition message.cpp:503
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
Message(Private *, bool incref=true)
Definition message.cpp:376
RefPtrI< Private > _pvt
Definition message.h:208
Message copy()
Definition message.cpp:404
friend class ReturnMessage
Definition message.h:213
MessageIter writer()
Definition message.cpp:476
bool is_signal(const char *interface, const char *member) const
Definition message.cpp:471
void terminate()
Definition message.cpp:421
int reply_serial() const
Definition message.cpp:436
bool append(int first_type,...)
Definition message.cpp:410
bool is_error() const
Definition message.cpp:466
Message & operator=(const Message &m)
Definition message.cpp:393
const char * destination() const
Definition message.cpp:456
const char * sender() const
Definition message.cpp:446
MessageIter reader() const
Definition message.cpp:483
friend class MessageIter
Definition message.h:214
int type() const
Definition message.cpp:426
int serial() const
Definition message.cpp:431
const char * signature() const
Definition message.cpp:642
const char * member() const
Definition message.cpp:547
const char * interface() const
Definition message.cpp:537
const char * path() const
Definition message.cpp:557
SignalMessage(const char *name)
Definition message.cpp:521
char ** path_split() const
Definition message.cpp:562
bool operator==(const SignalMessage &) const
Definition message.cpp:532
static bool is_basic_type(int typecode)
Definition message.cpp:307
DXXAPI LogFunction debug_log
Definition debug.cpp:55