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