1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-message.c DBusMessage object
4 * Copyright (C) 2002, 2003 Red Hat Inc.
5 * Copyright (C) 2002, 2003 CodeFactory AB
7 * Licensed under the Academic Free License version 1.2
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.
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.
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
25 #include "dbus-internals.h"
26 #include "dbus-marshal.h"
27 #include "dbus-message.h"
28 #include "dbus-message-internal.h"
29 #include "dbus-memory.h"
30 #include "dbus-list.h"
31 #include "dbus-message-builder.h"
35 * @defgroup DBusMessageInternals DBusMessage implementation details
36 * @ingroup DBusInternals
37 * @brief DBusMessage private implementation details.
39 * The guts of DBusMessage and its methods.
57 static dbus_bool_t field_is_named[FIELD_LAST] =
59 FALSE, /* FIELD_HEADER_LENGTH */
60 FALSE, /* FIELD_BODY_LENGTH */
61 FALSE, /* FIELD_CLIENT_SERIAL */
62 TRUE, /* FIELD_NAME */
63 TRUE, /* FIELD_SERVICE */
64 TRUE, /* FIELD_SENDER */
65 TRUE /* FIELD_REPLY_SERIAL */
70 int offset; /**< Offset to start of field (location of name of field
76 * @brief Internals of DBusMessage
78 * Object representing a message received from or to be sent to
79 * another application. This is an opaque object, all members
84 DBusAtomic refcount; /**< Reference count */
86 DBusString header; /**< Header network data, stored
87 * separately from body so we can
88 * independently realloc it.
91 HeaderField header_fields[FIELD_LAST]; /**< Track the location
92 * of each field in "header"
95 dbus_uint32_t client_serial; /**< Cached client serial value for speed */
96 dbus_uint32_t reply_serial; /**< Cached reply serial value for speed */
98 int header_padding; /**< bytes of alignment in header */
100 DBusString body; /**< Body network data. */
102 char byte_order; /**< Message byte order. */
104 DBusList *size_counters; /**< 0-N DBusCounter used to track message size. */
105 long size_counter_delta; /**< Size we incremented the size counters by. */
107 dbus_uint32_t changed_stamp; /**< Incremented when iterators are invalidated. */
109 unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
113 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
114 DBUS_MESSAGE_ITER_TYPE_ARRAY,
115 DBUS_MESSAGE_ITER_TYPE_DICT
118 /** typedef for internals of message iterator */
119 typedef struct DBusMessageRealIter DBusMessageRealIter;
122 * @brief Internals of DBusMessageIter
124 * Object representing a position in a message. All fields are internal.
126 struct DBusMessageRealIter
128 DBusMessageRealIter *parent_iter; /**< parent iter, or NULL */
129 DBusMessage *message; /**< Message used */
130 dbus_uint32_t changed_stamp; /**< stamp to detect invalid iters */
132 /* This is an int instead of an enum to get a guaranteed size for the dummy: */
133 int type; /**< type of iter */
135 int pos; /**< Current position in the string */
136 int end; /**< position right after the container */
137 int container_start; /**< offset of the start of the container */
138 int container_length_pos; /**< offset of the length of the container */
140 int wrote_dict_key; /**< whether we wrote the dict key for the current dict element */
142 int array_type_pos; /**< pointer to the position of the array element type */
143 int array_type_done; /**< TRUE if the array type is fully finished */
147 * Gets the data to be sent over the network for this message.
148 * The header and then the body should be written out.
149 * This function is guaranteed to always return the same
150 * data once a message is locked (with _dbus_message_lock()).
152 * @param message the message.
153 * @param header return location for message header data.
154 * @param body return location for message body data.
157 _dbus_message_get_network_data (DBusMessage *message,
158 const DBusString **header,
159 const DBusString **body)
161 _dbus_assert (message->locked);
163 *header = &message->header;
164 *body = &message->body;
168 clear_header_padding (DBusMessage *message)
170 _dbus_string_shorten (&message->header,
171 message->header_padding);
172 message->header_padding = 0;
176 append_header_padding (DBusMessage *message)
179 old_len = _dbus_string_get_length (&message->header);
180 if (!_dbus_string_align_length (&message->header, 8))
183 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
189 adjust_field_offsets (DBusMessage *message,
199 while (i < FIELD_LAST)
201 if (message->header_fields[i].offset > offsets_after)
202 message->header_fields[i].offset += delta;
208 #ifdef DBUS_BUILD_TESTS
209 /* tests-only until it's actually used */
211 get_int_field (DBusMessage *message,
216 _dbus_assert (field < FIELD_LAST);
218 offset = message->header_fields[field].offset;
221 return -1; /* useless if -1 is a valid value of course */
223 return _dbus_demarshal_int32 (&message->header,
231 get_uint_field (DBusMessage *message,
236 _dbus_assert (field < FIELD_LAST);
238 offset = message->header_fields[field].offset;
241 return -1; /* useless if -1 is a valid value of course */
243 return _dbus_demarshal_uint32 (&message->header,
250 get_string_field (DBusMessage *message,
257 offset = message->header_fields[field].offset;
259 _dbus_assert (field < FIELD_LAST);
264 /* offset points to string length, string data follows it */
265 /* FIXME _dbus_demarshal_const_string() that returned
266 * a reference to the string plus its len might be nice.
270 *len = _dbus_demarshal_uint32 (&message->header,
275 data = _dbus_string_get_const_data (&message->header);
277 return data + (offset + 4);
280 #ifdef DBUS_BUILD_TESTS
282 append_int_field (DBusMessage *message,
289 _dbus_assert (!message->locked);
291 clear_header_padding (message);
293 orig_len = _dbus_string_get_length (&message->header);
295 if (!_dbus_string_align_length (&message->header, 4))
298 if (!_dbus_string_append_len (&message->header, name, 4))
301 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
304 if (!_dbus_string_align_length (&message->header, 4))
307 message->header_fields[FIELD_REPLY_SERIAL].offset =
308 _dbus_string_get_length (&message->header);
310 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
314 if (!append_header_padding (message))
320 message->header_fields[field].offset = -1;
321 _dbus_string_set_length (&message->header, orig_len);
323 /* this must succeed because it was allocated on function entry and
324 * DBusString doesn't ever realloc smaller
326 if (!append_header_padding (message))
327 _dbus_assert_not_reached ("failed to reappend header padding");
333 append_uint_field (DBusMessage *message,
340 _dbus_assert (!message->locked);
342 clear_header_padding (message);
344 orig_len = _dbus_string_get_length (&message->header);
346 if (!_dbus_string_align_length (&message->header, 4))
349 if (!_dbus_string_append_len (&message->header, name, 4))
352 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
355 if (!_dbus_string_align_length (&message->header, 4))
358 message->header_fields[FIELD_REPLY_SERIAL].offset =
359 _dbus_string_get_length (&message->header);
361 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
365 if (!append_header_padding (message))
371 message->header_fields[field].offset = -1;
372 _dbus_string_set_length (&message->header, orig_len);
374 /* this must succeed because it was allocated on function entry and
375 * DBusString doesn't ever realloc smaller
377 if (!append_header_padding (message))
378 _dbus_assert_not_reached ("failed to reappend header padding");
383 append_string_field (DBusMessage *message,
390 _dbus_assert (!message->locked);
392 clear_header_padding (message);
394 orig_len = _dbus_string_get_length (&message->header);
396 if (!_dbus_string_align_length (&message->header, 4))
399 if (!_dbus_string_append_len (&message->header, name, 4))
402 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING))
405 if (!_dbus_string_align_length (&message->header, 4))
408 message->header_fields[field].offset =
409 _dbus_string_get_length (&message->header);
411 if (!_dbus_marshal_string (&message->header, message->byte_order,
415 if (!append_header_padding (message))
421 message->header_fields[field].offset = -1;
422 _dbus_string_set_length (&message->header, orig_len);
424 /* this must succeed because it was allocated on function entry and
425 * DBusString doesn't ever realloc smaller
427 if (!append_header_padding (message))
428 _dbus_assert_not_reached ("failed to reappend header padding");
433 #ifdef DBUS_BUILD_TESTS
434 /* This isn't used, but building it when tests are enabled just to
435 * keep it compiling if we need it in future
438 delete_int_or_uint_field (DBusMessage *message,
441 int offset = message->header_fields[field].offset;
443 _dbus_assert (!message->locked);
444 _dbus_assert (field_is_named[field]);
449 clear_header_padding (message);
451 /* The field typecode and name take up 8 bytes */
452 _dbus_string_delete (&message->header,
456 message->header_fields[field].offset = -1;
458 adjust_field_offsets (message,
462 append_header_padding (message);
467 delete_string_field (DBusMessage *message,
470 int offset = message->header_fields[field].offset;
474 _dbus_assert (!message->locked);
475 _dbus_assert (field_is_named[field]);
480 clear_header_padding (message);
482 get_string_field (message, field, &len);
484 /* The field typecode and name take up 8 bytes, and the nul
485 * termination is 1 bytes, string length integer is 4 bytes
487 delete_len = 8 + 4 + 1 + len;
489 _dbus_string_delete (&message->header,
493 message->header_fields[field].offset = -1;
495 adjust_field_offsets (message,
499 append_header_padding (message);
502 #ifdef DBUS_BUILD_TESTS
504 set_int_field (DBusMessage *message,
508 int offset = message->header_fields[field].offset;
510 _dbus_assert (!message->locked);
514 /* need to append the field */
519 _dbus_assert_not_reached ("appending an int field we don't support appending");
525 _dbus_marshal_set_int32 (&message->header,
535 set_uint_field (DBusMessage *message,
539 int offset = message->header_fields[field].offset;
541 _dbus_assert (!message->locked);
545 /* need to append the field */
549 case FIELD_REPLY_SERIAL:
550 return append_uint_field (message, field,
551 DBUS_HEADER_FIELD_REPLY,
554 _dbus_assert_not_reached ("appending a uint field we don't support appending");
560 _dbus_marshal_set_uint32 (&message->header,
569 set_string_field (DBusMessage *message,
573 int offset = message->header_fields[field].offset;
575 _dbus_assert (!message->locked);
576 _dbus_assert (value != NULL);
580 /* need to append the field */
585 return append_string_field (message, field,
586 DBUS_HEADER_FIELD_SENDER,
589 _dbus_assert_not_reached ("appending a string field we don't support appending");
600 clear_header_padding (message);
602 old_len = _dbus_string_get_length (&message->header);
604 len = strlen (value);
606 _dbus_string_init_const_len (&v, value,
607 len + 1); /* include nul */
608 if (!_dbus_marshal_set_string (&message->header,
614 new_len = _dbus_string_get_length (&message->header);
616 adjust_field_offsets (message,
620 if (!append_header_padding (message))
626 /* this must succeed because it was allocated on function entry and
627 * DBusString doesn't ever realloc smaller
629 if (!append_header_padding (message))
630 _dbus_assert_not_reached ("failed to reappend header padding");
637 * Sets the serial number of a message.
638 * This can only be done once on a message.
640 * @param message the message
641 * @param serial the serial
644 _dbus_message_set_serial (DBusMessage *message,
647 _dbus_assert (!message->locked);
648 _dbus_assert (dbus_message_get_serial (message) == 0);
650 set_uint_field (message, FIELD_CLIENT_SERIAL,
652 message->client_serial = serial;
656 * Sets the reply serial of a message (the client serial
657 * of the message this is a reply to).
659 * @param message the message
660 * @param reply_serial the client serial
661 * @returns #FALSE if not enough memory
664 dbus_message_set_reply_serial (DBusMessage *message,
665 dbus_uint32_t reply_serial)
667 _dbus_assert (!message->locked);
669 if (set_uint_field (message, FIELD_REPLY_SERIAL,
672 message->reply_serial = reply_serial;
680 * Returns the serial of a message or -1 if none has been specified.
681 * The message's serial number is provided by the application sending
682 * the message and is used to identify replies to this message.
684 * @param message the message
685 * @returns the client serial
688 dbus_message_get_serial (DBusMessage *message)
690 return message->client_serial;
694 * Returns the serial that the message is
695 * a reply to or 0 if none.
697 * @param message the message
698 * @returns the reply serial
701 dbus_message_get_reply_serial (DBusMessage *message)
703 return message->reply_serial;
707 * Adds a counter to be incremented immediately with the
708 * size of this message, and decremented by the size
709 * of this message when this message if finalized.
710 * The link contains a counter with its refcount already
711 * incremented, but the counter itself not incremented.
712 * Ownership of link and counter refcount is passed to
715 * @param message the message
716 * @param link link with counter as data
719 _dbus_message_add_size_counter_link (DBusMessage *message,
722 /* right now we don't recompute the delta when message
723 * size changes, and that's OK for current purposes
724 * I think, but could be important to change later.
725 * Do recompute it whenever there are no outstanding counters,
726 * since it's basically free.
728 if (message->size_counters == NULL)
730 message->size_counter_delta =
731 _dbus_string_get_length (&message->header) +
732 _dbus_string_get_length (&message->body);
735 _dbus_verbose ("message has size %ld\n",
736 message->size_counter_delta);
740 _dbus_list_append_link (&message->size_counters, link);
742 _dbus_counter_adjust (link->data, message->size_counter_delta);
746 * Adds a counter to be incremented immediately with the
747 * size of this message, and decremented by the size
748 * of this message when this message if finalized.
750 * @param message the message
751 * @param counter the counter
752 * @returns #FALSE if no memory
755 _dbus_message_add_size_counter (DBusMessage *message,
756 DBusCounter *counter)
760 link = _dbus_list_alloc_link (counter);
764 _dbus_counter_ref (counter);
765 _dbus_message_add_size_counter_link (message, link);
771 * Removes a counter tracking the size of this message, and decrements
772 * the counter by the size of this message.
774 * @param message the message
775 * @param link_return return the link used
776 * @param counter the counter
779 _dbus_message_remove_size_counter (DBusMessage *message,
780 DBusCounter *counter,
781 DBusList **link_return)
785 link = _dbus_list_find_last (&message->size_counters,
787 _dbus_assert (link != NULL);
789 _dbus_list_unlink (&message->size_counters,
794 _dbus_list_free_link (link);
796 _dbus_counter_adjust (counter, message->size_counter_delta);
798 _dbus_counter_unref (counter);
802 dbus_message_create_header (DBusMessage *message,
808 if (!_dbus_string_append_byte (&message->header, message->byte_order))
812 if (!_dbus_string_append_byte (&message->header, flags))
815 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
818 if (!_dbus_string_append_byte (&message->header, 0))
821 message->header_fields[FIELD_HEADER_LENGTH].offset = 4;
822 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
825 message->header_fields[FIELD_BODY_LENGTH].offset = 8;
826 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
829 message->header_fields[FIELD_CLIENT_SERIAL].offset = 12;
830 if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
833 /* Marshal message service */
836 if (!append_string_field (message,
838 DBUS_HEADER_FIELD_SERVICE,
843 _dbus_assert (name != NULL);
844 if (!append_string_field (message,
846 DBUS_HEADER_FIELD_NAME,
854 * Locks a message. Allows checking that applications don't keep a
855 * reference to a message in the outgoing queue and change it
856 * underneath us. Messages are locked when they enter the outgoing
857 * queue (dbus_connection_send_message()), and the library complains
858 * if the message is modified while locked.
860 * @param message the message to lock.
863 _dbus_message_lock (DBusMessage *message)
865 if (!message->locked)
867 /* Fill in our lengths */
868 set_uint_field (message,
870 _dbus_string_get_length (&message->header));
872 set_uint_field (message,
874 _dbus_string_get_length (&message->body));
876 message->locked = TRUE;
883 * @defgroup DBusMessage DBusMessage
885 * @brief Message to be sent or received over a DBusConnection.
887 * A DBusMessage is the most basic unit of communication over a
888 * DBusConnection. A DBusConnection represents a stream of messages
889 * received from a remote application, and a stream of messages
890 * sent to a remote application.
896 * @typedef DBusMessage
898 * Opaque data type representing a message received from or to be
899 * sent to another application.
903 dbus_message_new_empty_header (void)
905 DBusMessage *message;
908 message = dbus_new0 (DBusMessage, 1);
912 message->refcount.value = 1;
913 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
914 message->client_serial = 0;
915 message->reply_serial = 0;
918 while (i < FIELD_LAST)
920 message->header_fields[i].offset = -1;
924 if (!_dbus_string_init_preallocated (&message->header, 64))
930 if (!_dbus_string_init_preallocated (&message->body, 64))
932 _dbus_string_free (&message->header);
942 * Constructs a new message. Returns #NULL if memory can't be
943 * allocated for the message. The service may be #NULL in which case
944 * no service is set; this is appropriate when using D-BUS in a
945 * peer-to-peer context (no message bus).
947 * @todo reverse the arguments, first 'name' then 'service'
948 * as 'name' is more fundamental
950 * @param name name of the message
951 * @param destination_service service that the message should be sent to or #NULL
952 * @returns a new DBusMessage, free with dbus_message_unref()
953 * @see dbus_message_unref()
956 dbus_message_new (const char *name,
957 const char *destination_service)
959 DBusMessage *message;
961 _dbus_return_val_if_fail (name != NULL, NULL);
963 message = dbus_message_new_empty_header ();
967 if (!dbus_message_create_header (message, name, destination_service))
969 dbus_message_unref (message);
977 * Constructs a message that is a reply to some other
978 * message. Returns #NULL if memory can't be allocated
981 * @param original_message the message which the created
982 * message is a reply to.
983 * @returns a new DBusMessage, free with dbus_message_unref()
984 * @see dbus_message_new(), dbus_message_unref()
987 dbus_message_new_reply (DBusMessage *original_message)
989 DBusMessage *message;
990 const char *sender, *name;
992 _dbus_return_val_if_fail (original_message != NULL, NULL);
994 sender = get_string_field (original_message,
996 name = get_string_field (original_message,
999 /* sender is allowed to be null here in peer-to-peer case */
1001 message = dbus_message_new (name, sender);
1003 if (message == NULL)
1006 if (!dbus_message_set_reply_serial (message,
1007 dbus_message_get_serial (original_message)))
1009 dbus_message_unref (message);
1017 * Creates a new message that is an error reply to a certain message.
1019 * @param original_message the original message
1020 * @param error_name the error name
1021 * @param error_message the error message string or #NULL for none
1022 * @returns a new error message
1025 dbus_message_new_error_reply (DBusMessage *original_message,
1026 const char *error_name,
1027 const char *error_message)
1029 DBusMessage *message;
1031 DBusMessageIter iter;
1033 _dbus_return_val_if_fail (original_message != NULL, NULL);
1034 _dbus_return_val_if_fail (error_name != NULL, NULL);
1036 sender = get_string_field (original_message,
1037 FIELD_SENDER, NULL);
1039 /* sender may be NULL for non-message-bus case or
1040 * when the message bus is dealing with an unregistered
1044 message = dbus_message_new (error_name, sender);
1046 if (message == NULL)
1049 if (!dbus_message_set_reply_serial (message,
1050 dbus_message_get_serial (original_message)))
1052 dbus_message_unref (message);
1056 if (error_message != NULL)
1058 dbus_message_append_iter_init (message, &iter);
1059 if (!dbus_message_iter_append_string (&iter, error_message))
1061 dbus_message_unref (message);
1066 dbus_message_set_is_error (message, TRUE);
1072 * Creates a new message that is an exact replica of the message
1073 * specified, except that its refcount is set to 1.
1075 * @param message the message.
1076 * @returns the new message.
1079 dbus_message_copy (const DBusMessage *message)
1081 DBusMessage *retval;
1084 _dbus_return_val_if_fail (message != NULL, NULL);
1086 retval = dbus_new0 (DBusMessage, 1);
1090 retval->refcount.value = 1;
1091 retval->byte_order = message->byte_order;
1092 retval->client_serial = message->client_serial;
1093 retval->reply_serial = message->reply_serial;
1094 retval->header_padding = message->header_padding;
1095 retval->locked = FALSE;
1097 if (!_dbus_string_init (&retval->header))
1103 if (!_dbus_string_init (&retval->body))
1105 _dbus_string_free (&retval->header);
1110 if (!_dbus_string_copy (&message->header, 0,
1111 &retval->header, 0))
1113 _dbus_string_free (&retval->header);
1114 _dbus_string_free (&retval->body);
1120 if (!_dbus_string_copy (&message->body, 0,
1123 _dbus_string_free (&retval->header);
1124 _dbus_string_free (&retval->body);
1130 for (i = 0; i < FIELD_LAST; i++)
1132 retval->header_fields[i].offset = message->header_fields[i].offset;
1140 * Increments the reference count of a DBusMessage.
1142 * @param message The message
1143 * @see dbus_message_unref
1146 dbus_message_ref (DBusMessage *message)
1148 dbus_int32_t old_refcount;
1150 _dbus_return_if_fail (message != NULL);
1152 old_refcount = _dbus_atomic_inc (&message->refcount);
1153 _dbus_assert (old_refcount >= 1);
1157 free_size_counter (void *element,
1160 DBusCounter *counter = element;
1161 DBusMessage *message = data;
1163 _dbus_counter_adjust (counter, - message->size_counter_delta);
1165 _dbus_counter_unref (counter);
1169 * Decrements the reference count of a DBusMessage.
1171 * @param message The message
1172 * @see dbus_message_ref
1175 dbus_message_unref (DBusMessage *message)
1177 dbus_int32_t old_refcount;
1179 _dbus_return_if_fail (message != NULL);
1181 old_refcount = _dbus_atomic_dec (&message->refcount);
1183 _dbus_assert (old_refcount >= 0);
1185 if (old_refcount == 1)
1187 _dbus_list_foreach (&message->size_counters,
1188 free_size_counter, message);
1189 _dbus_list_clear (&message->size_counters);
1191 _dbus_string_free (&message->header);
1192 _dbus_string_free (&message->body);
1194 dbus_free (message);
1199 * Gets the name of a message.
1201 * @param message the message
1202 * @returns the message name (should not be freed)
1205 dbus_message_get_name (DBusMessage *message)
1207 _dbus_return_val_if_fail (message != NULL, NULL);
1209 return get_string_field (message, FIELD_NAME, NULL);
1213 * Gets the destination service of a message.
1215 * @param message the message
1216 * @returns the message destination service (should not be freed)
1219 dbus_message_get_destination (DBusMessage *message)
1221 _dbus_return_val_if_fail (message != NULL, NULL);
1223 return get_string_field (message, FIELD_SERVICE, NULL);
1227 * Appends fields to a message given a variable argument list. The
1228 * variable argument list should contain the type of the argument
1229 * followed by the value to add. Array values are specified by an int
1230 * typecode followed by a pointer to the array followed by an int
1231 * giving the length of the array. The argument list must be
1232 * terminated with #DBUS_TYPE_INVALID.
1234 * This function doesn't support dicts or non-fundamental arrays.
1236 * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64
1237 * only if #DBUS_HAVE_INT64 is defined.
1239 * @param message the message
1240 * @param first_arg_type type of the first argument
1241 * @param ... value of first argument, list of additional type-value pairs
1242 * @returns #TRUE on success
1245 dbus_message_append_args (DBusMessage *message,
1252 _dbus_return_val_if_fail (message != NULL, FALSE);
1254 va_start (var_args, first_arg_type);
1255 retval = dbus_message_append_args_valist (message,
1264 * This function takes a va_list for use by language bindings.
1265 * It's otherwise the same as dbus_message_append_args().
1267 * @todo: Shouldn't this function clean up the changes to the message
1268 * on failures? (Yes)
1270 * @see dbus_message_append_args.
1271 * @param message the message
1272 * @param first_arg_type type of first argument
1273 * @param var_args value of first argument, then list of type/value pairs
1274 * @returns #TRUE on success
1277 dbus_message_append_args_valist (DBusMessage *message,
1282 DBusMessageIter iter;
1284 _dbus_return_val_if_fail (message != NULL, FALSE);
1286 old_len = _dbus_string_get_length (&message->body);
1288 type = first_arg_type;
1290 dbus_message_append_iter_init (message, &iter);
1297 if (!dbus_message_iter_append_nil (&iter))
1300 case DBUS_TYPE_BOOLEAN:
1301 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
1304 case DBUS_TYPE_INT32:
1305 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
1308 case DBUS_TYPE_UINT32:
1309 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
1312 #ifdef DBUS_HAVE_INT64
1313 case DBUS_TYPE_INT64:
1314 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
1317 case DBUS_TYPE_UINT64:
1318 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
1321 #endif /* DBUS_HAVE_INT64 */
1322 case DBUS_TYPE_DOUBLE:
1323 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
1326 case DBUS_TYPE_STRING:
1327 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
1330 case DBUS_TYPE_NAMED:
1333 unsigned char *data;
1336 name = va_arg (var_args, const char *);
1337 data = va_arg (var_args, unsigned char *);
1338 len = va_arg (var_args, int);
1340 if (!dbus_message_iter_append_named (&iter, name, data, len))
1344 case DBUS_TYPE_ARRAY:
1349 type = va_arg (var_args, int);
1350 data = va_arg (var_args, void *);
1351 len = va_arg (var_args, int);
1355 case DBUS_TYPE_BYTE:
1356 if (!dbus_message_iter_append_byte_array (&iter, (unsigned char *)data, len))
1359 case DBUS_TYPE_BOOLEAN:
1360 if (!dbus_message_iter_append_boolean_array (&iter, (unsigned char *)data, len))
1363 case DBUS_TYPE_INT32:
1364 if (!dbus_message_iter_append_int32_array (&iter, (dbus_int32_t *)data, len))
1367 case DBUS_TYPE_UINT32:
1368 if (!dbus_message_iter_append_uint32_array (&iter, (dbus_uint32_t *)data, len))
1371 #ifdef DBUS_HAVE_INT64
1372 case DBUS_TYPE_INT64:
1373 if (!dbus_message_iter_append_int64_array (&iter, (dbus_int64_t *)data, len))
1376 case DBUS_TYPE_UINT64:
1377 if (!dbus_message_iter_append_uint64_array (&iter, (dbus_uint64_t *)data, len))
1380 #endif /* DBUS_HAVE_INT64 */
1381 case DBUS_TYPE_DOUBLE:
1382 if (!dbus_message_iter_append_double_array (&iter, (double *)data, len))
1385 case DBUS_TYPE_STRING:
1386 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
1390 case DBUS_TYPE_ARRAY:
1391 case DBUS_TYPE_NAMED:
1392 case DBUS_TYPE_DICT:
1393 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
1396 _dbus_warn ("Unknown field type %d\n", type);
1402 case DBUS_TYPE_DICT:
1403 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
1406 _dbus_warn ("Unknown field type %d\n", type);
1410 type = va_arg (var_args, int);
1421 * Gets arguments from a message given a variable argument list.
1422 * The variable argument list should contain the type of the
1423 * argumen followed by a pointer to where the value should be
1424 * stored. The list is terminated with #DBUS_TYPE_INVALID.
1426 * @param message the message
1427 * @param error error to be filled in on failure
1428 * @param first_arg_type the first argument type
1429 * @param ... location for first argument value, then list of type-location pairs
1430 * @returns #FALSE if the error was set
1433 dbus_message_get_args (DBusMessage *message,
1441 _dbus_return_val_if_fail (message != NULL, FALSE);
1442 _dbus_return_val_if_error_is_set (error, FALSE);
1444 va_start (var_args, first_arg_type);
1445 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1452 * This function takes a va_list for use by language bindings
1454 * @todo We need to free the argument data when an error occurs.
1456 * @see dbus_message_get_args
1457 * @param message the message
1458 * @param error error to be filled in
1459 * @param first_arg_type type of the first argument
1460 * @param var_args return location for first argument, followed by list of type/location pairs
1461 * @returns #FALSE if error was set
1464 dbus_message_get_args_valist (DBusMessage *message,
1469 DBusMessageIter iter;
1471 _dbus_return_val_if_fail (message != NULL, FALSE);
1472 _dbus_return_val_if_error_is_set (error, FALSE);
1474 dbus_message_iter_init (message, &iter);
1475 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1479 * Gets arguments from a message iterator given a variable argument list.
1480 * The variable argument list should contain the type of the
1481 * argumen followed by a pointer to where the value should be
1482 * stored. The list is terminated with 0.
1484 * @param iter the message iterator
1485 * @param error error to be filled in on failure
1486 * @param first_arg_type the first argument type
1487 * @param ... location for first argument value, then list of type-location pairs
1488 * @returns #FALSE if the error was set
1491 dbus_message_iter_get_args (DBusMessageIter *iter,
1499 _dbus_return_val_if_fail (iter != NULL, FALSE);
1500 _dbus_return_val_if_error_is_set (error, FALSE);
1502 va_start (var_args, first_arg_type);
1503 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
1510 * This function takes a va_list for use by language bindings
1512 * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64
1513 * only if #DBUS_HAVE_INT64 is defined.
1515 * @todo this function (or some lower-level non-convenience function)
1516 * needs better error handling; should allow the application to
1517 * distinguish between out of memory, and bad data from the remote
1518 * app. It also needs to not leak a bunch of args when it gets
1519 * to the arg that's bad, as that would be a security hole
1520 * (allow one app to force another to leak memory)
1522 * @todo We need to free the argument data when an error occurs.
1524 * @see dbus_message_get_args
1525 * @param iter the message iter
1526 * @param error error to be filled in
1527 * @param first_arg_type type of the first argument
1528 * @param var_args return location for first argument, followed by list of type/location pairs
1529 * @returns #FALSE if error was set
1532 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
1537 int spec_type, msg_type, i;
1540 _dbus_return_val_if_fail (iter != NULL, FALSE);
1541 _dbus_return_val_if_error_is_set (error, FALSE);
1545 spec_type = first_arg_type;
1548 while (spec_type != 0)
1550 msg_type = dbus_message_iter_get_arg_type (iter);
1552 if (msg_type != spec_type)
1554 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1555 "Argument %d is specified to be of type \"%s\", but "
1556 "is actually of type \"%s\"\n", i,
1557 _dbus_type_to_string (spec_type),
1558 _dbus_type_to_string (msg_type));
1567 case DBUS_TYPE_BYTE:
1571 ptr = va_arg (var_args, unsigned char *);
1573 *ptr = dbus_message_iter_get_byte (iter);
1576 case DBUS_TYPE_BOOLEAN:
1580 ptr = va_arg (var_args, dbus_bool_t *);
1582 *ptr = dbus_message_iter_get_boolean (iter);
1585 case DBUS_TYPE_INT32:
1589 ptr = va_arg (var_args, dbus_int32_t *);
1591 *ptr = dbus_message_iter_get_int32 (iter);
1594 case DBUS_TYPE_UINT32:
1598 ptr = va_arg (var_args, dbus_uint32_t *);
1600 *ptr = dbus_message_iter_get_uint32 (iter);
1603 #ifdef DBUS_HAVE_INT64
1604 case DBUS_TYPE_INT64:
1608 ptr = va_arg (var_args, dbus_int64_t *);
1610 *ptr = dbus_message_iter_get_int64 (iter);
1613 case DBUS_TYPE_UINT64:
1617 ptr = va_arg (var_args, dbus_uint64_t *);
1619 *ptr = dbus_message_iter_get_uint64 (iter);
1622 #endif /* DBUS_HAVE_INT64 */
1624 case DBUS_TYPE_DOUBLE:
1628 ptr = va_arg (var_args, double *);
1630 *ptr = dbus_message_iter_get_double (iter);
1634 case DBUS_TYPE_STRING:
1638 ptr = va_arg (var_args, char **);
1640 *ptr = dbus_message_iter_get_string (iter);
1644 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1651 case DBUS_TYPE_NAMED:
1654 unsigned char **data;
1657 name = va_arg (var_args, char **);
1658 data = va_arg (var_args, unsigned char **);
1659 len = va_arg (var_args, int *);
1661 if (!dbus_message_iter_get_named (iter, name, data, len))
1663 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1668 case DBUS_TYPE_ARRAY:
1673 type = va_arg (var_args, int);
1674 data = va_arg (var_args, void *);
1675 len = va_arg (var_args, int *);
1677 if (dbus_message_iter_get_array_type (iter) != type)
1679 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1680 "Argument %d is specified to be of type \"array of %s\", but "
1681 "is actually of type \"array of %s\"\n", i,
1682 _dbus_type_to_string (type),
1683 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
1689 case DBUS_TYPE_BYTE:
1690 if (!dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len))
1692 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1696 case DBUS_TYPE_BOOLEAN:
1697 if (!dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len))
1699 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1703 case DBUS_TYPE_INT32:
1704 if (!dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len))
1706 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1710 case DBUS_TYPE_UINT32:
1711 if (!dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len))
1713 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1717 #ifdef DBUS_HAVE_INT64
1718 case DBUS_TYPE_INT64:
1719 if (!dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len))
1721 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1725 case DBUS_TYPE_UINT64:
1726 if (!dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len))
1728 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1732 #endif /* DBUS_HAVE_INT64 */
1733 case DBUS_TYPE_DOUBLE:
1734 if (!dbus_message_iter_get_double_array (iter, (double **)data, len))
1736 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1740 case DBUS_TYPE_STRING:
1741 if (!dbus_message_iter_get_string_array (iter, (char ***)data, len))
1743 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1748 case DBUS_TYPE_ARRAY:
1749 case DBUS_TYPE_NAMED:
1750 case DBUS_TYPE_DICT:
1751 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
1752 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
1755 _dbus_warn ("Unknown field type %d\n", type);
1756 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
1761 case DBUS_TYPE_DICT:
1762 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
1763 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
1766 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
1767 _dbus_warn ("Unknown field type %d\n", spec_type);
1771 spec_type = va_arg (var_args, int);
1772 if (spec_type != 0 && !dbus_message_iter_next (iter))
1774 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1775 "Message has only %d arguments, but more were expected", i);
1791 * Initializes a DBusMessageIter representing the arguments of the
1792 * message passed in.
1794 * @param message the message
1795 * @param iter pointer to an iterator to initialize
1798 dbus_message_iter_init (DBusMessage *message,
1799 DBusMessageIter *iter)
1801 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1803 _dbus_return_if_fail (message != NULL);
1804 _dbus_return_if_fail (iter != NULL);
1806 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
1808 real->message = message;
1809 real->parent_iter = NULL;
1810 real->changed_stamp = message->changed_stamp;
1812 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
1814 real->end = _dbus_string_get_length (&message->body);
1816 real->container_start = 0;
1817 real->container_length_pos = 0;
1818 real->wrote_dict_key = 0;
1819 real->array_type_pos = 0;
1822 #ifndef DBUS_DISABLE_CHECKS
1824 dbus_message_iter_check (DBusMessageRealIter *iter)
1828 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
1832 if (iter->changed_stamp != iter->message->changed_stamp)
1834 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
1838 if (iter->pos < 0 || iter->pos > iter->end)
1840 _dbus_warn ("dbus iterator check failed: invalid position\n");
1846 #endif /* DBUS_DISABLE_CHECKS */
1849 skip_array_type (DBusMessageRealIter *iter, int pos)
1855 data = _dbus_string_get_const_data_len (&iter->message->body,
1858 while (*data == DBUS_TYPE_ARRAY);
1864 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
1871 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
1872 data = _dbus_string_get_const_data_len (&iter->message->body,
1874 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1877 *type = DBUS_TYPE_INVALID;
1879 return skip_array_type (iter, iter->pos);
1881 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
1882 data = _dbus_string_get_const_data_len (&iter->message->body,
1883 iter->array_type_pos, 1);
1884 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1887 *type = DBUS_TYPE_INVALID;
1891 case DBUS_MESSAGE_ITER_TYPE_DICT:
1892 /* Get the length of the string */
1893 len = _dbus_demarshal_uint32 (&iter->message->body,
1894 iter->message->byte_order,
1896 pos = pos + len + 1;
1898 data = _dbus_string_get_const_data_len (&iter->message->body,
1900 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1903 *type = DBUS_TYPE_INVALID;
1905 return skip_array_type (iter, pos);
1908 _dbus_assert_not_reached ("Invalid iter type");
1911 *type = DBUS_TYPE_INVALID;
1917 * Checks if an iterator has any more fields.
1919 * @param iter the message iter
1920 * @returns #TRUE if there are more fields
1924 dbus_message_iter_has_next (DBusMessageIter *iter)
1926 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1930 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
1932 if (real->pos >= real->end)
1935 pos = dbus_message_iter_get_data_start (real, &type);
1937 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
1938 real->message->byte_order,
1939 type, pos, &end_pos))
1942 if (end_pos >= real->end)
1949 * Moves the iterator to the next field.
1951 * @param iter The message iter
1952 * @returns #TRUE if the iterator was moved to the next field
1955 dbus_message_iter_next (DBusMessageIter *iter)
1957 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1961 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
1963 pos = dbus_message_iter_get_data_start (real, &type);
1965 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
1966 real->message->byte_order,
1967 type, pos, &end_pos))
1970 if (end_pos >= real->end)
1973 real->pos = end_pos;
1979 * Returns the argument type of the argument that the
1980 * message iterator points at.
1982 * @param iter the message iter
1983 * @returns the field type
1986 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
1988 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
1991 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
1993 if (real->pos >= real->end)
1994 return DBUS_TYPE_INVALID;
1996 pos = dbus_message_iter_get_data_start (real, &type);
2002 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
2005 int _array_type_pos;
2010 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
2011 _array_type_pos = iter->pos + 1;
2013 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
2014 _array_type_pos = iter->array_type_pos + 1;
2016 case DBUS_MESSAGE_ITER_TYPE_DICT:
2017 /* Get the length of the string */
2018 len = _dbus_demarshal_uint32 (&iter->message->body,
2019 iter->message->byte_order,
2021 pos = pos + len + 1;
2022 data = _dbus_string_get_const_data_len (&iter->message->body,
2024 _array_type_pos = pos + 1;
2027 _dbus_assert_not_reached ("wrong iter type");
2028 return DBUS_TYPE_INVALID;
2031 if (array_type_pos != NULL)
2032 *array_type_pos = _array_type_pos;
2034 data = _dbus_string_get_const_data_len (&iter->message->body,
2035 _array_type_pos, 1);
2036 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
2039 return DBUS_TYPE_INVALID;
2044 * Returns the element type of the array that the
2045 * message iterator points at. Note that you need
2046 * to check that the iterator points to an array
2047 * prior to using this function.
2049 * @param iter the message iter
2050 * @returns the field type
2053 dbus_message_iter_get_array_type (DBusMessageIter *iter)
2055 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2058 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2060 if (real->pos >= real->end)
2061 return DBUS_TYPE_INVALID;
2063 pos = dbus_message_iter_get_data_start (real, &type);
2065 _dbus_assert (type == DBUS_TYPE_ARRAY);
2067 return iter_get_array_type (real, NULL);
2072 * Returns the string value that an iterator may point to.
2073 * Note that you need to check that the iterator points to
2074 * a string value before using this function.
2076 * @see dbus_message_iter_get_arg_type
2077 * @param iter the message iter
2078 * @returns the string
2081 dbus_message_iter_get_string (DBusMessageIter *iter)
2083 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2086 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
2088 pos = dbus_message_iter_get_data_start (real, &type);
2090 _dbus_assert (type == DBUS_TYPE_STRING);
2092 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
2097 * Returns the name and data from a named type that an
2098 * iterator may point to. Note that you need to check that
2099 * the iterator points to a named type before using this
2102 * @see dbus_message_iter_get_arg_type
2103 * @param iter the message iter
2104 * @param name return location for the name
2105 * @param value return location for data
2106 * @param len return location for length of data
2107 * @returns TRUE if get succeed
2111 dbus_message_iter_get_named (DBusMessageIter *iter,
2113 unsigned char **value,
2116 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2120 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2122 pos = dbus_message_iter_get_data_start (real, &type);
2124 _dbus_assert (type == DBUS_TYPE_NAMED);
2126 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
2132 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
2133 pos + 1, NULL, value, len))
2145 * Returns the byte value that an iterator may point to.
2146 * Note that you need to check that the iterator points to
2147 * a byte value before using this function.
2149 * @see dbus_message_iter_get_arg_type
2150 * @param iter the message iter
2151 * @returns the byte value
2154 dbus_message_iter_get_byte (DBusMessageIter *iter)
2156 unsigned char value;
2157 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2160 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2162 pos = dbus_message_iter_get_data_start (real, &type);
2164 _dbus_assert (type == DBUS_TYPE_BYTE);
2166 value = _dbus_string_get_byte (&real->message->body, pos);
2173 * Returns the boolean value that an iterator may point to.
2174 * Note that you need to check that the iterator points to
2175 * a boolean value before using this function.
2177 * @see dbus_message_iter_get_arg_type
2178 * @param iter the message iter
2179 * @returns the boolean value
2182 dbus_message_iter_get_boolean (DBusMessageIter *iter)
2184 unsigned char value;
2185 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2188 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2190 pos = dbus_message_iter_get_data_start (real, &type);
2192 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
2194 value = _dbus_string_get_byte (&real->message->body, pos);
2200 * Returns the 32 bit signed integer value that an iterator may point to.
2201 * Note that you need to check that the iterator points to
2202 * a 32-bit integer value before using this function.
2204 * @see dbus_message_iter_get_arg_type
2205 * @param iter the message iter
2206 * @returns the integer
2209 dbus_message_iter_get_int32 (DBusMessageIter *iter)
2211 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2214 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2216 pos = dbus_message_iter_get_data_start (real, &type);
2218 _dbus_assert (type == DBUS_TYPE_INT32);
2220 return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order,
2225 * Returns the 32 bit unsigned integer value that an iterator may point to.
2226 * Note that you need to check that the iterator points to
2227 * a 32-bit unsigned integer value before using this function.
2229 * @see dbus_message_iter_get_arg_type
2230 * @param iter the message iter
2231 * @returns the integer
2234 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
2236 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2239 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2241 pos = dbus_message_iter_get_data_start (real, &type);
2243 _dbus_assert (type == DBUS_TYPE_UINT32);
2245 return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
2249 #ifdef DBUS_HAVE_INT64
2252 * Returns the 64 bit signed integer value that an iterator may point
2253 * to. Note that you need to check that the iterator points to a
2254 * 64-bit integer value before using this function.
2256 * This function only exists if #DBUS_HAVE_INT64 is defined.
2258 * @see dbus_message_iter_get_arg_type
2259 * @param iter the message iter
2260 * @returns the integer
2263 dbus_message_iter_get_int64 (DBusMessageIter *iter)
2265 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2268 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2270 pos = dbus_message_iter_get_data_start (real, &type);
2272 _dbus_assert (type == DBUS_TYPE_INT64);
2274 return _dbus_demarshal_int64 (&real->message->body, real->message->byte_order,
2279 * Returns the 64 bit unsigned integer value that an iterator may point to.
2280 * Note that you need to check that the iterator points to
2281 * a 64-bit unsigned integer value before using this function.
2283 * This function only exists if #DBUS_HAVE_INT64 is defined.
2285 * @see dbus_message_iter_get_arg_type
2286 * @param iter the message iter
2287 * @returns the integer
2290 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
2292 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2295 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2297 pos = dbus_message_iter_get_data_start (real, &type);
2299 _dbus_assert (type == DBUS_TYPE_UINT64);
2301 return _dbus_demarshal_uint64 (&real->message->body, real->message->byte_order,
2305 #endif /* DBUS_HAVE_INT64 */
2308 * Returns the double value that an iterator may point to.
2309 * Note that you need to check that the iterator points to
2310 * a string value before using this function.
2312 * @see dbus_message_iter_get_arg_type
2313 * @param iter the message iter
2314 * @returns the double
2317 dbus_message_iter_get_double (DBusMessageIter *iter)
2319 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2322 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0.0);
2324 pos = dbus_message_iter_get_data_start (real, &type);
2326 _dbus_assert (type == DBUS_TYPE_DOUBLE);
2328 return _dbus_demarshal_double (&real->message->body, real->message->byte_order,
2333 * Initializes an iterator for the array that the iterator
2334 * may point to. Note that you need to check that the iterator
2335 * points to an array prior to using this function.
2337 * The array element type is returned in array_type, and the array
2338 * iterator can only be used to get that type of data.
2340 * @param iter the iterator
2341 * @param array_iter pointer to an iterator to initialize
2342 * @param array_type gets set to the type of the array elements
2343 * @returns #TRUE on success
2346 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
2347 DBusMessageIter *array_iter,
2350 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2351 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
2352 int type, pos, len_pos, len, array_type_pos;
2355 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2357 pos = dbus_message_iter_get_data_start (real, &type);
2359 _dbus_assert (type == DBUS_TYPE_ARRAY);
2361 _array_type = iter_get_array_type (real, &array_type_pos);
2363 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
2364 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
2367 array_real->parent_iter = real;
2368 array_real->message = real->message;
2369 array_real->changed_stamp = real->message->changed_stamp;
2371 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
2372 array_real->pos = pos;
2373 array_real->end = pos + len;
2375 array_real->container_start = pos;
2376 array_real->container_length_pos = len_pos;
2377 array_real->wrote_dict_key = 0;
2378 array_real->array_type_pos = array_type_pos;
2379 array_real->array_type_done = TRUE;
2381 if (array_type != NULL)
2382 *array_type = _array_type;
2389 * Initializes an iterator for the dict that the iterator
2390 * may point to. Note that you need to check that the iterator
2391 * points to a dict prior to using this function.
2393 * @param iter the iterator
2394 * @param dict_iter pointer to an iterator to initialize
2395 * @returns #TRUE on success
2398 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
2399 DBusMessageIter *dict_iter)
2401 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2402 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
2403 int type, pos, len_pos, len;
2405 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2407 pos = dbus_message_iter_get_data_start (real, &type);
2409 _dbus_assert (type == DBUS_TYPE_DICT);
2411 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
2412 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
2415 dict_real->parent_iter = real;
2416 dict_real->message = real->message;
2417 dict_real->changed_stamp = real->message->changed_stamp;
2419 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
2420 dict_real->pos = pos;
2421 dict_real->end = pos + len;
2423 dict_real->container_start = pos;
2424 dict_real->container_length_pos = len_pos;
2425 dict_real->wrote_dict_key = 0;
2431 * Returns the byte array that the iterator may point to.
2432 * Note that you need to check that the iterator points
2433 * to a byte array prior to using this function.
2435 * @param iter the iterator
2436 * @param value return location for array values
2437 * @param len return location for length of byte array
2438 * @returns #TRUE on success
2441 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
2442 unsigned char **value,
2445 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2448 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2450 pos = dbus_message_iter_get_data_start (real, &type);
2452 _dbus_assert (type == DBUS_TYPE_ARRAY);
2454 type = iter_get_array_type (real, NULL);
2456 _dbus_assert (type == DBUS_TYPE_BYTE);
2458 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
2459 pos, NULL, value, len))
2466 * Returns the boolean array that the iterator may point to. Note that
2467 * you need to check that the iterator points to an array of the
2468 * correct type prior to using this function.
2470 * @param iter the iterator
2471 * @param value return location for the array
2472 * @param len return location for the array length
2473 * @returns #TRUE on success
2476 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
2477 unsigned char **value,
2480 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2483 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2485 pos = dbus_message_iter_get_data_start (real, &type);
2487 _dbus_assert (type == DBUS_TYPE_ARRAY);
2489 type = iter_get_array_type (real, NULL);
2491 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
2493 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
2494 pos, NULL, value, len))
2501 * Returns the 32 bit signed integer array that the iterator may point
2502 * to. Note that you need to check that the iterator points to an
2503 * array of the correct type prior to using this function.
2505 * @param iter the iterator
2506 * @param value return location for the array
2507 * @param len return location for the array length
2508 * @returns #TRUE on success
2511 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
2512 dbus_int32_t **value,
2515 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2518 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2520 pos = dbus_message_iter_get_data_start (real, &type);
2522 _dbus_assert (type == DBUS_TYPE_ARRAY);
2524 type = iter_get_array_type (real, NULL);
2526 _dbus_assert (type == DBUS_TYPE_INT32);
2528 if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order,
2529 pos, NULL, value, len))
2536 * Returns the 32 bit unsigned integer array that the iterator may point
2537 * to. Note that you need to check that the iterator points to an
2538 * array of the correct type prior to using this function.
2540 * @param iter the iterator
2541 * @param value return location for the array
2542 * @param len return location for the array length
2543 * @returns #TRUE on success
2546 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
2547 dbus_uint32_t **value,
2550 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2553 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2555 pos = dbus_message_iter_get_data_start (real, &type);
2557 _dbus_assert (type == DBUS_TYPE_ARRAY);
2559 type = iter_get_array_type (real, NULL);
2560 _dbus_assert (type == DBUS_TYPE_UINT32);
2562 if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order,
2563 pos, NULL, value, len))
2569 #ifdef DBUS_HAVE_INT64
2572 * Returns the 64 bit signed integer array that the iterator may point
2573 * to. Note that you need to check that the iterator points to an
2574 * array of the correct type prior to using this function.
2576 * This function only exists if #DBUS_HAVE_INT64 is defined.
2578 * @param iter the iterator
2579 * @param value return location for the array
2580 * @param len return location for the array length
2581 * @returns #TRUE on success
2584 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
2585 dbus_int64_t **value,
2588 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2591 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2593 pos = dbus_message_iter_get_data_start (real, &type);
2595 _dbus_assert (type == DBUS_TYPE_ARRAY);
2597 type = iter_get_array_type (real, NULL);
2599 _dbus_assert (type == DBUS_TYPE_INT64);
2601 if (!_dbus_demarshal_int64_array (&real->message->body, real->message->byte_order,
2602 pos, NULL, value, len))
2609 * Returns the 64 bit unsigned integer array that the iterator may point
2610 * to. Note that you need to check that the iterator points to an
2611 * array of the correct type prior to using this function.
2613 * This function only exists if #DBUS_HAVE_INT64 is defined.
2615 * @param iter the iterator
2616 * @param value return location for the array
2617 * @param len return location for the array length
2618 * @returns #TRUE on success
2621 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
2622 dbus_uint64_t **value,
2625 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2628 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2630 pos = dbus_message_iter_get_data_start (real, &type);
2632 _dbus_assert (type == DBUS_TYPE_ARRAY);
2634 type = iter_get_array_type (real, NULL);
2635 _dbus_assert (type == DBUS_TYPE_UINT64);
2637 if (!_dbus_demarshal_uint64_array (&real->message->body, real->message->byte_order,
2638 pos, NULL, value, len))
2644 #endif /* DBUS_HAVE_INT64 */
2647 * Returns the double array that the iterator may point to. Note that
2648 * you need to check that the iterator points to an array of the
2649 * correct type prior to using this function.
2651 * @param iter the iterator
2652 * @param value return location for the array
2653 * @param len return location for the array length
2654 * @returns #TRUE on success
2657 dbus_message_iter_get_double_array (DBusMessageIter *iter,
2661 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2664 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2666 pos = dbus_message_iter_get_data_start (real, &type);
2668 _dbus_assert (type == DBUS_TYPE_ARRAY);
2670 type = iter_get_array_type (real, NULL);
2671 _dbus_assert (type == DBUS_TYPE_DOUBLE);
2673 if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order,
2674 pos, NULL, value, len))
2681 * Returns the string array that the iterator may point to.
2682 * Note that you need to check that the iterator points
2683 * to a byte array prior to using this function.
2685 * The returned value is a #NULL-terminated array of strings.
2686 * Each string is a separate malloc block, and the array
2687 * itself is a malloc block. You can free this type of
2688 * string array with dbus_free_string_array().
2690 * @param iter the iterator
2691 * @param value return location for string values
2692 * @param len return location for length of byte array
2693 * @returns #TRUE on success
2696 dbus_message_iter_get_string_array (DBusMessageIter *iter,
2700 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2703 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2705 pos = dbus_message_iter_get_data_start (real, &type);
2707 _dbus_assert (type == DBUS_TYPE_ARRAY);
2709 type = iter_get_array_type (real, NULL);
2710 _dbus_assert (type == DBUS_TYPE_STRING);
2712 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
2713 pos, NULL, value, len))
2720 * Returns the key name fot the dict entry that an iterator
2721 * may point to. Note that you need to check that the iterator
2722 * points to a dict entry before using this function.
2724 * @see dbus_message_iter_init_dict_iterator
2725 * @param iter the message iter
2726 * @returns the key name
2729 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
2731 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2733 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
2735 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
2737 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
2742 * Initializes a DBusMessageIter pointing to the end of the
2743 * message. This iterator can be used to append data to the
2746 * @param message the message
2747 * @param iter pointer to an iterator to initialize
2750 dbus_message_append_iter_init (DBusMessage *message,
2751 DBusMessageIter *iter)
2753 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2755 _dbus_return_if_fail (message != NULL);
2756 _dbus_return_if_fail (iter != NULL);
2758 real->message = message;
2759 real->parent_iter = NULL;
2760 real->changed_stamp = message->changed_stamp;
2762 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
2763 real->end = _dbus_string_get_length (&real->message->body);
2764 real->pos = real->end;
2766 real->container_length_pos = 0;
2767 real->wrote_dict_key = 0;
2770 #ifndef DBUS_DISABLE_CHECKS
2772 dbus_message_iter_append_check (DBusMessageRealIter *iter)
2776 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
2780 if (iter->message->locked)
2782 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
2786 if (iter->changed_stamp != iter->message->changed_stamp)
2788 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
2792 if (iter->pos != iter->end)
2794 _dbus_warn ("dbus iterator check failed: can only append at end of message");
2798 if (iter->pos != _dbus_string_get_length (&iter->message->body))
2800 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
2806 #endif /* DBUS_DISABLE_CHECKS */
2809 dbus_message_iter_append_type (DBusMessageRealIter *iter,
2815 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
2816 if (!_dbus_string_append_byte (&iter->message->body, type))
2820 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
2821 data = _dbus_string_get_const_data_len (&iter->message->body,
2822 iter->array_type_pos, 1);
2825 _dbus_warn ("Appended element of wrong type for array\n");
2830 case DBUS_MESSAGE_ITER_TYPE_DICT:
2831 if (!iter->wrote_dict_key)
2833 _dbus_warn ("Appending dict data before key name\n");
2837 if (!_dbus_string_append_byte (&iter->message->body, type))
2843 _dbus_assert_not_reached ("Invalid iter type");
2851 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
2853 iter->changed_stamp = iter->message->changed_stamp;
2855 /* Set new end of iter */
2856 iter->end = _dbus_string_get_length (&iter->message->body);
2857 iter->pos = iter->end;
2859 /* Set container length */
2860 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
2861 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
2862 _dbus_marshal_set_uint32 (&iter->message->body,
2863 iter->message->byte_order,
2864 iter->container_length_pos,
2865 iter->end - iter->container_start);
2867 if (iter->parent_iter)
2868 dbus_message_iter_update_after_change (iter->parent_iter);
2872 dbus_message_iter_append_done (DBusMessageRealIter *iter)
2874 iter->message->changed_stamp++;
2875 dbus_message_iter_update_after_change (iter);
2876 iter->wrote_dict_key = FALSE;
2880 * Appends a nil value to the message
2882 * @param iter an iterator pointing to the end of the message
2883 * @returns #TRUE on success
2886 dbus_message_iter_append_nil (DBusMessageIter *iter)
2888 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2890 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
2892 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
2895 dbus_message_iter_append_done (real);
2901 * Appends a boolean value to the message
2903 * @param iter an iterator pointing to the end of the message
2904 * @param value the boolean value
2905 * @returns #TRUE on success
2908 dbus_message_iter_append_boolean (DBusMessageIter *iter,
2911 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2913 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
2915 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN))
2918 if (!_dbus_string_append_byte (&real->message->body, (value != FALSE)))
2920 _dbus_string_set_length (&real->message->body, real->pos);
2924 dbus_message_iter_append_done (real);
2930 * Appends a byte to the message
2932 * @param iter an iterator pointing to the end of the message
2933 * @param value the byte value
2934 * @returns #TRUE on success
2937 dbus_message_iter_append_byte (DBusMessageIter *iter,
2938 unsigned char value)
2940 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2942 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
2944 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BYTE))
2947 if (!_dbus_string_append_byte (&real->message->body, value))
2949 _dbus_string_set_length (&real->message->body, real->pos);
2953 dbus_message_iter_append_done (real);
2960 * Appends a 32 bit signed integer to the message.
2962 * @param iter an iterator pointing to the end of the message
2963 * @param value the integer value
2964 * @returns #TRUE on success
2967 dbus_message_iter_append_int32 (DBusMessageIter *iter,
2970 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2972 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
2974 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT32))
2977 if (!_dbus_marshal_int32 (&real->message->body, real->message->byte_order, value))
2979 _dbus_string_set_length (&real->message->body, real->pos);
2983 dbus_message_iter_append_done (real);
2989 * Appends a 32 bit unsigned integer to the message.
2991 * @param iter an iterator pointing to the end of the message
2992 * @param value the integer value
2993 * @returns #TRUE on success
2996 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
2997 dbus_uint32_t value)
2999 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3001 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3003 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT32))
3006 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, value))
3008 _dbus_string_set_length (&real->message->body, real->pos);
3012 dbus_message_iter_append_done (real);
3017 #ifdef DBUS_HAVE_INT64
3020 * Appends a 64 bit signed integer to the message.
3022 * This function only exists if #DBUS_HAVE_INT64 is defined.
3024 * @param iter an iterator pointing to the end of the message
3025 * @param value the integer value
3026 * @returns #TRUE on success
3029 dbus_message_iter_append_int64 (DBusMessageIter *iter,
3032 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3034 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3036 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT64))
3039 if (!_dbus_marshal_int64 (&real->message->body, real->message->byte_order, value))
3041 _dbus_string_set_length (&real->message->body, real->pos);
3045 dbus_message_iter_append_done (real);
3051 * Appends a 64 bit unsigned integer to the message.
3053 * This function only exists if #DBUS_HAVE_INT64 is defined.
3055 * @param iter an iterator pointing to the end of the message
3056 * @param value the integer value
3057 * @returns #TRUE on success
3060 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
3061 dbus_uint64_t value)
3063 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3065 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3067 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT64))
3070 if (!_dbus_marshal_uint64 (&real->message->body, real->message->byte_order, value))
3072 _dbus_string_set_length (&real->message->body, real->pos);
3076 dbus_message_iter_append_done (real);
3081 #endif /* DBUS_HAVE_INT64 */
3084 * Appends a double value to the message.
3086 * @param iter an iterator pointing to the end of the message
3087 * @param value the double value
3088 * @returns #TRUE on success
3091 dbus_message_iter_append_double (DBusMessageIter *iter,
3094 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3096 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3098 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DOUBLE))
3101 if (!_dbus_marshal_double (&real->message->body, real->message->byte_order, value))
3103 _dbus_string_set_length (&real->message->body, real->pos);
3107 dbus_message_iter_append_done (real);
3113 * Appends a UTF-8 string to the message.
3115 * @param iter an iterator pointing to the end of the message
3116 * @param value the string
3117 * @returns #TRUE on success
3120 dbus_message_iter_append_string (DBusMessageIter *iter,
3123 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3125 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3127 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
3130 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
3132 _dbus_string_set_length (&real->message->body, real->pos);
3136 dbus_message_iter_append_done (real);
3142 * Appends a named type data chunk to the message. A named
3143 * type is simply an arbitrary UTF-8 string used as a type
3144 * tag, plus an array of arbitrary bytes to be interpreted
3145 * according to the type tag.
3147 * @param iter an iterator pointing to the end of the message
3148 * @param name the name of the type
3149 * @param data the binary data used to store the value
3150 * @param len the length of the binary data in bytes
3151 * @returns #TRUE on success
3154 dbus_message_iter_append_named (DBusMessageIter *iter,
3156 const unsigned char *data,
3159 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3161 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3163 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NAMED))
3166 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
3168 _dbus_string_set_length (&real->message->body, real->pos);
3172 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
3174 _dbus_string_set_length (&real->message->body, real->pos);
3178 dbus_message_iter_append_done (real);
3185 * Appends a dict key name to the message. The iterator used
3186 * must point to a dict.
3188 * @param iter an iterator pointing to the end of the message
3189 * @param value the string
3190 * @returns #TRUE on success
3193 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
3196 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3198 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3199 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
3201 if (real->wrote_dict_key)
3203 _dbus_warn ("Appendinging multiple dict key names\n");
3207 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
3212 dbus_message_iter_append_done (real);
3213 real->wrote_dict_key = TRUE;
3219 array_iter_type_mark_done (DBusMessageRealIter *iter)
3223 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
3224 array_iter_type_mark_done (iter->parent_iter);
3228 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
3229 sizeof (dbus_uint32_t));
3231 /* Empty length for now, backfill later */
3232 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
3234 _dbus_string_set_length (&iter->message->body, iter->pos);
3238 iter->container_start = _dbus_string_get_length (&iter->message->body);
3239 iter->container_length_pos = len_pos;
3240 iter->array_type_done = TRUE;
3246 append_array_type (DBusMessageRealIter *real,
3248 dbus_bool_t *array_type_done,
3249 int *array_type_pos)
3251 int existing_element_type;
3253 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
3256 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
3257 real->array_type_done)
3259 existing_element_type = iter_get_array_type (real, array_type_pos);
3260 if (existing_element_type != element_type)
3262 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
3263 _dbus_type_to_string (element_type),
3264 _dbus_type_to_string (existing_element_type));
3265 _dbus_string_set_length (&real->message->body, real->pos);
3268 if (array_type_done != NULL)
3269 *array_type_done = TRUE;
3273 if (array_type_pos != NULL)
3274 *array_type_pos = _dbus_string_get_length (&real->message->body);
3276 /* Append element type */
3277 if (!_dbus_string_append_byte (&real->message->body, element_type))
3279 _dbus_string_set_length (&real->message->body, real->pos);
3283 if (array_type_done != NULL)
3284 *array_type_done = element_type != DBUS_TYPE_ARRAY;
3286 if (element_type != DBUS_TYPE_ARRAY &&
3287 !array_iter_type_mark_done (real))
3295 * Appends an array to the message and initializes an iterator that
3296 * can be used to append to the array.
3298 * @param iter an iterator pointing to the end of the message
3299 * @param array_iter pointer to an iter that will be initialized
3300 * @param element_type the type of the array elements
3301 * @returns #TRUE on success
3304 dbus_message_iter_append_array (DBusMessageIter *iter,
3305 DBusMessageIter *array_iter,
3308 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3309 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
3312 dbus_bool_t array_type_done;
3314 if (element_type == DBUS_TYPE_NIL)
3316 _dbus_warn ("Can't create NIL arrays\n");
3320 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3322 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
3325 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
3327 if (array_type_done)
3329 /* Empty length for now, backfill later */
3330 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
3332 _dbus_string_set_length (&real->message->body, real->pos);
3337 array_real->parent_iter = real;
3338 array_real->message = real->message;
3339 array_real->changed_stamp = real->message->changed_stamp;
3341 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
3342 array_real->pos = _dbus_string_get_length (&real->message->body);
3343 array_real->end = array_real->end;
3345 array_real->container_start = array_real->pos;
3346 array_real->container_length_pos = len_pos;
3347 array_real->wrote_dict_key = 0;
3348 array_real->array_type_done = array_type_done;
3349 array_real->array_type_pos = array_type_pos;
3351 dbus_message_iter_append_done (array_real);
3357 * Appends a dict to the message and initializes an iterator that
3358 * can be used to append to the dict.
3360 * @param iter an iterator pointing to the end of the message
3361 * @param dict_iter pointer to an iter that will be initialized
3362 * @returns #TRUE on success
3365 dbus_message_iter_append_dict (DBusMessageIter *iter,
3366 DBusMessageIter *dict_iter)
3368 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3369 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
3372 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3374 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
3377 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
3379 /* Empty length for now, backfill later */
3380 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
3382 _dbus_string_set_length (&real->message->body, real->pos);
3386 dict_real->parent_iter = real;
3387 dict_real->message = real->message;
3388 dict_real->changed_stamp = real->message->changed_stamp;
3390 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
3391 dict_real->pos = _dbus_string_get_length (&real->message->body);
3392 dict_real->end = dict_real->end;
3394 dict_real->container_start = dict_real->pos;
3395 dict_real->container_length_pos = len_pos;
3396 dict_real->wrote_dict_key = 0;
3398 dbus_message_iter_append_done (dict_real);
3405 * Appends a boolean array to the message.
3407 * @param iter an iterator pointing to the end of the message
3408 * @param value the array
3409 * @param len the length of the array
3410 * @returns #TRUE on success
3413 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
3414 unsigned const char *value,
3417 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3419 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3421 if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL))
3424 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
3426 _dbus_string_set_length (&real->message->body, real->pos);
3430 dbus_message_iter_append_done (real);
3436 * Appends a 32 bit signed integer array to the message.
3438 * @param iter an iterator pointing to the end of the message
3439 * @param value the array
3440 * @param len the length of the array
3441 * @returns #TRUE on success
3444 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
3445 const dbus_int32_t *value,
3448 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3450 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3452 if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL))
3455 if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len))
3457 _dbus_string_set_length (&real->message->body, real->pos);
3461 dbus_message_iter_append_done (real);
3467 * Appends a 32 bit unsigned integer array to the message.
3469 * @param iter an iterator pointing to the end of the message
3470 * @param value the array
3471 * @param len the length of the array
3472 * @returns #TRUE on success
3475 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
3476 const dbus_uint32_t *value,
3479 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3481 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3483 if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL))
3486 if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len))
3488 _dbus_string_set_length (&real->message->body, real->pos);
3492 dbus_message_iter_append_done (real);
3497 #ifdef DBUS_HAVE_INT64
3500 * Appends a 64 bit signed integer array to the message.
3502 * This function only exists if #DBUS_HAVE_INT64 is defined.
3504 * @param iter an iterator pointing to the end of the message
3505 * @param value the array
3506 * @param len the length of the array
3507 * @returns #TRUE on success
3510 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
3511 const dbus_int64_t *value,
3514 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3516 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3518 if (!append_array_type (real, DBUS_TYPE_INT64, NULL, NULL))
3521 if (!_dbus_marshal_int64_array (&real->message->body, real->message->byte_order, value, len))
3523 _dbus_string_set_length (&real->message->body, real->pos);
3527 dbus_message_iter_append_done (real);
3533 * Appends a 64 bit unsigned integer array to the message.
3535 * This function only exists if #DBUS_HAVE_INT64 is defined.
3537 * @param iter an iterator pointing to the end of the message
3538 * @param value the array
3539 * @param len the length of the array
3540 * @returns #TRUE on success
3543 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
3544 const dbus_uint64_t *value,
3547 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3549 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3551 if (!append_array_type (real, DBUS_TYPE_UINT64, NULL, NULL))
3554 if (!_dbus_marshal_uint64_array (&real->message->body, real->message->byte_order, value, len))
3556 _dbus_string_set_length (&real->message->body, real->pos);
3560 dbus_message_iter_append_done (real);
3564 #endif /* DBUS_HAVE_INT64 */
3567 * Appends a double array to the message.
3569 * @param iter an iterator pointing to the end of the message
3570 * @param value the array
3571 * @param len the length of the array
3572 * @returns #TRUE on success
3575 dbus_message_iter_append_double_array (DBusMessageIter *iter,
3576 const double *value,
3579 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3581 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3583 if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL))
3586 if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len))
3588 _dbus_string_set_length (&real->message->body, real->pos);
3592 dbus_message_iter_append_done (real);
3598 * Appends a byte array to the message.
3600 * @param iter an iterator pointing to the end of the message
3601 * @param value the array
3602 * @param len the length of the array
3603 * @returns #TRUE on success
3606 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
3607 unsigned const char *value,
3610 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3612 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3614 if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL))
3617 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
3619 _dbus_string_set_length (&real->message->body, real->pos);
3623 dbus_message_iter_append_done (real);
3629 * Appends a string array to the message.
3631 * @param iter an iterator pointing to the end of the message
3632 * @param value the array
3633 * @param len the length of the array
3634 * @returns #TRUE on success
3637 dbus_message_iter_append_string_array (DBusMessageIter *iter,
3641 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3643 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3645 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
3648 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
3650 _dbus_string_set_length (&real->message->body, real->pos);
3654 dbus_message_iter_append_done (real);
3660 * Sets the message sender.
3662 * @param message the message
3663 * @param sender the sender
3664 * @returns #FALSE if not enough memory
3667 dbus_message_set_sender (DBusMessage *message,
3670 _dbus_return_val_if_fail (message != NULL, FALSE);
3671 _dbus_return_val_if_fail (!message->locked, FALSE);
3675 delete_string_field (message, FIELD_SENDER);
3680 return set_string_field (message,
3687 * Sets a flag indicating that the message is an error reply
3688 * message, i.e. an "exception" rather than a normal response.
3690 * @param message the message
3691 * @param is_error_reply #TRUE if this is an error message.
3694 dbus_message_set_is_error (DBusMessage *message,
3695 dbus_bool_t is_error_reply)
3699 _dbus_return_if_fail (message != NULL);
3700 _dbus_return_if_fail (!message->locked);
3702 header = _dbus_string_get_data_len (&message->header, 1, 1);
3705 *header |= DBUS_HEADER_FLAG_ERROR;
3707 *header &= ~DBUS_HEADER_FLAG_ERROR;
3711 * Returns #TRUE if the message is an error
3712 * reply to some previous message we sent.
3714 * @param message the message
3715 * @returns #TRUE if the message is an error
3718 dbus_message_get_is_error (DBusMessage *message)
3722 _dbus_return_val_if_fail (message != NULL, FALSE);
3724 header = _dbus_string_get_const_data_len (&message->header, 1, 1);
3726 return (*header & DBUS_HEADER_FLAG_ERROR) != 0;
3730 * Gets the service which originated this message,
3731 * or #NULL if unknown or inapplicable.
3733 * @param message the message
3734 * @returns the service name or #NULL
3737 dbus_message_get_sender (DBusMessage *message)
3739 _dbus_return_val_if_fail (message != NULL, NULL);
3741 return get_string_field (message, FIELD_SENDER, NULL);
3745 * Checks whether the message has the given name.
3746 * If the message has no name or has a different
3747 * name, returns #FALSE.
3749 * @param message the message
3750 * @param name the name to check (must not be #NULL)
3752 * @returns #TRUE if the message has the given name
3755 dbus_message_has_name (DBusMessage *message,
3760 _dbus_return_val_if_fail (message != NULL, FALSE);
3761 _dbus_return_val_if_fail (name != NULL, FALSE);
3763 n = dbus_message_get_name (message);
3765 if (n && strcmp (n, name) == 0)
3772 * Checks whether the message was sent to the given service. If the
3773 * message has no service specified or has a different name, returns
3776 * @param message the message
3777 * @param service the service to check (must not be #NULL)
3779 * @returns #TRUE if the message has the given destination service
3782 dbus_message_has_destination (DBusMessage *message,
3783 const char *service)
3787 _dbus_return_val_if_fail (message != NULL, FALSE);
3788 _dbus_return_val_if_fail (service != NULL, FALSE);
3790 s = dbus_message_get_destination (message);
3792 if (s && strcmp (s, service) == 0)
3799 * Checks whether the message has the given service as its sender. If
3800 * the message has no sender specified or has a different sender,
3801 * returns #FALSE. Note that if a peer application owns multiple
3802 * services, its messages will have only one of those services as the
3803 * sender (usually the base service). So you can't use this
3804 * function to prove the sender didn't own service Foo, you can
3805 * only use it to prove that it did.
3807 * @param message the message
3808 * @param service the service to check (must not be #NULL)
3810 * @returns #TRUE if the message has the given origin service
3813 dbus_message_has_sender (DBusMessage *message,
3814 const char *service)
3818 _dbus_assert (service != NULL);
3820 s = dbus_message_get_sender (message);
3822 if (s && strcmp (s, service) == 0)
3829 * Sets a #DBusError based on the contents of the given
3830 * message. The error is only set if the message
3831 * is an error message, as in dbus_message_get_is_error().
3832 * The name of the error is set to the name of the message,
3833 * and the error message is set to the first argument
3834 * if the argument exists and is a string.
3836 * The return value indicates whether the error was set (the error is
3837 * set if and only if the message is an error message).
3838 * So you can check for an error reply and convert it to DBusError
3841 * @param error the error to set
3842 * @param message the message to set it from
3843 * @returns #TRUE if dbus_message_get_is_error() returns #TRUE for the message
3846 dbus_set_error_from_message (DBusError *error,
3847 DBusMessage *message)
3851 _dbus_return_val_if_fail (message != NULL, FALSE);
3852 _dbus_return_val_if_error_is_set (error, FALSE);
3854 if (!dbus_message_get_is_error (message))
3858 dbus_message_get_args (message, NULL,
3859 DBUS_TYPE_STRING, &str,
3862 dbus_set_error (error, dbus_message_get_name (message),
3863 str ? "%s" : NULL, str);
3873 * @addtogroup DBusMessageInternals
3878 * @typedef DBusMessageLoader
3880 * The DBusMessageLoader object encapsulates the process of converting
3881 * a byte stream into a series of DBusMessage. It buffers the incoming
3882 * bytes as efficiently as possible, and generates a queue of
3883 * messages. DBusMessageLoader is typically used as part of a
3884 * DBusTransport implementation. The DBusTransport then hands off
3885 * the loaded messages to a DBusConnection, making the messages
3886 * visible to the application.
3888 * @todo write tests for break-loader that a) randomly delete header
3889 * fields and b) set string fields to zero-length and other funky
3894 /* we definitely use signed ints for sizes, so don't exceed
3895 * _DBUS_INT_MAX; and add 16 for paranoia, since a message
3896 * over 128M is pretty nuts anyhow.
3900 * The maximum sane message size.
3902 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
3905 * Implementation details of DBusMessageLoader.
3906 * All members are private.
3908 struct DBusMessageLoader
3910 int refcount; /**< Reference count. */
3912 DBusString data; /**< Buffered data */
3914 DBusList *messages; /**< Complete messages. */
3916 long max_message_size; /**< Maximum size of a message */
3918 unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
3920 unsigned int corrupted : 1; /**< We got broken data, and are no longer working */
3924 * The initial buffer size of the message loader.
3926 * @todo this should be based on min header size plus some average
3927 * body size, or something. Or rather, the min header size only, if we
3928 * want to try to read only the header, store that in a DBusMessage,
3929 * then read only the body and store that, etc., depends on
3930 * how we optimize _dbus_message_loader_get_buffer() and what
3931 * the exact message format is.
3933 #define INITIAL_LOADER_DATA_LEN 32
3936 * Creates a new message loader. Returns #NULL if memory can't
3939 * @returns new loader, or #NULL.
3942 _dbus_message_loader_new (void)
3944 DBusMessageLoader *loader;
3946 loader = dbus_new0 (DBusMessageLoader, 1);
3950 loader->refcount = 1;
3952 /* Try to cap message size at something that won't *totally* hose
3953 * the system if we have a couple of them.
3955 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
3957 if (!_dbus_string_init (&loader->data))
3963 /* preallocate the buffer for speed, ignore failure */
3964 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
3965 _dbus_string_set_length (&loader->data, 0);
3971 * Increments the reference count of the loader.
3973 * @param loader the loader.
3976 _dbus_message_loader_ref (DBusMessageLoader *loader)
3978 loader->refcount += 1;
3982 * Decrements the reference count of the loader and finalizes the
3983 * loader when the count reaches zero.
3985 * @param loader the loader.
3988 _dbus_message_loader_unref (DBusMessageLoader *loader)
3990 loader->refcount -= 1;
3991 if (loader->refcount == 0)
3993 _dbus_list_foreach (&loader->messages,
3994 (DBusForeachFunction) dbus_message_unref,
3996 _dbus_list_clear (&loader->messages);
3997 _dbus_string_free (&loader->data);
4003 * Gets the buffer to use for reading data from the network. Network
4004 * data is read directly into an allocated buffer, which is then used
4005 * in the DBusMessage, to avoid as many extra memcpy's as possible.
4006 * The buffer must always be returned immediately using
4007 * _dbus_message_loader_return_buffer(), even if no bytes are
4008 * successfully read.
4010 * @todo this function can be a lot more clever. For example
4011 * it can probably always return a buffer size to read exactly
4012 * the body of the next message, thus avoiding any memory wastage
4015 * @todo we need to enforce a max length on strings in header fields.
4017 * @param loader the message loader.
4018 * @param buffer the buffer
4021 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
4022 DBusString **buffer)
4024 _dbus_assert (!loader->buffer_outstanding);
4026 *buffer = &loader->data;
4028 loader->buffer_outstanding = TRUE;
4032 * The smallest header size that can occur.
4033 * (It won't be valid)
4035 #define DBUS_MINIMUM_HEADER_SIZE 16
4037 /** Pack four characters as in "abcd" into a uint32 */
4038 #define FOUR_CHARS_TO_UINT32(a, b, c, d) \
4039 ((((dbus_uint32_t)a) << 24) | \
4040 (((dbus_uint32_t)b) << 16) | \
4041 (((dbus_uint32_t)c) << 8) | \
4044 /** DBUS_HEADER_FIELD_NAME packed into a dbus_uint32_t */
4045 #define DBUS_HEADER_FIELD_NAME_AS_UINT32 \
4046 FOUR_CHARS_TO_UINT32 ('n', 'a', 'm', 'e')
4048 /** DBUS_HEADER_FIELD_SERVICE packed into a dbus_uint32_t */
4049 #define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
4050 FOUR_CHARS_TO_UINT32 ('s', 'r', 'v', 'c')
4052 /** DBUS_HEADER_FIELD_REPLY packed into a dbus_uint32_t */
4053 #define DBUS_HEADER_FIELD_REPLY_AS_UINT32 \
4054 FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
4056 /** DBUS_HEADER_FIELD_SENDER Packed into a dbus_uint32_t */
4057 #define DBUS_HEADER_FIELD_SENDER_AS_UINT32 \
4058 FOUR_CHARS_TO_UINT32 ('s', 'n', 'd', 'r')
4061 decode_string_field (const DBusString *data,
4062 HeaderField fields[FIELD_LAST],
4066 const char *field_name)
4069 int string_data_pos;
4071 if (fields[field].offset >= 0)
4073 _dbus_verbose ("%s field provided twice\n",
4078 if (type != DBUS_TYPE_STRING)
4080 _dbus_verbose ("%s field has wrong type %s\n",
4081 field_name, _dbus_type_to_string (type));
4085 /* skip padding after typecode, skip string length;
4086 * we assume that the string arg has already been validated
4087 * for sanity and UTF-8
4089 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
4090 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
4092 _dbus_string_init_const (&tmp,
4093 _dbus_string_get_const_data (data) + string_data_pos);
4095 if (field == FIELD_NAME)
4097 if (!_dbus_string_validate_name (&tmp, 0, _dbus_string_get_length (&tmp)))
4099 _dbus_verbose ("%s field has invalid content \"%s\"\n",
4100 field_name, _dbus_string_get_const_data (&tmp));
4104 if (_dbus_string_starts_with_c_str (&tmp,
4105 DBUS_NAMESPACE_LOCAL_MESSAGE))
4107 _dbus_verbose ("Message is in the local namespace\n");
4113 if (!_dbus_string_validate_service (&tmp, 0, _dbus_string_get_length (&tmp)))
4115 _dbus_verbose ("%s field has invalid content \"%s\"\n",
4116 field_name, _dbus_string_get_const_data (&tmp));
4121 fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
4124 _dbus_verbose ("Found field %s name at offset %d\n",
4125 field_name, fields[field].offset);
4132 decode_header_data (const DBusString *data,
4135 HeaderField fields[FIELD_LAST],
4136 int *message_padding)
4143 if (header_len < 16)
4147 while (i < FIELD_LAST)
4149 fields[i].offset = -1;
4153 fields[FIELD_HEADER_LENGTH].offset = 4;
4154 fields[FIELD_BODY_LENGTH].offset = 8;
4155 fields[FIELD_CLIENT_SERIAL].offset = 12;
4157 /* Now handle the named fields. A real named field is at least 4
4158 * bytes for the name, plus a type code (1 byte) plus padding. So
4159 * if we have less than 8 bytes left, it must be alignment padding,
4160 * not a field. While >= 8 bytes can't be entirely alignment
4164 while ((pos + 7) < header_len)
4166 pos = _DBUS_ALIGN_VALUE (pos, 4);
4168 if ((pos + 4) > header_len)
4171 field =_dbus_string_get_const_data_len (data, pos, 4);
4174 _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
4176 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
4178 _dbus_verbose ("Failed to validate type of named header field\n");
4182 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
4184 _dbus_verbose ("Failed to validate argument to named header field\n");
4188 if (new_pos > header_len)
4190 _dbus_verbose ("Named header field tries to extend beyond header length\n");
4194 switch (DBUS_UINT32_FROM_BE (*(int*)field))
4196 case DBUS_HEADER_FIELD_SERVICE_AS_UINT32:
4197 if (!decode_string_field (data, fields, pos, type,
4199 DBUS_HEADER_FIELD_SERVICE))
4203 case DBUS_HEADER_FIELD_NAME_AS_UINT32:
4204 if (!decode_string_field (data, fields, pos, type,
4206 DBUS_HEADER_FIELD_NAME))
4210 case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
4211 if (!decode_string_field (data, fields, pos, type,
4213 DBUS_HEADER_FIELD_SENDER))
4217 case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
4218 if (fields[FIELD_REPLY_SERIAL].offset >= 0)
4220 _dbus_verbose ("%s field provided twice\n",
4221 DBUS_HEADER_FIELD_REPLY);
4225 if (type != DBUS_TYPE_UINT32)
4227 _dbus_verbose ("%s field has wrong type\n", DBUS_HEADER_FIELD_REPLY);
4231 fields[FIELD_REPLY_SERIAL].offset = _DBUS_ALIGN_VALUE (pos, 4);
4233 _dbus_verbose ("Found reply serial at offset %d\n",
4234 fields[FIELD_REPLY_SERIAL].offset);
4238 _dbus_verbose ("Ignoring an unknown header field: %c%c%c%c at offset %d\n",
4239 field[0], field[1], field[2], field[3], pos);
4245 if (pos < header_len)
4247 /* Alignment padding, verify that it's nul */
4248 _dbus_assert ((header_len - pos) < 8);
4250 if (!_dbus_string_validate_nul (data,
4251 pos, (header_len - pos)))
4253 _dbus_verbose ("header alignment padding is not nul\n");
4258 /* Name field is mandatory */
4259 if (fields[FIELD_NAME].offset < 0)
4261 _dbus_verbose ("No %s field provided\n",
4262 DBUS_HEADER_FIELD_NAME);
4266 if (message_padding)
4267 *message_padding = header_len - pos;
4273 * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
4274 * indicating to the loader how many bytes of the buffer were filled
4275 * in. This function must always be called, even if no bytes were
4276 * successfully read.
4278 * @param loader the loader.
4279 * @param buffer the buffer.
4280 * @param bytes_read number of bytes that were read into the buffer.
4283 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
4287 _dbus_assert (loader->buffer_outstanding);
4288 _dbus_assert (buffer == &loader->data);
4290 loader->buffer_outstanding = FALSE;
4294 * Converts buffered data into messages.
4296 * @param loader the loader.
4297 * @returns #TRUE if we had enough memory to finish.
4300 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4302 if (loader->corrupted)
4305 while (_dbus_string_get_length (&loader->data) >= 16)
4307 DBusMessage *message;
4308 const char *header_data;
4309 int byte_order, header_len, body_len, header_padding;
4310 dbus_uint32_t header_len_unsigned, body_len_unsigned;
4312 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
4314 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
4316 if (header_data[2] != DBUS_MAJOR_PROTOCOL_VERSION)
4318 _dbus_verbose ("Message has protocol version %d ours is %d\n",
4319 (int) header_data[2], DBUS_MAJOR_PROTOCOL_VERSION);
4320 loader->corrupted = TRUE;
4324 byte_order = header_data[0];
4326 if (byte_order != DBUS_LITTLE_ENDIAN &&
4327 byte_order != DBUS_BIG_ENDIAN)
4329 _dbus_verbose ("Message with bad byte order '%c' received\n",
4331 loader->corrupted = TRUE;
4335 header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
4336 body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
4338 if (header_len_unsigned < 16)
4340 _dbus_verbose ("Message had broken too-small header length %u\n",
4341 header_len_unsigned);
4342 loader->corrupted = TRUE;
4346 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
4347 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
4349 _dbus_verbose ("Header or body length too large (%u %u)\n",
4350 header_len_unsigned,
4352 loader->corrupted = TRUE;
4356 /* Now that we know the values are in signed range, get
4357 * rid of stupid unsigned, just causes bugs
4359 header_len = header_len_unsigned;
4360 body_len = body_len_unsigned;
4362 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
4365 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
4367 loader->corrupted = TRUE;
4371 if (header_len + body_len > loader->max_message_size)
4373 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
4374 header_len, body_len, loader->max_message_size);
4375 loader->corrupted = TRUE;
4379 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
4381 HeaderField fields[FIELD_LAST];
4386 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len);
4388 if (!decode_header_data (&loader->data, header_len, byte_order,
4389 fields, &header_padding))
4391 _dbus_verbose ("Header was invalid\n");
4392 loader->corrupted = TRUE;
4396 next_arg = header_len;
4397 while (next_arg < (header_len + body_len))
4400 int prev = next_arg;
4402 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
4405 _dbus_verbose ("invalid typecode at offset %d\n", prev);
4406 loader->corrupted = TRUE;
4410 if (!_dbus_marshal_validate_arg (&loader->data,
4417 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
4418 loader->corrupted = TRUE;
4422 _dbus_assert (next_arg > prev);
4425 if (next_arg > (header_len + body_len))
4427 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
4428 next_arg, header_len, body_len,
4429 header_len + body_len);
4430 loader->corrupted = TRUE;
4434 message = dbus_message_new_empty_header ();
4435 if (message == NULL)
4437 _dbus_verbose ("Failed to allocate empty message\n");
4441 message->byte_order = byte_order;
4442 message->header_padding = header_padding;
4444 /* Copy in the offsets we found */
4446 while (i < FIELD_LAST)
4448 message->header_fields[i] = fields[i];
4452 if (!_dbus_list_append (&loader->messages, message))
4454 _dbus_verbose ("Failed to append new message to loader queue\n");
4455 dbus_message_unref (message);
4459 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
4460 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4462 _dbus_assert (_dbus_string_get_length (&loader->data) >=
4463 (header_len + body_len));
4465 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
4467 _dbus_verbose ("Failed to move header into new message\n");
4468 _dbus_list_remove_last (&loader->messages, message);
4469 dbus_message_unref (message);
4473 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
4477 _dbus_verbose ("Failed to move body into new message\n");
4479 /* put the header back, we'll try again later */
4480 result = _dbus_string_copy_len (&message->header, 0, header_len,
4482 _dbus_assert (result); /* because DBusString never reallocs smaller */
4484 _dbus_list_remove_last (&loader->messages, message);
4485 dbus_message_unref (message);
4489 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
4490 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4492 /* Fill in caches (we checked the types of these fields
4495 message->reply_serial = get_uint_field (message,
4496 FIELD_REPLY_SERIAL);
4497 message->client_serial = get_uint_field (message,
4498 FIELD_CLIENT_SERIAL);
4500 _dbus_verbose ("Loaded message %p\n", message);
4510 * Peeks at first loaded message, returns #NULL if no messages have
4513 * @param loader the loader.
4514 * @returns the next message, or #NULL if none.
4517 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
4519 if (loader->messages)
4520 return loader->messages->data;
4526 * Pops a loaded message (passing ownership of the message
4527 * to the caller). Returns #NULL if no messages have been
4530 * @param loader the loader.
4531 * @returns the next message, or #NULL if none.
4534 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
4536 return _dbus_list_pop_first (&loader->messages);
4540 * Pops a loaded message inside a list link (passing ownership of the
4541 * message and link to the caller). Returns #NULL if no messages have
4544 * @param loader the loader.
4545 * @returns the next message link, or #NULL if none.
4548 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
4550 return _dbus_list_pop_first_link (&loader->messages);
4554 * Returns a popped message link, used to undo a pop.
4556 * @param loader the loader
4557 * @param link the link with a message in it
4560 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
4563 _dbus_list_prepend_link (&loader->messages, link);
4567 * Checks whether the loader is confused due to bad data.
4568 * If messages are received that are invalid, the
4569 * loader gets confused and gives up permanently.
4570 * This state is called "corrupted."
4572 * @param loader the loader
4573 * @returns #TRUE if the loader is hosed.
4576 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
4578 return loader->corrupted;
4582 * Sets the maximum size message we allow.
4584 * @param loader the loader
4585 * @param size the max message size in bytes
4588 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
4591 if (size > MAX_SANE_MESSAGE_SIZE)
4593 _dbus_verbose ("clamping requested max message size %ld to %d\n",
4594 size, MAX_SANE_MESSAGE_SIZE);
4595 size = MAX_SANE_MESSAGE_SIZE;
4597 loader->max_message_size = size;
4601 * Gets the maximum allowed message size in bytes.
4603 * @param loader the loader
4604 * @returns max size in bytes
4607 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
4609 return loader->max_message_size;
4613 #ifdef DBUS_BUILD_TESTS
4614 #include "dbus-test.h"
4618 message_iter_test (DBusMessage *message)
4620 DBusMessageIter iter, dict, array, array2;
4622 unsigned char *data;
4623 dbus_int32_t *our_int_array;
4626 dbus_message_iter_init (message, &iter);
4629 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
4630 _dbus_assert_not_reached ("Argument type isn't string");
4632 str = dbus_message_iter_get_string (&iter);
4633 if (strcmp (str, "Test string") != 0)
4634 _dbus_assert_not_reached ("Strings differ");
4637 if (!dbus_message_iter_next (&iter))
4638 _dbus_assert_not_reached ("Reached end of arguments");
4640 /* Signed integer tests */
4641 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
4642 _dbus_assert_not_reached ("Argument type isn't int32");
4644 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
4645 _dbus_assert_not_reached ("Signed integers differ");
4647 if (!dbus_message_iter_next (&iter))
4648 _dbus_assert_not_reached ("Reached end of fields");
4650 /* Unsigned integer tests */
4651 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
4652 _dbus_assert_not_reached ("Argument type isn't int32");
4654 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
4655 _dbus_assert_not_reached ("Unsigned integers differ");
4657 if (!dbus_message_iter_next (&iter))
4658 _dbus_assert_not_reached ("Reached end of arguments");
4661 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
4662 _dbus_assert_not_reached ("Argument type isn't double");
4664 if (dbus_message_iter_get_double (&iter) != 3.14159)
4665 _dbus_assert_not_reached ("Doubles differ");
4667 if (!dbus_message_iter_next (&iter))
4668 _dbus_assert_not_reached ("Reached end of arguments");
4670 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
4671 _dbus_assert_not_reached ("Argument type not an array");
4673 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
4674 _dbus_assert_not_reached ("Array type not double");
4677 if (!dbus_message_iter_init_array_iterator (&iter, &array, NULL))
4678 _dbus_assert_not_reached ("Array init failed");
4680 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
4681 _dbus_assert_not_reached ("Argument type isn't double");
4683 if (dbus_message_iter_get_double (&array) != 1.5)
4684 _dbus_assert_not_reached ("Unsigned integers differ");
4686 if (!dbus_message_iter_next (&array))
4687 _dbus_assert_not_reached ("Reached end of arguments");
4689 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
4690 _dbus_assert_not_reached ("Argument type isn't double");
4692 if (dbus_message_iter_get_double (&array) != 2.5)
4693 _dbus_assert_not_reached ("Unsigned integers differ");
4695 if (dbus_message_iter_next (&array))
4696 _dbus_assert_not_reached ("Didn't reach end of arguments");
4698 if (!dbus_message_iter_next (&iter))
4699 _dbus_assert_not_reached ("Reached end of arguments");
4704 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
4705 _dbus_assert_not_reached ("not dict type");
4707 if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
4708 _dbus_assert_not_reached ("dict iter failed");
4710 str = dbus_message_iter_get_dict_key (&dict);
4711 if (str == NULL || strcmp (str, "test") != 0)
4712 _dbus_assert_not_reached ("wrong dict key");
4715 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
4716 _dbus_assert_not_reached ("wrong dict entry type");
4718 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
4719 _dbus_assert_not_reached ("wrong dict entry value");
4721 if (!dbus_message_iter_next (&dict))
4722 _dbus_assert_not_reached ("reached end of dict");
4724 /* array of array of int32 (in dict) */
4726 str = dbus_message_iter_get_dict_key (&dict);
4727 if (str == NULL || strcmp (str, "array") != 0)
4728 _dbus_assert_not_reached ("wrong dict key");
4731 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
4732 _dbus_assert_not_reached ("Argument type not an array");
4734 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
4735 _dbus_assert_not_reached ("Array type not array");
4737 if (!dbus_message_iter_init_array_iterator (&dict, &array, NULL))
4738 _dbus_assert_not_reached ("Array init failed");
4740 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
4741 _dbus_assert_not_reached ("Argument type isn't array");
4743 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
4744 _dbus_assert_not_reached ("Array type not int32");
4746 if (!dbus_message_iter_init_array_iterator (&array, &array2, NULL))
4747 _dbus_assert_not_reached ("Array init failed");
4749 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
4750 _dbus_assert_not_reached ("Argument type isn't int32");
4752 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
4753 _dbus_assert_not_reached ("Signed integers differ");
4755 if (!dbus_message_iter_next (&array2))
4756 _dbus_assert_not_reached ("Reached end of arguments");
4758 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
4759 _dbus_assert_not_reached ("Signed integers differ");
4761 if (dbus_message_iter_next (&array2))
4762 _dbus_assert_not_reached ("Didn't reached end of arguments");
4764 if (!dbus_message_iter_next (&array))
4765 _dbus_assert_not_reached ("Reached end of arguments");
4767 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
4768 _dbus_assert_not_reached ("Array type not int32");
4770 if (!dbus_message_iter_get_int32_array (&array,
4773 _dbus_assert_not_reached ("couldn't get int32 array");
4775 _dbus_assert (len == 3);
4776 _dbus_assert (our_int_array[0] == 0x34567812 &&
4777 our_int_array[1] == 0x45678123 &&
4778 our_int_array[2] == 0x56781234);
4779 dbus_free (our_int_array);
4781 if (dbus_message_iter_next (&array))
4782 _dbus_assert_not_reached ("Didn't reach end of array");
4784 if (dbus_message_iter_next (&dict))
4785 _dbus_assert_not_reached ("Didn't reach end of dict");
4787 if (!dbus_message_iter_next (&iter))
4788 _dbus_assert_not_reached ("Reached end of arguments");
4790 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
4792 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
4793 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
4796 if (dbus_message_iter_get_byte (&iter) != 0xF0)
4797 _dbus_assert_not_reached ("wrong value after dict");
4800 if (!dbus_message_iter_next (&iter))
4801 _dbus_assert_not_reached ("Reached end of arguments");
4803 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
4804 _dbus_assert_not_reached ("not a nil type");
4806 if (!dbus_message_iter_next (&iter))
4807 _dbus_assert_not_reached ("Reached end of arguments");
4809 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NAMED)
4810 _dbus_assert_not_reached ("wrong type after dict");
4812 if (!dbus_message_iter_get_named (&iter, &str, &data, &len))
4813 _dbus_assert_not_reached ("failed to get named");
4815 _dbus_assert (strcmp (str, "named")==0);
4816 _dbus_assert (len == 5);
4817 _dbus_assert (strcmp (data, "data")==0);
4821 if (dbus_message_iter_next (&iter))
4822 _dbus_assert_not_reached ("Didn't reach end of arguments");
4827 check_message_handling_type (DBusMessageIter *iter,
4830 DBusMessageIter child_iter;
4836 case DBUS_TYPE_BYTE:
4837 dbus_message_iter_get_byte (iter);
4839 case DBUS_TYPE_BOOLEAN:
4840 dbus_message_iter_get_boolean (iter);
4842 case DBUS_TYPE_INT32:
4843 dbus_message_iter_get_int32 (iter);
4845 case DBUS_TYPE_UINT32:
4846 dbus_message_iter_get_uint32 (iter);
4848 case DBUS_TYPE_INT64:
4849 #ifdef DBUS_HAVE_INT64
4850 dbus_message_iter_get_int64 (iter);
4853 case DBUS_TYPE_UINT64:
4854 #ifdef DBUS_HAVE_INT64
4855 dbus_message_iter_get_uint64 (iter);
4858 case DBUS_TYPE_DOUBLE:
4859 dbus_message_iter_get_double (iter);
4861 case DBUS_TYPE_STRING:
4864 str = dbus_message_iter_get_string (iter);
4867 _dbus_warn ("NULL string in message\n");
4873 case DBUS_TYPE_NAMED:
4876 unsigned char *data;
4879 if (!dbus_message_iter_get_named (iter, &name, &data, &len))
4881 _dbus_warn ("error reading name from named type\n");
4888 case DBUS_TYPE_ARRAY:
4892 if (!dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type))
4894 _dbus_warn ("Failed to init array iterator\n");
4898 while (dbus_message_iter_has_next (&child_iter))
4900 if (!check_message_handling_type (&child_iter, array_type))
4902 _dbus_warn ("error in array element\n");
4906 if (!dbus_message_iter_next (&child_iter))
4911 case DBUS_TYPE_DICT:
4916 if (!dbus_message_iter_init_dict_iterator (iter, &child_iter))
4918 _dbus_warn ("Failed to init dict iterator\n");
4922 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
4924 key = dbus_message_iter_get_dict_key (&child_iter);
4927 _dbus_warn ("error reading dict key\n");
4932 if (!check_message_handling_type (&child_iter, entry_type))
4934 _dbus_warn ("error in dict value\n");
4938 if (!dbus_message_iter_next (&child_iter))
4945 _dbus_warn ("unknown type %d\n", type);
4954 check_message_handling (DBusMessage *message)
4956 DBusMessageIter iter;
4959 dbus_uint32_t client_serial;
4963 client_serial = dbus_message_get_serial (message);
4965 /* can't use set_serial due to the assertions at the start of it */
4966 set_uint_field (message, FIELD_CLIENT_SERIAL,
4969 if (client_serial != dbus_message_get_serial (message))
4971 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
4975 /* If we implement message_set_arg (message, n, value)
4976 * then we would want to test it here
4979 dbus_message_iter_init (message, &iter);
4980 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
4982 if (!check_message_handling_type (&iter, type))
4985 if (!dbus_message_iter_next (&iter))
4996 check_have_valid_message (DBusMessageLoader *loader)
4998 DBusMessage *message;
5004 if (!_dbus_message_loader_queue_messages (loader))
5005 _dbus_assert_not_reached ("no memory to queue messages");
5007 if (_dbus_message_loader_get_is_corrupted (loader))
5009 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
5013 message = _dbus_message_loader_pop_message (loader);
5014 if (message == NULL)
5016 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
5020 if (_dbus_string_get_length (&loader->data) > 0)
5022 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
5026 /* Verify that we're able to properly deal with the message.
5027 * For example, this would detect improper handling of messages
5028 * in nonstandard byte order.
5030 if (!check_message_handling (message))
5037 dbus_message_unref (message);
5043 check_invalid_message (DBusMessageLoader *loader)
5049 if (!_dbus_message_loader_queue_messages (loader))
5050 _dbus_assert_not_reached ("no memory to queue messages");
5052 if (!_dbus_message_loader_get_is_corrupted (loader))
5054 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
5065 check_incomplete_message (DBusMessageLoader *loader)
5067 DBusMessage *message;
5073 if (!_dbus_message_loader_queue_messages (loader))
5074 _dbus_assert_not_reached ("no memory to queue messages");
5076 if (_dbus_message_loader_get_is_corrupted (loader))
5078 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
5082 message = _dbus_message_loader_pop_message (loader);
5083 if (message != NULL)
5085 _dbus_warn ("loaded message that was expected to be incomplete\n");
5093 dbus_message_unref (message);
5098 check_loader_results (DBusMessageLoader *loader,
5099 DBusMessageValidity validity)
5101 if (!_dbus_message_loader_queue_messages (loader))
5102 _dbus_assert_not_reached ("no memory to queue messages");
5106 case _DBUS_MESSAGE_VALID:
5107 return check_have_valid_message (loader);
5108 case _DBUS_MESSAGE_INVALID:
5109 return check_invalid_message (loader);
5110 case _DBUS_MESSAGE_INCOMPLETE:
5111 return check_incomplete_message (loader);
5112 case _DBUS_MESSAGE_UNKNOWN:
5116 _dbus_assert_not_reached ("bad DBusMessageValidity");
5122 * Loads the message in the given message file.
5124 * @param filename filename to load
5125 * @param is_raw if #TRUE load as binary data, if #FALSE as message builder language
5126 * @param data string to load message into
5127 * @returns #TRUE if the message was loaded
5130 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
5142 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
5143 dbus_error_init (&error);
5144 if (!_dbus_file_get_contents (data, filename, &error))
5146 _dbus_warn ("Could not load message file %s: %s\n",
5147 _dbus_string_get_const_data (filename),
5149 dbus_error_free (&error);
5155 if (!_dbus_message_data_load (data, filename))
5157 _dbus_warn ("Could not load message file %s\n",
5158 _dbus_string_get_const_data (filename));
5171 * Tries loading the message in the given message file
5172 * and verifies that DBusMessageLoader can handle it.
5174 * @param filename filename to load
5175 * @param is_raw if #TRUE load as binary data, if #FALSE as message builder language
5176 * @param expected_validity what the message has to be like to return #TRUE
5177 * @returns #TRUE if the message has the expected validity
5180 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
5182 DBusMessageValidity expected_validity)
5189 if (!_dbus_string_init (&data))
5190 _dbus_assert_not_reached ("could not allocate string\n");
5192 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
5196 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
5202 if (_dbus_string_get_length (&data) > 0)
5203 _dbus_verbose_bytes_of_string (&data, 0,
5204 _dbus_string_get_length (&data));
5206 _dbus_warn ("Failed message loader test on %s\n",
5207 _dbus_string_get_const_data (filename));
5210 _dbus_string_free (&data);
5216 * Tries loading the given message data.
5219 * @param data the message data
5220 * @param expected_validity what the message has to be like to return #TRUE
5221 * @returns #TRUE if the message has the expected validity
5224 dbus_internal_do_not_use_try_message_data (const DBusString *data,
5225 DBusMessageValidity expected_validity)
5227 DBusMessageLoader *loader;
5235 /* Write the data one byte at a time */
5237 loader = _dbus_message_loader_new ();
5239 /* check some trivial loader functions */
5240 _dbus_message_loader_ref (loader);
5241 _dbus_message_loader_unref (loader);
5242 _dbus_message_loader_get_max_message_size (loader);
5244 len = _dbus_string_get_length (data);
5245 for (i = 0; i < len; i++)
5249 _dbus_message_loader_get_buffer (loader, &buffer);
5250 _dbus_string_append_byte (buffer,
5251 _dbus_string_get_byte (data, i));
5252 _dbus_message_loader_return_buffer (loader, buffer, 1);
5255 if (!check_loader_results (loader, expected_validity))
5258 _dbus_message_loader_unref (loader);
5261 /* Write the data all at once */
5263 loader = _dbus_message_loader_new ();
5268 _dbus_message_loader_get_buffer (loader, &buffer);
5269 _dbus_string_copy (data, 0, buffer,
5270 _dbus_string_get_length (buffer));
5271 _dbus_message_loader_return_buffer (loader, buffer, 1);
5274 if (!check_loader_results (loader, expected_validity))
5277 _dbus_message_loader_unref (loader);
5280 /* Write the data 2 bytes at a time */
5282 loader = _dbus_message_loader_new ();
5284 len = _dbus_string_get_length (data);
5285 for (i = 0; i < len; i += 2)
5289 _dbus_message_loader_get_buffer (loader, &buffer);
5290 _dbus_string_append_byte (buffer,
5291 _dbus_string_get_byte (data, i));
5293 _dbus_string_append_byte (buffer,
5294 _dbus_string_get_byte (data, i+1));
5295 _dbus_message_loader_return_buffer (loader, buffer, 1);
5298 if (!check_loader_results (loader, expected_validity))
5301 _dbus_message_loader_unref (loader);
5309 _dbus_message_loader_unref (loader);
5315 process_test_subdir (const DBusString *test_base_dir,
5317 DBusMessageValidity validity,
5318 DBusForeachMessageFileFunc function,
5321 DBusString test_directory;
5322 DBusString filename;
5330 if (!_dbus_string_init (&test_directory))
5331 _dbus_assert_not_reached ("didn't allocate test_directory\n");
5333 _dbus_string_init_const (&filename, subdir);
5335 if (!_dbus_string_copy (test_base_dir, 0,
5336 &test_directory, 0))
5337 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
5339 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
5340 _dbus_assert_not_reached ("couldn't allocate full path");
5342 _dbus_string_free (&filename);
5343 if (!_dbus_string_init (&filename))
5344 _dbus_assert_not_reached ("didn't allocate filename string\n");
5346 dbus_error_init (&error);
5347 dir = _dbus_directory_open (&test_directory, &error);
5350 _dbus_warn ("Could not open %s: %s\n",
5351 _dbus_string_get_const_data (&test_directory),
5353 dbus_error_free (&error);
5357 printf ("Testing:\n");
5360 while (_dbus_directory_get_next_file (dir, &filename, &error))
5362 DBusString full_path;
5365 if (!_dbus_string_init (&full_path))
5366 _dbus_assert_not_reached ("couldn't init string");
5368 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
5369 _dbus_assert_not_reached ("couldn't copy dir to full_path");
5371 if (!_dbus_concat_dir_and_file (&full_path, &filename))
5372 _dbus_assert_not_reached ("couldn't concat file to dir");
5374 if (_dbus_string_ends_with_c_str (&filename, ".message"))
5376 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
5380 _dbus_verbose ("Skipping non-.message file %s\n",
5381 _dbus_string_get_const_data (&filename));
5382 _dbus_string_free (&full_path);
5387 _dbus_string_get_const_data (&filename));
5389 _dbus_verbose (" expecting %s\n",
5390 validity == _DBUS_MESSAGE_VALID ? "valid" :
5391 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
5392 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")));
5394 if (! (*function) (&full_path, is_raw, validity, user_data))
5396 _dbus_string_free (&full_path);
5400 _dbus_string_free (&full_path);
5403 if (dbus_error_is_set (&error))
5405 _dbus_warn ("Could not get next file in %s: %s\n",
5406 _dbus_string_get_const_data (&test_directory),
5408 dbus_error_free (&error);
5417 _dbus_directory_close (dir);
5418 _dbus_string_free (&test_directory);
5419 _dbus_string_free (&filename);
5425 * Runs the given function on every message file in the test suite.
5426 * The function should return #FALSE on test failure or fatal error.
5428 * @param test_data_dir root dir of the test suite data files (top_srcdir/test/data)
5429 * @param func the function to run
5430 * @param user_data data for function
5431 * @returns #FALSE if there's a failure
5434 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
5435 DBusForeachMessageFileFunc func,
5438 DBusString test_directory;
5443 _dbus_string_init_const (&test_directory, test_data_dir);
5445 if (!process_test_subdir (&test_directory, "valid-messages",
5446 _DBUS_MESSAGE_VALID, func, user_data))
5449 if (!process_test_subdir (&test_directory, "invalid-messages",
5450 _DBUS_MESSAGE_INVALID, func, user_data))
5453 if (!process_test_subdir (&test_directory, "incomplete-messages",
5454 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
5461 _dbus_string_free (&test_directory);
5467 verify_test_message (DBusMessage *message)
5469 DBusMessageIter iter, dict;
5471 dbus_int32_t our_int;
5474 dbus_bool_t our_bool;
5475 dbus_uint32_t our_uint32;
5476 dbus_int32_t *our_uint32_array;
5477 int our_uint32_array_len;
5478 dbus_int32_t *our_int32_array;
5479 int our_int32_array_len;
5480 char **our_string_array;
5481 int our_string_array_len;
5482 #ifdef DBUS_HAVE_INT64
5483 dbus_int64_t our_int64;
5484 dbus_uint64_t our_uint64;
5485 dbus_int64_t *our_uint64_array;
5486 int our_uint64_array_len;
5487 dbus_int64_t *our_int64_array;
5488 int our_int64_array_len;
5490 double *our_double_array;
5491 int our_double_array_len;
5492 unsigned char *our_byte_array;
5493 int our_byte_array_len;
5494 unsigned char *our_boolean_array;
5495 int our_boolean_array_len;
5497 dbus_message_iter_init (message, &iter);
5499 dbus_error_init (&error);
5500 if (!dbus_message_iter_get_args (&iter, &error,
5501 DBUS_TYPE_INT32, &our_int,
5502 #ifdef DBUS_HAVE_INT64
5503 DBUS_TYPE_INT64, &our_int64,
5504 DBUS_TYPE_UINT64, &our_uint64,
5506 DBUS_TYPE_STRING, &our_str,
5507 DBUS_TYPE_DOUBLE, &our_double,
5508 DBUS_TYPE_BOOLEAN, &our_bool,
5509 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
5510 &our_uint32_array, &our_uint32_array_len,
5511 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
5512 &our_int32_array, &our_int32_array_len,
5513 #ifdef DBUS_HAVE_INT64
5514 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
5515 &our_uint64_array, &our_uint64_array_len,
5516 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
5517 &our_int64_array, &our_int64_array_len,
5519 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
5520 &our_string_array, &our_string_array_len,
5521 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
5522 &our_double_array, &our_double_array_len,
5523 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
5524 &our_byte_array, &our_byte_array_len,
5525 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
5526 &our_boolean_array, &our_boolean_array_len,
5529 _dbus_warn ("error: %s - %s\n", error.name,
5530 (error.message != NULL) ? error.message : "no message");
5531 _dbus_assert_not_reached ("Could not get arguments");
5534 if (our_int != -0x12345678)
5535 _dbus_assert_not_reached ("integers differ!");
5537 #ifdef DBUS_HAVE_INT64
5538 if (our_int64 != -0x123456789abcd)
5539 _dbus_assert_not_reached ("64-bit integers differ!");
5540 if (our_uint64 != 0x123456789abcd)
5541 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
5544 if (our_double != 3.14159)
5545 _dbus_assert_not_reached ("doubles differ!");
5547 if (strcmp (our_str, "Test string") != 0)
5548 _dbus_assert_not_reached ("strings differ!");
5549 dbus_free (our_str);
5552 _dbus_assert_not_reached ("booleans differ");
5554 if (our_uint32_array_len != 4 ||
5555 our_uint32_array[0] != 0x12345678 ||
5556 our_uint32_array[1] != 0x23456781 ||
5557 our_uint32_array[2] != 0x34567812 ||
5558 our_uint32_array[3] != 0x45678123)
5559 _dbus_assert_not_reached ("uint array differs");
5560 dbus_free (our_uint32_array);
5562 if (our_int32_array_len != 4 ||
5563 our_int32_array[0] != 0x12345678 ||
5564 our_int32_array[1] != -0x23456781 ||
5565 our_int32_array[2] != 0x34567812 ||
5566 our_int32_array[3] != -0x45678123)
5567 _dbus_assert_not_reached ("int array differs");
5568 dbus_free (our_int32_array);
5570 #ifdef DBUS_HAVE_INT64
5571 if (our_uint64_array_len != 4 ||
5572 our_uint64_array[0] != 0x12345678 ||
5573 our_uint64_array[1] != 0x23456781 ||
5574 our_uint64_array[2] != 0x34567812 ||
5575 our_uint64_array[3] != 0x45678123)
5576 _dbus_assert_not_reached ("uint64 array differs");
5577 dbus_free (our_uint64_array);
5579 if (our_int64_array_len != 4 ||
5580 our_int64_array[0] != 0x12345678 ||
5581 our_int64_array[1] != -0x23456781 ||
5582 our_int64_array[2] != 0x34567812 ||
5583 our_int64_array[3] != -0x45678123)
5584 _dbus_assert_not_reached ("int64 array differs");
5585 dbus_free (our_int64_array);
5586 #endif /* DBUS_HAVE_INT64 */
5588 if (our_string_array_len != 4)
5589 _dbus_assert_not_reached ("string array has wrong length");
5591 if (strcmp (our_string_array[0], "Foo") != 0 ||
5592 strcmp (our_string_array[1], "bar") != 0 ||
5593 strcmp (our_string_array[2], "") != 0 ||
5594 strcmp (our_string_array[3], "woo woo woo woo") != 0)
5595 _dbus_assert_not_reached ("string array differs");
5597 dbus_free_string_array (our_string_array);
5599 if (our_double_array_len != 3)
5600 _dbus_assert_not_reached ("double array had wrong length");
5602 /* On all IEEE machines (i.e. everything sane) exact equality
5603 * should be preserved over the wire
5605 if (our_double_array[0] != 0.1234 ||
5606 our_double_array[1] != 9876.54321 ||
5607 our_double_array[2] != -300.0)
5608 _dbus_assert_not_reached ("double array had wrong values");
5610 dbus_free (our_double_array);
5612 if (our_byte_array_len != 4)
5613 _dbus_assert_not_reached ("byte array had wrong length");
5615 if (our_byte_array[0] != 'a' ||
5616 our_byte_array[1] != 'b' ||
5617 our_byte_array[2] != 'c' ||
5618 our_byte_array[3] != 234)
5619 _dbus_assert_not_reached ("byte array had wrong values");
5621 dbus_free (our_byte_array);
5623 if (our_boolean_array_len != 5)
5624 _dbus_assert_not_reached ("bool array had wrong length");
5626 if (our_boolean_array[0] != TRUE ||
5627 our_boolean_array[1] != FALSE ||
5628 our_boolean_array[2] != TRUE ||
5629 our_boolean_array[3] != TRUE ||
5630 our_boolean_array[4] != FALSE)
5631 _dbus_assert_not_reached ("bool array had wrong values");
5633 dbus_free (our_boolean_array);
5635 if (!dbus_message_iter_next (&iter))
5636 _dbus_assert_not_reached ("Reached end of arguments");
5638 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
5639 _dbus_assert_not_reached ("not dict type");
5641 if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
5642 _dbus_assert_not_reached ("dict iter failed");
5644 our_str = dbus_message_iter_get_dict_key (&dict);
5645 if (our_str == NULL || strcmp (our_str, "test") != 0)
5646 _dbus_assert_not_reached ("wrong dict key");
5647 dbus_free (our_str);
5649 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
5651 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
5652 _dbus_assert_not_reached ("wrong dict entry type");
5655 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
5657 _dbus_verbose ("dict entry val: %x\n", our_uint32);
5658 _dbus_assert_not_reached ("wrong dict entry value");
5661 if (dbus_message_iter_next (&dict))
5662 _dbus_assert_not_reached ("Didn't reach end of dict");
5664 if (!dbus_message_iter_next (&iter))
5665 _dbus_assert_not_reached ("Reached end of arguments");
5667 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
5668 _dbus_assert_not_reached ("wrong type after dict");
5670 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
5671 _dbus_assert_not_reached ("wrong value after dict");
5673 if (dbus_message_iter_next (&iter))
5674 _dbus_assert_not_reached ("Didn't reach end of arguments");
5678 * @ingroup DBusMessageInternals
5679 * Unit test for DBusMessage.
5681 * @returns #TRUE on success.
5684 _dbus_message_test (const char *test_data_dir)
5686 DBusMessage *message;
5687 DBusMessageLoader *loader;
5688 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
5694 const dbus_uint32_t our_uint32_array[] =
5695 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
5696 const dbus_uint32_t our_int32_array[] =
5697 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
5698 #ifdef DBUS_HAVE_INT64
5699 const dbus_uint64_t our_uint64_array[] =
5700 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
5701 const dbus_uint64_t our_int64_array[] =
5702 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
5704 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
5705 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
5706 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
5707 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
5709 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
5711 message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
5712 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
5713 _dbus_message_set_serial (message, 1234);
5714 dbus_message_set_sender (message, "org.foo.bar");
5715 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar"));
5716 dbus_message_set_sender (message, NULL);
5717 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar"));
5718 _dbus_assert (dbus_message_get_serial (message) == 1234);
5719 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
5721 _dbus_assert (dbus_message_get_is_error (message) == FALSE);
5722 dbus_message_set_is_error (message, TRUE);
5723 _dbus_assert (dbus_message_get_is_error (message) == TRUE);
5724 dbus_message_set_is_error (message, FALSE);
5725 _dbus_assert (dbus_message_get_is_error (message) == FALSE);
5727 dbus_message_unref (message);
5729 /* Test the vararg functions */
5730 message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
5731 _dbus_message_set_serial (message, 1);
5732 dbus_message_append_args (message,
5733 DBUS_TYPE_INT32, -0x12345678,
5734 #ifdef DBUS_HAVE_INT64
5735 DBUS_TYPE_INT64, -0x123456789abcd,
5736 DBUS_TYPE_UINT64, 0x123456789abcd,
5738 DBUS_TYPE_STRING, "Test string",
5739 DBUS_TYPE_DOUBLE, 3.14159,
5740 DBUS_TYPE_BOOLEAN, TRUE,
5741 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
5742 _DBUS_N_ELEMENTS (our_uint32_array),
5743 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
5744 _DBUS_N_ELEMENTS (our_int32_array),
5745 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
5746 _DBUS_N_ELEMENTS (our_uint64_array),
5747 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
5748 _DBUS_N_ELEMENTS (our_int64_array),
5749 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
5750 _DBUS_N_ELEMENTS (our_string_array),
5751 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
5752 _DBUS_N_ELEMENTS (our_double_array),
5753 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
5754 _DBUS_N_ELEMENTS (our_byte_array),
5755 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
5756 _DBUS_N_ELEMENTS (our_boolean_array),
5759 dbus_message_append_iter_init (message, &iter);
5760 dbus_message_iter_append_dict (&iter, &child_iter);
5761 dbus_message_iter_append_dict_key (&child_iter, "test");
5762 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
5763 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
5765 _dbus_verbose_bytes_of_string (&message->header, 0,
5766 _dbus_string_get_length (&message->header));
5767 _dbus_verbose_bytes_of_string (&message->body, 0,
5768 _dbus_string_get_length (&message->body));
5770 verify_test_message (message);
5772 copy = dbus_message_copy (message);
5774 _dbus_assert (message->client_serial == copy->client_serial);
5775 _dbus_assert (message->reply_serial == copy->reply_serial);
5776 _dbus_assert (message->header_padding == copy->header_padding);
5778 _dbus_assert (_dbus_string_get_length (&message->header) ==
5779 _dbus_string_get_length (©->header));
5781 _dbus_assert (_dbus_string_get_length (&message->body) ==
5782 _dbus_string_get_length (©->body));
5784 verify_test_message (copy);
5786 name1 = dbus_message_get_name (message);
5787 name2 = dbus_message_get_name (copy);
5789 _dbus_assert (strcmp (name1, name2) == 0);
5791 dbus_message_unref (message);
5792 dbus_message_unref (copy);
5794 message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
5795 _dbus_message_set_serial (message, 1);
5796 dbus_message_set_reply_serial (message, 0x12345678);
5798 dbus_message_append_iter_init (message, &iter);
5799 dbus_message_iter_append_string (&iter, "Test string");
5800 dbus_message_iter_append_int32 (&iter, -0x12345678);
5801 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
5802 dbus_message_iter_append_double (&iter, 3.14159);
5804 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
5805 dbus_message_iter_append_double (&child_iter, 1.5);
5806 dbus_message_iter_append_double (&child_iter, 2.5);
5809 dbus_message_iter_append_dict (&iter, &child_iter);
5810 dbus_message_iter_append_dict_key (&child_iter, "test");
5811 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
5813 /* array of array of int32 (in dict) */
5814 dbus_message_iter_append_dict_key (&child_iter, "array");
5815 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
5816 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
5817 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
5818 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
5819 _dbus_warn ("next call expected to fail with wrong array type\n");
5820 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
5821 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
5822 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
5823 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
5824 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
5826 dbus_message_iter_append_byte (&iter, 0xF0);
5828 dbus_message_iter_append_nil (&iter);
5830 dbus_message_iter_append_named (&iter, "named",
5833 message_iter_test (message);
5835 /* Message loader test */
5836 _dbus_message_lock (message);
5837 loader = _dbus_message_loader_new ();
5839 /* check ref/unref */
5840 _dbus_message_loader_ref (loader);
5841 _dbus_message_loader_unref (loader);
5843 /* Write the header data one byte at a time */
5844 data = _dbus_string_get_const_data (&message->header);
5845 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
5849 _dbus_message_loader_get_buffer (loader, &buffer);
5850 _dbus_string_append_byte (buffer, data[i]);
5851 _dbus_message_loader_return_buffer (loader, buffer, 1);
5854 /* Write the body data one byte at a time */
5855 data = _dbus_string_get_const_data (&message->body);
5856 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
5860 _dbus_message_loader_get_buffer (loader, &buffer);
5861 _dbus_string_append_byte (buffer, data[i]);
5862 _dbus_message_loader_return_buffer (loader, buffer, 1);
5865 dbus_message_unref (message);
5867 /* Now pop back the message */
5868 if (!_dbus_message_loader_queue_messages (loader))
5869 _dbus_assert_not_reached ("no memory to queue messages");
5871 if (_dbus_message_loader_get_is_corrupted (loader))
5872 _dbus_assert_not_reached ("message loader corrupted");
5874 message = _dbus_message_loader_pop_message (loader);
5876 _dbus_assert_not_reached ("received a NULL message");
5878 if (dbus_message_get_reply_serial (message) != 0x12345678)
5879 _dbus_assert_not_reached ("reply serial fields differ");
5881 message_iter_test (message);
5883 dbus_message_unref (message);
5884 _dbus_message_loader_unref (loader);
5886 /* Now load every message in test_data_dir if we have one */
5887 if (test_data_dir == NULL)
5890 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
5891 (DBusForeachMessageFileFunc)
5892 dbus_internal_do_not_use_try_message_file,
5896 #endif /* DBUS_BUILD_TESTS */