2005-02-24 Colin Walters <walters@verbum.org>
[platform/upstream/dbus.git] / dbus / dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-message.c  DBusMessage object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005  Red Hat Inc.
5  * Copyright (C) 2002, 2003  CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-internals.h"
26 #include "dbus-marshal-recursive.h"
27 #include "dbus-marshal-validate.h"
28 #include "dbus-marshal-byteswap.h"
29 #include "dbus-marshal-header.h"
30 #include "dbus-signature.h"
31 #include "dbus-message-private.h"
32 #include "dbus-object-tree.h"
33 #include "dbus-memory.h"
34 #include "dbus-list.h"
35 #include <string.h>
36
37 /**
38  * @defgroup DBusMessageInternals DBusMessage implementation details
39  * @ingroup DBusInternals
40  * @brief DBusMessage private implementation details.
41  *
42  * The guts of DBusMessage and its methods.
43  *
44  * @{
45  */
46
47 /* Not thread locked, but strictly const/read-only so should be OK
48  */
49 /** An static string representing an empty signature */
50 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str,  "");
51
52 /* these have wacky values to help trap uninitialized iterators;
53  * but has to fit in 3 bits
54  */
55 enum {
56   DBUS_MESSAGE_ITER_TYPE_READER = 3,
57   DBUS_MESSAGE_ITER_TYPE_WRITER = 7
58 };
59
60 /** typedef for internals of message iterator */
61 typedef struct DBusMessageRealIter DBusMessageRealIter;
62
63 /**
64  * @brief Internals of DBusMessageIter
65  *
66  * Object representing a position in a message. All fields are internal.
67  */
68 struct DBusMessageRealIter
69 {
70   DBusMessage *message; /**< Message used */
71   dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS; /**< stamp to detect invalid iters */
72   dbus_uint32_t iter_type : 3;      /**< whether this is a reader or writer iter */
73   dbus_uint32_t sig_refcount : 8;   /**< depth of open_signature() */
74   union
75   {
76     DBusTypeWriter writer; /**< writer */
77     DBusTypeReader reader; /**< reader */
78   } u; /**< the type writer or reader that does all the work */
79 };
80
81 static void
82 get_const_signature (DBusHeader        *header,
83                      const DBusString **type_str_p,
84                      int               *type_pos_p)
85 {
86   if (_dbus_header_get_field_raw (header,
87                                   DBUS_HEADER_FIELD_SIGNATURE,
88                                   type_str_p,
89                                   type_pos_p))
90     {
91       *type_pos_p += 1; /* skip the signature length which is 1 byte */
92     }
93   else
94     {
95       *type_str_p = &_dbus_empty_signature_str;
96       *type_pos_p = 0;
97     }
98 }
99
100 /**
101  * Swaps the message to compiler byte order if required
102  *
103  * @param message the message
104  */
105 static void
106 _dbus_message_byteswap (DBusMessage *message)
107 {
108   const DBusString *type_str;
109   int type_pos;
110   
111   if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
112     return;
113
114   _dbus_verbose ("Swapping message into compiler byte order\n");
115   
116   get_const_signature (&message->header, &type_str, &type_pos);
117   
118   _dbus_marshal_byteswap (type_str, type_pos,
119                           message->byte_order,
120                           DBUS_COMPILER_BYTE_ORDER,
121                           &message->body, 0);
122
123   message->byte_order = DBUS_COMPILER_BYTE_ORDER;
124   
125   _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
126 }
127
128 #define ensure_byte_order(message)                      \
129  if (message->byte_order != DBUS_COMPILER_BYTE_ORDER)   \
130    _dbus_message_byteswap (message)
131
132 /**
133  * Gets the data to be sent over the network for this message.
134  * The header and then the body should be written out.
135  * This function is guaranteed to always return the same
136  * data once a message is locked (with _dbus_message_lock()).
137  *
138  * @param message the message.
139  * @param header return location for message header data.
140  * @param body return location for message body data.
141  */
142 void
143 _dbus_message_get_network_data (DBusMessage          *message,
144                                 const DBusString    **header,
145                                 const DBusString    **body)
146 {
147   _dbus_assert (message->locked);
148
149   *header = &message->header.data;
150   *body = &message->body;
151 }
152
153 /**
154  * Sets the serial number of a message.
155  * This can only be done once on a message.
156  *
157  * @param message the message
158  * @param serial the serial
159  */
160 void
161 _dbus_message_set_serial (DBusMessage   *message,
162                           dbus_uint32_t  serial)
163 {
164   _dbus_assert (message != NULL);
165   _dbus_assert (!message->locked);
166   _dbus_assert (dbus_message_get_serial (message) == 0);
167
168   _dbus_header_set_serial (&message->header, serial);
169 }
170
171 /**
172  * Adds a counter to be incremented immediately with the
173  * size of this message, and decremented by the size
174  * of this message when this message if finalized.
175  * The link contains a counter with its refcount already
176  * incremented, but the counter itself not incremented.
177  * Ownership of link and counter refcount is passed to
178  * the message.
179  *
180  * @param message the message
181  * @param link link with counter as data
182  */
183 void
184 _dbus_message_add_size_counter_link (DBusMessage  *message,
185                                      DBusList     *link)
186 {
187   /* right now we don't recompute the delta when message
188    * size changes, and that's OK for current purposes
189    * I think, but could be important to change later.
190    * Do recompute it whenever there are no outstanding counters,
191    * since it's basically free.
192    */
193   if (message->size_counters == NULL)
194     {
195       message->size_counter_delta =
196         _dbus_string_get_length (&message->header.data) +
197         _dbus_string_get_length (&message->body);
198
199 #if 0
200       _dbus_verbose ("message has size %ld\n",
201                      message->size_counter_delta);
202 #endif
203     }
204
205   _dbus_list_append_link (&message->size_counters, link);
206
207   _dbus_counter_adjust (link->data, message->size_counter_delta);
208 }
209
210 /**
211  * Adds a counter to be incremented immediately with the
212  * size of this message, and decremented by the size
213  * of this message when this message if finalized.
214  *
215  * @param message the message
216  * @param counter the counter
217  * @returns #FALSE if no memory
218  */
219 dbus_bool_t
220 _dbus_message_add_size_counter (DBusMessage *message,
221                                 DBusCounter *counter)
222 {
223   DBusList *link;
224
225   link = _dbus_list_alloc_link (counter);
226   if (link == NULL)
227     return FALSE;
228
229   _dbus_counter_ref (counter);
230   _dbus_message_add_size_counter_link (message, link);
231
232   return TRUE;
233 }
234
235 /**
236  * Removes a counter tracking the size of this message, and decrements
237  * the counter by the size of this message.
238  *
239  * @param message the message
240  * @param link_return return the link used
241  * @param counter the counter
242  */
243 void
244 _dbus_message_remove_size_counter (DBusMessage  *message,
245                                    DBusCounter  *counter,
246                                    DBusList    **link_return)
247 {
248   DBusList *link;
249
250   link = _dbus_list_find_last (&message->size_counters,
251                                counter);
252   _dbus_assert (link != NULL);
253
254   _dbus_list_unlink (&message->size_counters,
255                      link);
256   if (link_return)
257     *link_return = link;
258   else
259     _dbus_list_free_link (link);
260
261   _dbus_counter_adjust (counter, - message->size_counter_delta);
262
263   _dbus_counter_unref (counter);
264 }
265
266 /**
267  * Locks a message. Allows checking that applications don't keep a
268  * reference to a message in the outgoing queue and change it
269  * underneath us. Messages are locked when they enter the outgoing
270  * queue (dbus_connection_send_message()), and the library complains
271  * if the message is modified while locked.
272  *
273  * @param message the message to lock.
274  */
275 void
276 _dbus_message_lock (DBusMessage  *message)
277 {
278   if (!message->locked)
279     {
280       _dbus_header_update_lengths (&message->header,
281                                    _dbus_string_get_length (&message->body));
282
283       /* must have a signature if you have a body */
284       _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
285                     dbus_message_get_signature (message) != NULL);
286
287       message->locked = TRUE;
288     }
289 }
290
291 static dbus_bool_t
292 set_or_delete_string_field (DBusMessage *message,
293                             int          field,
294                             int          typecode,
295                             const char  *value)
296 {
297   if (value == NULL)
298     return _dbus_header_delete_field (&message->header, field);
299   else
300     return _dbus_header_set_field_basic (&message->header,
301                                          field,
302                                          typecode,
303                                          &value);
304 }
305
306 #if 0
307 /* Probably we don't need to use this */
308 /**
309  * Sets the signature of the message, i.e. the arguments in the
310  * message payload. The signature includes only "in" arguments for
311  * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
312  * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
313  * what you might expect (it does not include the signature of the
314  * entire C++-style method).
315  *
316  * The signature is a string made up of type codes such as
317  * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also
318  * the value of #DBUS_TYPE_INVALID). The macros such as
319  * #DBUS_TYPE_INT32 evaluate to integers; to assemble a signature you
320  * may find it useful to use the string forms, such as
321  * #DBUS_TYPE_INT32_AS_STRING.
322  *
323  * An "unset" or #NULL signature is considered the same as an empty
324  * signature. In fact dbus_message_get_signature() will never return
325  * #NULL.
326  *
327  * @param message the message
328  * @param signature the type signature or #NULL to unset
329  * @returns #FALSE if no memory
330  */
331 static dbus_bool_t
332 _dbus_message_set_signature (DBusMessage *message,
333                              const char  *signature)
334 {
335   _dbus_return_val_if_fail (message != NULL, FALSE);
336   _dbus_return_val_if_fail (!message->locked, FALSE);
337   _dbus_return_val_if_fail (signature == NULL ||
338                             _dbus_check_is_valid_signature (signature));
339   /* can't delete the signature if you have a message body */
340   _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
341                             signature != NULL);
342
343   return set_or_delete_string_field (message,
344                                      DBUS_HEADER_FIELD_SIGNATURE,
345                                      DBUS_TYPE_SIGNATURE,
346                                      signature);
347 }
348 #endif
349
350 /** @} */
351
352 /**
353  * @defgroup DBusMessage DBusMessage
354  * @ingroup  DBus
355  * @brief Message to be sent or received over a DBusConnection.
356  *
357  * A DBusMessage is the most basic unit of communication over a
358  * DBusConnection. A DBusConnection represents a stream of messages
359  * received from a remote application, and a stream of messages
360  * sent to a remote application.
361  *
362  * @{
363  */
364
365 /**
366  * @typedef DBusMessage
367  *
368  * Opaque data type representing a message received from or to be
369  * sent to another application.
370  */
371
372 /**
373  * Returns the serial of a message or 0 if none has been specified.
374  * The message's serial number is provided by the application sending
375  * the message and is used to identify replies to this message.  All
376  * messages received on a connection will have a serial, but messages
377  * you haven't sent yet may return 0.
378  *
379  * @param message the message
380  * @returns the client serial
381  */
382 dbus_uint32_t
383 dbus_message_get_serial (DBusMessage *message)
384 {
385   _dbus_return_val_if_fail (message != NULL, 0);
386
387   return _dbus_header_get_serial (&message->header);
388 }
389
390 /**
391  * Sets the reply serial of a message (the client serial
392  * of the message this is a reply to).
393  *
394  * @param message the message
395  * @param reply_serial the client serial
396  * @returns #FALSE if not enough memory
397  */
398 dbus_bool_t
399 dbus_message_set_reply_serial (DBusMessage   *message,
400                                dbus_uint32_t  reply_serial)
401 {
402   _dbus_return_val_if_fail (message != NULL, FALSE);
403   _dbus_return_val_if_fail (!message->locked, FALSE);
404
405   return _dbus_header_set_field_basic (&message->header,
406                                        DBUS_HEADER_FIELD_REPLY_SERIAL,
407                                        DBUS_TYPE_UINT32,
408                                        &reply_serial);
409 }
410
411 /**
412  * Returns the serial that the message is a reply to or 0 if none.
413  *
414  * @param message the message
415  * @returns the reply serial
416  */
417 dbus_uint32_t
418 dbus_message_get_reply_serial  (DBusMessage *message)
419 {
420   dbus_uint32_t v_UINT32;
421
422   _dbus_return_val_if_fail (message != NULL, 0);
423
424   if (_dbus_header_get_field_basic (&message->header,
425                                     DBUS_HEADER_FIELD_REPLY_SERIAL,
426                                     DBUS_TYPE_UINT32,
427                                     &v_UINT32))
428     return v_UINT32;
429   else
430     return 0;
431 }
432
433 static void
434 free_size_counter (void *element,
435                    void *data)
436 {
437   DBusCounter *counter = element;
438   DBusMessage *message = data;
439
440   _dbus_counter_adjust (counter, - message->size_counter_delta);
441
442   _dbus_counter_unref (counter);
443 }
444
445 static void
446 dbus_message_finalize (DBusMessage *message)
447 {
448   _dbus_assert (message->refcount.value == 0);
449
450   /* This calls application callbacks! */
451   _dbus_data_slot_list_free (&message->slot_list);
452
453   _dbus_list_foreach (&message->size_counters,
454                       free_size_counter, message);
455   _dbus_list_clear (&message->size_counters);
456
457   _dbus_header_free (&message->header);
458   _dbus_string_free (&message->body);
459
460   _dbus_assert (message->refcount.value == 0);
461   
462   dbus_free (message);
463 }
464
465 /* Message Cache
466  *
467  * We cache some DBusMessage to reduce the overhead of allocating
468  * them.  In my profiling this consistently made about an 8%
469  * difference.  It avoids the malloc for the message, the malloc for
470  * the slot list, the malloc for the header string and body string,
471  * and the associated free() calls. It does introduce another global
472  * lock which could be a performance issue in certain cases.
473  *
474  * For the echo client/server the round trip time goes from around
475  * .000077 to .000069 with the message cache on my laptop. The sysprof
476  * change is as follows (numbers are cumulative percentage):
477  *
478  *  with message cache implemented as array as it is now (0.000069 per):
479  *    new_empty_header           1.46
480  *      mutex_lock               0.56    # i.e. _DBUS_LOCK(message_cache)
481  *      mutex_unlock             0.25
482  *      self                     0.41
483  *    unref                      2.24
484  *      self                     0.68
485  *      list_clear               0.43
486  *      mutex_lock               0.33    # i.e. _DBUS_LOCK(message_cache)
487  *      mutex_unlock             0.25
488  *
489  *  with message cache implemented as list (0.000070 per roundtrip):
490  *    new_empty_header           2.72
491  *      list_pop_first           1.88
492  *    unref                      3.3
493  *      list_prepend             1.63
494  *
495  * without cache (0.000077 per roundtrip):
496  *    new_empty_header           6.7
497  *      string_init_preallocated 3.43
498  *        dbus_malloc            2.43
499  *      dbus_malloc0             2.59
500  *
501  *    unref                      4.02
502  *      string_free              1.82
503  *        dbus_free              1.63
504  *      dbus_free                0.71
505  *
506  * If you implement the message_cache with a list, the primary reason
507  * it's slower is that you add another thread lock (on the DBusList
508  * mempool).
509  */
510
511 /** Avoid caching huge messages */
512 #define MAX_MESSAGE_SIZE_TO_CACHE _DBUS_ONE_MEGABYTE
513
514 /** Avoid caching too many messages */
515 #define MAX_MESSAGE_CACHE_SIZE    5
516
517 _DBUS_DEFINE_GLOBAL_LOCK (message_cache);
518 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
519 static int message_cache_count = 0;
520 static dbus_bool_t message_cache_shutdown_registered = FALSE;
521
522 static void
523 dbus_message_cache_shutdown (void *data)
524 {
525   int i;
526
527   _DBUS_LOCK (message_cache);
528
529   i = 0;
530   while (i < MAX_MESSAGE_CACHE_SIZE)
531     {
532       if (message_cache[i])
533         dbus_message_finalize (message_cache[i]);
534
535       ++i;
536     }
537
538   message_cache_count = 0;
539   message_cache_shutdown_registered = FALSE;
540
541   _DBUS_UNLOCK (message_cache);
542 }
543
544 /**
545  * Tries to get a message from the message cache.  The retrieved
546  * message will have junk in it, so it still needs to be cleared out
547  * in dbus_message_new_empty_header()
548  *
549  * @returns the message, or #NULL if none cached
550  */
551 static DBusMessage*
552 dbus_message_get_cached (void)
553 {
554   DBusMessage *message;
555   int i;
556
557   message = NULL;
558
559   _DBUS_LOCK (message_cache);
560
561   _dbus_assert (message_cache_count >= 0);
562
563   if (message_cache_count == 0)
564     {
565       _DBUS_UNLOCK (message_cache);
566       return NULL;
567     }
568
569   /* This is not necessarily true unless count > 0, and
570    * message_cache is uninitialized until the shutdown is
571    * registered
572    */
573   _dbus_assert (message_cache_shutdown_registered);
574
575   i = 0;
576   while (i < MAX_MESSAGE_CACHE_SIZE)
577     {
578       if (message_cache[i])
579         {
580           message = message_cache[i];
581           message_cache[i] = NULL;
582           message_cache_count -= 1;
583           break;
584         }
585       ++i;
586     }
587   _dbus_assert (message_cache_count >= 0);
588   _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
589   _dbus_assert (message != NULL);
590
591   _DBUS_UNLOCK (message_cache);
592
593   _dbus_assert (message->refcount.value == 0);
594   _dbus_assert (message->size_counters == NULL);
595
596   return message;
597 }
598
599 /**
600  * Tries to cache a message, otherwise finalize it.
601  *
602  * @param message the message
603  */
604 static void
605 dbus_message_cache_or_finalize (DBusMessage *message)
606 {
607   dbus_bool_t was_cached;
608   int i;
609   
610   _dbus_assert (message->refcount.value == 0);
611
612   /* This calls application code and has to be done first thing
613    * without holding the lock
614    */
615   _dbus_data_slot_list_clear (&message->slot_list);
616
617   _dbus_list_foreach (&message->size_counters,
618                       free_size_counter, message);
619   _dbus_list_clear (&message->size_counters);
620
621   was_cached = FALSE;
622
623   _DBUS_LOCK (message_cache);
624
625   if (!message_cache_shutdown_registered)
626     {
627       _dbus_assert (message_cache_count == 0);
628
629       if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
630         goto out;
631
632       i = 0;
633       while (i < MAX_MESSAGE_CACHE_SIZE)
634         {
635           message_cache[i] = NULL;
636           ++i;
637         }
638
639       message_cache_shutdown_registered = TRUE;
640     }
641
642   _dbus_assert (message_cache_count >= 0);
643
644   if ((_dbus_string_get_length (&message->header.data) +
645        _dbus_string_get_length (&message->body)) >
646       MAX_MESSAGE_SIZE_TO_CACHE)
647     goto out;
648
649   if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
650     goto out;
651
652   /* Find empty slot */
653   i = 0;
654   while (message_cache[i] != NULL)
655     ++i;
656
657   _dbus_assert (i < MAX_MESSAGE_CACHE_SIZE);
658
659   _dbus_assert (message_cache[i] == NULL);
660   message_cache[i] = message;
661   message_cache_count += 1;
662   was_cached = TRUE;
663 #ifndef DBUS_DISABLE_CHECKS
664   message->in_cache = TRUE;
665 #endif
666
667  out:
668   _DBUS_UNLOCK (message_cache);
669
670   _dbus_assert (message->refcount.value == 0);
671   
672   if (!was_cached)
673     dbus_message_finalize (message);
674 }
675
676 static DBusMessage*
677 dbus_message_new_empty_header (void)
678 {
679   DBusMessage *message;
680   dbus_bool_t from_cache;
681
682   message = dbus_message_get_cached ();
683
684   if (message != NULL)
685     {
686       from_cache = TRUE;
687     }
688   else
689     {
690       from_cache = FALSE;
691       message = dbus_new (DBusMessage, 1);
692       if (message == NULL)
693         return NULL;
694 #ifndef DBUS_DISABLE_CHECKS
695       message->generation = _dbus_current_generation;
696 #endif
697     }
698   
699   message->refcount.value = 1;
700   message->byte_order = DBUS_COMPILER_BYTE_ORDER;
701   message->locked = FALSE;
702 #ifndef DBUS_DISABLE_CHECKS
703   message->in_cache = FALSE;
704 #endif
705   message->size_counters = NULL;
706   message->size_counter_delta = 0;
707   message->changed_stamp = 0;
708
709   if (!from_cache)
710     _dbus_data_slot_list_init (&message->slot_list);
711
712   if (from_cache)
713     {
714       _dbus_header_reinit (&message->header, message->byte_order);
715       _dbus_string_set_length (&message->body, 0);
716     }
717   else
718     {
719       if (!_dbus_header_init (&message->header, message->byte_order))
720         {
721           dbus_free (message);
722           return NULL;
723         }
724
725       if (!_dbus_string_init_preallocated (&message->body, 32))
726         {
727           _dbus_header_free (&message->header);
728           dbus_free (message);
729           return NULL;
730         }
731     }
732
733   return message;
734 }
735
736 /**
737  * Constructs a new message of the given message type.
738  * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL,
739  * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth.
740  *
741  * @param message_type type of message
742  * @returns new message or #NULL If no memory
743  */
744 DBusMessage*
745 dbus_message_new (int message_type)
746 {
747   DBusMessage *message;
748
749   _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
750
751   message = dbus_message_new_empty_header ();
752   if (message == NULL)
753     return NULL;
754
755   if (!_dbus_header_create (&message->header,
756                             message_type,
757                             NULL, NULL, NULL, NULL, NULL))
758     {
759       dbus_message_unref (message);
760       return NULL;
761     }
762
763   return message;
764 }
765
766 /**
767  * Constructs a new message to invoke a method on a remote
768  * object. Returns #NULL if memory can't be allocated for the
769  * message. The destination may be #NULL in which case no destination
770  * is set; this is appropriate when using D-BUS in a peer-to-peer
771  * context (no message bus). The interface may be #NULL, which means
772  * that if multiple methods with the given name exist it is undefined
773  * which one will be invoked.
774   *
775  * @param destination name that the message should be sent to or #NULL
776  * @param path object path the message should be sent to
777  * @param interface interface to invoke method on
778  * @param method method to invoke
779  *
780  * @returns a new DBusMessage, free with dbus_message_unref()
781  * @see dbus_message_unref()
782  */
783 DBusMessage*
784 dbus_message_new_method_call (const char *destination,
785                               const char *path,
786                               const char *interface,
787                               const char *method)
788 {
789   DBusMessage *message;
790
791   _dbus_return_val_if_fail (path != NULL, NULL);
792   _dbus_return_val_if_fail (method != NULL, NULL);
793   _dbus_return_val_if_fail (destination == NULL ||
794                             _dbus_check_is_valid_bus_name (destination), NULL);
795   _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
796   _dbus_return_val_if_fail (interface == NULL ||
797                             _dbus_check_is_valid_interface (interface), NULL);
798   _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
799
800   message = dbus_message_new_empty_header ();
801   if (message == NULL)
802     return NULL;
803
804   if (!_dbus_header_create (&message->header,
805                             DBUS_MESSAGE_TYPE_METHOD_CALL,
806                             destination, path, interface, method, NULL))
807     {
808       dbus_message_unref (message);
809       return NULL;
810     }
811
812   return message;
813 }
814
815 /**
816  * Constructs a message that is a reply to a method call. Returns
817  * #NULL if memory can't be allocated for the message.
818  *
819  * @param method_call the message which the created
820  * message is a reply to.
821  * @returns a new DBusMessage, free with dbus_message_unref()
822  * @see dbus_message_new_method_call(), dbus_message_unref()
823  */
824 DBusMessage*
825 dbus_message_new_method_return (DBusMessage *method_call)
826 {
827   DBusMessage *message;
828   const char *sender;
829
830   _dbus_return_val_if_fail (method_call != NULL, NULL);
831
832   sender = dbus_message_get_sender (method_call);
833
834   /* sender is allowed to be null here in peer-to-peer case */
835
836   message = dbus_message_new_empty_header ();
837   if (message == NULL)
838     return NULL;
839
840   if (!_dbus_header_create (&message->header,
841                             DBUS_MESSAGE_TYPE_METHOD_RETURN,
842                             sender, NULL, NULL, NULL, NULL))
843     {
844       dbus_message_unref (message);
845       return NULL;
846     }
847
848   dbus_message_set_no_reply (message, TRUE);
849
850   if (!dbus_message_set_reply_serial (message,
851                                       dbus_message_get_serial (method_call)))
852     {
853       dbus_message_unref (message);
854       return NULL;
855     }
856
857   return message;
858 }
859
860 /**
861  * Constructs a new message representing a signal emission. Returns
862  * #NULL if memory can't be allocated for the message.  A signal is
863  * identified by its originating interface, and the name of the
864  * signal.
865  *
866  * @param path the path to the object emitting the signal
867  * @param interface the interface the signal is emitted from
868  * @param name name of the signal
869  * @returns a new DBusMessage, free with dbus_message_unref()
870  * @see dbus_message_unref()
871  */
872 DBusMessage*
873 dbus_message_new_signal (const char *path,
874                          const char *interface,
875                          const char *name)
876 {
877   DBusMessage *message;
878
879   _dbus_return_val_if_fail (path != NULL, NULL);
880   _dbus_return_val_if_fail (interface != NULL, NULL);
881   _dbus_return_val_if_fail (name != NULL, NULL);
882   _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
883   _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
884   _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
885
886   message = dbus_message_new_empty_header ();
887   if (message == NULL)
888     return NULL;
889
890   if (!_dbus_header_create (&message->header,
891                             DBUS_MESSAGE_TYPE_SIGNAL,
892                             NULL, path, interface, name, NULL))
893     {
894       dbus_message_unref (message);
895       return NULL;
896     }
897
898   dbus_message_set_no_reply (message, TRUE);
899
900   return message;
901 }
902
903 /**
904  * Creates a new message that is an error reply to a certain message.
905  * Error replies are possible in response to method calls primarily.
906  *
907  * @param reply_to the original message
908  * @param error_name the error name
909  * @param error_message the error message string or #NULL for none
910  * @returns a new error message
911  */
912 DBusMessage*
913 dbus_message_new_error (DBusMessage *reply_to,
914                         const char  *error_name,
915                         const char  *error_message)
916 {
917   DBusMessage *message;
918   const char *sender;
919   DBusMessageIter iter;
920
921   _dbus_return_val_if_fail (reply_to != NULL, NULL);
922   _dbus_return_val_if_fail (error_name != NULL, NULL);
923   _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
924
925   sender = dbus_message_get_sender (reply_to);
926
927   /* sender may be NULL for non-message-bus case or
928    * when the message bus is dealing with an unregistered
929    * connection.
930    */
931   message = dbus_message_new_empty_header ();
932   if (message == NULL)
933     return NULL;
934
935   if (!_dbus_header_create (&message->header,
936                             DBUS_MESSAGE_TYPE_ERROR,
937                             sender, NULL, NULL, NULL, error_name))
938     {
939       dbus_message_unref (message);
940       return NULL;
941     }
942
943   dbus_message_set_no_reply (message, TRUE);
944
945   if (!dbus_message_set_reply_serial (message,
946                                       dbus_message_get_serial (reply_to)))
947     {
948       dbus_message_unref (message);
949       return NULL;
950     }
951
952   if (error_message != NULL)
953     {
954       dbus_message_iter_init_append (message, &iter);
955       if (!dbus_message_iter_append_basic (&iter,
956                                            DBUS_TYPE_STRING,
957                                            &error_message))
958         {
959           dbus_message_unref (message);
960           return NULL;
961         }
962     }
963
964   return message;
965 }
966
967 /**
968  * Creates a new message that is an error reply to a certain message.
969  * Error replies are possible in response to method calls primarily.
970  *
971  * @param reply_to the original message
972  * @param error_name the error name
973  * @param error_format the error message format as with printf
974  * @param ... format string arguments
975  * @returns a new error message
976  */
977 DBusMessage*
978 dbus_message_new_error_printf (DBusMessage *reply_to,
979                                const char  *error_name,
980                                const char  *error_format,
981                                ...)
982 {
983   va_list args;
984   DBusString str;
985   DBusMessage *message;
986
987   _dbus_return_val_if_fail (reply_to != NULL, NULL);
988   _dbus_return_val_if_fail (error_name != NULL, NULL);
989   _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
990
991   if (!_dbus_string_init (&str))
992     return NULL;
993
994   va_start (args, error_format);
995
996   if (_dbus_string_append_printf_valist (&str, error_format, args))
997     message = dbus_message_new_error (reply_to, error_name,
998                                       _dbus_string_get_const_data (&str));
999   else
1000     message = NULL;
1001
1002   _dbus_string_free (&str);
1003
1004   va_end (args);
1005
1006   return message;
1007 }
1008
1009
1010 /**
1011  * Creates a new message that is an exact replica of the message
1012  * specified, except that its refcount is set to 1, its message serial
1013  * is reset to 0, and if the original message was "locked" (in the
1014  * outgoing message queue and thus not modifiable) the new message
1015  * will not be locked.
1016  *
1017  * @param message the message.
1018  * @returns the new message.
1019  */
1020 DBusMessage *
1021 dbus_message_copy (const DBusMessage *message)
1022 {
1023   DBusMessage *retval;
1024
1025   _dbus_return_val_if_fail (message != NULL, NULL);
1026
1027   retval = dbus_new0 (DBusMessage, 1);
1028   if (retval == NULL)
1029     return NULL;
1030
1031   retval->refcount.value = 1;
1032   retval->byte_order = message->byte_order;
1033   retval->locked = FALSE;
1034 #ifndef DBUS_DISABLE_CHECKS
1035   retval->generation = message->generation;
1036 #endif
1037
1038   if (!_dbus_header_copy (&message->header, &retval->header))
1039     {
1040       dbus_free (retval);
1041       return NULL;
1042     }
1043
1044   if (!_dbus_string_init_preallocated (&retval->body,
1045                                        _dbus_string_get_length (&message->body)))
1046     {
1047       _dbus_header_free (&retval->header);
1048       dbus_free (retval);
1049       return NULL;
1050     }
1051
1052   if (!_dbus_string_copy (&message->body, 0,
1053                           &retval->body, 0))
1054     goto failed_copy;
1055
1056   return retval;
1057
1058  failed_copy:
1059   _dbus_header_free (&retval->header);
1060   _dbus_string_free (&retval->body);
1061   dbus_free (retval);
1062
1063   return NULL;
1064 }
1065
1066
1067 /**
1068  * Increments the reference count of a DBusMessage.
1069  *
1070  * @param message The message
1071  * @returns the message
1072  * @see dbus_message_unref
1073  */
1074 DBusMessage *
1075 dbus_message_ref (DBusMessage *message)
1076 {
1077   dbus_int32_t old_refcount;
1078
1079   _dbus_return_val_if_fail (message != NULL, NULL);
1080   _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1081   _dbus_return_val_if_fail (!message->in_cache, NULL);
1082   
1083   old_refcount = _dbus_atomic_inc (&message->refcount);
1084   _dbus_assert (old_refcount >= 1);
1085
1086   return message;
1087 }
1088
1089 /**
1090  * Decrements the reference count of a DBusMessage.
1091  *
1092  * @param message The message
1093  * @see dbus_message_ref
1094  */
1095 void
1096 dbus_message_unref (DBusMessage *message)
1097 {
1098  dbus_int32_t old_refcount;
1099
1100   _dbus_return_if_fail (message != NULL);
1101   _dbus_return_if_fail (message->generation == _dbus_current_generation);
1102   _dbus_return_if_fail (!message->in_cache);
1103
1104   old_refcount = _dbus_atomic_dec (&message->refcount);
1105
1106   _dbus_assert (old_refcount >= 0);
1107
1108   if (old_refcount == 1)
1109     {
1110       /* Calls application callbacks! */
1111       dbus_message_cache_or_finalize (message);
1112     }
1113 }
1114
1115 /**
1116  * Gets the type of a message. Types include
1117  * #DBUS_MESSAGE_TYPE_METHOD_CALL, #DBUS_MESSAGE_TYPE_METHOD_RETURN,
1118  * #DBUS_MESSAGE_TYPE_ERROR, #DBUS_MESSAGE_TYPE_SIGNAL, but other
1119  * types are allowed and all code must silently ignore messages of
1120  * unknown type. DBUS_MESSAGE_TYPE_INVALID will never be returned,
1121  * however.
1122  *
1123  *
1124  * @param message the message
1125  * @returns the type of the message
1126  */
1127 int
1128 dbus_message_get_type (DBusMessage *message)
1129 {
1130   _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1131
1132   return _dbus_header_get_message_type (&message->header);
1133 }
1134
1135 /**
1136  * Appends fields to a message given a variable argument list. The
1137  * variable argument list should contain the type of each argument
1138  * followed by the value to append. Appendable types are basic types,
1139  * and arrays of fixed-length basic types. To append variable-length
1140  * basic types, or any more complex value, you have to use an iterator
1141  * rather than this function.
1142  *
1143  * To append a basic type, specify its type code followed by the
1144  * value. For example:
1145  *
1146  * @code
1147  * DBUS_TYPE_INT32, 42,
1148  * DBUS_TYPE_STRING, "Hello World"
1149  * @endcode
1150  * or
1151  * @code
1152  * dbus_int32_t val = 42;
1153  * DBUS_TYPE_INT32, val
1154  * @endcode
1155  *
1156  * Be sure that your provided value is the right size. For example, this
1157  * won't work:
1158  * @code
1159  * DBUS_TYPE_INT64, 42
1160  * @endcode
1161  * Because the "42" will be a 32-bit integer. You need to cast to
1162  * 64-bit.
1163  *
1164  * To append an array of fixed-length basic types, pass in the
1165  * DBUS_TYPE_ARRAY typecode, the element typecode, the address of
1166  * the array pointer, and a 32-bit integer giving the number of
1167  * elements in the array. So for example:
1168  * @code
1169  * const dbus_int32_t array[] = { 1, 2, 3 };
1170  * const dbus_int32_t *v_ARRAY = array;
1171  * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3
1172  * @endcode
1173  *
1174  * @warning in C, given "int array[]", "&array == array" (the
1175  * comp.lang.c FAQ says otherwise, but gcc and the FAQ don't agree).
1176  * So if you're using an array instead of a pointer you have to create
1177  * a pointer variable, assign the array to it, then take the address
1178  * of the pointer variable. For strings it works to write
1179  * const char *array = "Hello" and then use &array though.
1180  *
1181  * The last argument to this function must be #DBUS_TYPE_INVALID,
1182  * marking the end of the argument list.
1183  *
1184  * String/signature/path arrays should be passed in as "const char***
1185  * address_of_array" and "int n_elements"
1186  *
1187  * @todo support DBUS_TYPE_STRUCT and DBUS_TYPE_VARIANT and complex arrays
1188  *
1189  * @todo If this fails due to lack of memory, the message is hosed and
1190  * you have to start over building the whole message.
1191  *
1192  * @param message the message
1193  * @param first_arg_type type of the first argument
1194  * @param ... value of first argument, list of additional type-value pairs
1195  * @returns #TRUE on success
1196  */
1197 dbus_bool_t
1198 dbus_message_append_args (DBusMessage *message,
1199                           int          first_arg_type,
1200                           ...)
1201 {
1202   dbus_bool_t retval;
1203   va_list var_args;
1204
1205   _dbus_return_val_if_fail (message != NULL, FALSE);
1206
1207   va_start (var_args, first_arg_type);
1208   retval = dbus_message_append_args_valist (message,
1209                                             first_arg_type,
1210                                             var_args);
1211   va_end (var_args);
1212
1213   return retval;
1214 }
1215
1216 /**
1217  * This function takes a va_list for use by language bindings.
1218  * It's otherwise the same as dbus_message_append_args().
1219  *
1220  * @todo for now, if this function fails due to OOM it will leave
1221  * the message half-written and you have to discard the message
1222  * and start over.
1223  *
1224  * @see dbus_message_append_args.
1225  * @param message the message
1226  * @param first_arg_type type of first argument
1227  * @param var_args value of first argument, then list of type/value pairs
1228  * @returns #TRUE on success
1229  */
1230 dbus_bool_t
1231 dbus_message_append_args_valist (DBusMessage *message,
1232                                  int          first_arg_type,
1233                                  va_list      var_args)
1234 {
1235   int type;
1236   DBusMessageIter iter;
1237
1238   _dbus_return_val_if_fail (message != NULL, FALSE);
1239
1240   type = first_arg_type;
1241
1242   dbus_message_iter_init_append (message, &iter);
1243
1244   while (type != DBUS_TYPE_INVALID)
1245     {
1246       if (dbus_type_is_basic (type))
1247         {
1248           const DBusBasicValue *value;
1249           value = va_arg (var_args, const DBusBasicValue*);
1250
1251           if (!dbus_message_iter_append_basic (&iter,
1252                                                type,
1253                                                value))
1254             goto failed;
1255         }
1256       else if (type == DBUS_TYPE_ARRAY)
1257         {
1258           int element_type;
1259           DBusMessageIter array;
1260           char buf[2];
1261
1262           element_type = va_arg (var_args, int);
1263               
1264           buf[0] = element_type;
1265           buf[1] = '\0';
1266           if (!dbus_message_iter_open_container (&iter,
1267                                                  DBUS_TYPE_ARRAY,
1268                                                  buf,
1269                                                  &array))
1270             goto failed;
1271           
1272           if (_dbus_type_is_fixed (element_type))
1273             {
1274               const DBusBasicValue **value;
1275               int n_elements;
1276
1277               value = va_arg (var_args, const DBusBasicValue**);
1278               n_elements = va_arg (var_args, int);
1279               
1280               if (!dbus_message_iter_append_fixed_array (&array,
1281                                                          element_type,
1282                                                          value,
1283                                                          n_elements))
1284                 goto failed;
1285             }
1286           else if (element_type == DBUS_TYPE_STRING ||
1287                    element_type == DBUS_TYPE_SIGNATURE ||
1288                    element_type == DBUS_TYPE_OBJECT_PATH)
1289             {
1290               const char ***value_p;
1291               const char **value;
1292               int n_elements;
1293               int i;
1294               
1295               value_p = va_arg (var_args, const char***);
1296               n_elements = va_arg (var_args, int);
1297
1298               value = *value_p;
1299               
1300               i = 0;
1301               while (i < n_elements)
1302                 {
1303                   if (!dbus_message_iter_append_basic (&array,
1304                                                        element_type,
1305                                                        &value[i]))
1306                     goto failed;
1307                   ++i;
1308                 }
1309             }
1310           else
1311             {
1312               _dbus_warn ("arrays of %s can't be appended with %s for now\n",
1313                           _dbus_type_to_string (element_type),
1314                           _DBUS_FUNCTION_NAME);
1315               goto failed;
1316             }
1317
1318           if (!dbus_message_iter_close_container (&iter, &array))
1319             goto failed;
1320         }
1321 #ifndef DBUS_DISABLE_CHECKS
1322       else
1323         {
1324           _dbus_warn ("type %s isn't supported yet in %s\n",
1325                       _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1326           goto failed;
1327         }
1328 #endif
1329
1330       type = va_arg (var_args, int);
1331     }
1332
1333   return TRUE;
1334
1335  failed:
1336   return FALSE;
1337 }
1338
1339 /**
1340  * Gets arguments from a message given a variable argument list.  The
1341  * supported types include those supported by
1342  * dbus_message_append_args(); that is, basic types and arrays of
1343  * fixed-length basic types.  The arguments are the same as they would
1344  * be for dbus_message_iter_get_basic() or
1345  * dbus_message_iter_get_fixed_array().
1346  *
1347  * In addition to those types, arrays of string, object path, and
1348  * signature are supported; but these are returned as allocated memory
1349  * and must be freed with dbus_free_string_array(), while the other
1350  * types are returned as const references. To get a string array
1351  * pass in "char ***array_location" and "int *n_elements"
1352  *
1353  * The variable argument list should contain the type of the argument
1354  * followed by a pointer to where the value should be stored. The list
1355  * is terminated with #DBUS_TYPE_INVALID.
1356  *
1357  * The returned values are constant; do not free them. They point
1358  * into the #DBusMessage.
1359  *
1360  * If the requested arguments are not present, or do not have the
1361  * requested types, then an error will be set.
1362  *
1363  * @todo support DBUS_TYPE_STRUCT and DBUS_TYPE_VARIANT and complex arrays
1364  *
1365  * @param message the message
1366  * @param error error to be filled in on failure
1367  * @param first_arg_type the first argument type
1368  * @param ... location for first argument value, then list of type-location pairs
1369  * @returns #FALSE if the error was set
1370  */
1371 dbus_bool_t
1372 dbus_message_get_args (DBusMessage     *message,
1373                        DBusError       *error,
1374                        int              first_arg_type,
1375                        ...)
1376 {
1377   dbus_bool_t retval;
1378   va_list var_args;
1379
1380   _dbus_return_val_if_fail (message != NULL, FALSE);
1381   _dbus_return_val_if_error_is_set (error, FALSE);
1382
1383   va_start (var_args, first_arg_type);
1384   retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1385   va_end (var_args);
1386
1387   return retval;
1388 }
1389
1390 /**
1391  * This function takes a va_list for use by language bindings. It is
1392  * otherwise the same as dbus_message_get_args().
1393  *
1394  * @see dbus_message_get_args
1395  * @param message the message
1396  * @param error error to be filled in
1397  * @param first_arg_type type of the first argument
1398  * @param var_args return location for first argument, followed by list of type/location pairs
1399  * @returns #FALSE if error was set
1400  */
1401 dbus_bool_t
1402 dbus_message_get_args_valist (DBusMessage     *message,
1403                               DBusError       *error,
1404                               int              first_arg_type,
1405                               va_list          var_args)
1406 {
1407   DBusMessageIter iter;
1408
1409   _dbus_return_val_if_fail (message != NULL, FALSE);
1410   _dbus_return_val_if_error_is_set (error, FALSE);
1411
1412   dbus_message_iter_init (message, &iter);
1413   return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1414 }
1415
1416 static void
1417 _dbus_message_iter_init_common (DBusMessage         *message,
1418                                 DBusMessageRealIter *real,
1419                                 int                  iter_type)
1420 {
1421   _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1422
1423   /* Since the iterator will read or write who-knows-what from the
1424    * message, we need to get in the right byte order
1425    */
1426   ensure_byte_order (message);
1427   
1428   real->message = message;
1429   real->changed_stamp = message->changed_stamp;
1430   real->iter_type = iter_type;
1431   real->sig_refcount = 0;
1432 }
1433
1434 /**
1435  * Initializes a #DBusMessageIter for reading the arguments of the
1436  * message passed in.
1437  *
1438  * @param message the message
1439  * @param iter pointer to an iterator to initialize
1440  * @returns #FALSE if the message has no arguments
1441  */
1442 dbus_bool_t
1443 dbus_message_iter_init (DBusMessage     *message,
1444                         DBusMessageIter *iter)
1445 {
1446   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1447   const DBusString *type_str;
1448   int type_pos;
1449
1450   _dbus_return_val_if_fail (message != NULL, FALSE);
1451   _dbus_return_val_if_fail (iter != NULL, FALSE);
1452
1453   get_const_signature (&message->header, &type_str, &type_pos);
1454
1455   _dbus_message_iter_init_common (message, real,
1456                                   DBUS_MESSAGE_ITER_TYPE_READER);
1457
1458   _dbus_type_reader_init (&real->u.reader,
1459                           message->byte_order,
1460                           type_str, type_pos,
1461                           &message->body,
1462                           0);
1463
1464   return _dbus_type_reader_get_current_type (&real->u.reader) != DBUS_TYPE_INVALID;
1465 }
1466
1467 #ifndef DBUS_DISABLE_CHECKS
1468 static dbus_bool_t
1469 _dbus_message_iter_check (DBusMessageRealIter *iter)
1470 {
1471   if (iter == NULL)
1472     {
1473       _dbus_warn ("dbus message iterator is NULL\n");
1474       return FALSE;
1475     }
1476
1477   if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
1478     {
1479       if (iter->u.reader.byte_order != iter->message->byte_order)
1480         {
1481           _dbus_warn ("dbus message changed byte order since iterator was created\n");
1482           return FALSE;
1483         }
1484       /* because we swap the message into compiler order when you init an iter */
1485       _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
1486     }
1487   else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
1488     {
1489       if (iter->u.writer.byte_order != iter->message->byte_order)
1490         {
1491           _dbus_warn ("dbus message changed byte order since append iterator was created\n");
1492           return FALSE;
1493         }
1494       /* because we swap the message into compiler order when you init an iter */
1495       _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
1496     }
1497   else
1498     {
1499       _dbus_warn ("dbus message iterator looks uninitialized or corrupted\n");
1500       return FALSE;
1501     }
1502
1503   if (iter->changed_stamp != iter->message->changed_stamp)
1504     {
1505       _dbus_warn ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
1506       return FALSE;
1507     }
1508
1509   return TRUE;
1510 }
1511 #endif /* DBUS_DISABLE_CHECKS */
1512
1513 /**
1514  * Checks if an iterator has any more fields.
1515  *
1516  * @param iter the message iter
1517  * @returns #TRUE if there are more fields
1518  * following
1519  */
1520 dbus_bool_t
1521 dbus_message_iter_has_next (DBusMessageIter *iter)
1522 {
1523   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1524
1525   _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
1526   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1527
1528   return _dbus_type_reader_has_next (&real->u.reader);
1529 }
1530
1531 /**
1532  * Moves the iterator to the next field, if any. If there's no next
1533  * field, returns #FALSE. If the iterator moves forward, returns
1534  * #TRUE.
1535  *
1536  * @param iter the message iter
1537  * @returns #TRUE if the iterator was moved to the next field
1538  */
1539 dbus_bool_t
1540 dbus_message_iter_next (DBusMessageIter *iter)
1541 {
1542   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1543
1544   _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
1545   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1546
1547   return _dbus_type_reader_next (&real->u.reader);
1548 }
1549
1550 /**
1551  * Returns the argument type of the argument that the message iterator
1552  * points to. If the iterator is at the end of the message, returns
1553  * #DBUS_TYPE_INVALID. You can thus write a loop as follows:
1554  *
1555  * @code
1556  * dbus_message_iter_init (&iter);
1557  * while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
1558  *   dbus_message_iter_next (&iter);
1559  * @endcode
1560  *
1561  * @param iter the message iter
1562  * @returns the argument type
1563  */
1564 int
1565 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
1566 {
1567   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1568
1569   _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
1570   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
1571
1572   return _dbus_type_reader_get_current_type (&real->u.reader);
1573 }
1574
1575 /**
1576  * Returns the element type of the array that the message iterator
1577  * points to. Note that you need to check that the iterator points to
1578  * an array prior to using this function.
1579  *
1580  * @param iter the message iter
1581  * @returns the array element type
1582  */
1583 int
1584 dbus_message_iter_get_element_type (DBusMessageIter *iter)
1585 {
1586   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1587
1588   _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
1589   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
1590   _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
1591
1592   return _dbus_type_reader_get_element_type (&real->u.reader);
1593 }
1594
1595 /**
1596  * Recurses into a container value when reading values from a message,
1597  * initializing a sub-iterator to use for traversing the child values
1598  * of the container.
1599  *
1600  * Note that this recurses into a value, not a type, so you can only
1601  * recurse if the value exists. The main implication of this is that
1602  * if you have for example an empty array of array of int32, you can
1603  * recurse into the outermost array, but it will have no values, so
1604  * you won't be able to recurse further. There's no array of int32 to
1605  * recurse into.
1606  *
1607  * @param iter the message iterator
1608  * @param sub the sub-iterator to initialize
1609  */
1610 void
1611 dbus_message_iter_recurse (DBusMessageIter  *iter,
1612                            DBusMessageIter  *sub)
1613 {
1614   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1615   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
1616
1617   _dbus_return_if_fail (_dbus_message_iter_check (real));
1618   _dbus_return_if_fail (sub != NULL);
1619
1620   *real_sub = *real;
1621   _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
1622 }
1623
1624 /**
1625  * Reads a basic-typed value from the message iterator.
1626  * Basic types are the non-containers such as integer and string.
1627  *
1628  * The value argument should be the address of a location to store
1629  * the returned value. So for int32 it should be a "dbus_int32_t*"
1630  * and for string a "const char**". The returned value is
1631  * by reference and should not be freed.
1632  *
1633  * All returned values are guaranteed to fit in 8 bytes. So you can
1634  * write code like this:
1635  *
1636  * @code
1637  * #ifdef DBUS_HAVE_INT64
1638  * dbus_uint64_t value;
1639  * int type;
1640  * dbus_message_iter_get_basic (&read_iter, &value);
1641  * type = dbus_message_iter_get_arg_type (&read_iter);
1642  * dbus_message_iter_append_basic (&write_iter, type, &value);
1643  * #endif
1644  * @endcode
1645  *
1646  * To avoid the #DBUS_HAVE_INT64 conditional, create a struct or
1647  * something that occupies at least 8 bytes, e.g. you could use a
1648  * struct with two int32 values in it. dbus_uint64_t is just one
1649  * example of a type that's large enough to hold any possible value.
1650  *
1651  * Be sure you have somehow checked that
1652  * dbus_message_iter_get_arg_type() matches the type you are
1653  * expecting, or you'll crash when you try to use an integer as a
1654  * string or something.
1655  *
1656  * @param iter the iterator
1657  * @param value location to store the value
1658  */
1659 void
1660 dbus_message_iter_get_basic (DBusMessageIter  *iter,
1661                              void             *value)
1662 {
1663   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1664
1665   _dbus_return_if_fail (_dbus_message_iter_check (real));
1666   _dbus_return_if_fail (value != NULL);
1667
1668   _dbus_type_reader_read_basic (&real->u.reader,
1669                                 value);
1670 }
1671
1672 /**
1673  * Reads a block of fixed-length values from the message iterator.
1674  * Fixed-length values are those basic types that are not string-like,
1675  * such as integers, bool, double. The block read will be from the
1676  * current position in the array until the end of the array.
1677  *
1678  * The value argument should be the address of a location to store the
1679  * returned array. So for int32 it should be a "const dbus_int32_t**"
1680  * The returned value is by reference and should not be freed.
1681  *
1682  * @param iter the iterator
1683  * @param value location to store the block
1684  * @param n_elements number of elements in the block
1685  */
1686 void
1687 dbus_message_iter_get_fixed_array (DBusMessageIter  *iter,
1688                                    void             *value,
1689                                    int              *n_elements)
1690 {
1691   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1692
1693   _dbus_return_if_fail (_dbus_message_iter_check (real));
1694   _dbus_return_if_fail (value != NULL);
1695   _dbus_return_if_fail (_dbus_type_is_fixed (_dbus_type_reader_get_element_type (&real->u.reader)));
1696
1697   _dbus_type_reader_read_fixed_multi (&real->u.reader,
1698                                       value, n_elements);
1699 }
1700
1701 /**
1702  * This function takes a va_list for use by language bindings and is
1703  * otherwise the same as dbus_message_iter_get_args().
1704  * dbus_message_get_args() is the place to go for complete
1705  * documentation.
1706  *
1707  * @see dbus_message_get_args
1708  * @param iter the message iter
1709  * @param error error to be filled in
1710  * @param first_arg_type type of the first argument
1711  * @param var_args return location for first argument, followed by list of type/location pairs
1712  * @returns #FALSE if error was set
1713  */
1714 dbus_bool_t
1715 _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
1716                                     DBusError       *error,
1717                                     int              first_arg_type,
1718                                     va_list          var_args)
1719 {
1720   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1721   int spec_type, msg_type, i;
1722   dbus_bool_t retval;
1723
1724   _dbus_assert (_dbus_message_iter_check (real));
1725
1726   retval = FALSE;
1727
1728   spec_type = first_arg_type;
1729   i = 0;
1730
1731   while (spec_type != DBUS_TYPE_INVALID)
1732     {
1733       msg_type = dbus_message_iter_get_arg_type (iter);
1734
1735       if (msg_type != spec_type)
1736         {
1737           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1738                           "Argument %d is specified to be of type \"%s\", but "
1739                           "is actually of type \"%s\"\n", i,
1740                           _dbus_type_to_string (spec_type),
1741                           _dbus_type_to_string (msg_type));
1742
1743           goto out;
1744         }
1745
1746       if (dbus_type_is_basic (spec_type))
1747         {
1748           DBusBasicValue *ptr;
1749
1750           ptr = va_arg (var_args, DBusBasicValue*);
1751
1752           _dbus_assert (ptr != NULL);
1753
1754           _dbus_type_reader_read_basic (&real->u.reader,
1755                                         ptr);
1756         }
1757       else if (spec_type == DBUS_TYPE_ARRAY)
1758         {
1759           int element_type;
1760           int spec_element_type;
1761           const DBusBasicValue **ptr;
1762           int *n_elements_p;
1763           DBusTypeReader array;
1764
1765           spec_element_type = va_arg (var_args, int);
1766           element_type = _dbus_type_reader_get_element_type (&real->u.reader);
1767
1768           if (spec_element_type != element_type)
1769             {
1770               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1771                               "Argument %d is specified to be an array of \"%s\", but "
1772                               "is actually an array of \"%s\"\n",
1773                               i,
1774                               _dbus_type_to_string (spec_element_type),
1775                               _dbus_type_to_string (element_type));
1776
1777               goto out;
1778             }
1779
1780           if (_dbus_type_is_fixed (spec_element_type))
1781             {
1782               ptr = va_arg (var_args, const DBusBasicValue**);
1783               n_elements_p = va_arg (var_args, int*);
1784
1785               _dbus_assert (ptr != NULL);
1786               _dbus_assert (n_elements_p != NULL);
1787
1788               _dbus_type_reader_recurse (&real->u.reader, &array);
1789
1790               _dbus_type_reader_read_fixed_multi (&array,
1791                                                   ptr, n_elements_p);
1792             }
1793           else if (spec_element_type == DBUS_TYPE_STRING ||
1794                    spec_element_type == DBUS_TYPE_SIGNATURE ||
1795                    spec_element_type == DBUS_TYPE_OBJECT_PATH)
1796             {
1797               char ***str_array_p;
1798               int n_elements;
1799               char **str_array;
1800
1801               str_array_p = va_arg (var_args, char***);
1802               n_elements_p = va_arg (var_args, int*);
1803
1804               _dbus_assert (str_array_p != NULL);
1805               _dbus_assert (n_elements_p != NULL);
1806
1807               /* Count elements in the array */
1808               _dbus_type_reader_recurse (&real->u.reader, &array);
1809
1810               n_elements = 0;
1811               while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
1812                 {
1813                   ++n_elements;
1814                   _dbus_type_reader_next (&array);
1815                 }
1816
1817               str_array = dbus_new0 (char*, n_elements + 1);
1818               if (str_array == NULL)
1819                 {
1820                   _DBUS_SET_OOM (error);
1821                   goto out;
1822                 }
1823
1824               /* Now go through and dup each string */
1825               _dbus_type_reader_recurse (&real->u.reader, &array);
1826
1827               i = 0;
1828               while (i < n_elements)
1829                 {
1830                   const char *s;
1831                   _dbus_type_reader_read_basic (&array,
1832                                                 &s);
1833                   
1834                   str_array[i] = _dbus_strdup (s);
1835                   if (str_array[i] == NULL)
1836                     {
1837                       dbus_free_string_array (str_array);
1838                       _DBUS_SET_OOM (error);
1839                       goto out;
1840                     }
1841                   
1842                   ++i;
1843                   
1844                   if (!_dbus_type_reader_next (&array))
1845                     _dbus_assert (i == n_elements);
1846                 }
1847
1848               _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
1849               _dbus_assert (i == n_elements);
1850               _dbus_assert (str_array[i] == NULL);
1851
1852               *str_array_p = str_array;
1853               *n_elements_p = n_elements;
1854             }
1855 #ifndef DBUS_DISABLE_CHECKS
1856           else
1857             {
1858               _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
1859                           _DBUS_FUNCTION_NAME);
1860               goto out;
1861             }
1862 #endif
1863         }
1864 #ifndef DBUS_DISABLE_CHECKS
1865       else
1866         {
1867           _dbus_warn ("you can only read arrays and basic types with %s for now\n",
1868                       _DBUS_FUNCTION_NAME);
1869           goto out;
1870         }
1871 #endif
1872
1873       spec_type = va_arg (var_args, int);
1874       if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1875         {
1876           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1877                           "Message has only %d arguments, but more were expected", i);
1878           goto out;
1879         }
1880
1881       i++;
1882     }
1883
1884   retval = TRUE;
1885
1886  out:
1887
1888   return retval;
1889 }
1890
1891 /**
1892  * Initializes a #DBusMessageIter for appending arguments to the end
1893  * of a message.
1894  *
1895  * @todo If appending any of the arguments fails due to lack of
1896  * memory, generally the message is hosed and you have to start over
1897  * building the whole message.
1898  *
1899  * @param message the message
1900  * @param iter pointer to an iterator to initialize
1901  */
1902 void
1903 dbus_message_iter_init_append (DBusMessage     *message,
1904                                DBusMessageIter *iter)
1905 {
1906   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1907
1908   _dbus_return_if_fail (message != NULL);
1909   _dbus_return_if_fail (iter != NULL);
1910
1911   _dbus_message_iter_init_common (message, real,
1912                                   DBUS_MESSAGE_ITER_TYPE_WRITER);
1913
1914   /* We create the signature string and point iterators at it "on demand"
1915    * when a value is actually appended. That means that init() never fails
1916    * due to OOM.
1917    */
1918   _dbus_type_writer_init_types_delayed (&real->u.writer,
1919                                         message->byte_order,
1920                                         &message->body,
1921                                         _dbus_string_get_length (&message->body));
1922 }
1923
1924 /**
1925  * Creates a temporary signature string containing the current
1926  * signature, stores it in the iterator, and points the iterator to
1927  * the end of it. Used any time we write to the message.
1928  *
1929  * @param real an iterator without a type_str
1930  * @returns #FALSE if no memory
1931  */
1932 static dbus_bool_t
1933 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
1934 {
1935   DBusString *str;
1936   const DBusString *current_sig;
1937   int current_sig_pos;
1938
1939   _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
1940
1941   if (real->u.writer.type_str != NULL)
1942     {
1943       _dbus_assert (real->sig_refcount > 0);
1944       real->sig_refcount += 1;
1945       return TRUE;
1946     }
1947
1948   str = dbus_new (DBusString, 1);
1949   if (str == NULL)
1950     return FALSE;
1951
1952   if (!_dbus_header_get_field_raw (&real->message->header,
1953                                    DBUS_HEADER_FIELD_SIGNATURE,
1954                                    &current_sig, &current_sig_pos))
1955     current_sig = NULL;
1956
1957   if (current_sig)
1958     {
1959       int current_len;
1960
1961       current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
1962       current_sig_pos += 1; /* move on to sig data */
1963
1964       if (!_dbus_string_init_preallocated (str, current_len + 4))
1965         {
1966           dbus_free (str);
1967           return FALSE;
1968         }
1969
1970       if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
1971                                   str, 0))
1972         {
1973           _dbus_string_free (str);
1974           dbus_free (str);
1975           return FALSE;
1976         }
1977     }
1978   else
1979     {
1980       if (!_dbus_string_init_preallocated (str, 4))
1981         {
1982           dbus_free (str);
1983           return FALSE;
1984         }
1985     }
1986
1987   real->sig_refcount = 1;
1988
1989   _dbus_type_writer_add_types (&real->u.writer,
1990                                str, _dbus_string_get_length (str));
1991   return TRUE;
1992 }
1993
1994 /**
1995  * Sets the new signature as the message signature, frees the
1996  * signature string, and marks the iterator as not having a type_str
1997  * anymore. Frees the signature even if it fails, so you can't
1998  * really recover from failure. Kinda busted.
1999  *
2000  * @param real an iterator without a type_str
2001  * @returns #FALSE if no memory
2002  */
2003 static dbus_bool_t
2004 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2005 {
2006   DBusString *str;
2007   const char *v_STRING;
2008   dbus_bool_t retval;
2009
2010   _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2011   _dbus_assert (real->u.writer.type_str != NULL);
2012   _dbus_assert (real->sig_refcount > 0);
2013
2014   real->sig_refcount -= 1;
2015
2016   if (real->sig_refcount > 0)
2017     return TRUE;
2018   _dbus_assert (real->sig_refcount == 0);
2019
2020   retval = TRUE;
2021
2022   str = real->u.writer.type_str;
2023
2024   v_STRING = _dbus_string_get_const_data (str);
2025   if (!_dbus_header_set_field_basic (&real->message->header,
2026                                      DBUS_HEADER_FIELD_SIGNATURE,
2027                                      DBUS_TYPE_SIGNATURE,
2028                                      &v_STRING))
2029     retval = FALSE;
2030
2031   _dbus_type_writer_remove_types (&real->u.writer);
2032   _dbus_string_free (str);
2033   dbus_free (str);
2034
2035   return retval;
2036 }
2037
2038 #ifndef DBUS_DISABLE_CHECKS
2039 static dbus_bool_t
2040 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2041 {
2042   if (!_dbus_message_iter_check (iter))
2043     return FALSE;
2044
2045   if (iter->message->locked)
2046     {
2047       _dbus_warn ("dbus append iterator can't be used: message is locked (has already been sent)\n");
2048       return FALSE;
2049     }
2050
2051   return TRUE;
2052 }
2053 #endif /* DBUS_DISABLE_CHECKS */
2054
2055 /**
2056  * Appends a basic-typed value to the message. The basic types are the
2057  * non-container types such as integer and string.
2058  *
2059  * The "value" argument should be the address of a basic-typed value.
2060  * So for string, const char**. For integer, dbus_int32_t*.
2061  *
2062  * @todo If this fails due to lack of memory, the message is hosed and
2063  * you have to start over building the whole message.
2064  *
2065  * @param iter the append iterator
2066  * @param type the type of the value
2067  * @param value the address of the value
2068  * @returns #FALSE if not enough memory
2069  */
2070 dbus_bool_t
2071 dbus_message_iter_append_basic (DBusMessageIter *iter,
2072                                 int              type,
2073                                 const void      *value)
2074 {
2075   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2076   dbus_bool_t ret;
2077
2078   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2079   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2080   _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2081   _dbus_return_val_if_fail (value != NULL, FALSE);
2082
2083   if (!_dbus_message_iter_open_signature (real))
2084     return FALSE;
2085
2086   ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2087
2088   if (!_dbus_message_iter_close_signature (real))
2089     ret = FALSE;
2090
2091   return ret;
2092 }
2093
2094 /**
2095  * Appends a block of fixed-length values to an array. The
2096  * fixed-length types are all basic types that are not string-like. So
2097  * int32, double, bool, etc. You must call
2098  * dbus_message_iter_open_container() to open an array of values
2099  * before calling this function. You may call this function multiple
2100  * times (and intermixed with calls to
2101  * dbus_message_iter_append_basic()) for the same array.
2102  *
2103  * The "value" argument should be the address of the array.  So for
2104  * integer, "dbus_int32_t**" is expected for example.
2105  *
2106  * @warning in C, given "int array[]", "&array == array" (the
2107  * comp.lang.c FAQ says otherwise, but gcc and the FAQ don't agree).
2108  * So if you're using an array instead of a pointer you have to create
2109  * a pointer variable, assign the array to it, then take the address
2110  * of the pointer variable.
2111  * @code
2112  * const dbus_int32_t array[] = { 1, 2, 3 };
2113  * const dbus_int32_t *v_ARRAY = array;
2114  * if (!dbus_message_iter_append_fixed_array (&iter, DBUS_TYPE_INT32, &v_ARRAY, 3))
2115  *   fprintf (stderr, "No memory!\n");
2116  * @endcode
2117  * For strings it works to write const char *array = "Hello" and then
2118  * use &array though.
2119  *
2120  * @todo If this fails due to lack of memory, the message is hosed and
2121  * you have to start over building the whole message.
2122  *
2123  * @param iter the append iterator
2124  * @param element_type the type of the array elements
2125  * @param value the address of the array
2126  * @param n_elements the number of elements to append
2127  * @returns #FALSE if not enough memory
2128  */
2129 dbus_bool_t
2130 dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
2131                                       int              element_type,
2132                                       const void      *value,
2133                                       int              n_elements)
2134 {
2135   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2136   dbus_bool_t ret;
2137
2138   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2139   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2140   _dbus_return_val_if_fail (_dbus_type_is_fixed (element_type), FALSE);
2141   _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2142   _dbus_return_val_if_fail (value != NULL, FALSE);
2143   _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2144   _dbus_return_val_if_fail (n_elements <=
2145                             DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type),
2146                             FALSE);
2147
2148   ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2149
2150   return ret;
2151 }
2152
2153 /**
2154  * Appends a container-typed value to the message; you are required to
2155  * append the contents of the container using the returned
2156  * sub-iterator, and then call
2157  * dbus_message_iter_close_container(). Container types are for
2158  * example struct, variant, and array. For variants, the
2159  * contained_signature should be the type of the single value inside
2160  * the variant. For structs and dict entries, contained_signature
2161  * should be #NULL; it will be set to whatever types you write into
2162  * the struct.  For arrays, contained_signature should be the type of
2163  * the array elements.
2164  *
2165  * @todo If this fails due to lack of memory, the message is hosed and
2166  * you have to start over building the whole message.
2167  *
2168  * @param iter the append iterator
2169  * @param type the type of the value
2170  * @param contained_signature the type of container contents
2171  * @param sub sub-iterator to initialize
2172  * @returns #FALSE if not enough memory
2173  */
2174 dbus_bool_t
2175 dbus_message_iter_open_container (DBusMessageIter *iter,
2176                                   int              type,
2177                                   const char      *contained_signature,
2178                                   DBusMessageIter *sub)
2179 {
2180   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2181   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2182   DBusString contained_str;
2183
2184   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2185   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2186   _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2187   _dbus_return_val_if_fail (sub != NULL, FALSE);
2188   _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2189                              contained_signature == NULL) ||
2190                             (type == DBUS_TYPE_DICT_ENTRY &&
2191                              contained_signature == NULL) ||
2192                             contained_signature != NULL, FALSE);
2193   
2194 #if 0
2195   /* FIXME this would fail if the contained_signature is a dict entry,
2196    * since dict entries are invalid signatures standalone (they must be in
2197    * an array)
2198    */
2199   _dbus_return_val_if_fail (contained_signature == NULL ||
2200                             _dbus_check_is_valid_signature (contained_signature));
2201 #endif
2202
2203   if (!_dbus_message_iter_open_signature (real))
2204     return FALSE;
2205
2206   *real_sub = *real;
2207
2208   if (contained_signature != NULL)
2209     {
2210       _dbus_string_init_const (&contained_str, contained_signature);
2211
2212       return _dbus_type_writer_recurse (&real->u.writer,
2213                                         type,
2214                                         &contained_str, 0,
2215                                         &real_sub->u.writer);
2216     }
2217   else
2218     {
2219       return _dbus_type_writer_recurse (&real->u.writer,
2220                                         type,
2221                                         NULL, 0,
2222                                         &real_sub->u.writer);
2223     } 
2224 }
2225
2226
2227 /**
2228  * Closes a container-typed value appended to the message; may write
2229  * out more information to the message known only after the entire
2230  * container is written, and may free resources created by
2231  * dbus_message_iter_open_container().
2232  *
2233  * @todo If this fails due to lack of memory, the message is hosed and
2234  * you have to start over building the whole message.
2235  *
2236  * @param iter the append iterator
2237  * @param sub sub-iterator to close
2238  * @returns #FALSE if not enough memory
2239  */
2240 dbus_bool_t
2241 dbus_message_iter_close_container (DBusMessageIter *iter,
2242                                    DBusMessageIter *sub)
2243 {
2244   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2245   DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2246   dbus_bool_t ret;
2247
2248   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2249   _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2250   _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
2251   _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2252
2253   ret = _dbus_type_writer_unrecurse (&real->u.writer,
2254                                      &real_sub->u.writer);
2255
2256   if (!_dbus_message_iter_close_signature (real))
2257     ret = FALSE;
2258
2259   return ret;
2260 }
2261
2262 /**
2263  * Sets a flag indicating that the message does not want a reply; if
2264  * this flag is set, the other end of the connection may (but is not
2265  * required to) optimize by not sending method return or error
2266  * replies. If this flag is set, there is no way to know whether the
2267  * message successfully arrived at the remote end. Normally you know a
2268  * message was received when you receive the reply to it.
2269  *
2270  * @param message the message
2271  * @param no_reply #TRUE if no reply is desired
2272  */
2273 void
2274 dbus_message_set_no_reply (DBusMessage *message,
2275                            dbus_bool_t  no_reply)
2276 {
2277   _dbus_return_if_fail (message != NULL);
2278   _dbus_return_if_fail (!message->locked);
2279
2280   _dbus_header_toggle_flag (&message->header,
2281                             DBUS_HEADER_FLAG_NO_REPLY_EXPECTED,
2282                             no_reply);
2283 }
2284
2285 /**
2286  * Returns #TRUE if the message does not expect
2287  * a reply.
2288  *
2289  * @param message the message
2290  * @returns #TRUE if the message sender isn't waiting for a reply
2291  */
2292 dbus_bool_t
2293 dbus_message_get_no_reply (DBusMessage *message)
2294 {
2295   _dbus_return_val_if_fail (message != NULL, FALSE);
2296
2297   return _dbus_header_get_flag (&message->header,
2298                                 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED);
2299 }
2300
2301 /**
2302  * Sets a flag indicating that an owner for the destination name will
2303  * be automatically started before the message is delivered. When this
2304  * flag is set, the message is held until a name owner finishes
2305  * starting up, or fails to start up. In case of failure, the reply
2306  * will be an error.
2307  *
2308  * @param message the message
2309  * @param auto_start #TRUE if auto-starting is desired
2310  */
2311 void
2312 dbus_message_set_auto_start (DBusMessage *message,
2313                              dbus_bool_t  auto_start)
2314 {
2315   _dbus_return_if_fail (message != NULL);
2316   _dbus_return_if_fail (!message->locked);
2317
2318   _dbus_header_toggle_flag (&message->header,
2319                             DBUS_HEADER_FLAG_NO_AUTO_START,
2320                             !auto_start);
2321 }
2322
2323 /**
2324  * Returns #TRUE if the message will cause an owner for
2325  * destination name to be auto-started.
2326  *
2327  * @param message the message
2328  * @returns #TRUE if the message will use auto-start
2329  */
2330 dbus_bool_t
2331 dbus_message_get_auto_start (DBusMessage *message)
2332 {
2333   _dbus_return_val_if_fail (message != NULL, FALSE);
2334
2335   return !_dbus_header_get_flag (&message->header,
2336                                  DBUS_HEADER_FLAG_NO_AUTO_START);
2337 }
2338
2339
2340 /**
2341  * Sets the object path this message is being sent to (for
2342  * DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a signal is being
2343  * emitted from (for DBUS_MESSAGE_TYPE_SIGNAL).
2344  *
2345  * @param message the message
2346  * @param object_path the path or #NULL to unset
2347  * @returns #FALSE if not enough memory
2348  */
2349 dbus_bool_t
2350 dbus_message_set_path (DBusMessage   *message,
2351                        const char    *object_path)
2352 {
2353   _dbus_return_val_if_fail (message != NULL, FALSE);
2354   _dbus_return_val_if_fail (!message->locked, FALSE);
2355   _dbus_return_val_if_fail (object_path == NULL ||
2356                             _dbus_check_is_valid_path (object_path),
2357                             FALSE);
2358
2359   return set_or_delete_string_field (message,
2360                                      DBUS_HEADER_FIELD_PATH,
2361                                      DBUS_TYPE_OBJECT_PATH,
2362                                      object_path);
2363 }
2364
2365 /**
2366  * Gets the object path this message is being sent to (for
2367  * DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted from (for
2368  * DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none.
2369  *
2370  * @param message the message
2371  * @returns the path (should not be freed) or #NULL
2372  */
2373 const char*
2374 dbus_message_get_path (DBusMessage   *message)
2375 {
2376   const char *v;
2377
2378   _dbus_return_val_if_fail (message != NULL, NULL);
2379
2380   v = NULL; /* in case field doesn't exist */
2381   _dbus_header_get_field_basic (&message->header,
2382                                 DBUS_HEADER_FIELD_PATH,
2383                                 DBUS_TYPE_OBJECT_PATH,
2384                                 &v);
2385   return v;
2386 }
2387
2388 /**
2389  * Gets the object path this message is being sent to
2390  * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
2391  * from (for DBUS_MESSAGE_TYPE_SIGNAL) in a decomposed
2392  * format (one array element per path component).
2393  * Free the returned array with dbus_free_string_array().
2394  *
2395  * An empty but non-NULL path array means the path "/".
2396  * So the path "/foo/bar" becomes { "foo", "bar", NULL }
2397  * and the path "/" becomes { NULL }.
2398  *
2399  * @todo this could be optimized by using the len from the message
2400  * instead of calling strlen() again
2401  *
2402  * @param message the message
2403  * @param path place to store allocated array of path components; #NULL set here if no path field exists
2404  * @returns #FALSE if no memory to allocate the array
2405  */
2406 dbus_bool_t
2407 dbus_message_get_path_decomposed (DBusMessage   *message,
2408                                   char        ***path)
2409 {
2410   const char *v;
2411
2412   _dbus_return_val_if_fail (message != NULL, FALSE);
2413   _dbus_return_val_if_fail (path != NULL, FALSE);
2414
2415   *path = NULL;
2416
2417   v = dbus_message_get_path (message);
2418   if (v != NULL)
2419     {
2420       if (!_dbus_decompose_path (v, strlen (v),
2421                                  path, NULL))
2422         return FALSE;
2423     }
2424   return TRUE;
2425 }
2426
2427 /**
2428  * Sets the interface this message is being sent to
2429  * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or
2430  * the interface a signal is being emitted from
2431  * (for DBUS_MESSAGE_TYPE_SIGNAL).
2432  *
2433  * @param message the message
2434  * @param interface the interface or #NULL to unset
2435  * @returns #FALSE if not enough memory
2436  */
2437 dbus_bool_t
2438 dbus_message_set_interface (DBusMessage  *message,
2439                             const char   *interface)
2440 {
2441   _dbus_return_val_if_fail (message != NULL, FALSE);
2442   _dbus_return_val_if_fail (!message->locked, FALSE);
2443   _dbus_return_val_if_fail (interface == NULL ||
2444                             _dbus_check_is_valid_interface (interface),
2445                             FALSE);
2446
2447   return set_or_delete_string_field (message,
2448                                      DBUS_HEADER_FIELD_INTERFACE,
2449                                      DBUS_TYPE_STRING,
2450                                      interface);
2451 }
2452
2453 /**
2454  * Gets the interface this message is being sent to
2455  * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
2456  * from (for DBUS_MESSAGE_TYPE_SIGNAL).
2457  * The interface name is fully-qualified (namespaced).
2458  * Returns #NULL if none.
2459  *
2460  * @param message the message
2461  * @returns the message interface (should not be freed) or #NULL
2462  */
2463 const char*
2464 dbus_message_get_interface (DBusMessage *message)
2465 {
2466   const char *v;
2467
2468   _dbus_return_val_if_fail (message != NULL, NULL);
2469
2470   v = NULL; /* in case field doesn't exist */
2471   _dbus_header_get_field_basic (&message->header,
2472                                 DBUS_HEADER_FIELD_INTERFACE,
2473                                 DBUS_TYPE_STRING,
2474                                 &v);
2475   return v;
2476 }
2477
2478 /**
2479  * Sets the interface member being invoked
2480  * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
2481  * (DBUS_MESSAGE_TYPE_SIGNAL).
2482  * The interface name is fully-qualified (namespaced).
2483  *
2484  * @param message the message
2485  * @param member the member or #NULL to unset
2486  * @returns #FALSE if not enough memory
2487  */
2488 dbus_bool_t
2489 dbus_message_set_member (DBusMessage  *message,
2490                          const char   *member)
2491 {
2492   _dbus_return_val_if_fail (message != NULL, FALSE);
2493   _dbus_return_val_if_fail (!message->locked, FALSE);
2494   _dbus_return_val_if_fail (member == NULL ||
2495                             _dbus_check_is_valid_member (member),
2496                             FALSE);
2497
2498   return set_or_delete_string_field (message,
2499                                      DBUS_HEADER_FIELD_MEMBER,
2500                                      DBUS_TYPE_STRING,
2501                                      member);
2502 }
2503
2504 /**
2505  * Gets the interface member being invoked
2506  * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
2507  * (DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none.
2508  *
2509  * @param message the message
2510  * @returns the member name (should not be freed) or #NULL
2511  */
2512 const char*
2513 dbus_message_get_member (DBusMessage *message)
2514 {
2515   const char *v;
2516
2517   _dbus_return_val_if_fail (message != NULL, NULL);
2518
2519   v = NULL; /* in case field doesn't exist */
2520   _dbus_header_get_field_basic (&message->header,
2521                                 DBUS_HEADER_FIELD_MEMBER,
2522                                 DBUS_TYPE_STRING,
2523                                 &v);
2524   return v;
2525 }
2526
2527 /**
2528  * Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
2529  * The name is fully-qualified (namespaced).
2530  *
2531  * @param message the message
2532  * @param error_name the name or #NULL to unset
2533  * @returns #FALSE if not enough memory
2534  */
2535 dbus_bool_t
2536 dbus_message_set_error_name (DBusMessage  *message,
2537                              const char   *error_name)
2538 {
2539   _dbus_return_val_if_fail (message != NULL, FALSE);
2540   _dbus_return_val_if_fail (!message->locked, FALSE);
2541   _dbus_return_val_if_fail (error_name == NULL ||
2542                             _dbus_check_is_valid_error_name (error_name),
2543                             FALSE);
2544
2545   return set_or_delete_string_field (message,
2546                                      DBUS_HEADER_FIELD_ERROR_NAME,
2547                                      DBUS_TYPE_STRING,
2548                                      error_name);
2549 }
2550
2551 /**
2552  * Gets the error name (DBUS_MESSAGE_TYPE_ERROR only)
2553  * or #NULL if none.
2554  *
2555  * @param message the message
2556  * @returns the error name (should not be freed) or #NULL
2557  */
2558 const char*
2559 dbus_message_get_error_name (DBusMessage *message)
2560 {
2561   const char *v;
2562
2563   _dbus_return_val_if_fail (message != NULL, NULL);
2564
2565   v = NULL; /* in case field doesn't exist */
2566   _dbus_header_get_field_basic (&message->header,
2567                                 DBUS_HEADER_FIELD_ERROR_NAME,
2568                                 DBUS_TYPE_STRING,
2569                                 &v);
2570   return v;
2571 }
2572
2573 /**
2574  * Sets the message's destination. The destination is the name of
2575  * another connection on the bus and may be either the unique name
2576  * assigned by the bus to each connection, or a well-known name
2577  * specified in advance.
2578  *
2579  * @param message the message
2580  * @param destination the destination name or #NULL to unset
2581  * @returns #FALSE if not enough memory
2582  */
2583 dbus_bool_t
2584 dbus_message_set_destination (DBusMessage  *message,
2585                               const char   *destination)
2586 {
2587   _dbus_return_val_if_fail (message != NULL, FALSE);
2588   _dbus_return_val_if_fail (!message->locked, FALSE);
2589   _dbus_return_val_if_fail (destination == NULL ||
2590                             _dbus_check_is_valid_bus_name (destination),
2591                             FALSE);
2592
2593   return set_or_delete_string_field (message,
2594                                      DBUS_HEADER_FIELD_DESTINATION,
2595                                      DBUS_TYPE_STRING,
2596                                      destination);
2597 }
2598
2599 /**
2600  * Gets the destination of a message or #NULL if there is none set.
2601  *
2602  * @param message the message
2603  * @returns the message destination (should not be freed) or #NULL
2604  */
2605 const char*
2606 dbus_message_get_destination (DBusMessage *message)
2607 {
2608   const char *v;
2609
2610   _dbus_return_val_if_fail (message != NULL, NULL);
2611
2612   v = NULL; /* in case field doesn't exist */
2613   _dbus_header_get_field_basic (&message->header,
2614                                 DBUS_HEADER_FIELD_DESTINATION,
2615                                 DBUS_TYPE_STRING,
2616                                 &v);
2617   return v;
2618 }
2619
2620 /**
2621  * Sets the message sender.
2622  *
2623  * @param message the message
2624  * @param sender the sender or #NULL to unset
2625  * @returns #FALSE if not enough memory
2626  */
2627 dbus_bool_t
2628 dbus_message_set_sender (DBusMessage  *message,
2629                          const char   *sender)
2630 {
2631   _dbus_return_val_if_fail (message != NULL, FALSE);
2632   _dbus_return_val_if_fail (!message->locked, FALSE);
2633   _dbus_return_val_if_fail (sender == NULL ||
2634                             _dbus_check_is_valid_bus_name (sender),
2635                             FALSE);
2636
2637   return set_or_delete_string_field (message,
2638                                      DBUS_HEADER_FIELD_SENDER,
2639                                      DBUS_TYPE_STRING,
2640                                      sender);
2641 }
2642
2643 /**
2644  * Gets the unique name of the connection which originated this
2645  * message, or #NULL if unknown or inapplicable. The sender is filled
2646  * in by the message bus.
2647  *
2648  * @param message the message
2649  * @returns the unique name of the sender or #NULL
2650  */
2651 const char*
2652 dbus_message_get_sender (DBusMessage *message)
2653 {
2654   const char *v;
2655
2656   _dbus_return_val_if_fail (message != NULL, NULL);
2657
2658   v = NULL; /* in case field doesn't exist */
2659   _dbus_header_get_field_basic (&message->header,
2660                                 DBUS_HEADER_FIELD_SENDER,
2661                                 DBUS_TYPE_STRING,
2662                                 &v);
2663   return v;
2664 }
2665
2666 /**
2667  * Gets the type signature of the message, i.e. the arguments in the
2668  * message payload. The signature includes only "in" arguments for
2669  * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
2670  * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
2671  * what you might expect (it does not include the signature of the
2672  * entire C++-style method).
2673  *
2674  * The signature is a string made up of type codes such as
2675  * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also
2676  * the value of #DBUS_TYPE_INVALID).
2677  *
2678  * @param message the message
2679  * @returns the type signature
2680  */
2681 const char*
2682 dbus_message_get_signature (DBusMessage *message)
2683 {
2684   const DBusString *type_str;
2685   int type_pos;
2686
2687   _dbus_return_val_if_fail (message != NULL, NULL);
2688
2689   get_const_signature (&message->header, &type_str, &type_pos);
2690
2691   return _dbus_string_get_const_data_len (type_str, type_pos, 0);
2692 }
2693
2694 static dbus_bool_t
2695 _dbus_message_has_type_interface_member (DBusMessage *message,
2696                                          int          type,
2697                                          const char  *interface,
2698                                          const char  *member)
2699 {
2700   const char *n;
2701
2702   _dbus_assert (message != NULL);
2703   _dbus_assert (interface != NULL);
2704   _dbus_assert (member != NULL);
2705
2706   if (dbus_message_get_type (message) != type)
2707     return FALSE;
2708
2709   /* Optimize by checking the short member name first
2710    * instead of the longer interface name
2711    */
2712
2713   n = dbus_message_get_member (message);
2714
2715   if (n && strcmp (n, member) == 0)
2716     {
2717       n = dbus_message_get_interface (message);
2718
2719       if (n == NULL || strcmp (n, interface) == 0)
2720         return TRUE;
2721     }
2722
2723   return FALSE;
2724 }
2725
2726 /**
2727  * Checks whether the message is a method call with the given
2728  * interface and member fields.  If the message is not
2729  * #DBUS_MESSAGE_TYPE_METHOD_CALL, or has a different interface or
2730  * member field, returns #FALSE. If the interface field is missing,
2731  * then it will be assumed equal to the provided interface.  The D-BUS
2732  * protocol allows method callers to leave out the interface name.
2733  *
2734  * @param message the message
2735  * @param interface the name to check (must not be #NULL)
2736  * @param method the name to check (must not be #NULL)
2737  *
2738  * @returns #TRUE if the message is the specified method call
2739  */
2740 dbus_bool_t
2741 dbus_message_is_method_call (DBusMessage *message,
2742                              const char  *interface,
2743                              const char  *method)
2744 {
2745   _dbus_return_val_if_fail (message != NULL, FALSE);
2746   _dbus_return_val_if_fail (interface != NULL, FALSE);
2747   _dbus_return_val_if_fail (method != NULL, FALSE);
2748   /* don't check that interface/method are valid since it would be
2749    * expensive, and not catch many common errors
2750    */
2751
2752   return _dbus_message_has_type_interface_member (message,
2753                                                   DBUS_MESSAGE_TYPE_METHOD_CALL,
2754                                                   interface, method);
2755 }
2756
2757 /**
2758  * Checks whether the message is a signal with the given interface and
2759  * member fields.  If the message is not #DBUS_MESSAGE_TYPE_SIGNAL, or
2760  * has a different interface or member field, returns #FALSE.  If the
2761  * interface field in the message is missing, it is assumed to match
2762  * any interface you pass in to this function.
2763  *
2764  * @param message the message
2765  * @param interface the name to check (must not be #NULL)
2766  * @param signal_name the name to check (must not be #NULL)
2767  *
2768  * @returns #TRUE if the message is the specified signal
2769  */
2770 dbus_bool_t
2771 dbus_message_is_signal (DBusMessage *message,
2772                         const char  *interface,
2773                         const char  *signal_name)
2774 {
2775   _dbus_return_val_if_fail (message != NULL, FALSE);
2776   _dbus_return_val_if_fail (interface != NULL, FALSE);
2777   _dbus_return_val_if_fail (signal_name != NULL, FALSE);
2778   /* don't check that interface/name are valid since it would be
2779    * expensive, and not catch many common errors
2780    */
2781
2782   return _dbus_message_has_type_interface_member (message,
2783                                                   DBUS_MESSAGE_TYPE_SIGNAL,
2784                                                   interface, signal_name);
2785 }
2786
2787 /**
2788  * Checks whether the message is an error reply with the given error
2789  * name.  If the message is not #DBUS_MESSAGE_TYPE_ERROR, or has a
2790  * different name, returns #FALSE.
2791  *
2792  * @param message the message
2793  * @param error_name the name to check (must not be #NULL)
2794  *
2795  * @returns #TRUE if the message is the specified error
2796  */
2797 dbus_bool_t
2798 dbus_message_is_error (DBusMessage *message,
2799                        const char  *error_name)
2800 {
2801   const char *n;
2802
2803   _dbus_return_val_if_fail (message != NULL, FALSE);
2804   _dbus_return_val_if_fail (error_name != NULL, FALSE);
2805   /* don't check that error_name is valid since it would be expensive,
2806    * and not catch many common errors
2807    */
2808
2809   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2810     return FALSE;
2811
2812   n = dbus_message_get_error_name (message);
2813
2814   if (n && strcmp (n, error_name) == 0)
2815     return TRUE;
2816   else
2817     return FALSE;
2818 }
2819
2820 /**
2821  * Checks whether the message was sent to the given name.  If the
2822  * message has no destination specified or has a different
2823  * destination, returns #FALSE.
2824  *
2825  * @param message the message
2826  * @param name the name to check (must not be #NULL)
2827  *
2828  * @returns #TRUE if the message has the given destination name
2829  */
2830 dbus_bool_t
2831 dbus_message_has_destination (DBusMessage  *message,
2832                               const char   *name)
2833 {
2834   const char *s;
2835
2836   _dbus_return_val_if_fail (message != NULL, FALSE);
2837   _dbus_return_val_if_fail (name != NULL, FALSE);
2838   /* don't check that name is valid since it would be expensive, and
2839    * not catch many common errors
2840    */
2841
2842   s = dbus_message_get_destination (message);
2843
2844   if (s && strcmp (s, name) == 0)
2845     return TRUE;
2846   else
2847     return FALSE;
2848 }
2849
2850 /**
2851  * Checks whether the message has the given unique name as its sender.
2852  * If the message has no sender specified or has a different sender,
2853  * returns #FALSE. Note that a peer application will always have the
2854  * unique name of the connection as the sender. So you can't use this
2855  * function to see whether a sender owned a well-known name.
2856  *
2857  * Messages from the bus itself will have #DBUS_SERVICE_DBUS
2858  * as the sender.
2859  *
2860  * @param message the message
2861  * @param name the name to check (must not be #NULL)
2862  *
2863  * @returns #TRUE if the message has the given sender
2864  */
2865 dbus_bool_t
2866 dbus_message_has_sender (DBusMessage  *message,
2867                          const char   *name)
2868 {
2869   const char *s;
2870
2871   _dbus_return_val_if_fail (message != NULL, FALSE);
2872   _dbus_return_val_if_fail (name != NULL, FALSE);
2873   /* don't check that name is valid since it would be expensive, and
2874    * not catch many common errors
2875    */
2876
2877   s = dbus_message_get_sender (message);
2878
2879   if (s && strcmp (s, name) == 0)
2880     return TRUE;
2881   else
2882     return FALSE;
2883 }
2884
2885 /**
2886  * Checks whether the message has the given signature; see
2887  * dbus_message_get_signature() for more details on what the signature
2888  * looks like.
2889  *
2890  * @param message the message
2891  * @param signature typecode array
2892  * @returns #TRUE if message has the given signature
2893 */
2894 dbus_bool_t
2895 dbus_message_has_signature (DBusMessage   *message,
2896                             const char    *signature)
2897 {
2898   const char *s;
2899
2900   _dbus_return_val_if_fail (message != NULL, FALSE);
2901   _dbus_return_val_if_fail (signature != NULL, FALSE);
2902   /* don't check that signature is valid since it would be expensive,
2903    * and not catch many common errors
2904    */
2905
2906   s = dbus_message_get_signature (message);
2907
2908   if (s && strcmp (s, signature) == 0)
2909     return TRUE;
2910   else
2911     return FALSE;
2912 }
2913
2914 /**
2915  * Sets a #DBusError based on the contents of the given
2916  * message. The error is only set if the message
2917  * is an error message, as in DBUS_MESSAGE_TYPE_ERROR.
2918  * The name of the error is set to the name of the message,
2919  * and the error message is set to the first argument
2920  * if the argument exists and is a string.
2921  *
2922  * The return value indicates whether the error was set (the error is
2923  * set if and only if the message is an error message).  So you can
2924  * check for an error reply and convert it to DBusError in one go:
2925  * @code
2926  *  if (dbus_set_error_from_message (error, reply))
2927  *    return error;
2928  *  else
2929  *    process reply;
2930  * @endcode
2931  *
2932  * @param error the error to set
2933  * @param message the message to set it from
2934  * @returns #TRUE if dbus_message_get_is_error() returns #TRUE for the message
2935  */
2936 dbus_bool_t
2937 dbus_set_error_from_message (DBusError   *error,
2938                              DBusMessage *message)
2939 {
2940   const char *str;
2941
2942   _dbus_return_val_if_fail (message != NULL, FALSE);
2943   _dbus_return_val_if_error_is_set (error, FALSE);
2944
2945   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2946     return FALSE;
2947
2948   str = NULL;
2949   dbus_message_get_args (message, NULL,
2950                          DBUS_TYPE_STRING, &str,
2951                          DBUS_TYPE_INVALID);
2952
2953   dbus_set_error (error, dbus_message_get_error_name (message),
2954                   str ? "%s" : NULL, str);
2955
2956   return TRUE;
2957 }
2958
2959 /** @} */
2960
2961 /**
2962  * @addtogroup DBusMessageInternals
2963  *
2964  * @{
2965  */
2966
2967 /**
2968  * The initial buffer size of the message loader.
2969  *
2970  * @todo this should be based on min header size plus some average
2971  * body size, or something. Or rather, the min header size only, if we
2972  * want to try to read only the header, store that in a DBusMessage,
2973  * then read only the body and store that, etc., depends on
2974  * how we optimize _dbus_message_loader_get_buffer() and what
2975  * the exact message format is.
2976  */
2977 #define INITIAL_LOADER_DATA_LEN 32
2978
2979 /**
2980  * Creates a new message loader. Returns #NULL if memory can't
2981  * be allocated.
2982  *
2983  * @returns new loader, or #NULL.
2984  */
2985 DBusMessageLoader*
2986 _dbus_message_loader_new (void)
2987 {
2988   DBusMessageLoader *loader;
2989
2990   loader = dbus_new0 (DBusMessageLoader, 1);
2991   if (loader == NULL)
2992     return NULL;
2993   
2994   loader->refcount = 1;
2995
2996   loader->corrupted = FALSE;
2997   loader->corruption_reason = DBUS_VALID;
2998
2999   /* this can be configured by the app, but defaults to the protocol max */
3000   loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
3001
3002   if (!_dbus_string_init (&loader->data))
3003     {
3004       dbus_free (loader);
3005       return NULL;
3006     }
3007
3008   /* preallocate the buffer for speed, ignore failure */
3009   _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
3010   _dbus_string_set_length (&loader->data, 0);
3011
3012   return loader;
3013 }
3014
3015 /**
3016  * Increments the reference count of the loader.
3017  *
3018  * @param loader the loader.
3019  * @returns the loader
3020  */
3021 DBusMessageLoader *
3022 _dbus_message_loader_ref (DBusMessageLoader *loader)
3023 {
3024   loader->refcount += 1;
3025
3026   return loader;
3027 }
3028
3029 /**
3030  * Decrements the reference count of the loader and finalizes the
3031  * loader when the count reaches zero.
3032  *
3033  * @param loader the loader.
3034  */
3035 void
3036 _dbus_message_loader_unref (DBusMessageLoader *loader)
3037 {
3038   loader->refcount -= 1;
3039   if (loader->refcount == 0)
3040     {
3041       _dbus_list_foreach (&loader->messages,
3042                           (DBusForeachFunction) dbus_message_unref,
3043                           NULL);
3044       _dbus_list_clear (&loader->messages);
3045       _dbus_string_free (&loader->data);
3046       dbus_free (loader);
3047     }
3048 }
3049
3050 /**
3051  * Gets the buffer to use for reading data from the network.  Network
3052  * data is read directly into an allocated buffer, which is then used
3053  * in the DBusMessage, to avoid as many extra memcpy's as possible.
3054  * The buffer must always be returned immediately using
3055  * _dbus_message_loader_return_buffer(), even if no bytes are
3056  * successfully read.
3057  *
3058  * @todo this function can be a lot more clever. For example
3059  * it can probably always return a buffer size to read exactly
3060  * the body of the next message, thus avoiding any memory wastage
3061  * or reallocs.
3062  *
3063  * @todo we need to enforce a max length on strings in header fields.
3064  *
3065  * @param loader the message loader.
3066  * @param buffer the buffer
3067  */
3068 void
3069 _dbus_message_loader_get_buffer (DBusMessageLoader  *loader,
3070                                  DBusString        **buffer)
3071 {
3072   _dbus_assert (!loader->buffer_outstanding);
3073
3074   *buffer = &loader->data;
3075
3076   loader->buffer_outstanding = TRUE;
3077 }
3078
3079 /**
3080  * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
3081  * indicating to the loader how many bytes of the buffer were filled
3082  * in. This function must always be called, even if no bytes were
3083  * successfully read.
3084  *
3085  * @param loader the loader.
3086  * @param buffer the buffer.
3087  * @param bytes_read number of bytes that were read into the buffer.
3088  */
3089 void
3090 _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
3091                                     DBusString         *buffer,
3092                                     int                 bytes_read)
3093 {
3094   _dbus_assert (loader->buffer_outstanding);
3095   _dbus_assert (buffer == &loader->data);
3096
3097   loader->buffer_outstanding = FALSE;
3098 }
3099
3100 /*
3101  * FIXME when we move the header out of the buffer, that memmoves all
3102  * buffered messages. Kind of crappy.
3103  *
3104  * Also we copy the header and body, which is kind of crappy.  To
3105  * avoid this, we have to allow header and body to be in a single
3106  * memory block, which is good for messages we read and bad for
3107  * messages we are creating. But we could move_len() the buffer into
3108  * this single memory block, and move_len() will just swap the buffers
3109  * if you're moving the entire buffer replacing the dest string.
3110  *
3111  * We could also have the message loader tell the transport how many
3112  * bytes to read; so it would first ask for some arbitrary number like
3113  * 256, then if the message was incomplete it would use the
3114  * header/body len to ask for exactly the size of the message (or
3115  * blocks the size of a typical kernel buffer for the socket). That
3116  * way we don't get trailing bytes in the buffer that have to be
3117  * memmoved. Though I suppose we also don't have a chance of reading a
3118  * bunch of small messages at once, so the optimization may be stupid.
3119  *
3120  * Another approach would be to keep a "start" index into
3121  * loader->data and only delete it occasionally, instead of after
3122  * each message is loaded.
3123  *
3124  * load_message() returns FALSE if not enough memory OR the loader was corrupted
3125  */
3126 static dbus_bool_t
3127 load_message (DBusMessageLoader *loader,
3128               DBusMessage       *message,
3129               int                byte_order,
3130               int                fields_array_len,
3131               int                header_len,
3132               int                body_len)
3133 {
3134   dbus_bool_t oom;
3135   DBusValidity validity;
3136   const DBusString *type_str;
3137   int type_pos;
3138   DBusValidationMode mode;
3139
3140   mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
3141   
3142   oom = FALSE;
3143
3144 #if 0
3145   _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
3146 #endif
3147
3148   /* 1. VALIDATE AND COPY OVER HEADER */
3149   _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
3150   _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
3151
3152   if (!_dbus_header_load (&message->header,
3153                           mode,
3154                           &validity,
3155                           byte_order,
3156                           fields_array_len,
3157                           header_len,
3158                           body_len,
3159                           &loader->data, 0,
3160                           _dbus_string_get_length (&loader->data)))
3161     {
3162       _dbus_verbose ("Failed to load header for new message code %d\n", validity);
3163       if (validity == DBUS_VALID)
3164         oom = TRUE;
3165       else
3166         {
3167           loader->corrupted = TRUE;
3168           loader->corruption_reason = validity;
3169         }
3170       goto failed;
3171     }
3172
3173   _dbus_assert (validity == DBUS_VALID);
3174
3175   message->byte_order = byte_order;
3176
3177   /* 2. VALIDATE BODY */
3178   if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
3179     {
3180       get_const_signature (&message->header, &type_str, &type_pos);
3181       
3182       /* Because the bytes_remaining arg is NULL, this validates that the
3183        * body is the right length
3184        */
3185       validity = _dbus_validate_body_with_reason (type_str,
3186                                                   type_pos,
3187                                                   byte_order,
3188                                                   NULL,
3189                                                   &loader->data,
3190                                                   header_len,
3191                                                   body_len);
3192       if (validity != DBUS_VALID)
3193         {
3194           _dbus_verbose ("Failed to validate message body code %d\n", validity);
3195
3196           loader->corrupted = TRUE;
3197           loader->corruption_reason = validity;
3198           
3199           goto failed;
3200         }
3201     }
3202
3203   /* 3. COPY OVER BODY AND QUEUE MESSAGE */
3204
3205   if (!_dbus_list_append (&loader->messages, message))
3206     {
3207       _dbus_verbose ("Failed to append new message to loader queue\n");
3208       oom = TRUE;
3209       goto failed;
3210     }
3211
3212   _dbus_assert (_dbus_string_get_length (&message->body) == 0);
3213   _dbus_assert (_dbus_string_get_length (&loader->data) >=
3214                 (header_len + body_len));
3215
3216   if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
3217     {
3218       _dbus_verbose ("Failed to move body into new message\n");
3219       oom = TRUE;
3220       goto failed;
3221     }
3222
3223   _dbus_string_delete (&loader->data, 0, header_len + body_len);
3224
3225   _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
3226   _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
3227
3228   _dbus_verbose ("Loaded message %p\n", message);
3229
3230   _dbus_assert (!oom);
3231   _dbus_assert (!loader->corrupted);
3232   _dbus_assert (loader->messages != NULL);
3233   _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
3234
3235   return TRUE;
3236
3237  failed:
3238
3239   /* Clean up */
3240
3241   /* does nothing if the message isn't in the list */
3242   _dbus_list_remove_last (&loader->messages, message);
3243   
3244   if (oom)
3245     _dbus_assert (!loader->corrupted);
3246   else
3247     _dbus_assert (loader->corrupted);
3248
3249   _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data));
3250
3251   return FALSE;
3252 }
3253
3254 /**
3255  * Converts buffered data into messages, if we have enough data.  If
3256  * we don't have enough data, does nothing.
3257  *
3258  * @todo we need to check that the proper named header fields exist
3259  * for each message type.
3260  *
3261  * @todo If a message has unknown type, we should probably eat it
3262  * right here rather than passing it out to applications.  However
3263  * it's not an error to see messages of unknown type.
3264  *
3265  * @param loader the loader.
3266  * @returns #TRUE if we had enough memory to finish.
3267  */
3268 dbus_bool_t
3269 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
3270 {
3271   while (!loader->corrupted &&
3272          _dbus_string_get_length (&loader->data) >= DBUS_MINIMUM_HEADER_SIZE)
3273     {
3274       DBusValidity validity;
3275       int byte_order, fields_array_len, header_len, body_len;
3276
3277       if (_dbus_header_have_message_untrusted (loader->max_message_size,
3278                                                &validity,
3279                                                &byte_order,
3280                                                &fields_array_len,
3281                                                &header_len,
3282                                                &body_len,
3283                                                &loader->data, 0,
3284                                                _dbus_string_get_length (&loader->data)))
3285         {
3286           DBusMessage *message;
3287
3288           _dbus_assert (validity == DBUS_VALID);
3289
3290           message = dbus_message_new_empty_header ();
3291           if (message == NULL)
3292             return FALSE;
3293
3294           if (!load_message (loader, message,
3295                              byte_order, fields_array_len,
3296                              header_len, body_len))
3297             {
3298               dbus_message_unref (message);
3299               /* load_message() returns false if corrupted or OOM; if
3300                * corrupted then return TRUE for not OOM
3301                */
3302               return loader->corrupted;
3303             }
3304
3305           _dbus_assert (loader->messages != NULL);
3306           _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
3307         }
3308       else
3309         {
3310           _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
3311                          validity);
3312           if (validity != DBUS_VALID)
3313             {
3314               loader->corrupted = TRUE;
3315               loader->corruption_reason = validity;
3316             }
3317           return TRUE;
3318         }
3319     }
3320
3321   return TRUE;
3322 }
3323
3324 /**
3325  * Peeks at first loaded message, returns #NULL if no messages have
3326  * been queued.
3327  *
3328  * @param loader the loader.
3329  * @returns the next message, or #NULL if none.
3330  */
3331 DBusMessage*
3332 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
3333 {
3334   if (loader->messages)
3335     return loader->messages->data;
3336   else
3337     return NULL;
3338 }
3339
3340 /**
3341  * Pops a loaded message (passing ownership of the message
3342  * to the caller). Returns #NULL if no messages have been
3343  * queued.
3344  *
3345  * @param loader the loader.
3346  * @returns the next message, or #NULL if none.
3347  */
3348 DBusMessage*
3349 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
3350 {
3351   return _dbus_list_pop_first (&loader->messages);
3352 }
3353
3354 /**
3355  * Pops a loaded message inside a list link (passing ownership of the
3356  * message and link to the caller). Returns #NULL if no messages have
3357  * been loaded.
3358  *
3359  * @param loader the loader.
3360  * @returns the next message link, or #NULL if none.
3361  */
3362 DBusList*
3363 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
3364 {
3365   return _dbus_list_pop_first_link (&loader->messages);
3366 }
3367
3368 /**
3369  * Returns a popped message link, used to undo a pop.
3370  *
3371  * @param loader the loader
3372  * @param link the link with a message in it
3373  */
3374 void
3375 _dbus_message_loader_putback_message_link (DBusMessageLoader  *loader,
3376                                            DBusList           *link)
3377 {
3378   _dbus_list_prepend_link (&loader->messages, link);
3379 }
3380
3381 /**
3382  * Checks whether the loader is confused due to bad data.
3383  * If messages are received that are invalid, the
3384  * loader gets confused and gives up permanently.
3385  * This state is called "corrupted."
3386  *
3387  * @param loader the loader
3388  * @returns #TRUE if the loader is hosed.
3389  */
3390 dbus_bool_t
3391 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
3392 {
3393   _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
3394                 (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
3395   return loader->corrupted;
3396 }
3397
3398 /**
3399  * Sets the maximum size message we allow.
3400  *
3401  * @param loader the loader
3402  * @param size the max message size in bytes
3403  */
3404 void
3405 _dbus_message_loader_set_max_message_size (DBusMessageLoader  *loader,
3406                                            long                size)
3407 {
3408   if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
3409     {
3410       _dbus_verbose ("clamping requested max message size %ld to %d\n",
3411                      size, DBUS_MAXIMUM_MESSAGE_LENGTH);
3412       size = DBUS_MAXIMUM_MESSAGE_LENGTH;
3413     }
3414   loader->max_message_size = size;
3415 }
3416
3417 /**
3418  * Gets the maximum allowed message size in bytes.
3419  *
3420  * @param loader the loader
3421  * @returns max size in bytes
3422  */
3423 long
3424 _dbus_message_loader_get_max_message_size (DBusMessageLoader  *loader)
3425 {
3426   return loader->max_message_size;
3427 }
3428
3429 static DBusDataSlotAllocator slot_allocator;
3430 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
3431
3432 /**
3433  * Allocates an integer ID to be used for storing application-specific
3434  * data on any DBusMessage. The allocated ID may then be used
3435  * with dbus_message_set_data() and dbus_message_get_data().
3436  * The passed-in slot must be initialized to -1, and is filled in
3437  * with the slot ID. If the passed-in slot is not -1, it's assumed
3438  * to be already allocated, and its refcount is incremented.
3439  *
3440  * The allocated slot is global, i.e. all DBusMessage objects will
3441  * have a slot with the given integer ID reserved.
3442  *
3443  * @param slot_p address of a global variable storing the slot
3444  * @returns #FALSE on failure (no memory)
3445  */
3446 dbus_bool_t
3447 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
3448 {
3449   return _dbus_data_slot_allocator_alloc (&slot_allocator,
3450                                           _DBUS_LOCK_NAME (message_slots),
3451                                           slot_p);
3452 }
3453
3454 /**
3455  * Deallocates a global ID for message data slots.
3456  * dbus_message_get_data() and dbus_message_set_data() may no
3457  * longer be used with this slot.  Existing data stored on existing
3458  * DBusMessage objects will be freed when the message is
3459  * finalized, but may not be retrieved (and may only be replaced if
3460  * someone else reallocates the slot).  When the refcount on the
3461  * passed-in slot reaches 0, it is set to -1.
3462  *
3463  * @param slot_p address storing the slot to deallocate
3464  */
3465 void
3466 dbus_message_free_data_slot (dbus_int32_t *slot_p)
3467 {
3468   _dbus_return_if_fail (*slot_p >= 0);
3469
3470   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
3471 }
3472
3473 /**
3474  * Stores a pointer on a DBusMessage, along
3475  * with an optional function to be used for freeing
3476  * the data when the data is set again, or when
3477  * the message is finalized. The slot number
3478  * must have been allocated with dbus_message_allocate_data_slot().
3479  *
3480  * @param message the message
3481  * @param slot the slot number
3482  * @param data the data to store
3483  * @param free_data_func finalizer function for the data
3484  * @returns #TRUE if there was enough memory to store the data
3485  */
3486 dbus_bool_t
3487 dbus_message_set_data (DBusMessage     *message,
3488                        dbus_int32_t     slot,
3489                        void            *data,
3490                        DBusFreeFunction free_data_func)
3491 {
3492   DBusFreeFunction old_free_func;
3493   void *old_data;
3494   dbus_bool_t retval;
3495
3496   _dbus_return_val_if_fail (message != NULL, FALSE);
3497   _dbus_return_val_if_fail (slot >= 0, FALSE);
3498
3499   retval = _dbus_data_slot_list_set (&slot_allocator,
3500                                      &message->slot_list,
3501                                      slot, data, free_data_func,
3502                                      &old_free_func, &old_data);
3503
3504   if (retval)
3505     {
3506       /* Do the actual free outside the message lock */
3507       if (old_free_func)
3508         (* old_free_func) (old_data);
3509     }
3510
3511   return retval;
3512 }
3513
3514 /**
3515  * Retrieves data previously set with dbus_message_set_data().
3516  * The slot must still be allocated (must not have been freed).
3517  *
3518  * @param message the message
3519  * @param slot the slot to get data from
3520  * @returns the data, or #NULL if not found
3521  */
3522 void*
3523 dbus_message_get_data (DBusMessage   *message,
3524                        dbus_int32_t   slot)
3525 {
3526   void *res;
3527
3528   _dbus_return_val_if_fail (message != NULL, NULL);
3529
3530   res = _dbus_data_slot_list_get (&slot_allocator,
3531                                   &message->slot_list,
3532                                   slot);
3533
3534   return res;
3535 }
3536
3537 /**
3538  * Utility function to convert a machine-readable (not translated)
3539  * string into a D-BUS message type.
3540  *
3541  * @code
3542  *   "method_call"    -> DBUS_MESSAGE_TYPE_METHOD_CALL
3543  *   "method_return"  -> DBUS_MESSAGE_TYPE_METHOD_RETURN
3544  *   "signal"         -> DBUS_MESSAGE_TYPE_SIGNAL
3545  *   "error"          -> DBUS_MESSAGE_TYPE_ERROR
3546  *   anything else    -> DBUS_MESSAGE_TYPE_INVALID
3547  * @endcode
3548  *
3549  */
3550 int
3551 dbus_message_type_from_string (const char *type_str)
3552 {
3553   if (strcmp (type_str, "method_call") == 0)
3554     return DBUS_MESSAGE_TYPE_METHOD_CALL;
3555   if (strcmp (type_str, "method_return") == 0)
3556     return DBUS_MESSAGE_TYPE_METHOD_RETURN;
3557   else if (strcmp (type_str, "signal") == 0)
3558     return DBUS_MESSAGE_TYPE_SIGNAL;
3559   else if (strcmp (type_str, "error") == 0)
3560     return DBUS_MESSAGE_TYPE_ERROR;
3561   else
3562     return DBUS_MESSAGE_TYPE_INVALID;
3563 }
3564
3565 /**
3566  * Utility function to convert a D-BUS message type into a
3567  * machine-readable string (not translated).
3568  *
3569  * @code
3570  *   DBUS_MESSAGE_TYPE_METHOD_CALL    -> "method_call"
3571  *   DBUS_MESSAGE_TYPE_METHOD_RETURN  -> "method_return"
3572  *   DBUS_MESSAGE_TYPE_SIGNAL         -> "signal"
3573  *   DBUS_MESSAGE_TYPE_ERROR          -> "error"
3574  *   DBUS_MESSAGE_TYPE_INVALID        -> "invalid"
3575  * @endcode
3576  *
3577  */
3578 const char *
3579 dbus_message_type_to_string (int type)
3580 {
3581   switch (type)
3582     {
3583     case DBUS_MESSAGE_TYPE_METHOD_CALL:
3584       return "method_call";
3585     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
3586       return "method_return";
3587     case DBUS_MESSAGE_TYPE_SIGNAL:
3588       return "signal";
3589     case DBUS_MESSAGE_TYPE_ERROR:
3590       return "error";
3591     default:
3592       return "invalid";
3593     }
3594 }
3595
3596 /** @} */
3597
3598 /* tests in dbus-message-util.c */