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"
32 #include "dbus-dataslot.h"
36 * @defgroup DBusMessageInternals DBusMessage implementation details
37 * @ingroup DBusInternals
38 * @brief DBusMessage private implementation details.
40 * The guts of DBusMessage and its methods.
46 * Cached information about a header field in the message
50 int name_offset; /**< Offset to name of field */
51 int value_offset; /**< Offset to value of field */
54 /** Offset to byte order from start of header */
55 #define BYTE_ORDER_OFFSET 0
56 /** Offset to type from start of header */
58 /** Offset to flags from start of header */
59 #define FLAGS_OFFSET 2
60 /** Offset to version from start of header */
61 #define VERSION_OFFSET 3
62 /** Offset to header length from start of header */
63 #define HEADER_LENGTH_OFFSET 4
64 /** Offset to body length from start of header */
65 #define BODY_LENGTH_OFFSET 8
66 /** Offset to client serial from start of header */
67 #define CLIENT_SERIAL_OFFSET 12
71 * @brief Internals of DBusMessage
73 * Object representing a message received from or to be sent to
74 * another application. This is an opaque object, all members
79 DBusAtomic refcount; /**< Reference count */
81 DBusString header; /**< Header network data, stored
82 * separately from body so we can
83 * independently realloc it.
86 HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1]; /**< Track the location
87 * of each field in "header"
90 dbus_uint32_t client_serial; /**< Cached client serial value for speed */
91 dbus_uint32_t reply_serial; /**< Cached reply serial value for speed */
93 int header_padding; /**< bytes of alignment in header */
95 DBusString body; /**< Body network data. */
97 char byte_order; /**< Message byte order. */
99 DBusList *size_counters; /**< 0-N DBusCounter used to track message size. */
100 long size_counter_delta; /**< Size we incremented the size counters by. */
102 dbus_uint32_t changed_stamp; /**< Incremented when iterators are invalidated. */
104 unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
106 DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
110 DBUS_MESSAGE_ITER_TYPE_MESSAGE,
111 DBUS_MESSAGE_ITER_TYPE_ARRAY,
112 DBUS_MESSAGE_ITER_TYPE_DICT
115 /** typedef for internals of message iterator */
116 typedef struct DBusMessageRealIter DBusMessageRealIter;
119 * @brief Internals of DBusMessageIter
121 * Object representing a position in a message. All fields are internal.
123 struct DBusMessageRealIter
125 DBusMessageRealIter *parent_iter; /**< parent iter, or NULL */
126 DBusMessage *message; /**< Message used */
127 dbus_uint32_t changed_stamp; /**< stamp to detect invalid iters */
129 /* This is an int instead of an enum to get a guaranteed size for the dummy: */
130 int type; /**< type of iter */
132 int pos; /**< Current position in the string */
133 int end; /**< position right after the container */
134 int container_start; /**< offset of the start of the container */
135 int container_length_pos; /**< offset of the length of the container */
137 int wrote_dict_key; /**< whether we wrote the dict key for the current dict element */
139 int array_type_pos; /**< pointer to the position of the array element type */
140 int array_type_done; /**< TRUE if the array type is fully finished */
144 * Gets the data to be sent over the network for this message.
145 * The header and then the body should be written out.
146 * This function is guaranteed to always return the same
147 * data once a message is locked (with _dbus_message_lock()).
149 * @param message the message.
150 * @param header return location for message header data.
151 * @param body return location for message body data.
154 _dbus_message_get_network_data (DBusMessage *message,
155 const DBusString **header,
156 const DBusString **body)
158 _dbus_assert (message->locked);
160 *header = &message->header;
161 *body = &message->body;
165 clear_header_padding (DBusMessage *message)
167 _dbus_string_shorten (&message->header,
168 message->header_padding);
169 message->header_padding = 0;
173 append_header_padding (DBusMessage *message)
176 old_len = _dbus_string_get_length (&message->header);
177 if (!_dbus_string_align_length (&message->header, 8))
180 message->header_padding = _dbus_string_get_length (&message->header) - old_len;
185 #ifdef DBUS_BUILD_TESTS
186 /* tests-only until it's actually used */
188 get_int_field (DBusMessage *message,
193 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
195 offset = message->header_fields[field].value_offset;
198 return -1; /* useless if -1 is a valid value of course */
200 return _dbus_demarshal_int32 (&message->header,
208 get_uint_field (DBusMessage *message,
213 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
215 offset = message->header_fields[field].value_offset;
218 return -1; /* useless if -1 is a valid value of course */
220 return _dbus_demarshal_uint32 (&message->header,
227 get_string_field (DBusMessage *message,
234 offset = message->header_fields[field].value_offset;
236 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
241 /* offset points to string length, string data follows it */
242 /* FIXME _dbus_demarshal_const_string() that returned
243 * a reference to the string plus its len might be nice.
247 *len = _dbus_demarshal_uint32 (&message->header,
252 data = _dbus_string_get_const_data (&message->header);
254 return data + (offset + 4);
257 /* returns FALSE if no memory, TRUE with NULL path if no field */
259 get_path_field_decomposed (DBusMessage *message,
265 offset = message->header_fields[field].value_offset;
267 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
275 return _dbus_demarshal_object_path (&message->header,
282 #ifdef DBUS_BUILD_TESTS
284 append_int_field (DBusMessage *message,
288 _dbus_assert (!message->locked);
290 clear_header_padding (message);
292 message->header_fields[field].name_offset =
293 _dbus_string_get_length (&message->header);
295 if (!_dbus_string_append_byte (&message->header, field))
298 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
301 if (!_dbus_string_align_length (&message->header, 4))
304 message->header_fields[field].value_offset =
305 _dbus_string_get_length (&message->header);
307 if (!_dbus_marshal_int32 (&message->header, message->byte_order,
311 if (!append_header_padding (message))
317 _dbus_string_set_length (&message->header,
318 message->header_fields[field].name_offset);
319 message->header_fields[field].name_offset = -1;
320 message->header_fields[field].value_offset = -1;
322 /* this must succeed because it was allocated on function entry and
323 * DBusString doesn't ever realloc smaller
325 if (!append_header_padding (message))
326 _dbus_assert_not_reached ("failed to reappend header padding");
332 append_uint_field (DBusMessage *message,
336 _dbus_assert (!message->locked);
338 clear_header_padding (message);
340 message->header_fields[field].name_offset =
341 _dbus_string_get_length (&message->header);
343 if (!_dbus_string_append_byte (&message->header, field))
346 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
349 if (!_dbus_string_align_length (&message->header, 4))
352 message->header_fields[field].value_offset =
353 _dbus_string_get_length (&message->header);
355 if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
359 if (!append_header_padding (message))
365 _dbus_string_set_length (&message->header,
366 message->header_fields[field].name_offset);
367 message->header_fields[field].name_offset = -1;
368 message->header_fields[field].value_offset = -1;
370 /* this must succeed because it was allocated on function entry and
371 * DBusString doesn't ever realloc smaller
373 if (!append_header_padding (message))
374 _dbus_assert_not_reached ("failed to reappend header padding");
379 append_string_field (DBusMessage *message,
384 _dbus_assert (!message->locked);
386 clear_header_padding (message);
388 message->header_fields[field].name_offset =
389 _dbus_string_get_length (&message->header);
391 if (!_dbus_string_append_byte (&message->header, field))
394 if (!_dbus_string_append_byte (&message->header, type))
397 if (!_dbus_string_align_length (&message->header, 4))
400 message->header_fields[field].value_offset =
401 _dbus_string_get_length (&message->header);
403 if (!_dbus_marshal_string (&message->header, message->byte_order,
407 if (!append_header_padding (message))
413 _dbus_string_set_length (&message->header,
414 message->header_fields[field].name_offset);
415 message->header_fields[field].name_offset = -1;
416 message->header_fields[field].value_offset = -1;
418 /* this must succeed because it was allocated on function entry and
419 * DBusString doesn't ever realloc smaller
421 if (!append_header_padding (message))
422 _dbus_assert_not_reached ("failed to reappend header padding");
428 get_next_field (DBusMessage *message,
431 int offset = message->header_fields[field].name_offset;
434 int retval = DBUS_HEADER_FIELD_INVALID;
437 closest = _DBUS_INT_MAX;
438 while (i < DBUS_HEADER_FIELD_LAST)
440 if (message->header_fields[i].name_offset > offset &&
441 message->header_fields[i].name_offset < closest)
443 closest = message->header_fields[i].name_offset;
453 re_align_field_recurse (DBusMessage *message,
457 int old_name_offset = message->header_fields[field].name_offset;
458 int old_value_offset = message->header_fields[field].value_offset;
459 int prev_padding, padding, delta;
464 /* padding between the typecode byte and the value itself */
465 prev_padding = old_value_offset - old_name_offset + 2;
468 type = _dbus_string_get_byte (&message->header, pos);
475 case DBUS_TYPE_BOOLEAN:
478 case DBUS_TYPE_INT32:
479 case DBUS_TYPE_UINT32:
480 case DBUS_TYPE_STRING:
481 case DBUS_TYPE_OBJECT_PATH:
482 padding = _DBUS_ALIGN_VALUE (pos, 4) - pos;
484 case DBUS_TYPE_INT64:
485 case DBUS_TYPE_UINT64:
486 case DBUS_TYPE_DOUBLE:
487 padding = _DBUS_ALIGN_VALUE (pos, 8) - pos;
489 case DBUS_TYPE_NAMED:
490 case DBUS_TYPE_ARRAY:
492 _dbus_assert_not_reached ("no defined header fields may contain a named, array or dict value");
494 case DBUS_TYPE_INVALID:
496 _dbus_assert_not_reached ("invalid type in marshalled header");
500 delta = padding - prev_padding;
503 if (!_dbus_string_insert_bytes (&message->header, pos, delta, 0))
508 _dbus_string_delete (&message->header, pos, -delta);
511 next_field = get_next_field (message, field);
512 if (next_field != DBUS_HEADER_FIELD_INVALID)
514 int next_offset = message->header_fields[next_field].name_offset;
516 _dbus_assert (next_offset > 0);
518 if (!re_align_field_recurse (message, field,
519 pos + padding + (next_offset - old_value_offset)))
524 if (!append_header_padding (message))
528 message->header_fields[field].name_offset = offset;
529 message->header_fields[field].value_offset = pos + padding;
536 _dbus_string_delete (&message->header, pos, delta);
540 /* this must succeed because it was allocated on function entry and
541 * DBusString doesn't ever realloc smaller
543 _dbus_string_insert_bytes (&message->header, pos, -delta, 0);
550 delete_field (DBusMessage *message,
553 int offset = message->header_fields[field].name_offset;
556 _dbus_assert (!message->locked);
561 clear_header_padding (message);
563 next_field = get_next_field (message, field);
564 if (next_field == DBUS_HEADER_FIELD_INVALID)
566 _dbus_string_set_length (&message->header, offset);
568 message->header_fields[field].name_offset = -1;
569 message->header_fields[field].value_offset = -1;
571 /* this must succeed because it was allocated on function entry and
572 * DBusString doesn't ever realloc smaller
574 if (!append_header_padding (message))
575 _dbus_assert_not_reached ("failed to reappend header padding");
582 int next_offset = message->header_fields[next_field].name_offset;
584 _dbus_assert (next_offset > 0);
586 if (!_dbus_string_init (&deleted))
589 if (!_dbus_string_move_len (&message->header,
590 offset, next_offset - offset,
593 _dbus_string_free (&deleted);
597 /* appends the header padding */
598 if (!re_align_field_recurse (message, next_field, offset))
600 /* this must succeed because it was allocated on function entry and
601 * DBusString doesn't ever realloc smaller
603 if (!_dbus_string_copy (&deleted, 0, &message->header, offset))
604 _dbus_assert_not_reached ("failed to revert to original field");
606 _dbus_string_free (&deleted);
610 _dbus_string_free (&deleted);
612 message->header_fields[field].name_offset = -1;
613 message->header_fields[field].value_offset = -1;
618 /* this must succeed because it was allocated on function entry and
619 * DBusString doesn't ever realloc smaller
621 if (!append_header_padding (message))
622 _dbus_assert_not_reached ("failed to reappend header padding");
628 #ifdef DBUS_BUILD_TESTS
630 set_int_field (DBusMessage *message,
634 int offset = message->header_fields[field].value_offset;
636 _dbus_assert (!message->locked);
640 /* need to append the field */
641 return append_int_field (message, field, value);
645 _dbus_marshal_set_int32 (&message->header,
655 set_uint_field (DBusMessage *message,
659 int offset = message->header_fields[field].value_offset;
661 _dbus_assert (!message->locked);
665 /* need to append the field */
666 return append_uint_field (message, field, value);
670 _dbus_marshal_set_uint32 (&message->header,
679 set_string_field (DBusMessage *message,
684 int offset = message->header_fields[field].value_offset;
686 _dbus_assert (!message->locked);
687 _dbus_assert (value != NULL);
691 /* need to append the field */
692 return append_string_field (message, field, type, value);
702 clear_header_padding (message);
704 old_value = _dbus_demarshal_string (&message->header,
711 len = strlen (value);
713 _dbus_string_init_const_len (&v, value,
714 len + 1); /* include nul */
715 if (!_dbus_marshal_set_string (&message->header,
719 dbus_free (old_value);
723 next_field = get_next_field (message, field);
724 if (next_field != DBUS_HEADER_FIELD_INVALID)
726 /* re-appends the header padding */
727 if (!re_align_field_recurse (message, next_field, next_offset))
729 len = strlen (old_value);
731 _dbus_string_init_const_len (&v, old_value,
732 len + 1); /* include nul */
733 if (!_dbus_marshal_set_string (&message->header,
736 _dbus_assert_not_reached ("failed to revert to original string");
738 dbus_free (old_value);
743 dbus_free (old_value);
748 /* this must succeed because it was allocated on function entry and
749 * DBusString doesn't ever realloc smaller
751 if (!append_header_padding (message))
752 _dbus_assert_not_reached ("failed to reappend header padding");
759 * Sets the serial number of a message.
760 * This can only be done once on a message.
762 * @param message the message
763 * @param serial the serial
766 _dbus_message_set_serial (DBusMessage *message,
769 _dbus_assert (!message->locked);
770 _dbus_assert (dbus_message_get_serial (message) == 0);
772 _dbus_marshal_set_uint32 (&message->header,
774 CLIENT_SERIAL_OFFSET,
777 message->client_serial = serial;
781 * Sets the reply serial of a message (the client serial
782 * of the message this is a reply to).
784 * @param message the message
785 * @param reply_serial the client serial
786 * @returns #FALSE if not enough memory
789 dbus_message_set_reply_serial (DBusMessage *message,
790 dbus_uint32_t reply_serial)
792 _dbus_assert (!message->locked);
794 if (set_uint_field (message,
795 DBUS_HEADER_FIELD_REPLY_SERIAL,
798 message->reply_serial = reply_serial;
806 * Returns the serial of a message or -1 if none has been specified.
807 * The message's serial number is provided by the application sending
808 * the message and is used to identify replies to this message.
810 * @param message the message
811 * @returns the client serial
814 dbus_message_get_serial (DBusMessage *message)
816 return message->client_serial;
820 * Returns the serial that the message is
821 * a reply to or 0 if none.
823 * @param message the message
824 * @returns the reply serial
827 dbus_message_get_reply_serial (DBusMessage *message)
829 return message->reply_serial;
833 * Adds a counter to be incremented immediately with the
834 * size of this message, and decremented by the size
835 * of this message when this message if finalized.
836 * The link contains a counter with its refcount already
837 * incremented, but the counter itself not incremented.
838 * Ownership of link and counter refcount is passed to
841 * @param message the message
842 * @param link link with counter as data
845 _dbus_message_add_size_counter_link (DBusMessage *message,
848 /* right now we don't recompute the delta when message
849 * size changes, and that's OK for current purposes
850 * I think, but could be important to change later.
851 * Do recompute it whenever there are no outstanding counters,
852 * since it's basically free.
854 if (message->size_counters == NULL)
856 message->size_counter_delta =
857 _dbus_string_get_length (&message->header) +
858 _dbus_string_get_length (&message->body);
861 _dbus_verbose ("message has size %ld\n",
862 message->size_counter_delta);
866 _dbus_list_append_link (&message->size_counters, link);
868 _dbus_counter_adjust (link->data, message->size_counter_delta);
872 * Adds a counter to be incremented immediately with the
873 * size of this message, and decremented by the size
874 * of this message when this message if finalized.
876 * @param message the message
877 * @param counter the counter
878 * @returns #FALSE if no memory
881 _dbus_message_add_size_counter (DBusMessage *message,
882 DBusCounter *counter)
886 link = _dbus_list_alloc_link (counter);
890 _dbus_counter_ref (counter);
891 _dbus_message_add_size_counter_link (message, link);
897 * Removes a counter tracking the size of this message, and decrements
898 * the counter by the size of this message.
900 * @param message the message
901 * @param link_return return the link used
902 * @param counter the counter
905 _dbus_message_remove_size_counter (DBusMessage *message,
906 DBusCounter *counter,
907 DBusList **link_return)
911 link = _dbus_list_find_last (&message->size_counters,
913 _dbus_assert (link != NULL);
915 _dbus_list_unlink (&message->size_counters,
920 _dbus_list_free_link (link);
922 _dbus_counter_adjust (counter, message->size_counter_delta);
924 _dbus_counter_unref (counter);
928 dbus_message_create_header (DBusMessage *message,
932 const char *interface,
934 const char *error_name)
938 _dbus_assert ((interface && member) ||
940 !(interface || member || error_name));
942 if (!_dbus_string_append_byte (&message->header, message->byte_order))
945 if (!_dbus_string_append_byte (&message->header, type))
949 if (!_dbus_string_append_byte (&message->header, flags))
952 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
955 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
958 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
961 if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
964 /* Marshal all the fields (Marshall Fields?) */
968 if (!append_string_field (message,
969 DBUS_HEADER_FIELD_PATH,
970 DBUS_TYPE_OBJECT_PATH,
977 if (!append_string_field (message,
978 DBUS_HEADER_FIELD_SERVICE,
984 if (interface != NULL)
986 if (!append_string_field (message,
987 DBUS_HEADER_FIELD_INTERFACE,
995 if (!append_string_field (message,
996 DBUS_HEADER_FIELD_MEMBER,
1002 if (error_name != NULL)
1004 if (!append_string_field (message,
1005 DBUS_HEADER_FIELD_ERROR_NAME,
1015 * Locks a message. Allows checking that applications don't keep a
1016 * reference to a message in the outgoing queue and change it
1017 * underneath us. Messages are locked when they enter the outgoing
1018 * queue (dbus_connection_send_message()), and the library complains
1019 * if the message is modified while locked.
1021 * @param message the message to lock.
1024 _dbus_message_lock (DBusMessage *message)
1026 if (!message->locked)
1028 /* Fill in our lengths */
1029 _dbus_marshal_set_uint32 (&message->header,
1030 message->byte_order,
1031 HEADER_LENGTH_OFFSET,
1032 _dbus_string_get_length (&message->header));
1034 _dbus_marshal_set_uint32 (&message->header,
1035 message->byte_order,
1037 _dbus_string_get_length (&message->body));
1039 message->locked = TRUE;
1046 * @defgroup DBusMessage DBusMessage
1048 * @brief Message to be sent or received over a DBusConnection.
1050 * A DBusMessage is the most basic unit of communication over a
1051 * DBusConnection. A DBusConnection represents a stream of messages
1052 * received from a remote application, and a stream of messages
1053 * sent to a remote application.
1059 * @typedef DBusMessage
1061 * Opaque data type representing a message received from or to be
1062 * sent to another application.
1066 dbus_message_new_empty_header (void)
1068 DBusMessage *message;
1071 message = dbus_new0 (DBusMessage, 1);
1072 if (message == NULL)
1075 message->refcount.value = 1;
1076 message->byte_order = DBUS_COMPILER_BYTE_ORDER;
1077 message->client_serial = 0;
1078 message->reply_serial = 0;
1080 _dbus_data_slot_list_init (&message->slot_list);
1083 while (i <= DBUS_HEADER_FIELD_LAST)
1085 message->header_fields[i].name_offset = -1;
1086 message->header_fields[i].value_offset = -1;
1090 if (!_dbus_string_init_preallocated (&message->header, 64))
1092 dbus_free (message);
1096 if (!_dbus_string_init_preallocated (&message->body, 64))
1098 _dbus_string_free (&message->header);
1099 dbus_free (message);
1107 * Constructs a new message of the given message type.
1108 * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL,
1109 * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth.
1111 * @param message_type type of message
1112 * @returns new message or #NULL If no memory
1115 dbus_message_new (int message_type)
1117 DBusMessage *message;
1119 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1121 message = dbus_message_new_empty_header ();
1122 if (message == NULL)
1125 if (!dbus_message_create_header (message,
1127 NULL, NULL, NULL, NULL, NULL))
1129 dbus_message_unref (message);
1137 * Constructs a new message to invoke a method on a remote
1138 * object. Returns #NULL if memory can't be allocated for the
1139 * message. The service may be #NULL in which case no service is set;
1140 * this is appropriate when using D-BUS in a peer-to-peer context (no
1141 * message bus). The interface may be #NULL, which means that
1142 * if multiple methods with the given name exist it is undefined
1143 * which one will be invoked.
1145 * @param service service that the message should be sent to or #NULL
1146 * @param path object path the message should be sent to
1147 * @param interface interface to invoke method on
1148 * @param method method to invoke
1150 * @returns a new DBusMessage, free with dbus_message_unref()
1151 * @see dbus_message_unref()
1154 dbus_message_new_method_call (const char *service,
1156 const char *interface,
1159 DBusMessage *message;
1161 _dbus_return_val_if_fail (path != NULL, NULL);
1162 _dbus_return_val_if_fail (method != NULL, NULL);
1164 message = dbus_message_new_empty_header ();
1165 if (message == NULL)
1168 if (!dbus_message_create_header (message,
1169 DBUS_MESSAGE_TYPE_METHOD_CALL,
1170 service, path, interface, method, NULL))
1172 dbus_message_unref (message);
1180 * Constructs a message that is a reply to a method call. Returns
1181 * #NULL if memory can't be allocated for the message.
1183 * @param method_call the message which the created
1184 * message is a reply to.
1185 * @returns a new DBusMessage, free with dbus_message_unref()
1186 * @see dbus_message_new_method_call(), dbus_message_unref()
1189 dbus_message_new_method_return (DBusMessage *method_call)
1191 DBusMessage *message;
1194 _dbus_return_val_if_fail (method_call != NULL, NULL);
1196 sender = get_string_field (method_call,
1197 DBUS_HEADER_FIELD_SENDER_SERVICE,
1200 /* sender is allowed to be null here in peer-to-peer case */
1202 message = dbus_message_new_empty_header ();
1203 if (message == NULL)
1206 if (!dbus_message_create_header (message,
1207 DBUS_MESSAGE_TYPE_METHOD_RETURN,
1208 sender, NULL, NULL, NULL, NULL))
1210 dbus_message_unref (message);
1214 if (!dbus_message_set_reply_serial (message,
1215 dbus_message_get_serial (method_call)))
1217 dbus_message_unref (message);
1225 * Constructs a new message representing a signal emission. Returns
1226 * #NULL if memory can't be allocated for the message.
1227 * A signal is identified by its originating interface, and
1228 * the name of the signal.
1230 * @param path the path to the object emitting the signal
1231 * @param interface the interface the signal is emitted from
1232 * @param name name of the signal
1233 * @returns a new DBusMessage, free with dbus_message_unref()
1234 * @see dbus_message_unref()
1237 dbus_message_new_signal (const char *path,
1238 const char *interface,
1241 DBusMessage *message;
1243 _dbus_return_val_if_fail (path != NULL, NULL);
1244 _dbus_return_val_if_fail (interface != NULL, NULL);
1245 _dbus_return_val_if_fail (name != NULL, NULL);
1247 message = dbus_message_new_empty_header ();
1248 if (message == NULL)
1251 if (!dbus_message_create_header (message,
1252 DBUS_MESSAGE_TYPE_SIGNAL,
1253 NULL, path, interface, name, NULL))
1255 dbus_message_unref (message);
1263 * Creates a new message that is an error reply to a certain message.
1264 * Error replies are possible in response to method calls primarily.
1266 * @param reply_to the original message
1267 * @param error_name the error name
1268 * @param error_message the error message string or #NULL for none
1269 * @returns a new error message
1272 dbus_message_new_error (DBusMessage *reply_to,
1273 const char *error_name,
1274 const char *error_message)
1276 DBusMessage *message;
1278 DBusMessageIter iter;
1280 _dbus_return_val_if_fail (reply_to != NULL, NULL);
1281 _dbus_return_val_if_fail (error_name != NULL, NULL);
1283 sender = get_string_field (reply_to,
1284 DBUS_HEADER_FIELD_SENDER_SERVICE,
1287 /* sender may be NULL for non-message-bus case or
1288 * when the message bus is dealing with an unregistered
1291 message = dbus_message_new_empty_header ();
1292 if (message == NULL)
1295 if (!dbus_message_create_header (message,
1296 DBUS_MESSAGE_TYPE_ERROR,
1297 sender, NULL, NULL, NULL, error_name))
1299 dbus_message_unref (message);
1303 if (!dbus_message_set_reply_serial (message,
1304 dbus_message_get_serial (reply_to)))
1306 dbus_message_unref (message);
1310 if (error_message != NULL)
1312 dbus_message_append_iter_init (message, &iter);
1313 if (!dbus_message_iter_append_string (&iter, error_message))
1315 dbus_message_unref (message);
1324 * Creates a new message that is an exact replica of the message
1325 * specified, except that its refcount is set to 1.
1327 * @param message the message.
1328 * @returns the new message.
1331 dbus_message_copy (const DBusMessage *message)
1333 DBusMessage *retval;
1336 _dbus_return_val_if_fail (message != NULL, NULL);
1338 retval = dbus_new0 (DBusMessage, 1);
1342 retval->refcount.value = 1;
1343 retval->byte_order = message->byte_order;
1344 retval->client_serial = message->client_serial;
1345 retval->reply_serial = message->reply_serial;
1346 retval->header_padding = message->header_padding;
1347 retval->locked = FALSE;
1349 if (!_dbus_string_init (&retval->header))
1355 if (!_dbus_string_init (&retval->body))
1357 _dbus_string_free (&retval->header);
1362 if (!_dbus_string_copy (&message->header, 0,
1363 &retval->header, 0))
1365 _dbus_string_free (&retval->header);
1366 _dbus_string_free (&retval->body);
1372 if (!_dbus_string_copy (&message->body, 0,
1375 _dbus_string_free (&retval->header);
1376 _dbus_string_free (&retval->body);
1382 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
1384 retval->header_fields[i] = message->header_fields[i];
1392 * Increments the reference count of a DBusMessage.
1394 * @param message The message
1395 * @see dbus_message_unref
1398 dbus_message_ref (DBusMessage *message)
1400 dbus_int32_t old_refcount;
1402 _dbus_return_if_fail (message != NULL);
1404 old_refcount = _dbus_atomic_inc (&message->refcount);
1405 _dbus_assert (old_refcount >= 1);
1409 free_size_counter (void *element,
1412 DBusCounter *counter = element;
1413 DBusMessage *message = data;
1415 _dbus_counter_adjust (counter, - message->size_counter_delta);
1417 _dbus_counter_unref (counter);
1421 * Decrements the reference count of a DBusMessage.
1423 * @param message The message
1424 * @see dbus_message_ref
1427 dbus_message_unref (DBusMessage *message)
1429 dbus_int32_t old_refcount;
1431 _dbus_return_if_fail (message != NULL);
1433 old_refcount = _dbus_atomic_dec (&message->refcount);
1435 _dbus_assert (old_refcount >= 0);
1437 if (old_refcount == 1)
1439 /* This calls application callbacks! */
1440 _dbus_data_slot_list_free (&message->slot_list);
1442 _dbus_list_foreach (&message->size_counters,
1443 free_size_counter, message);
1444 _dbus_list_clear (&message->size_counters);
1446 _dbus_string_free (&message->header);
1447 _dbus_string_free (&message->body);
1449 dbus_free (message);
1454 * Gets the type of a message. Types include
1455 * DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_METHOD_RETURN,
1456 * DBUS_MESSAGE_TYPE_ERROR, DBUS_MESSAGE_TYPE_SIGNAL, but other types
1457 * are allowed and all code must silently ignore messages of unknown
1458 * type. DBUS_MESSAGE_TYPE_INVALID will never be returned, however.
1461 * @param message the message
1462 * @returns the type of the message
1465 dbus_message_get_type (DBusMessage *message)
1469 type = _dbus_string_get_byte (&message->header, 1);
1470 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
1476 * Sets the object path this message is being sent to (for
1477 * DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a signal is being
1478 * emitted from (for DBUS_MESSAGE_TYPE_SIGNAL).
1480 * @param message the message
1481 * @param object_path the path
1482 * @returns #FALSE if not enough memory
1485 dbus_message_set_path (DBusMessage *message,
1486 const char *object_path)
1488 _dbus_return_val_if_fail (message != NULL, FALSE);
1489 _dbus_return_val_if_fail (!message->locked, FALSE);
1491 if (object_path == NULL)
1493 delete_field (message, DBUS_HEADER_FIELD_PATH);
1498 return set_string_field (message,
1499 DBUS_HEADER_FIELD_PATH,
1500 DBUS_TYPE_OBJECT_PATH,
1506 * Gets the object path this message is being sent to
1507 * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
1508 * from (for DBUS_MESSAGE_TYPE_SIGNAL).
1510 * @param message the message
1511 * @returns the path (should not be freed)
1514 dbus_message_get_path (DBusMessage *message)
1516 _dbus_return_val_if_fail (message != NULL, NULL);
1518 return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
1522 * Gets the object path this message is being sent to
1523 * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
1524 * from (for DBUS_MESSAGE_TYPE_SIGNAL) in a decomposed
1525 * format (one array element per path component).
1526 * Free the returned array with dbus_free_string_array().
1528 * An empty but non-NULL path array means the path "/".
1529 * So the path "/foo/bar" becomes { "foo", "bar", NULL }
1530 * and the path "/" becomes { NULL }.
1532 * @param message the message
1533 * @param path place to store allocated array of path components; #NULL set here if no path field exists
1534 * @returns #FALSE if no memory to allocate the array
1537 dbus_message_get_path_decomposed (DBusMessage *message,
1540 _dbus_return_val_if_fail (message != NULL, FALSE);
1541 _dbus_return_val_if_fail (path != NULL, FALSE);
1543 return get_path_field_decomposed (message,
1544 DBUS_HEADER_FIELD_PATH,
1549 * Sets the interface this message is being sent to
1550 * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or
1551 * the interface a signal is being emitted from
1552 * (for DBUS_MESSAGE_TYPE_SIGNAL).
1554 * @param message the message
1555 * @param interface the interface
1556 * @returns #FALSE if not enough memory
1559 dbus_message_set_interface (DBusMessage *message,
1560 const char *interface)
1562 _dbus_return_val_if_fail (message != NULL, FALSE);
1563 _dbus_return_val_if_fail (!message->locked, FALSE);
1565 if (interface == NULL)
1567 delete_field (message, DBUS_HEADER_FIELD_INTERFACE);
1572 return set_string_field (message,
1573 DBUS_HEADER_FIELD_INTERFACE,
1580 * Gets the interface this message is being sent to
1581 * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
1582 * from (for DBUS_MESSAGE_TYPE_SIGNAL).
1583 * The interface name is fully-qualified (namespaced).
1585 * @param message the message
1586 * @returns the message interface (should not be freed)
1589 dbus_message_get_interface (DBusMessage *message)
1591 _dbus_return_val_if_fail (message != NULL, NULL);
1593 return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
1597 * Sets the interface member being invoked
1598 * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
1599 * (DBUS_MESSAGE_TYPE_SIGNAL).
1600 * The interface name is fully-qualified (namespaced).
1602 * @param message the message
1603 * @param member the member
1604 * @returns #FALSE if not enough memory
1607 dbus_message_set_member (DBusMessage *message,
1610 _dbus_return_val_if_fail (message != NULL, FALSE);
1611 _dbus_return_val_if_fail (!message->locked, FALSE);
1615 delete_field (message, DBUS_HEADER_FIELD_MEMBER);
1620 return set_string_field (message,
1621 DBUS_HEADER_FIELD_MEMBER,
1628 * Gets the interface member being invoked
1629 * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
1630 * (DBUS_MESSAGE_TYPE_SIGNAL).
1632 * @param message the message
1633 * @returns the member name (should not be freed)
1636 dbus_message_get_member (DBusMessage *message)
1638 _dbus_return_val_if_fail (message != NULL, NULL);
1640 return get_string_field (message,
1641 DBUS_HEADER_FIELD_MEMBER,
1646 * Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
1647 * The name is fully-qualified (namespaced).
1649 * @param message the message
1650 * @param error_name the name
1651 * @returns #FALSE if not enough memory
1654 dbus_message_set_error_name (DBusMessage *message,
1655 const char *error_name)
1657 _dbus_return_val_if_fail (message != NULL, FALSE);
1658 _dbus_return_val_if_fail (!message->locked, FALSE);
1660 if (error_name == NULL)
1662 delete_field (message, DBUS_HEADER_FIELD_ERROR_NAME);
1667 return set_string_field (message,
1668 DBUS_HEADER_FIELD_ERROR_NAME,
1675 * Gets the error name (DBUS_MESSAGE_TYPE_ERROR only).
1677 * @param message the message
1678 * @returns the error name (should not be freed)
1681 dbus_message_get_error_name (DBusMessage *message)
1683 _dbus_return_val_if_fail (message != NULL, NULL);
1685 return get_string_field (message,
1686 DBUS_HEADER_FIELD_ERROR_NAME,
1691 * Sets the message's destination service.
1693 * @param message the message
1694 * @param destination the destination service name
1695 * @returns #FALSE if not enough memory
1698 dbus_message_set_destination (DBusMessage *message,
1699 const char *destination)
1701 _dbus_return_val_if_fail (message != NULL, FALSE);
1702 _dbus_return_val_if_fail (!message->locked, FALSE);
1704 if (destination == NULL)
1706 delete_field (message, DBUS_HEADER_FIELD_SERVICE);
1711 return set_string_field (message,
1712 DBUS_HEADER_FIELD_SERVICE,
1719 * Gets the destination service of a message.
1721 * @param message the message
1722 * @returns the message destination service (should not be freed)
1725 dbus_message_get_destination (DBusMessage *message)
1727 _dbus_return_val_if_fail (message != NULL, NULL);
1729 return get_string_field (message,
1730 DBUS_HEADER_FIELD_SERVICE,
1735 * Appends fields to a message given a variable argument list. The
1736 * variable argument list should contain the type of the argument
1737 * followed by the value to add. Array values are specified by an int
1738 * typecode followed by a pointer to the array followed by an int
1739 * giving the length of the array. The argument list must be
1740 * terminated with #DBUS_TYPE_INVALID.
1742 * This function doesn't support dicts or non-fundamental arrays.
1744 * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64
1745 * only if #DBUS_HAVE_INT64 is defined.
1747 * @param message the message
1748 * @param first_arg_type type of the first argument
1749 * @param ... value of first argument, list of additional type-value pairs
1750 * @returns #TRUE on success
1753 dbus_message_append_args (DBusMessage *message,
1760 _dbus_return_val_if_fail (message != NULL, FALSE);
1762 va_start (var_args, first_arg_type);
1763 retval = dbus_message_append_args_valist (message,
1772 * This function takes a va_list for use by language bindings.
1773 * It's otherwise the same as dbus_message_append_args().
1775 * @todo: Shouldn't this function clean up the changes to the message
1776 * on failures? (Yes)
1778 * @see dbus_message_append_args.
1779 * @param message the message
1780 * @param first_arg_type type of first argument
1781 * @param var_args value of first argument, then list of type/value pairs
1782 * @returns #TRUE on success
1785 dbus_message_append_args_valist (DBusMessage *message,
1790 DBusMessageIter iter;
1792 _dbus_return_val_if_fail (message != NULL, FALSE);
1794 old_len = _dbus_string_get_length (&message->body);
1796 type = first_arg_type;
1798 dbus_message_append_iter_init (message, &iter);
1805 if (!dbus_message_iter_append_nil (&iter))
1808 case DBUS_TYPE_BOOLEAN:
1809 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
1812 case DBUS_TYPE_INT32:
1813 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
1816 case DBUS_TYPE_UINT32:
1817 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
1820 #ifdef DBUS_HAVE_INT64
1821 case DBUS_TYPE_INT64:
1822 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
1825 case DBUS_TYPE_UINT64:
1826 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
1829 #endif /* DBUS_HAVE_INT64 */
1830 case DBUS_TYPE_DOUBLE:
1831 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
1834 case DBUS_TYPE_STRING:
1835 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
1838 case DBUS_TYPE_NAMED:
1841 unsigned char *data;
1844 name = va_arg (var_args, const char *);
1845 data = va_arg (var_args, unsigned char *);
1846 len = va_arg (var_args, int);
1848 if (!dbus_message_iter_append_named (&iter, name, data, len))
1852 case DBUS_TYPE_ARRAY:
1857 type = va_arg (var_args, int);
1858 data = va_arg (var_args, void *);
1859 len = va_arg (var_args, int);
1863 case DBUS_TYPE_BYTE:
1864 if (!dbus_message_iter_append_byte_array (&iter, (unsigned char *)data, len))
1867 case DBUS_TYPE_BOOLEAN:
1868 if (!dbus_message_iter_append_boolean_array (&iter, (unsigned char *)data, len))
1871 case DBUS_TYPE_INT32:
1872 if (!dbus_message_iter_append_int32_array (&iter, (dbus_int32_t *)data, len))
1875 case DBUS_TYPE_UINT32:
1876 if (!dbus_message_iter_append_uint32_array (&iter, (dbus_uint32_t *)data, len))
1879 #ifdef DBUS_HAVE_INT64
1880 case DBUS_TYPE_INT64:
1881 if (!dbus_message_iter_append_int64_array (&iter, (dbus_int64_t *)data, len))
1884 case DBUS_TYPE_UINT64:
1885 if (!dbus_message_iter_append_uint64_array (&iter, (dbus_uint64_t *)data, len))
1888 #endif /* DBUS_HAVE_INT64 */
1889 case DBUS_TYPE_DOUBLE:
1890 if (!dbus_message_iter_append_double_array (&iter, (double *)data, len))
1893 case DBUS_TYPE_STRING:
1894 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
1898 case DBUS_TYPE_ARRAY:
1899 case DBUS_TYPE_NAMED:
1900 case DBUS_TYPE_DICT:
1901 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
1904 _dbus_warn ("Unknown field type %d\n", type);
1910 case DBUS_TYPE_DICT:
1911 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
1914 _dbus_warn ("Unknown field type %d\n", type);
1918 type = va_arg (var_args, int);
1929 * Gets arguments from a message given a variable argument list.
1930 * The variable argument list should contain the type of the
1931 * argumen followed by a pointer to where the value should be
1932 * stored. The list is terminated with #DBUS_TYPE_INVALID.
1934 * @param message the message
1935 * @param error error to be filled in on failure
1936 * @param first_arg_type the first argument type
1937 * @param ... location for first argument value, then list of type-location pairs
1938 * @returns #FALSE if the error was set
1941 dbus_message_get_args (DBusMessage *message,
1949 _dbus_return_val_if_fail (message != NULL, FALSE);
1950 _dbus_return_val_if_error_is_set (error, FALSE);
1952 va_start (var_args, first_arg_type);
1953 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
1960 * This function takes a va_list for use by language bindings
1962 * @todo We need to free the argument data when an error occurs.
1964 * @see dbus_message_get_args
1965 * @param message the message
1966 * @param error error to be filled in
1967 * @param first_arg_type type of the first argument
1968 * @param var_args return location for first argument, followed by list of type/location pairs
1969 * @returns #FALSE if error was set
1972 dbus_message_get_args_valist (DBusMessage *message,
1977 DBusMessageIter iter;
1979 _dbus_return_val_if_fail (message != NULL, FALSE);
1980 _dbus_return_val_if_error_is_set (error, FALSE);
1982 dbus_message_iter_init (message, &iter);
1983 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
1987 * Gets arguments from a message iterator given a variable argument list.
1988 * The variable argument list should contain the type of the
1989 * argumen followed by a pointer to where the value should be
1990 * stored. The list is terminated with 0.
1992 * @param iter the message iterator
1993 * @param error error to be filled in on failure
1994 * @param first_arg_type the first argument type
1995 * @param ... location for first argument value, then list of type-location pairs
1996 * @returns #FALSE if the error was set
1999 dbus_message_iter_get_args (DBusMessageIter *iter,
2007 _dbus_return_val_if_fail (iter != NULL, FALSE);
2008 _dbus_return_val_if_error_is_set (error, FALSE);
2010 va_start (var_args, first_arg_type);
2011 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
2018 * This function takes a va_list for use by language bindings
2020 * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64
2021 * only if #DBUS_HAVE_INT64 is defined.
2023 * @todo this function (or some lower-level non-convenience function)
2024 * needs better error handling; should allow the application to
2025 * distinguish between out of memory, and bad data from the remote
2026 * app. It also needs to not leak a bunch of args when it gets
2027 * to the arg that's bad, as that would be a security hole
2028 * (allow one app to force another to leak memory)
2030 * @todo We need to free the argument data when an error occurs.
2032 * @see dbus_message_get_args
2033 * @param iter the message iter
2034 * @param error error to be filled in
2035 * @param first_arg_type type of the first argument
2036 * @param var_args return location for first argument, followed by list of type/location pairs
2037 * @returns #FALSE if error was set
2040 dbus_message_iter_get_args_valist (DBusMessageIter *iter,
2045 int spec_type, msg_type, i;
2048 _dbus_return_val_if_fail (iter != NULL, FALSE);
2049 _dbus_return_val_if_error_is_set (error, FALSE);
2053 spec_type = first_arg_type;
2056 while (spec_type != 0)
2058 msg_type = dbus_message_iter_get_arg_type (iter);
2060 if (msg_type != spec_type)
2062 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2063 "Argument %d is specified to be of type \"%s\", but "
2064 "is actually of type \"%s\"\n", i,
2065 _dbus_type_to_string (spec_type),
2066 _dbus_type_to_string (msg_type));
2075 case DBUS_TYPE_BYTE:
2079 ptr = va_arg (var_args, unsigned char *);
2081 *ptr = dbus_message_iter_get_byte (iter);
2084 case DBUS_TYPE_BOOLEAN:
2088 ptr = va_arg (var_args, dbus_bool_t *);
2090 *ptr = dbus_message_iter_get_boolean (iter);
2093 case DBUS_TYPE_INT32:
2097 ptr = va_arg (var_args, dbus_int32_t *);
2099 *ptr = dbus_message_iter_get_int32 (iter);
2102 case DBUS_TYPE_UINT32:
2106 ptr = va_arg (var_args, dbus_uint32_t *);
2108 *ptr = dbus_message_iter_get_uint32 (iter);
2111 #ifdef DBUS_HAVE_INT64
2112 case DBUS_TYPE_INT64:
2116 ptr = va_arg (var_args, dbus_int64_t *);
2118 *ptr = dbus_message_iter_get_int64 (iter);
2121 case DBUS_TYPE_UINT64:
2125 ptr = va_arg (var_args, dbus_uint64_t *);
2127 *ptr = dbus_message_iter_get_uint64 (iter);
2130 #endif /* DBUS_HAVE_INT64 */
2132 case DBUS_TYPE_DOUBLE:
2136 ptr = va_arg (var_args, double *);
2138 *ptr = dbus_message_iter_get_double (iter);
2142 case DBUS_TYPE_STRING:
2146 ptr = va_arg (var_args, char **);
2148 *ptr = dbus_message_iter_get_string (iter);
2152 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2159 case DBUS_TYPE_NAMED:
2162 unsigned char **data;
2165 name = va_arg (var_args, char **);
2166 data = va_arg (var_args, unsigned char **);
2167 len = va_arg (var_args, int *);
2169 if (!dbus_message_iter_get_named (iter, name, data, len))
2171 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2176 case DBUS_TYPE_ARRAY:
2181 type = va_arg (var_args, int);
2182 data = va_arg (var_args, void *);
2183 len = va_arg (var_args, int *);
2185 if (dbus_message_iter_get_array_type (iter) != type)
2187 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2188 "Argument %d is specified to be of type \"array of %s\", but "
2189 "is actually of type \"array of %s\"\n", i,
2190 _dbus_type_to_string (type),
2191 _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
2197 case DBUS_TYPE_BYTE:
2198 if (!dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len))
2200 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2204 case DBUS_TYPE_BOOLEAN:
2205 if (!dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len))
2207 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2211 case DBUS_TYPE_INT32:
2212 if (!dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len))
2214 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2218 case DBUS_TYPE_UINT32:
2219 if (!dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len))
2221 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2225 #ifdef DBUS_HAVE_INT64
2226 case DBUS_TYPE_INT64:
2227 if (!dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len))
2229 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2233 case DBUS_TYPE_UINT64:
2234 if (!dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len))
2236 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2240 #endif /* DBUS_HAVE_INT64 */
2241 case DBUS_TYPE_DOUBLE:
2242 if (!dbus_message_iter_get_double_array (iter, (double **)data, len))
2244 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2248 case DBUS_TYPE_STRING:
2249 if (!dbus_message_iter_get_string_array (iter, (char ***)data, len))
2251 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2256 case DBUS_TYPE_ARRAY:
2257 case DBUS_TYPE_NAMED:
2258 case DBUS_TYPE_DICT:
2259 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
2260 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
2263 _dbus_warn ("Unknown field type %d\n", type);
2264 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
2269 case DBUS_TYPE_DICT:
2270 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
2271 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
2274 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
2275 _dbus_warn ("Unknown field type %d\n", spec_type);
2279 spec_type = va_arg (var_args, int);
2280 if (spec_type != 0 && !dbus_message_iter_next (iter))
2282 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2283 "Message has only %d arguments, but more were expected", i);
2299 * Initializes a DBusMessageIter representing the arguments of the
2300 * message passed in.
2302 * @param message the message
2303 * @param iter pointer to an iterator to initialize
2306 dbus_message_iter_init (DBusMessage *message,
2307 DBusMessageIter *iter)
2309 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2311 _dbus_return_if_fail (message != NULL);
2312 _dbus_return_if_fail (iter != NULL);
2314 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2316 real->message = message;
2317 real->parent_iter = NULL;
2318 real->changed_stamp = message->changed_stamp;
2320 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
2322 real->end = _dbus_string_get_length (&message->body);
2324 real->container_start = 0;
2325 real->container_length_pos = 0;
2326 real->wrote_dict_key = 0;
2327 real->array_type_pos = 0;
2330 #ifndef DBUS_DISABLE_CHECKS
2332 dbus_message_iter_check (DBusMessageRealIter *iter)
2336 _dbus_warn ("dbus iterator check failed: iterator is NULL\n");
2340 if (iter->changed_stamp != iter->message->changed_stamp)
2342 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n");
2346 if (iter->pos < 0 || iter->pos > iter->end)
2348 _dbus_warn ("dbus iterator check failed: invalid position\n");
2354 #endif /* DBUS_DISABLE_CHECKS */
2357 skip_array_type (DBusMessageRealIter *iter, int pos)
2363 data = _dbus_string_get_const_data_len (&iter->message->body,
2366 while (*data == DBUS_TYPE_ARRAY);
2372 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
2379 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
2380 data = _dbus_string_get_const_data_len (&iter->message->body,
2382 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
2385 *type = DBUS_TYPE_INVALID;
2387 return skip_array_type (iter, iter->pos);
2389 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
2390 data = _dbus_string_get_const_data_len (&iter->message->body,
2391 iter->array_type_pos, 1);
2392 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
2395 *type = DBUS_TYPE_INVALID;
2399 case DBUS_MESSAGE_ITER_TYPE_DICT:
2400 /* Get the length of the string */
2401 len = _dbus_demarshal_uint32 (&iter->message->body,
2402 iter->message->byte_order,
2404 pos = pos + len + 1;
2406 data = _dbus_string_get_const_data_len (&iter->message->body,
2408 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
2411 *type = DBUS_TYPE_INVALID;
2413 return skip_array_type (iter, pos);
2416 _dbus_assert_not_reached ("Invalid iter type");
2419 *type = DBUS_TYPE_INVALID;
2425 * Checks if an iterator has any more fields.
2427 * @param iter the message iter
2428 * @returns #TRUE if there are more fields
2432 dbus_message_iter_has_next (DBusMessageIter *iter)
2434 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2438 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2440 if (real->pos >= real->end)
2443 pos = dbus_message_iter_get_data_start (real, &type);
2445 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
2446 real->message->byte_order,
2447 type, pos, &end_pos))
2450 if (end_pos >= real->end)
2457 * Moves the iterator to the next field.
2459 * @param iter The message iter
2460 * @returns #TRUE if the iterator was moved to the next field
2463 dbus_message_iter_next (DBusMessageIter *iter)
2465 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2469 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2471 pos = dbus_message_iter_get_data_start (real, &type);
2473 if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
2474 real->message->byte_order,
2475 type, pos, &end_pos))
2478 if (end_pos >= real->end)
2481 real->pos = end_pos;
2487 * Returns the argument type of the argument that the
2488 * message iterator points at.
2490 * @param iter the message iter
2491 * @returns the field type
2494 dbus_message_iter_get_arg_type (DBusMessageIter *iter)
2496 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2499 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2501 if (real->pos >= real->end)
2502 return DBUS_TYPE_INVALID;
2504 pos = dbus_message_iter_get_data_start (real, &type);
2510 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
2513 int _array_type_pos;
2518 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
2519 _array_type_pos = iter->pos + 1;
2521 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
2522 _array_type_pos = iter->array_type_pos + 1;
2524 case DBUS_MESSAGE_ITER_TYPE_DICT:
2525 /* Get the length of the string */
2526 len = _dbus_demarshal_uint32 (&iter->message->body,
2527 iter->message->byte_order,
2529 pos = pos + len + 1;
2530 data = _dbus_string_get_const_data_len (&iter->message->body,
2532 _array_type_pos = pos + 1;
2535 _dbus_assert_not_reached ("wrong iter type");
2536 return DBUS_TYPE_INVALID;
2539 if (array_type_pos != NULL)
2540 *array_type_pos = _array_type_pos;
2542 data = _dbus_string_get_const_data_len (&iter->message->body,
2543 _array_type_pos, 1);
2544 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
2547 return DBUS_TYPE_INVALID;
2552 * Returns the element type of the array that the
2553 * message iterator points at. Note that you need
2554 * to check that the iterator points to an array
2555 * prior to using this function.
2557 * @param iter the message iter
2558 * @returns the field type
2561 dbus_message_iter_get_array_type (DBusMessageIter *iter)
2563 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2566 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2568 if (real->pos >= real->end)
2569 return DBUS_TYPE_INVALID;
2571 pos = dbus_message_iter_get_data_start (real, &type);
2573 _dbus_assert (type == DBUS_TYPE_ARRAY);
2575 return iter_get_array_type (real, NULL);
2580 * Returns the string value that an iterator may point to.
2581 * Note that you need to check that the iterator points to
2582 * a string value before using this function.
2584 * @see dbus_message_iter_get_arg_type
2585 * @param iter the message iter
2586 * @returns the string
2589 dbus_message_iter_get_string (DBusMessageIter *iter)
2591 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2594 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
2596 pos = dbus_message_iter_get_data_start (real, &type);
2598 _dbus_assert (type == DBUS_TYPE_STRING);
2600 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
2605 * Returns the name and data from a named type that an
2606 * iterator may point to. Note that you need to check that
2607 * the iterator points to a named type before using this
2610 * @see dbus_message_iter_get_arg_type
2611 * @param iter the message iter
2612 * @param name return location for the name
2613 * @param value return location for data
2614 * @param len return location for length of data
2615 * @returns TRUE if get succeed
2619 dbus_message_iter_get_named (DBusMessageIter *iter,
2621 unsigned char **value,
2624 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_NAMED);
2634 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
2640 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
2641 pos, NULL, value, len))
2653 * Returns the byte value that an iterator may point to.
2654 * Note that you need to check that the iterator points to
2655 * a byte value before using this function.
2657 * @see dbus_message_iter_get_arg_type
2658 * @param iter the message iter
2659 * @returns the byte value
2662 dbus_message_iter_get_byte (DBusMessageIter *iter)
2664 unsigned char value;
2665 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2668 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2670 pos = dbus_message_iter_get_data_start (real, &type);
2672 _dbus_assert (type == DBUS_TYPE_BYTE);
2674 value = _dbus_string_get_byte (&real->message->body, pos);
2681 * Returns the boolean value that an iterator may point to.
2682 * Note that you need to check that the iterator points to
2683 * a boolean value before using this function.
2685 * @see dbus_message_iter_get_arg_type
2686 * @param iter the message iter
2687 * @returns the boolean value
2690 dbus_message_iter_get_boolean (DBusMessageIter *iter)
2692 unsigned char value;
2693 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2696 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2698 pos = dbus_message_iter_get_data_start (real, &type);
2700 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
2702 value = _dbus_string_get_byte (&real->message->body, pos);
2708 * Returns the 32 bit signed integer value that an iterator may point to.
2709 * Note that you need to check that the iterator points to
2710 * a 32-bit integer value before using this function.
2712 * @see dbus_message_iter_get_arg_type
2713 * @param iter the message iter
2714 * @returns the integer
2717 dbus_message_iter_get_int32 (DBusMessageIter *iter)
2719 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2722 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2724 pos = dbus_message_iter_get_data_start (real, &type);
2726 _dbus_assert (type == DBUS_TYPE_INT32);
2728 return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order,
2733 * Returns the 32 bit unsigned integer value that an iterator may point to.
2734 * Note that you need to check that the iterator points to
2735 * a 32-bit unsigned integer value before using this function.
2737 * @see dbus_message_iter_get_arg_type
2738 * @param iter the message iter
2739 * @returns the integer
2742 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
2744 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2747 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2749 pos = dbus_message_iter_get_data_start (real, &type);
2751 _dbus_assert (type == DBUS_TYPE_UINT32);
2753 return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
2757 #ifdef DBUS_HAVE_INT64
2760 * Returns the 64 bit signed integer value that an iterator may point
2761 * to. Note that you need to check that the iterator points to a
2762 * 64-bit integer value before using this function.
2764 * This function only exists if #DBUS_HAVE_INT64 is defined.
2766 * @see dbus_message_iter_get_arg_type
2767 * @param iter the message iter
2768 * @returns the integer
2771 dbus_message_iter_get_int64 (DBusMessageIter *iter)
2773 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2776 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2778 pos = dbus_message_iter_get_data_start (real, &type);
2780 _dbus_assert (type == DBUS_TYPE_INT64);
2782 return _dbus_demarshal_int64 (&real->message->body, real->message->byte_order,
2787 * Returns the 64 bit unsigned integer value that an iterator may point to.
2788 * Note that you need to check that the iterator points to
2789 * a 64-bit unsigned integer value before using this function.
2791 * This function only exists if #DBUS_HAVE_INT64 is defined.
2793 * @see dbus_message_iter_get_arg_type
2794 * @param iter the message iter
2795 * @returns the integer
2798 dbus_message_iter_get_uint64 (DBusMessageIter *iter)
2800 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2803 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
2805 pos = dbus_message_iter_get_data_start (real, &type);
2807 _dbus_assert (type == DBUS_TYPE_UINT64);
2809 return _dbus_demarshal_uint64 (&real->message->body, real->message->byte_order,
2813 #endif /* DBUS_HAVE_INT64 */
2816 * Returns the double value that an iterator may point to.
2817 * Note that you need to check that the iterator points to
2818 * a string value before using this function.
2820 * @see dbus_message_iter_get_arg_type
2821 * @param iter the message iter
2822 * @returns the double
2825 dbus_message_iter_get_double (DBusMessageIter *iter)
2827 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2830 _dbus_return_val_if_fail (dbus_message_iter_check (real), 0.0);
2832 pos = dbus_message_iter_get_data_start (real, &type);
2834 _dbus_assert (type == DBUS_TYPE_DOUBLE);
2836 return _dbus_demarshal_double (&real->message->body, real->message->byte_order,
2841 * Initializes an iterator for the array that the iterator
2842 * may point to. Note that you need to check that the iterator
2843 * points to an array prior to using this function.
2845 * The array element type is returned in array_type, and the array
2846 * iterator can only be used to get that type of data.
2848 * @param iter the iterator
2849 * @param array_iter pointer to an iterator to initialize
2850 * @param array_type gets set to the type of the array elements
2851 * @returns #TRUE on success
2854 dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
2855 DBusMessageIter *array_iter,
2858 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2859 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
2860 int type, pos, len_pos, len, array_type_pos;
2863 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2865 pos = dbus_message_iter_get_data_start (real, &type);
2867 _dbus_assert (type == DBUS_TYPE_ARRAY);
2869 _array_type = iter_get_array_type (real, &array_type_pos);
2871 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
2872 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
2875 array_real->parent_iter = real;
2876 array_real->message = real->message;
2877 array_real->changed_stamp = real->message->changed_stamp;
2879 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
2880 array_real->pos = pos;
2881 array_real->end = pos + len;
2883 array_real->container_start = pos;
2884 array_real->container_length_pos = len_pos;
2885 array_real->wrote_dict_key = 0;
2886 array_real->array_type_pos = array_type_pos;
2887 array_real->array_type_done = TRUE;
2889 if (array_type != NULL)
2890 *array_type = _array_type;
2897 * Initializes an iterator for the dict that the iterator
2898 * may point to. Note that you need to check that the iterator
2899 * points to a dict prior to using this function.
2901 * @param iter the iterator
2902 * @param dict_iter pointer to an iterator to initialize
2903 * @returns #TRUE on success
2906 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
2907 DBusMessageIter *dict_iter)
2909 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2910 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
2911 int type, pos, len_pos, len;
2913 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2915 pos = dbus_message_iter_get_data_start (real, &type);
2917 _dbus_assert (type == DBUS_TYPE_DICT);
2919 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
2920 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
2923 dict_real->parent_iter = real;
2924 dict_real->message = real->message;
2925 dict_real->changed_stamp = real->message->changed_stamp;
2927 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
2928 dict_real->pos = pos;
2929 dict_real->end = pos + len;
2931 dict_real->container_start = pos;
2932 dict_real->container_length_pos = len_pos;
2933 dict_real->wrote_dict_key = 0;
2939 * Returns the byte array that the iterator may point to.
2940 * Note that you need to check that the iterator points
2941 * to a byte array prior to using this function.
2943 * @param iter the iterator
2944 * @param value return location for array values
2945 * @param len return location for length of byte array
2946 * @returns #TRUE on success
2949 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
2950 unsigned char **value,
2953 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2956 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2958 pos = dbus_message_iter_get_data_start (real, &type);
2960 _dbus_assert (type == DBUS_TYPE_ARRAY);
2962 type = iter_get_array_type (real, NULL);
2964 _dbus_assert (type == DBUS_TYPE_BYTE);
2966 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
2967 pos, NULL, value, len))
2974 * Returns the boolean array that the iterator may point to. Note that
2975 * you need to check that the iterator points to an array of the
2976 * correct type prior to using this function.
2978 * @param iter the iterator
2979 * @param value return location for the array
2980 * @param len return location for the array length
2981 * @returns #TRUE on success
2984 dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
2985 unsigned char **value,
2988 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2991 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
2993 pos = dbus_message_iter_get_data_start (real, &type);
2995 _dbus_assert (type == DBUS_TYPE_ARRAY);
2997 type = iter_get_array_type (real, NULL);
2999 _dbus_assert (type == DBUS_TYPE_BOOLEAN);
3001 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
3002 pos, NULL, value, len))
3009 * Returns the 32 bit signed integer array that the iterator may point
3010 * to. Note that you need to check that the iterator points to an
3011 * array of the correct type prior to using this function.
3013 * @param iter the iterator
3014 * @param value return location for the array
3015 * @param len return location for the array length
3016 * @returns #TRUE on success
3019 dbus_message_iter_get_int32_array (DBusMessageIter *iter,
3020 dbus_int32_t **value,
3023 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3026 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
3028 pos = dbus_message_iter_get_data_start (real, &type);
3030 _dbus_assert (type == DBUS_TYPE_ARRAY);
3032 type = iter_get_array_type (real, NULL);
3034 _dbus_assert (type == DBUS_TYPE_INT32);
3036 if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order,
3037 pos, NULL, value, len))
3044 * Returns the 32 bit unsigned integer array that the iterator may point
3045 * to. Note that you need to check that the iterator points to an
3046 * array of the correct type prior to using this function.
3048 * @param iter the iterator
3049 * @param value return location for the array
3050 * @param len return location for the array length
3051 * @returns #TRUE on success
3054 dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
3055 dbus_uint32_t **value,
3058 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3061 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
3063 pos = dbus_message_iter_get_data_start (real, &type);
3065 _dbus_assert (type == DBUS_TYPE_ARRAY);
3067 type = iter_get_array_type (real, NULL);
3068 _dbus_assert (type == DBUS_TYPE_UINT32);
3070 if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order,
3071 pos, NULL, value, len))
3077 #ifdef DBUS_HAVE_INT64
3080 * Returns the 64 bit signed integer array that the iterator may point
3081 * to. Note that you need to check that the iterator points to an
3082 * array of the correct type prior to using this function.
3084 * This function only exists if #DBUS_HAVE_INT64 is defined.
3086 * @param iter the iterator
3087 * @param value return location for the array
3088 * @param len return location for the array length
3089 * @returns #TRUE on success
3092 dbus_message_iter_get_int64_array (DBusMessageIter *iter,
3093 dbus_int64_t **value,
3096 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3099 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
3101 pos = dbus_message_iter_get_data_start (real, &type);
3103 _dbus_assert (type == DBUS_TYPE_ARRAY);
3105 type = iter_get_array_type (real, NULL);
3107 _dbus_assert (type == DBUS_TYPE_INT64);
3109 if (!_dbus_demarshal_int64_array (&real->message->body, real->message->byte_order,
3110 pos, NULL, value, len))
3117 * Returns the 64 bit unsigned integer array that the iterator may point
3118 * to. Note that you need to check that the iterator points to an
3119 * array of the correct type prior to using this function.
3121 * This function only exists if #DBUS_HAVE_INT64 is defined.
3123 * @param iter the iterator
3124 * @param value return location for the array
3125 * @param len return location for the array length
3126 * @returns #TRUE on success
3129 dbus_message_iter_get_uint64_array (DBusMessageIter *iter,
3130 dbus_uint64_t **value,
3133 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3136 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
3138 pos = dbus_message_iter_get_data_start (real, &type);
3140 _dbus_assert (type == DBUS_TYPE_ARRAY);
3142 type = iter_get_array_type (real, NULL);
3143 _dbus_assert (type == DBUS_TYPE_UINT64);
3145 if (!_dbus_demarshal_uint64_array (&real->message->body, real->message->byte_order,
3146 pos, NULL, value, len))
3152 #endif /* DBUS_HAVE_INT64 */
3155 * Returns the double array that the iterator may point to. Note that
3156 * you need to check that the iterator points to an array of the
3157 * correct type prior to using this function.
3159 * @param iter the iterator
3160 * @param value return location for the array
3161 * @param len return location for the array length
3162 * @returns #TRUE on success
3165 dbus_message_iter_get_double_array (DBusMessageIter *iter,
3169 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3172 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
3174 pos = dbus_message_iter_get_data_start (real, &type);
3176 _dbus_assert (type == DBUS_TYPE_ARRAY);
3178 type = iter_get_array_type (real, NULL);
3179 _dbus_assert (type == DBUS_TYPE_DOUBLE);
3181 if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order,
3182 pos, NULL, value, len))
3189 * Returns the string array that the iterator may point to.
3190 * Note that you need to check that the iterator points
3191 * to a byte array prior to using this function.
3193 * The returned value is a #NULL-terminated array of strings.
3194 * Each string is a separate malloc block, and the array
3195 * itself is a malloc block. You can free this type of
3196 * string array with dbus_free_string_array().
3198 * @param iter the iterator
3199 * @param value return location for string values
3200 * @param len return location for length of byte array
3201 * @returns #TRUE on success
3204 dbus_message_iter_get_string_array (DBusMessageIter *iter,
3208 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3211 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
3213 pos = dbus_message_iter_get_data_start (real, &type);
3215 _dbus_assert (type == DBUS_TYPE_ARRAY);
3217 type = iter_get_array_type (real, NULL);
3218 _dbus_assert (type == DBUS_TYPE_STRING);
3220 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
3221 pos, NULL, value, len))
3228 * Returns the key name fot the dict entry that an iterator
3229 * may point to. Note that you need to check that the iterator
3230 * points to a dict entry before using this function.
3232 * @see dbus_message_iter_init_dict_iterator
3233 * @param iter the message iter
3234 * @returns the key name
3237 dbus_message_iter_get_dict_key (DBusMessageIter *iter)
3239 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3241 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
3243 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
3245 return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
3250 * Initializes a DBusMessageIter pointing to the end of the
3251 * message. This iterator can be used to append data to the
3254 * @param message the message
3255 * @param iter pointer to an iterator to initialize
3258 dbus_message_append_iter_init (DBusMessage *message,
3259 DBusMessageIter *iter)
3261 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3263 _dbus_return_if_fail (message != NULL);
3264 _dbus_return_if_fail (iter != NULL);
3266 real->message = message;
3267 real->parent_iter = NULL;
3268 real->changed_stamp = message->changed_stamp;
3270 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
3271 real->end = _dbus_string_get_length (&real->message->body);
3272 real->pos = real->end;
3274 real->container_length_pos = 0;
3275 real->wrote_dict_key = 0;
3278 #ifndef DBUS_DISABLE_CHECKS
3280 dbus_message_iter_append_check (DBusMessageRealIter *iter)
3284 _dbus_warn ("dbus iterator check failed: NULL iterator\n");
3288 if (iter->message->locked)
3290 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n");
3294 if (iter->changed_stamp != iter->message->changed_stamp)
3296 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message");
3300 if (iter->pos != iter->end)
3302 _dbus_warn ("dbus iterator check failed: can only append at end of message");
3306 if (iter->pos != _dbus_string_get_length (&iter->message->body))
3308 _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
3314 #endif /* DBUS_DISABLE_CHECKS */
3317 dbus_message_iter_append_type (DBusMessageRealIter *iter,
3323 case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
3324 if (!_dbus_string_append_byte (&iter->message->body, type))
3328 case DBUS_MESSAGE_ITER_TYPE_ARRAY:
3329 data = _dbus_string_get_const_data_len (&iter->message->body,
3330 iter->array_type_pos, 1);
3333 _dbus_warn ("Appended element of wrong type for array\n");
3338 case DBUS_MESSAGE_ITER_TYPE_DICT:
3339 if (!iter->wrote_dict_key)
3341 _dbus_warn ("Appending dict data before key name\n");
3345 if (!_dbus_string_append_byte (&iter->message->body, type))
3351 _dbus_assert_not_reached ("Invalid iter type");
3359 dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
3361 iter->changed_stamp = iter->message->changed_stamp;
3363 /* Set new end of iter */
3364 iter->end = _dbus_string_get_length (&iter->message->body);
3365 iter->pos = iter->end;
3367 /* Set container length */
3368 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
3369 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))
3370 _dbus_marshal_set_uint32 (&iter->message->body,
3371 iter->message->byte_order,
3372 iter->container_length_pos,
3373 iter->end - iter->container_start);
3375 if (iter->parent_iter)
3376 dbus_message_iter_update_after_change (iter->parent_iter);
3380 dbus_message_iter_append_done (DBusMessageRealIter *iter)
3382 iter->message->changed_stamp++;
3383 dbus_message_iter_update_after_change (iter);
3384 iter->wrote_dict_key = FALSE;
3388 * Appends a nil value to the message
3390 * @param iter an iterator pointing to the end of the message
3391 * @returns #TRUE on success
3394 dbus_message_iter_append_nil (DBusMessageIter *iter)
3396 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3398 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3400 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
3403 dbus_message_iter_append_done (real);
3409 * Appends a boolean value to the message
3411 * @param iter an iterator pointing to the end of the message
3412 * @param value the boolean value
3413 * @returns #TRUE on success
3416 dbus_message_iter_append_boolean (DBusMessageIter *iter,
3419 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3421 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3423 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN))
3426 if (!_dbus_string_append_byte (&real->message->body, (value != FALSE)))
3428 _dbus_string_set_length (&real->message->body, real->pos);
3432 dbus_message_iter_append_done (real);
3438 * Appends a byte to the message
3440 * @param iter an iterator pointing to the end of the message
3441 * @param value the byte value
3442 * @returns #TRUE on success
3445 dbus_message_iter_append_byte (DBusMessageIter *iter,
3446 unsigned char value)
3448 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3450 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3452 if (!dbus_message_iter_append_type (real, DBUS_TYPE_BYTE))
3455 if (!_dbus_string_append_byte (&real->message->body, value))
3457 _dbus_string_set_length (&real->message->body, real->pos);
3461 dbus_message_iter_append_done (real);
3468 * Appends a 32 bit signed integer to the message.
3470 * @param iter an iterator pointing to the end of the message
3471 * @param value the integer value
3472 * @returns #TRUE on success
3475 dbus_message_iter_append_int32 (DBusMessageIter *iter,
3478 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3480 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3482 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT32))
3485 if (!_dbus_marshal_int32 (&real->message->body, real->message->byte_order, value))
3487 _dbus_string_set_length (&real->message->body, real->pos);
3491 dbus_message_iter_append_done (real);
3497 * Appends a 32 bit unsigned integer to the message.
3499 * @param iter an iterator pointing to the end of the message
3500 * @param value the integer value
3501 * @returns #TRUE on success
3504 dbus_message_iter_append_uint32 (DBusMessageIter *iter,
3505 dbus_uint32_t value)
3507 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3509 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3511 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT32))
3514 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, value))
3516 _dbus_string_set_length (&real->message->body, real->pos);
3520 dbus_message_iter_append_done (real);
3525 #ifdef DBUS_HAVE_INT64
3528 * Appends a 64 bit signed integer to the message.
3530 * This function only exists if #DBUS_HAVE_INT64 is defined.
3532 * @param iter an iterator pointing to the end of the message
3533 * @param value the integer value
3534 * @returns #TRUE on success
3537 dbus_message_iter_append_int64 (DBusMessageIter *iter,
3540 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3542 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3544 if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT64))
3547 if (!_dbus_marshal_int64 (&real->message->body, real->message->byte_order, value))
3549 _dbus_string_set_length (&real->message->body, real->pos);
3553 dbus_message_iter_append_done (real);
3559 * Appends a 64 bit unsigned integer to the message.
3561 * This function only exists if #DBUS_HAVE_INT64 is defined.
3563 * @param iter an iterator pointing to the end of the message
3564 * @param value the integer value
3565 * @returns #TRUE on success
3568 dbus_message_iter_append_uint64 (DBusMessageIter *iter,
3569 dbus_uint64_t value)
3571 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3573 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3575 if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT64))
3578 if (!_dbus_marshal_uint64 (&real->message->body, real->message->byte_order, value))
3580 _dbus_string_set_length (&real->message->body, real->pos);
3584 dbus_message_iter_append_done (real);
3589 #endif /* DBUS_HAVE_INT64 */
3592 * Appends a double value to the message.
3594 * @param iter an iterator pointing to the end of the message
3595 * @param value the double value
3596 * @returns #TRUE on success
3599 dbus_message_iter_append_double (DBusMessageIter *iter,
3602 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3604 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3606 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DOUBLE))
3609 if (!_dbus_marshal_double (&real->message->body, real->message->byte_order, value))
3611 _dbus_string_set_length (&real->message->body, real->pos);
3615 dbus_message_iter_append_done (real);
3621 * Appends a UTF-8 string to the message.
3623 * @param iter an iterator pointing to the end of the message
3624 * @param value the string
3625 * @returns #TRUE on success
3628 dbus_message_iter_append_string (DBusMessageIter *iter,
3631 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3633 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3635 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
3638 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
3640 _dbus_string_set_length (&real->message->body, real->pos);
3644 dbus_message_iter_append_done (real);
3650 * Appends a named type data chunk to the message. A named
3651 * type is simply an arbitrary UTF-8 string used as a type
3652 * tag, plus an array of arbitrary bytes to be interpreted
3653 * according to the type tag.
3655 * @param iter an iterator pointing to the end of the message
3656 * @param name the name of the type
3657 * @param data the binary data used to store the value
3658 * @param len the length of the binary data in bytes
3659 * @returns #TRUE on success
3662 dbus_message_iter_append_named (DBusMessageIter *iter,
3664 const unsigned char *data,
3667 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3669 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3671 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NAMED))
3674 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name))
3676 _dbus_string_set_length (&real->message->body, real->pos);
3680 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
3682 _dbus_string_set_length (&real->message->body, real->pos);
3686 dbus_message_iter_append_done (real);
3693 * Appends a dict key name to the message. The iterator used
3694 * must point to a dict.
3696 * @param iter an iterator pointing to the end of the message
3697 * @param value the string
3698 * @returns #TRUE on success
3701 dbus_message_iter_append_dict_key (DBusMessageIter *iter,
3704 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3706 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3707 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
3709 if (real->wrote_dict_key)
3711 _dbus_warn ("Appendinging multiple dict key names\n");
3715 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
3720 dbus_message_iter_append_done (real);
3721 real->wrote_dict_key = TRUE;
3727 array_iter_type_mark_done (DBusMessageRealIter *iter)
3731 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
3732 array_iter_type_mark_done (iter->parent_iter);
3736 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body),
3737 sizeof (dbus_uint32_t));
3739 /* Empty length for now, backfill later */
3740 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0))
3742 _dbus_string_set_length (&iter->message->body, iter->pos);
3746 iter->container_start = _dbus_string_get_length (&iter->message->body);
3747 iter->container_length_pos = len_pos;
3748 iter->array_type_done = TRUE;
3754 append_array_type (DBusMessageRealIter *real,
3756 dbus_bool_t *array_type_done,
3757 int *array_type_pos)
3759 int existing_element_type;
3761 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
3764 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY &&
3765 real->array_type_done)
3767 existing_element_type = iter_get_array_type (real, array_type_pos);
3768 if (existing_element_type != element_type)
3770 _dbus_warn ("Appending array of %s, when expecting array of %s\n",
3771 _dbus_type_to_string (element_type),
3772 _dbus_type_to_string (existing_element_type));
3773 _dbus_string_set_length (&real->message->body, real->pos);
3776 if (array_type_done != NULL)
3777 *array_type_done = TRUE;
3781 if (array_type_pos != NULL)
3782 *array_type_pos = _dbus_string_get_length (&real->message->body);
3784 /* Append element type */
3785 if (!_dbus_string_append_byte (&real->message->body, element_type))
3787 _dbus_string_set_length (&real->message->body, real->pos);
3791 if (array_type_done != NULL)
3792 *array_type_done = element_type != DBUS_TYPE_ARRAY;
3794 if (element_type != DBUS_TYPE_ARRAY &&
3795 !array_iter_type_mark_done (real))
3803 * Appends an array to the message and initializes an iterator that
3804 * can be used to append to the array.
3806 * @param iter an iterator pointing to the end of the message
3807 * @param array_iter pointer to an iter that will be initialized
3808 * @param element_type the type of the array elements
3809 * @returns #TRUE on success
3812 dbus_message_iter_append_array (DBusMessageIter *iter,
3813 DBusMessageIter *array_iter,
3816 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3817 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
3820 dbus_bool_t array_type_done;
3822 if (element_type == DBUS_TYPE_NIL)
3824 _dbus_warn ("Can't create NIL arrays\n");
3828 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3830 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos))
3833 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
3835 if (array_type_done)
3837 /* Empty length for now, backfill later */
3838 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
3840 _dbus_string_set_length (&real->message->body, real->pos);
3845 array_real->parent_iter = real;
3846 array_real->message = real->message;
3847 array_real->changed_stamp = real->message->changed_stamp;
3849 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
3850 array_real->pos = _dbus_string_get_length (&real->message->body);
3851 array_real->end = array_real->end;
3853 array_real->container_start = array_real->pos;
3854 array_real->container_length_pos = len_pos;
3855 array_real->wrote_dict_key = 0;
3856 array_real->array_type_done = array_type_done;
3857 array_real->array_type_pos = array_type_pos;
3859 dbus_message_iter_append_done (array_real);
3865 * Appends a dict to the message and initializes an iterator that
3866 * can be used to append to the dict.
3868 * @param iter an iterator pointing to the end of the message
3869 * @param dict_iter pointer to an iter that will be initialized
3870 * @returns #TRUE on success
3873 dbus_message_iter_append_dict (DBusMessageIter *iter,
3874 DBusMessageIter *dict_iter)
3876 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3877 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
3880 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3882 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
3885 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
3887 /* Empty length for now, backfill later */
3888 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
3890 _dbus_string_set_length (&real->message->body, real->pos);
3894 dict_real->parent_iter = real;
3895 dict_real->message = real->message;
3896 dict_real->changed_stamp = real->message->changed_stamp;
3898 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
3899 dict_real->pos = _dbus_string_get_length (&real->message->body);
3900 dict_real->end = dict_real->end;
3902 dict_real->container_start = dict_real->pos;
3903 dict_real->container_length_pos = len_pos;
3904 dict_real->wrote_dict_key = 0;
3906 dbus_message_iter_append_done (dict_real);
3913 * Appends a boolean array to the message.
3915 * @param iter an iterator pointing to the end of the message
3916 * @param value the array
3917 * @param len the length of the array
3918 * @returns #TRUE on success
3921 dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
3922 unsigned const char *value,
3925 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3927 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3929 if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL))
3932 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
3934 _dbus_string_set_length (&real->message->body, real->pos);
3938 dbus_message_iter_append_done (real);
3944 * Appends a 32 bit signed integer array to the message.
3946 * @param iter an iterator pointing to the end of the message
3947 * @param value the array
3948 * @param len the length of the array
3949 * @returns #TRUE on success
3952 dbus_message_iter_append_int32_array (DBusMessageIter *iter,
3953 const dbus_int32_t *value,
3956 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3958 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3960 if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL))
3963 if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len))
3965 _dbus_string_set_length (&real->message->body, real->pos);
3969 dbus_message_iter_append_done (real);
3975 * Appends a 32 bit unsigned integer array to the message.
3977 * @param iter an iterator pointing to the end of the message
3978 * @param value the array
3979 * @param len the length of the array
3980 * @returns #TRUE on success
3983 dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
3984 const dbus_uint32_t *value,
3987 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3989 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
3991 if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL))
3994 if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len))
3996 _dbus_string_set_length (&real->message->body, real->pos);
4000 dbus_message_iter_append_done (real);
4005 #ifdef DBUS_HAVE_INT64
4008 * Appends a 64 bit signed integer array to the message.
4010 * This function only exists if #DBUS_HAVE_INT64 is defined.
4012 * @param iter an iterator pointing to the end of the message
4013 * @param value the array
4014 * @param len the length of the array
4015 * @returns #TRUE on success
4018 dbus_message_iter_append_int64_array (DBusMessageIter *iter,
4019 const dbus_int64_t *value,
4022 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
4024 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
4026 if (!append_array_type (real, DBUS_TYPE_INT64, NULL, NULL))
4029 if (!_dbus_marshal_int64_array (&real->message->body, real->message->byte_order, value, len))
4031 _dbus_string_set_length (&real->message->body, real->pos);
4035 dbus_message_iter_append_done (real);
4041 * Appends a 64 bit unsigned integer array to the message.
4043 * This function only exists if #DBUS_HAVE_INT64 is defined.
4045 * @param iter an iterator pointing to the end of the message
4046 * @param value the array
4047 * @param len the length of the array
4048 * @returns #TRUE on success
4051 dbus_message_iter_append_uint64_array (DBusMessageIter *iter,
4052 const dbus_uint64_t *value,
4055 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
4057 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
4059 if (!append_array_type (real, DBUS_TYPE_UINT64, NULL, NULL))
4062 if (!_dbus_marshal_uint64_array (&real->message->body, real->message->byte_order, value, len))
4064 _dbus_string_set_length (&real->message->body, real->pos);
4068 dbus_message_iter_append_done (real);
4072 #endif /* DBUS_HAVE_INT64 */
4075 * Appends a double array to the message.
4077 * @param iter an iterator pointing to the end of the message
4078 * @param value the array
4079 * @param len the length of the array
4080 * @returns #TRUE on success
4083 dbus_message_iter_append_double_array (DBusMessageIter *iter,
4084 const double *value,
4087 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
4089 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
4091 if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL))
4094 if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len))
4096 _dbus_string_set_length (&real->message->body, real->pos);
4100 dbus_message_iter_append_done (real);
4106 * Appends a byte array to the message.
4108 * @param iter an iterator pointing to the end of the message
4109 * @param value the array
4110 * @param len the length of the array
4111 * @returns #TRUE on success
4114 dbus_message_iter_append_byte_array (DBusMessageIter *iter,
4115 unsigned const char *value,
4118 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
4120 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
4122 if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL))
4125 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
4127 _dbus_string_set_length (&real->message->body, real->pos);
4131 dbus_message_iter_append_done (real);
4137 * Appends a string array to the message.
4139 * @param iter an iterator pointing to the end of the message
4140 * @param value the array
4141 * @param len the length of the array
4142 * @returns #TRUE on success
4145 dbus_message_iter_append_string_array (DBusMessageIter *iter,
4149 DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
4151 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
4153 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))
4156 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
4158 _dbus_string_set_length (&real->message->body, real->pos);
4162 dbus_message_iter_append_done (real);
4168 * Sets the message sender.
4170 * @param message the message
4171 * @param sender the sender
4172 * @returns #FALSE if not enough memory
4175 dbus_message_set_sender (DBusMessage *message,
4178 _dbus_return_val_if_fail (message != NULL, FALSE);
4179 _dbus_return_val_if_fail (!message->locked, FALSE);
4183 delete_field (message, DBUS_HEADER_FIELD_SENDER_SERVICE);
4188 return set_string_field (message,
4189 DBUS_HEADER_FIELD_SENDER_SERVICE,
4196 * Sets a flag indicating that the message does not want a reply; if
4197 * this flag is set, the other end of the connection may (but is not
4198 * required to) optimize by not sending method return or error
4199 * replies. If this flag is set, there is no way to know whether the
4200 * message successfully arrived at the remote end.
4202 * @param message the message
4203 * @param no_reply #TRUE if no reply is desired
4206 dbus_message_set_no_reply (DBusMessage *message,
4207 dbus_bool_t no_reply)
4211 _dbus_return_if_fail (message != NULL);
4212 _dbus_return_if_fail (!message->locked);
4214 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
4217 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
4219 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
4223 * Returns #TRUE if the message does not expect
4226 * @param message the message
4227 * @returns #TRUE if the message sender isn't waiting for a reply
4230 dbus_message_get_no_reply (DBusMessage *message)
4234 _dbus_return_val_if_fail (message != NULL, FALSE);
4236 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
4238 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
4242 * Gets the service which originated this message,
4243 * or #NULL if unknown or inapplicable.
4245 * @param message the message
4246 * @returns the service name or #NULL
4249 dbus_message_get_sender (DBusMessage *message)
4251 _dbus_return_val_if_fail (message != NULL, NULL);
4253 return get_string_field (message,
4254 DBUS_HEADER_FIELD_SENDER_SERVICE,
4259 _dbus_message_has_type_interface_member (DBusMessage *message,
4261 const char *interface,
4266 _dbus_assert (message != NULL);
4267 _dbus_assert (interface != NULL);
4268 _dbus_assert (method != NULL);
4270 if (dbus_message_get_type (message) != type)
4273 /* Optimize by checking the short method name first
4274 * instead of the longer interface name
4277 n = dbus_message_get_member (message);
4279 if (n && strcmp (n, method) == 0)
4281 n = dbus_message_get_interface (message);
4283 if (n && strcmp (n, interface) == 0)
4291 * Checks whether the message is a method call with the given
4292 * interface and member fields. If the message is not
4293 * #DBUS_MESSAGE_TYPE_METHOD_CALL, or has a different interface or member field,
4296 * @param message the message
4297 * @param interface the name to check (must not be #NULL)
4298 * @param method the name to check (must not be #NULL)
4300 * @returns #TRUE if the message is the specified method call
4303 dbus_message_is_method_call (DBusMessage *message,
4304 const char *interface,
4307 _dbus_return_val_if_fail (message != NULL, FALSE);
4308 _dbus_return_val_if_fail (interface != NULL, FALSE);
4309 _dbus_return_val_if_fail (method != NULL, FALSE);
4311 return _dbus_message_has_type_interface_member (message,
4312 DBUS_MESSAGE_TYPE_METHOD_CALL,
4317 * Checks whether the message is a signal with the given
4318 * interface and member fields. If the message is not
4319 * #DBUS_MESSAGE_TYPE_SIGNAL, or has a different interface or member field,
4322 * @param message the message
4323 * @param interface the name to check (must not be #NULL)
4324 * @param signal_name the name to check (must not be #NULL)
4326 * @returns #TRUE if the message is the specified signal
4329 dbus_message_is_signal (DBusMessage *message,
4330 const char *interface,
4331 const char *signal_name)
4333 _dbus_return_val_if_fail (message != NULL, FALSE);
4334 _dbus_return_val_if_fail (interface != NULL, FALSE);
4335 _dbus_return_val_if_fail (signal_name != NULL, FALSE);
4337 return _dbus_message_has_type_interface_member (message,
4338 DBUS_MESSAGE_TYPE_SIGNAL,
4339 interface, signal_name);
4343 * Checks whether the message is an error reply with the given error
4344 * name. If the message is not #DBUS_MESSAGE_TYPE_ERROR, or has a
4345 * different name, returns #FALSE.
4347 * @param message the message
4348 * @param error_name the name to check (must not be #NULL)
4350 * @returns #TRUE if the message is the specified error
4353 dbus_message_is_error (DBusMessage *message,
4354 const char *error_name)
4358 _dbus_return_val_if_fail (message != NULL, FALSE);
4359 _dbus_return_val_if_fail (error_name != NULL, FALSE);
4361 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
4364 n = dbus_message_get_error_name (message);
4366 if (n && strcmp (n, error_name) == 0)
4373 * Checks whether the message was sent to the given service. If the
4374 * message has no service specified or has a different name, returns
4377 * @param message the message
4378 * @param service the service to check (must not be #NULL)
4380 * @returns #TRUE if the message has the given destination service
4383 dbus_message_has_destination (DBusMessage *message,
4384 const char *service)
4388 _dbus_return_val_if_fail (message != NULL, FALSE);
4389 _dbus_return_val_if_fail (service != NULL, FALSE);
4391 s = dbus_message_get_destination (message);
4393 if (s && strcmp (s, service) == 0)
4400 * Checks whether the message has the given service as its sender. If
4401 * the message has no sender specified or has a different sender,
4402 * returns #FALSE. Note that if a peer application owns multiple
4403 * services, its messages will have only one of those services as the
4404 * sender (usually the base service). So you can't use this
4405 * function to prove the sender didn't own service Foo, you can
4406 * only use it to prove that it did.
4408 * @param message the message
4409 * @param service the service to check (must not be #NULL)
4411 * @returns #TRUE if the message has the given origin service
4414 dbus_message_has_sender (DBusMessage *message,
4415 const char *service)
4419 _dbus_assert (service != NULL);
4421 s = dbus_message_get_sender (message);
4423 if (s && strcmp (s, service) == 0)
4430 * Sets a #DBusError based on the contents of the given
4431 * message. The error is only set if the message
4432 * is an error message, as in DBUS_MESSAGE_TYPE_ERROR.
4433 * The name of the error is set to the name of the message,
4434 * and the error message is set to the first argument
4435 * if the argument exists and is a string.
4437 * The return value indicates whether the error was set (the error is
4438 * set if and only if the message is an error message).
4439 * So you can check for an error reply and convert it to DBusError
4442 * @param error the error to set
4443 * @param message the message to set it from
4444 * @returns #TRUE if dbus_message_get_is_error() returns #TRUE for the message
4447 dbus_set_error_from_message (DBusError *error,
4448 DBusMessage *message)
4452 _dbus_return_val_if_fail (message != NULL, FALSE);
4453 _dbus_return_val_if_error_is_set (error, FALSE);
4455 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
4459 dbus_message_get_args (message, NULL,
4460 DBUS_TYPE_STRING, &str,
4463 dbus_set_error (error, dbus_message_get_error_name (message),
4464 str ? "%s" : NULL, str);
4474 * @addtogroup DBusMessageInternals
4479 * @typedef DBusMessageLoader
4481 * The DBusMessageLoader object encapsulates the process of converting
4482 * a byte stream into a series of DBusMessage. It buffers the incoming
4483 * bytes as efficiently as possible, and generates a queue of
4484 * messages. DBusMessageLoader is typically used as part of a
4485 * DBusTransport implementation. The DBusTransport then hands off
4486 * the loaded messages to a DBusConnection, making the messages
4487 * visible to the application.
4489 * @todo write tests for break-loader that a) randomly delete header
4490 * fields and b) set string fields to zero-length and other funky
4495 /* we definitely use signed ints for sizes, so don't exceed
4496 * _DBUS_INT_MAX; and add 16 for paranoia, since a message
4497 * over 128M is pretty nuts anyhow.
4501 * The maximum sane message size.
4503 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
4506 * Implementation details of DBusMessageLoader.
4507 * All members are private.
4509 struct DBusMessageLoader
4511 int refcount; /**< Reference count. */
4513 DBusString data; /**< Buffered data */
4515 DBusList *messages; /**< Complete messages. */
4517 long max_message_size; /**< Maximum size of a message */
4519 unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
4521 unsigned int corrupted : 1; /**< We got broken data, and are no longer working */
4525 * The initial buffer size of the message loader.
4527 * @todo this should be based on min header size plus some average
4528 * body size, or something. Or rather, the min header size only, if we
4529 * want to try to read only the header, store that in a DBusMessage,
4530 * then read only the body and store that, etc., depends on
4531 * how we optimize _dbus_message_loader_get_buffer() and what
4532 * the exact message format is.
4534 #define INITIAL_LOADER_DATA_LEN 32
4537 * Creates a new message loader. Returns #NULL if memory can't
4540 * @returns new loader, or #NULL.
4543 _dbus_message_loader_new (void)
4545 DBusMessageLoader *loader;
4547 loader = dbus_new0 (DBusMessageLoader, 1);
4551 loader->refcount = 1;
4553 /* Try to cap message size at something that won't *totally* hose
4554 * the system if we have a couple of them.
4556 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
4558 if (!_dbus_string_init (&loader->data))
4564 /* preallocate the buffer for speed, ignore failure */
4565 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
4566 _dbus_string_set_length (&loader->data, 0);
4572 * Increments the reference count of the loader.
4574 * @param loader the loader.
4577 _dbus_message_loader_ref (DBusMessageLoader *loader)
4579 loader->refcount += 1;
4583 * Decrements the reference count of the loader and finalizes the
4584 * loader when the count reaches zero.
4586 * @param loader the loader.
4589 _dbus_message_loader_unref (DBusMessageLoader *loader)
4591 loader->refcount -= 1;
4592 if (loader->refcount == 0)
4594 _dbus_list_foreach (&loader->messages,
4595 (DBusForeachFunction) dbus_message_unref,
4597 _dbus_list_clear (&loader->messages);
4598 _dbus_string_free (&loader->data);
4604 * Gets the buffer to use for reading data from the network. Network
4605 * data is read directly into an allocated buffer, which is then used
4606 * in the DBusMessage, to avoid as many extra memcpy's as possible.
4607 * The buffer must always be returned immediately using
4608 * _dbus_message_loader_return_buffer(), even if no bytes are
4609 * successfully read.
4611 * @todo this function can be a lot more clever. For example
4612 * it can probably always return a buffer size to read exactly
4613 * the body of the next message, thus avoiding any memory wastage
4616 * @todo we need to enforce a max length on strings in header fields.
4618 * @param loader the message loader.
4619 * @param buffer the buffer
4622 _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
4623 DBusString **buffer)
4625 _dbus_assert (!loader->buffer_outstanding);
4627 *buffer = &loader->data;
4629 loader->buffer_outstanding = TRUE;
4633 * The smallest header size that can occur.
4634 * (It won't be valid)
4636 #define DBUS_MINIMUM_HEADER_SIZE 16
4639 decode_string_field (const DBusString *data,
4641 HeaderField *header_field,
4642 DBusString *field_data,
4646 int string_data_pos;
4648 _dbus_assert (header_field != NULL);
4649 _dbus_assert (field_data != NULL);
4651 if (header_field->name_offset >= 0)
4653 _dbus_verbose ("%s field provided twice\n",
4654 _dbus_header_field_to_string (field));
4658 if (type != DBUS_TYPE_STRING)
4660 _dbus_verbose ("%s field has wrong type %s\n",
4661 _dbus_header_field_to_string (field),
4662 _dbus_type_to_string (type));
4666 /* skip padding after typecode, skip string length;
4667 * we assume that the string arg has already been validated
4668 * for sanity and UTF-8
4670 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
4671 _dbus_assert (string_data_pos < _dbus_string_get_length (data));
4673 _dbus_string_init_const (field_data,
4674 _dbus_string_get_const_data (data) + string_data_pos);
4676 header_field->name_offset = pos;
4677 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
4680 _dbus_verbose ("Found field %s at offset %d\n",
4681 _dbus_header_field_to_string (field),
4682 header_field->value_offset);
4689 decode_header_data (const DBusString *data,
4693 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
4694 int *message_padding)
4696 DBusString field_data;
4702 if (header_len < 16)
4704 _dbus_verbose ("Header length %d is too short\n", header_len);
4709 while (i <= DBUS_HEADER_FIELD_LAST)
4711 fields[i].name_offset = -1;
4712 fields[i].value_offset = -1;
4717 while (pos < header_len)
4719 field = _dbus_string_get_byte (data, pos);
4720 if (field == DBUS_HEADER_FIELD_INVALID)
4721 break; /* Must be padding */
4724 if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
4726 _dbus_verbose ("Failed to validate type of named header field\n");
4730 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))
4732 _dbus_verbose ("Failed to validate argument to named header field\n");
4736 if (new_pos > header_len)
4738 _dbus_verbose ("Named header field tries to extend beyond header length\n");
4744 case DBUS_HEADER_FIELD_SERVICE:
4745 if (!decode_string_field (data, field, &fields[field],
4746 &field_data, pos, type))
4749 if (!_dbus_string_validate_service (&field_data, 0,
4750 _dbus_string_get_length (&field_data)))
4752 _dbus_verbose ("service field has invalid content \"%s\"\n",
4753 _dbus_string_get_const_data (&field_data));
4758 case DBUS_HEADER_FIELD_INTERFACE:
4759 if (!decode_string_field (data, field, &fields[field],
4760 &field_data, pos, type))
4763 if (!_dbus_string_validate_interface (&field_data, 0,
4764 _dbus_string_get_length (&field_data)))
4766 _dbus_verbose ("interface field has invalid content \"%s\"\n",
4767 _dbus_string_get_const_data (&field_data));
4771 if (_dbus_string_equal_c_str (&field_data,
4772 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
4774 _dbus_verbose ("Message is on the local interface\n");
4779 case DBUS_HEADER_FIELD_MEMBER:
4780 if (!decode_string_field (data, field, &fields[field],
4781 &field_data, pos, type))
4784 if (!_dbus_string_validate_member (&field_data, 0,
4785 _dbus_string_get_length (&field_data)))
4787 _dbus_verbose ("member field has invalid content \"%s\"\n",
4788 _dbus_string_get_const_data (&field_data));
4793 case DBUS_HEADER_FIELD_ERROR_NAME:
4794 if (!decode_string_field (data, field, &fields[field],
4795 &field_data, pos, type))
4798 if (!_dbus_string_validate_error_name (&field_data, 0,
4799 _dbus_string_get_length (&field_data)))
4801 _dbus_verbose ("error-name field has invalid content \"%s\"\n",
4802 _dbus_string_get_const_data (&field_data));
4807 case DBUS_HEADER_FIELD_SENDER_SERVICE:
4808 if (!decode_string_field (data, field, &fields[field],
4809 &field_data, pos, type))
4812 if (!_dbus_string_validate_service (&field_data, 0,
4813 _dbus_string_get_length (&field_data)))
4815 _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
4816 _dbus_string_get_const_data (&field_data));
4821 case DBUS_HEADER_FIELD_PATH:
4823 /* Path was already validated as part of standard
4824 * type validation, since there's an OBJECT_PATH
4828 if (fields[field].name_offset >= 0)
4830 _dbus_verbose ("path field provided twice\n");
4833 if (type != DBUS_TYPE_OBJECT_PATH)
4835 _dbus_verbose ("path field has wrong type\n");
4839 fields[field].name_offset = pos;
4840 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
4842 /* No forging signals from the local path */
4845 s = _dbus_string_get_const_data_len (data,
4846 fields[field].value_offset,
4847 _dbus_string_get_length (data) -
4848 fields[field].value_offset);
4849 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
4851 _dbus_verbose ("Message is on the local path\n");
4856 _dbus_verbose ("Found path at offset %d\n",
4857 fields[field].value_offset);
4860 case DBUS_HEADER_FIELD_REPLY_SERIAL:
4861 if (fields[field].name_offset >= 0)
4863 _dbus_verbose ("reply field provided twice\n");
4867 if (type != DBUS_TYPE_UINT32)
4869 _dbus_verbose ("reply field has wrong type\n");
4873 fields[field].name_offset = pos;
4874 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
4876 _dbus_verbose ("Found reply serial at offset %d\n",
4877 fields[field].value_offset);
4881 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
4888 if (pos < header_len)
4890 /* Alignment padding, verify that it's nul */
4891 if ((header_len - pos) >= 8)
4893 _dbus_verbose ("too much header alignment padding\n");
4897 if (!_dbus_string_validate_nul (data,
4898 pos, (header_len - pos)))
4900 _dbus_verbose ("header alignment padding is not nul\n");
4905 /* Depending on message type, enforce presence of certain fields. */
4906 switch (message_type)
4908 case DBUS_MESSAGE_TYPE_SIGNAL:
4909 case DBUS_MESSAGE_TYPE_METHOD_CALL:
4910 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
4912 _dbus_verbose ("No path field provided\n");
4915 /* FIXME make this optional, only for method calls */
4916 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
4918 _dbus_verbose ("No interface field provided\n");
4921 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
4923 _dbus_verbose ("No member field provided\n");
4927 case DBUS_MESSAGE_TYPE_ERROR:
4928 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
4930 _dbus_verbose ("No error-name field provided\n");
4934 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
4937 /* An unknown type, spec requires us to ignore it */
4941 if (message_padding)
4942 *message_padding = header_len - pos;
4948 * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
4949 * indicating to the loader how many bytes of the buffer were filled
4950 * in. This function must always be called, even if no bytes were
4951 * successfully read.
4953 * @param loader the loader.
4954 * @param buffer the buffer.
4955 * @param bytes_read number of bytes that were read into the buffer.
4958 _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
4962 _dbus_assert (loader->buffer_outstanding);
4963 _dbus_assert (buffer == &loader->data);
4965 loader->buffer_outstanding = FALSE;
4969 * Converts buffered data into messages.
4971 * @todo we need to check that the proper named header fields exist
4972 * for each message type.
4974 * @todo If a message has unknown type, we should probably eat it
4975 * right here rather than passing it out to applications. However
4976 * it's not an error to see messages of unknown type.
4978 * @param loader the loader.
4979 * @returns #TRUE if we had enough memory to finish.
4982 _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
4984 if (loader->corrupted)
4987 while (_dbus_string_get_length (&loader->data) >= 16)
4989 DBusMessage *message;
4990 const char *header_data;
4991 int byte_order, message_type, header_len, body_len, header_padding;
4992 dbus_uint32_t header_len_unsigned, body_len_unsigned;
4994 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
4996 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
4998 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
5000 _dbus_verbose ("Message has protocol version %d ours is %d\n",
5001 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
5002 loader->corrupted = TRUE;
5006 byte_order = header_data[BYTE_ORDER_OFFSET];
5008 if (byte_order != DBUS_LITTLE_ENDIAN &&
5009 byte_order != DBUS_BIG_ENDIAN)
5011 _dbus_verbose ("Message with bad byte order '%c' received\n",
5013 loader->corrupted = TRUE;
5017 /* Unknown types are ignored, but INVALID is
5020 message_type = header_data[TYPE_OFFSET];
5021 if (message_type == DBUS_MESSAGE_TYPE_INVALID)
5023 _dbus_verbose ("Message with bad type '%d' received\n",
5025 loader->corrupted = TRUE;
5029 header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
5030 body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
5032 if (header_len_unsigned < 16)
5034 _dbus_verbose ("Message had broken too-small header length %u\n",
5035 header_len_unsigned);
5036 loader->corrupted = TRUE;
5040 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
5041 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
5043 _dbus_verbose ("Header or body length too large (%u %u)\n",
5044 header_len_unsigned,
5046 loader->corrupted = TRUE;
5050 /* Now that we know the values are in signed range, get
5051 * rid of stupid unsigned, just causes bugs
5053 header_len = header_len_unsigned;
5054 body_len = body_len_unsigned;
5056 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
5059 _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
5061 loader->corrupted = TRUE;
5065 if (header_len + body_len > loader->max_message_size)
5067 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
5068 header_len, body_len, loader->max_message_size);
5069 loader->corrupted = TRUE;
5073 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
5075 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
5080 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len);
5082 if (!decode_header_data (&loader->data,
5083 header_len, byte_order,
5085 fields, &header_padding))
5087 _dbus_verbose ("Header was invalid\n");
5088 loader->corrupted = TRUE;
5092 next_arg = header_len;
5093 while (next_arg < (header_len + body_len))
5096 int prev = next_arg;
5098 if (!_dbus_marshal_validate_type (&loader->data, next_arg,
5101 _dbus_verbose ("invalid typecode at offset %d\n", prev);
5102 loader->corrupted = TRUE;
5106 if (!_dbus_marshal_validate_arg (&loader->data,
5113 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
5114 loader->corrupted = TRUE;
5118 _dbus_assert (next_arg > prev);
5121 if (next_arg > (header_len + body_len))
5123 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
5124 next_arg, header_len, body_len,
5125 header_len + body_len);
5126 loader->corrupted = TRUE;
5130 message = dbus_message_new_empty_header ();
5131 if (message == NULL)
5133 _dbus_verbose ("Failed to allocate empty message\n");
5137 message->byte_order = byte_order;
5138 message->header_padding = header_padding;
5140 /* Copy in the offsets we found */
5142 while (i <= DBUS_HEADER_FIELD_LAST)
5144 message->header_fields[i] = fields[i];
5148 if (!_dbus_list_append (&loader->messages, message))
5150 _dbus_verbose ("Failed to append new message to loader queue\n");
5151 dbus_message_unref (message);
5155 _dbus_assert (_dbus_string_get_length (&message->header) == 0);
5156 _dbus_assert (_dbus_string_get_length (&message->body) == 0);
5158 _dbus_assert (_dbus_string_get_length (&loader->data) >=
5159 (header_len + body_len));
5161 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
5163 _dbus_verbose ("Failed to move header into new message\n");
5164 _dbus_list_remove_last (&loader->messages, message);
5165 dbus_message_unref (message);
5169 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
5173 _dbus_verbose ("Failed to move body into new message\n");
5175 /* put the header back, we'll try again later */
5176 result = _dbus_string_copy_len (&message->header, 0, header_len,
5178 _dbus_assert (result); /* because DBusString never reallocs smaller */
5180 _dbus_list_remove_last (&loader->messages, message);
5181 dbus_message_unref (message);
5185 _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
5186 _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
5188 /* Fill in caches (we checked the types of these fields
5191 message->reply_serial = get_uint_field (message,
5192 DBUS_HEADER_FIELD_REPLY_SERIAL);
5194 message->client_serial = _dbus_demarshal_uint32 (&message->header,
5195 message->byte_order,
5196 CLIENT_SERIAL_OFFSET,
5199 _dbus_verbose ("Loaded message %p\n", message);
5209 * Peeks at first loaded message, returns #NULL if no messages have
5212 * @param loader the loader.
5213 * @returns the next message, or #NULL if none.
5216 _dbus_message_loader_peek_message (DBusMessageLoader *loader)
5218 if (loader->messages)
5219 return loader->messages->data;
5225 * Pops a loaded message (passing ownership of the message
5226 * to the caller). Returns #NULL if no messages have been
5229 * @param loader the loader.
5230 * @returns the next message, or #NULL if none.
5233 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
5235 return _dbus_list_pop_first (&loader->messages);
5239 * Pops a loaded message inside a list link (passing ownership of the
5240 * message and link to the caller). Returns #NULL if no messages have
5243 * @param loader the loader.
5244 * @returns the next message link, or #NULL if none.
5247 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
5249 return _dbus_list_pop_first_link (&loader->messages);
5253 * Returns a popped message link, used to undo a pop.
5255 * @param loader the loader
5256 * @param link the link with a message in it
5259 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader,
5262 _dbus_list_prepend_link (&loader->messages, link);
5266 * Checks whether the loader is confused due to bad data.
5267 * If messages are received that are invalid, the
5268 * loader gets confused and gives up permanently.
5269 * This state is called "corrupted."
5271 * @param loader the loader
5272 * @returns #TRUE if the loader is hosed.
5275 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
5277 return loader->corrupted;
5281 * Sets the maximum size message we allow.
5283 * @param loader the loader
5284 * @param size the max message size in bytes
5287 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader,
5290 if (size > MAX_SANE_MESSAGE_SIZE)
5292 _dbus_verbose ("clamping requested max message size %ld to %d\n",
5293 size, MAX_SANE_MESSAGE_SIZE);
5294 size = MAX_SANE_MESSAGE_SIZE;
5296 loader->max_message_size = size;
5300 * Gets the maximum allowed message size in bytes.
5302 * @param loader the loader
5303 * @returns max size in bytes
5306 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
5308 return loader->max_message_size;
5311 static DBusDataSlotAllocator slot_allocator;
5312 _DBUS_DEFINE_GLOBAL_LOCK (message_slots);
5315 * Allocates an integer ID to be used for storing application-specific
5316 * data on any DBusMessage. The allocated ID may then be used
5317 * with dbus_message_set_data() and dbus_message_get_data().
5318 * The passed-in slot must be initialized to -1, and is filled in
5319 * with the slot ID. If the passed-in slot is not -1, it's assumed
5320 * to be already allocated, and its refcount is incremented.
5322 * The allocated slot is global, i.e. all DBusMessage objects will
5323 * have a slot with the given integer ID reserved.
5325 * @param slot_p address of a global variable storing the slot
5326 * @returns #FALSE on failure (no memory)
5329 dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
5331 return _dbus_data_slot_allocator_alloc (&slot_allocator,
5332 _DBUS_LOCK_NAME (message_slots),
5337 * Deallocates a global ID for message data slots.
5338 * dbus_message_get_data() and dbus_message_set_data() may no
5339 * longer be used with this slot. Existing data stored on existing
5340 * DBusMessage objects will be freed when the message is
5341 * finalized, but may not be retrieved (and may only be replaced if
5342 * someone else reallocates the slot). When the refcount on the
5343 * passed-in slot reaches 0, it is set to -1.
5345 * @param slot_p address storing the slot to deallocate
5348 dbus_message_free_data_slot (dbus_int32_t *slot_p)
5350 _dbus_return_if_fail (*slot_p >= 0);
5352 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
5356 * Stores a pointer on a DBusMessage, along
5357 * with an optional function to be used for freeing
5358 * the data when the data is set again, or when
5359 * the message is finalized. The slot number
5360 * must have been allocated with dbus_message_allocate_data_slot().
5362 * @param message the message
5363 * @param slot the slot number
5364 * @param data the data to store
5365 * @param free_data_func finalizer function for the data
5366 * @returns #TRUE if there was enough memory to store the data
5369 dbus_message_set_data (DBusMessage *message,
5372 DBusFreeFunction free_data_func)
5374 DBusFreeFunction old_free_func;
5378 _dbus_return_val_if_fail (message != NULL, FALSE);
5379 _dbus_return_val_if_fail (slot >= 0, FALSE);
5381 retval = _dbus_data_slot_list_set (&slot_allocator,
5382 &message->slot_list,
5383 slot, data, free_data_func,
5384 &old_free_func, &old_data);
5388 /* Do the actual free outside the message lock */
5390 (* old_free_func) (old_data);
5397 * Retrieves data previously set with dbus_message_set_data().
5398 * The slot must still be allocated (must not have been freed).
5400 * @param message the message
5401 * @param slot the slot to get data from
5402 * @returns the data, or #NULL if not found
5405 dbus_message_get_data (DBusMessage *message,
5410 _dbus_return_val_if_fail (message != NULL, NULL);
5412 res = _dbus_data_slot_list_get (&slot_allocator,
5413 &message->slot_list,
5420 #ifdef DBUS_BUILD_TESTS
5421 #include "dbus-test.h"
5425 message_iter_test (DBusMessage *message)
5427 DBusMessageIter iter, dict, array, array2;
5429 unsigned char *data;
5430 dbus_int32_t *our_int_array;
5433 dbus_message_iter_init (message, &iter);
5436 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
5437 _dbus_assert_not_reached ("Argument type isn't string");
5439 str = dbus_message_iter_get_string (&iter);
5440 if (strcmp (str, "Test string") != 0)
5441 _dbus_assert_not_reached ("Strings differ");
5444 if (!dbus_message_iter_next (&iter))
5445 _dbus_assert_not_reached ("Reached end of arguments");
5447 /* Signed integer tests */
5448 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
5449 _dbus_assert_not_reached ("Argument type isn't int32");
5451 if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
5452 _dbus_assert_not_reached ("Signed integers differ");
5454 if (!dbus_message_iter_next (&iter))
5455 _dbus_assert_not_reached ("Reached end of fields");
5457 /* Unsigned integer tests */
5458 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
5459 _dbus_assert_not_reached ("Argument type isn't int32");
5461 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
5462 _dbus_assert_not_reached ("Unsigned integers differ");
5464 if (!dbus_message_iter_next (&iter))
5465 _dbus_assert_not_reached ("Reached end of arguments");
5468 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
5469 _dbus_assert_not_reached ("Argument type isn't double");
5471 if (dbus_message_iter_get_double (&iter) != 3.14159)
5472 _dbus_assert_not_reached ("Doubles differ");
5474 if (!dbus_message_iter_next (&iter))
5475 _dbus_assert_not_reached ("Reached end of arguments");
5477 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
5478 _dbus_assert_not_reached ("Argument type not an array");
5480 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE)
5481 _dbus_assert_not_reached ("Array type not double");
5484 if (!dbus_message_iter_init_array_iterator (&iter, &array, NULL))
5485 _dbus_assert_not_reached ("Array init failed");
5487 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
5488 _dbus_assert_not_reached ("Argument type isn't double");
5490 if (dbus_message_iter_get_double (&array) != 1.5)
5491 _dbus_assert_not_reached ("Unsigned integers differ");
5493 if (!dbus_message_iter_next (&array))
5494 _dbus_assert_not_reached ("Reached end of arguments");
5496 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
5497 _dbus_assert_not_reached ("Argument type isn't double");
5499 if (dbus_message_iter_get_double (&array) != 2.5)
5500 _dbus_assert_not_reached ("Unsigned integers differ");
5502 if (dbus_message_iter_next (&array))
5503 _dbus_assert_not_reached ("Didn't reach end of arguments");
5505 if (!dbus_message_iter_next (&iter))
5506 _dbus_assert_not_reached ("Reached end of arguments");
5511 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
5512 _dbus_assert_not_reached ("not dict type");
5514 if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
5515 _dbus_assert_not_reached ("dict iter failed");
5517 str = dbus_message_iter_get_dict_key (&dict);
5518 if (str == NULL || strcmp (str, "test") != 0)
5519 _dbus_assert_not_reached ("wrong dict key");
5522 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
5523 _dbus_assert_not_reached ("wrong dict entry type");
5525 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
5526 _dbus_assert_not_reached ("wrong dict entry value");
5528 if (!dbus_message_iter_next (&dict))
5529 _dbus_assert_not_reached ("reached end of dict");
5531 /* array of array of int32 (in dict) */
5533 str = dbus_message_iter_get_dict_key (&dict);
5534 if (str == NULL || strcmp (str, "array") != 0)
5535 _dbus_assert_not_reached ("wrong dict key");
5538 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY)
5539 _dbus_assert_not_reached ("Argument type not an array");
5541 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
5542 _dbus_assert_not_reached ("Array type not array");
5544 if (!dbus_message_iter_init_array_iterator (&dict, &array, NULL))
5545 _dbus_assert_not_reached ("Array init failed");
5547 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
5548 _dbus_assert_not_reached ("Argument type isn't array");
5550 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
5551 _dbus_assert_not_reached ("Array type not int32");
5553 if (!dbus_message_iter_init_array_iterator (&array, &array2, NULL))
5554 _dbus_assert_not_reached ("Array init failed");
5556 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
5557 _dbus_assert_not_reached ("Argument type isn't int32");
5559 if (dbus_message_iter_get_int32 (&array2) != 0x12345678)
5560 _dbus_assert_not_reached ("Signed integers differ");
5562 if (!dbus_message_iter_next (&array2))
5563 _dbus_assert_not_reached ("Reached end of arguments");
5565 if (dbus_message_iter_get_int32 (&array2) != 0x23456781)
5566 _dbus_assert_not_reached ("Signed integers differ");
5568 if (dbus_message_iter_next (&array2))
5569 _dbus_assert_not_reached ("Didn't reached end of arguments");
5571 if (!dbus_message_iter_next (&array))
5572 _dbus_assert_not_reached ("Reached end of arguments");
5574 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
5575 _dbus_assert_not_reached ("Array type not int32");
5577 if (!dbus_message_iter_get_int32_array (&array,
5580 _dbus_assert_not_reached ("couldn't get int32 array");
5582 _dbus_assert (len == 3);
5583 _dbus_assert (our_int_array[0] == 0x34567812 &&
5584 our_int_array[1] == 0x45678123 &&
5585 our_int_array[2] == 0x56781234);
5586 dbus_free (our_int_array);
5588 if (dbus_message_iter_next (&array))
5589 _dbus_assert_not_reached ("Didn't reach end of array");
5591 if (dbus_message_iter_next (&dict))
5592 _dbus_assert_not_reached ("Didn't reach end of dict");
5594 if (!dbus_message_iter_next (&iter))
5595 _dbus_assert_not_reached ("Reached end of arguments");
5597 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE)
5599 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter));
5600 _dbus_assert_not_reached ("wrong type after dict (should be byte)");
5603 if (dbus_message_iter_get_byte (&iter) != 0xF0)
5604 _dbus_assert_not_reached ("wrong value after dict");
5607 if (!dbus_message_iter_next (&iter))
5608 _dbus_assert_not_reached ("Reached end of arguments");
5610 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL)
5611 _dbus_assert_not_reached ("not a nil type");
5613 if (!dbus_message_iter_next (&iter))
5614 _dbus_assert_not_reached ("Reached end of arguments");
5616 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NAMED)
5617 _dbus_assert_not_reached ("wrong type after dict");
5619 if (!dbus_message_iter_get_named (&iter, &str, &data, &len))
5620 _dbus_assert_not_reached ("failed to get named");
5622 _dbus_assert (strcmp (str, "named")==0);
5623 _dbus_assert (len == 5);
5624 _dbus_assert (strcmp (data, "data")==0);
5628 if (dbus_message_iter_next (&iter))
5629 _dbus_assert_not_reached ("Didn't reach end of arguments");
5634 check_message_handling_type (DBusMessageIter *iter,
5637 DBusMessageIter child_iter;
5643 case DBUS_TYPE_BYTE:
5644 dbus_message_iter_get_byte (iter);
5646 case DBUS_TYPE_BOOLEAN:
5647 dbus_message_iter_get_boolean (iter);
5649 case DBUS_TYPE_INT32:
5650 dbus_message_iter_get_int32 (iter);
5652 case DBUS_TYPE_UINT32:
5653 dbus_message_iter_get_uint32 (iter);
5655 case DBUS_TYPE_INT64:
5656 #ifdef DBUS_HAVE_INT64
5657 dbus_message_iter_get_int64 (iter);
5660 case DBUS_TYPE_UINT64:
5661 #ifdef DBUS_HAVE_INT64
5662 dbus_message_iter_get_uint64 (iter);
5665 case DBUS_TYPE_DOUBLE:
5666 dbus_message_iter_get_double (iter);
5668 case DBUS_TYPE_STRING:
5671 str = dbus_message_iter_get_string (iter);
5674 _dbus_warn ("NULL string in message\n");
5680 case DBUS_TYPE_NAMED:
5683 unsigned char *data;
5686 if (!dbus_message_iter_get_named (iter, &name, &data, &len))
5688 _dbus_warn ("error reading name from named type\n");
5695 case DBUS_TYPE_ARRAY:
5699 if (!dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type))
5701 _dbus_warn ("Failed to init array iterator\n");
5705 while (dbus_message_iter_has_next (&child_iter))
5707 if (!check_message_handling_type (&child_iter, array_type))
5709 _dbus_warn ("error in array element\n");
5713 if (!dbus_message_iter_next (&child_iter))
5718 case DBUS_TYPE_DICT:
5723 if (!dbus_message_iter_init_dict_iterator (iter, &child_iter))
5725 _dbus_warn ("Failed to init dict iterator\n");
5729 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
5731 key = dbus_message_iter_get_dict_key (&child_iter);
5734 _dbus_warn ("error reading dict key\n");
5739 if (!check_message_handling_type (&child_iter, entry_type))
5741 _dbus_warn ("error in dict value\n");
5745 if (!dbus_message_iter_next (&child_iter))
5752 _dbus_warn ("unknown type %d\n", type);
5761 check_message_handling (DBusMessage *message)
5763 DBusMessageIter iter;
5766 dbus_uint32_t client_serial;
5770 client_serial = dbus_message_get_serial (message);
5772 /* can't use set_serial due to the assertions at the start of it */
5773 _dbus_marshal_set_uint32 (&message->header,
5774 message->byte_order,
5775 CLIENT_SERIAL_OFFSET,
5778 if (client_serial != dbus_message_get_serial (message))
5780 _dbus_warn ("get/set cycle for client_serial did not succeed\n");
5784 /* If we implement message_set_arg (message, n, value)
5785 * then we would want to test it here
5788 dbus_message_iter_init (message, &iter);
5789 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
5791 if (!check_message_handling_type (&iter, type))
5794 if (!dbus_message_iter_next (&iter))
5805 check_have_valid_message (DBusMessageLoader *loader)
5807 DBusMessage *message;
5813 if (!_dbus_message_loader_queue_messages (loader))
5814 _dbus_assert_not_reached ("no memory to queue messages");
5816 if (_dbus_message_loader_get_is_corrupted (loader))
5818 _dbus_warn ("loader corrupted on message that was expected to be valid\n");
5822 message = _dbus_message_loader_pop_message (loader);
5823 if (message == NULL)
5825 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
5829 if (_dbus_string_get_length (&loader->data) > 0)
5831 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
5835 /* Verify that we're able to properly deal with the message.
5836 * For example, this would detect improper handling of messages
5837 * in nonstandard byte order.
5839 if (!check_message_handling (message))
5846 dbus_message_unref (message);
5852 check_invalid_message (DBusMessageLoader *loader)
5858 if (!_dbus_message_loader_queue_messages (loader))
5859 _dbus_assert_not_reached ("no memory to queue messages");
5861 if (!_dbus_message_loader_get_is_corrupted (loader))
5863 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
5874 check_incomplete_message (DBusMessageLoader *loader)
5876 DBusMessage *message;
5882 if (!_dbus_message_loader_queue_messages (loader))
5883 _dbus_assert_not_reached ("no memory to queue messages");
5885 if (_dbus_message_loader_get_is_corrupted (loader))
5887 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
5891 message = _dbus_message_loader_pop_message (loader);
5892 if (message != NULL)
5894 _dbus_warn ("loaded message that was expected to be incomplete\n");
5902 dbus_message_unref (message);
5907 check_loader_results (DBusMessageLoader *loader,
5908 DBusMessageValidity validity)
5910 if (!_dbus_message_loader_queue_messages (loader))
5911 _dbus_assert_not_reached ("no memory to queue messages");
5915 case _DBUS_MESSAGE_VALID:
5916 return check_have_valid_message (loader);
5917 case _DBUS_MESSAGE_INVALID:
5918 return check_invalid_message (loader);
5919 case _DBUS_MESSAGE_INCOMPLETE:
5920 return check_incomplete_message (loader);
5921 case _DBUS_MESSAGE_UNKNOWN:
5925 _dbus_assert_not_reached ("bad DBusMessageValidity");
5931 * Loads the message in the given message file.
5933 * @param filename filename to load
5934 * @param is_raw if #TRUE load as binary data, if #FALSE as message builder language
5935 * @param data string to load message into
5936 * @returns #TRUE if the message was loaded
5939 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
5951 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
5952 dbus_error_init (&error);
5953 if (!_dbus_file_get_contents (data, filename, &error))
5955 _dbus_warn ("Could not load message file %s: %s\n",
5956 _dbus_string_get_const_data (filename),
5958 dbus_error_free (&error);
5964 if (!_dbus_message_data_load (data, filename))
5966 _dbus_warn ("Could not load message file %s\n",
5967 _dbus_string_get_const_data (filename));
5980 * Tries loading the message in the given message file
5981 * and verifies that DBusMessageLoader can handle it.
5983 * @param filename filename to load
5984 * @param is_raw if #TRUE load as binary data, if #FALSE as message builder language
5985 * @param expected_validity what the message has to be like to return #TRUE
5986 * @returns #TRUE if the message has the expected validity
5989 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
5991 DBusMessageValidity expected_validity)
5998 if (!_dbus_string_init (&data))
5999 _dbus_assert_not_reached ("could not allocate string\n");
6001 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
6005 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
6011 if (_dbus_string_get_length (&data) > 0)
6012 _dbus_verbose_bytes_of_string (&data, 0,
6013 _dbus_string_get_length (&data));
6015 _dbus_warn ("Failed message loader test on %s\n",
6016 _dbus_string_get_const_data (filename));
6019 _dbus_string_free (&data);
6025 * Tries loading the given message data.
6028 * @param data the message data
6029 * @param expected_validity what the message has to be like to return #TRUE
6030 * @returns #TRUE if the message has the expected validity
6033 dbus_internal_do_not_use_try_message_data (const DBusString *data,
6034 DBusMessageValidity expected_validity)
6036 DBusMessageLoader *loader;
6044 /* Write the data one byte at a time */
6046 loader = _dbus_message_loader_new ();
6048 /* check some trivial loader functions */
6049 _dbus_message_loader_ref (loader);
6050 _dbus_message_loader_unref (loader);
6051 _dbus_message_loader_get_max_message_size (loader);
6053 len = _dbus_string_get_length (data);
6054 for (i = 0; i < len; i++)
6058 _dbus_message_loader_get_buffer (loader, &buffer);
6059 _dbus_string_append_byte (buffer,
6060 _dbus_string_get_byte (data, i));
6061 _dbus_message_loader_return_buffer (loader, buffer, 1);
6064 if (!check_loader_results (loader, expected_validity))
6067 _dbus_message_loader_unref (loader);
6070 /* Write the data all at once */
6072 loader = _dbus_message_loader_new ();
6077 _dbus_message_loader_get_buffer (loader, &buffer);
6078 _dbus_string_copy (data, 0, buffer,
6079 _dbus_string_get_length (buffer));
6080 _dbus_message_loader_return_buffer (loader, buffer, 1);
6083 if (!check_loader_results (loader, expected_validity))
6086 _dbus_message_loader_unref (loader);
6089 /* Write the data 2 bytes at a time */
6091 loader = _dbus_message_loader_new ();
6093 len = _dbus_string_get_length (data);
6094 for (i = 0; i < len; i += 2)
6098 _dbus_message_loader_get_buffer (loader, &buffer);
6099 _dbus_string_append_byte (buffer,
6100 _dbus_string_get_byte (data, i));
6102 _dbus_string_append_byte (buffer,
6103 _dbus_string_get_byte (data, i+1));
6104 _dbus_message_loader_return_buffer (loader, buffer, 1);
6107 if (!check_loader_results (loader, expected_validity))
6110 _dbus_message_loader_unref (loader);
6118 _dbus_message_loader_unref (loader);
6124 process_test_subdir (const DBusString *test_base_dir,
6126 DBusMessageValidity validity,
6127 DBusForeachMessageFileFunc function,
6130 DBusString test_directory;
6131 DBusString filename;
6139 if (!_dbus_string_init (&test_directory))
6140 _dbus_assert_not_reached ("didn't allocate test_directory\n");
6142 _dbus_string_init_const (&filename, subdir);
6144 if (!_dbus_string_copy (test_base_dir, 0,
6145 &test_directory, 0))
6146 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
6148 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
6149 _dbus_assert_not_reached ("couldn't allocate full path");
6151 _dbus_string_free (&filename);
6152 if (!_dbus_string_init (&filename))
6153 _dbus_assert_not_reached ("didn't allocate filename string\n");
6155 dbus_error_init (&error);
6156 dir = _dbus_directory_open (&test_directory, &error);
6159 _dbus_warn ("Could not open %s: %s\n",
6160 _dbus_string_get_const_data (&test_directory),
6162 dbus_error_free (&error);
6166 printf ("Testing %s:\n", subdir);
6169 while (_dbus_directory_get_next_file (dir, &filename, &error))
6171 DBusString full_path;
6174 if (!_dbus_string_init (&full_path))
6175 _dbus_assert_not_reached ("couldn't init string");
6177 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
6178 _dbus_assert_not_reached ("couldn't copy dir to full_path");
6180 if (!_dbus_concat_dir_and_file (&full_path, &filename))
6181 _dbus_assert_not_reached ("couldn't concat file to dir");
6183 if (_dbus_string_ends_with_c_str (&filename, ".message"))
6185 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
6189 _dbus_verbose ("Skipping non-.message file %s\n",
6190 _dbus_string_get_const_data (&filename));
6191 _dbus_string_free (&full_path);
6196 _dbus_string_get_const_data (&filename));
6198 _dbus_verbose (" expecting %s for %s\n",
6199 validity == _DBUS_MESSAGE_VALID ? "valid" :
6200 (validity == _DBUS_MESSAGE_INVALID ? "invalid" :
6201 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")),
6202 _dbus_string_get_const_data (&filename));
6204 if (! (*function) (&full_path, is_raw, validity, user_data))
6206 _dbus_string_free (&full_path);
6210 _dbus_string_free (&full_path);
6213 if (dbus_error_is_set (&error))
6215 _dbus_warn ("Could not get next file in %s: %s\n",
6216 _dbus_string_get_const_data (&test_directory),
6218 dbus_error_free (&error);
6227 _dbus_directory_close (dir);
6228 _dbus_string_free (&test_directory);
6229 _dbus_string_free (&filename);
6235 * Runs the given function on every message file in the test suite.
6236 * The function should return #FALSE on test failure or fatal error.
6238 * @param test_data_dir root dir of the test suite data files (top_srcdir/test/data)
6239 * @param func the function to run
6240 * @param user_data data for function
6241 * @returns #FALSE if there's a failure
6244 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
6245 DBusForeachMessageFileFunc func,
6248 DBusString test_directory;
6253 _dbus_string_init_const (&test_directory, test_data_dir);
6255 if (!process_test_subdir (&test_directory, "valid-messages",
6256 _DBUS_MESSAGE_VALID, func, user_data))
6259 if (!process_test_subdir (&test_directory, "invalid-messages",
6260 _DBUS_MESSAGE_INVALID, func, user_data))
6263 if (!process_test_subdir (&test_directory, "incomplete-messages",
6264 _DBUS_MESSAGE_INCOMPLETE, func, user_data))
6271 _dbus_string_free (&test_directory);
6277 verify_test_message (DBusMessage *message)
6279 DBusMessageIter iter, dict;
6281 dbus_int32_t our_int;
6284 dbus_bool_t our_bool;
6285 dbus_uint32_t our_uint32;
6286 dbus_int32_t *our_uint32_array;
6287 int our_uint32_array_len;
6288 dbus_int32_t *our_int32_array;
6289 int our_int32_array_len;
6290 char **our_string_array;
6291 int our_string_array_len;
6292 #ifdef DBUS_HAVE_INT64
6293 dbus_int64_t our_int64;
6294 dbus_uint64_t our_uint64;
6295 dbus_int64_t *our_uint64_array;
6296 int our_uint64_array_len;
6297 dbus_int64_t *our_int64_array;
6298 int our_int64_array_len;
6300 double *our_double_array;
6301 int our_double_array_len;
6302 unsigned char *our_byte_array;
6303 int our_byte_array_len;
6304 unsigned char *our_boolean_array;
6305 int our_boolean_array_len;
6307 dbus_message_iter_init (message, &iter);
6309 dbus_error_init (&error);
6310 if (!dbus_message_iter_get_args (&iter, &error,
6311 DBUS_TYPE_INT32, &our_int,
6312 #ifdef DBUS_HAVE_INT64
6313 DBUS_TYPE_INT64, &our_int64,
6314 DBUS_TYPE_UINT64, &our_uint64,
6316 DBUS_TYPE_STRING, &our_str,
6317 DBUS_TYPE_DOUBLE, &our_double,
6318 DBUS_TYPE_BOOLEAN, &our_bool,
6319 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
6320 &our_uint32_array, &our_uint32_array_len,
6321 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
6322 &our_int32_array, &our_int32_array_len,
6323 #ifdef DBUS_HAVE_INT64
6324 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
6325 &our_uint64_array, &our_uint64_array_len,
6326 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
6327 &our_int64_array, &our_int64_array_len,
6329 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
6330 &our_string_array, &our_string_array_len,
6331 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
6332 &our_double_array, &our_double_array_len,
6333 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
6334 &our_byte_array, &our_byte_array_len,
6335 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
6336 &our_boolean_array, &our_boolean_array_len,
6339 _dbus_warn ("error: %s - %s\n", error.name,
6340 (error.message != NULL) ? error.message : "no message");
6341 _dbus_assert_not_reached ("Could not get arguments");
6344 if (our_int != -0x12345678)
6345 _dbus_assert_not_reached ("integers differ!");
6347 #ifdef DBUS_HAVE_INT64
6348 if (our_int64 != -0x123456789abcd)
6349 _dbus_assert_not_reached ("64-bit integers differ!");
6350 if (our_uint64 != 0x123456789abcd)
6351 _dbus_assert_not_reached ("64-bit unsigned integers differ!");
6354 if (our_double != 3.14159)
6355 _dbus_assert_not_reached ("doubles differ!");
6357 if (strcmp (our_str, "Test string") != 0)
6358 _dbus_assert_not_reached ("strings differ!");
6359 dbus_free (our_str);
6362 _dbus_assert_not_reached ("booleans differ");
6364 if (our_uint32_array_len != 4 ||
6365 our_uint32_array[0] != 0x12345678 ||
6366 our_uint32_array[1] != 0x23456781 ||
6367 our_uint32_array[2] != 0x34567812 ||
6368 our_uint32_array[3] != 0x45678123)
6369 _dbus_assert_not_reached ("uint array differs");
6370 dbus_free (our_uint32_array);
6372 if (our_int32_array_len != 4 ||
6373 our_int32_array[0] != 0x12345678 ||
6374 our_int32_array[1] != -0x23456781 ||
6375 our_int32_array[2] != 0x34567812 ||
6376 our_int32_array[3] != -0x45678123)
6377 _dbus_assert_not_reached ("int array differs");
6378 dbus_free (our_int32_array);
6380 #ifdef DBUS_HAVE_INT64
6381 if (our_uint64_array_len != 4 ||
6382 our_uint64_array[0] != 0x12345678 ||
6383 our_uint64_array[1] != 0x23456781 ||
6384 our_uint64_array[2] != 0x34567812 ||
6385 our_uint64_array[3] != 0x45678123)
6386 _dbus_assert_not_reached ("uint64 array differs");
6387 dbus_free (our_uint64_array);
6389 if (our_int64_array_len != 4 ||
6390 our_int64_array[0] != 0x12345678 ||
6391 our_int64_array[1] != -0x23456781 ||
6392 our_int64_array[2] != 0x34567812 ||
6393 our_int64_array[3] != -0x45678123)
6394 _dbus_assert_not_reached ("int64 array differs");
6395 dbus_free (our_int64_array);
6396 #endif /* DBUS_HAVE_INT64 */
6398 if (our_string_array_len != 4)
6399 _dbus_assert_not_reached ("string array has wrong length");
6401 if (strcmp (our_string_array[0], "Foo") != 0 ||
6402 strcmp (our_string_array[1], "bar") != 0 ||
6403 strcmp (our_string_array[2], "") != 0 ||
6404 strcmp (our_string_array[3], "woo woo woo woo") != 0)
6405 _dbus_assert_not_reached ("string array differs");
6407 dbus_free_string_array (our_string_array);
6409 if (our_double_array_len != 3)
6410 _dbus_assert_not_reached ("double array had wrong length");
6412 /* On all IEEE machines (i.e. everything sane) exact equality
6413 * should be preserved over the wire
6415 if (our_double_array[0] != 0.1234 ||
6416 our_double_array[1] != 9876.54321 ||
6417 our_double_array[2] != -300.0)
6418 _dbus_assert_not_reached ("double array had wrong values");
6420 dbus_free (our_double_array);
6422 if (our_byte_array_len != 4)
6423 _dbus_assert_not_reached ("byte array had wrong length");
6425 if (our_byte_array[0] != 'a' ||
6426 our_byte_array[1] != 'b' ||
6427 our_byte_array[2] != 'c' ||
6428 our_byte_array[3] != 234)
6429 _dbus_assert_not_reached ("byte array had wrong values");
6431 dbus_free (our_byte_array);
6433 if (our_boolean_array_len != 5)
6434 _dbus_assert_not_reached ("bool array had wrong length");
6436 if (our_boolean_array[0] != TRUE ||
6437 our_boolean_array[1] != FALSE ||
6438 our_boolean_array[2] != TRUE ||
6439 our_boolean_array[3] != TRUE ||
6440 our_boolean_array[4] != FALSE)
6441 _dbus_assert_not_reached ("bool array had wrong values");
6443 dbus_free (our_boolean_array);
6445 if (!dbus_message_iter_next (&iter))
6446 _dbus_assert_not_reached ("Reached end of arguments");
6448 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
6449 _dbus_assert_not_reached ("not dict type");
6451 if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
6452 _dbus_assert_not_reached ("dict iter failed");
6454 our_str = dbus_message_iter_get_dict_key (&dict);
6455 if (our_str == NULL || strcmp (our_str, "test") != 0)
6456 _dbus_assert_not_reached ("wrong dict key");
6457 dbus_free (our_str);
6459 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
6461 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
6462 _dbus_assert_not_reached ("wrong dict entry type");
6465 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF)
6467 _dbus_verbose ("dict entry val: %x\n", our_uint32);
6468 _dbus_assert_not_reached ("wrong dict entry value");
6471 if (dbus_message_iter_next (&dict))
6472 _dbus_assert_not_reached ("Didn't reach end of dict");
6474 if (!dbus_message_iter_next (&iter))
6475 _dbus_assert_not_reached ("Reached end of arguments");
6477 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
6478 _dbus_assert_not_reached ("wrong type after dict");
6480 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
6481 _dbus_assert_not_reached ("wrong value after dict");
6483 if (dbus_message_iter_next (&iter))
6484 _dbus_assert_not_reached ("Didn't reach end of arguments");
6488 * @ingroup DBusMessageInternals
6489 * Unit test for DBusMessage.
6491 * @returns #TRUE on success.
6494 _dbus_message_test (const char *test_data_dir)
6496 DBusMessage *message;
6497 DBusMessageLoader *loader;
6498 DBusMessageIter iter, child_iter, child_iter2, child_iter3;
6504 const dbus_uint32_t our_uint32_array[] =
6505 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
6506 const dbus_uint32_t our_int32_array[] =
6507 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
6508 #ifdef DBUS_HAVE_INT64
6509 const dbus_uint64_t our_uint64_array[] =
6510 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
6511 const dbus_uint64_t our_int64_array[] =
6512 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
6514 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
6515 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
6516 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
6517 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
6519 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
6521 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
6522 "/org/freedesktop/TestPath",
6523 "Foo.TestInterface",
6525 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
6526 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
6528 _dbus_message_set_serial (message, 1234);
6529 /* string length including nul byte not a multiple of 4 */
6530 dbus_message_set_sender (message, "org.foo.bar1");
6531 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
6532 dbus_message_set_reply_serial (message, 5678);
6533 dbus_message_set_sender (message, NULL);
6534 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
6535 _dbus_assert (dbus_message_get_serial (message) == 1234);
6536 _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
6537 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
6539 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
6540 dbus_message_set_no_reply (message, TRUE);
6541 _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
6542 dbus_message_set_no_reply (message, FALSE);
6543 _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
6545 dbus_message_unref (message);
6547 /* Test the vararg functions */
6548 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
6549 "/org/freedesktop/TestPath",
6550 "Foo.TestInterface",
6552 _dbus_message_set_serial (message, 1);
6553 dbus_message_append_args (message,
6554 DBUS_TYPE_INT32, -0x12345678,
6555 #ifdef DBUS_HAVE_INT64
6556 DBUS_TYPE_INT64, -0x123456789abcd,
6557 DBUS_TYPE_UINT64, 0x123456789abcd,
6559 DBUS_TYPE_STRING, "Test string",
6560 DBUS_TYPE_DOUBLE, 3.14159,
6561 DBUS_TYPE_BOOLEAN, TRUE,
6562 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array,
6563 _DBUS_N_ELEMENTS (our_uint32_array),
6564 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
6565 _DBUS_N_ELEMENTS (our_int32_array),
6566 #ifdef DBUS_HAVE_INT64
6567 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
6568 _DBUS_N_ELEMENTS (our_uint64_array),
6569 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
6570 _DBUS_N_ELEMENTS (our_int64_array),
6572 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
6573 _DBUS_N_ELEMENTS (our_string_array),
6574 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
6575 _DBUS_N_ELEMENTS (our_double_array),
6576 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array,
6577 _DBUS_N_ELEMENTS (our_byte_array),
6578 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array,
6579 _DBUS_N_ELEMENTS (our_boolean_array),
6582 dbus_message_append_iter_init (message, &iter);
6583 dbus_message_iter_append_dict (&iter, &child_iter);
6584 dbus_message_iter_append_dict_key (&child_iter, "test");
6585 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
6586 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
6588 _dbus_verbose_bytes_of_string (&message->header, 0,
6589 _dbus_string_get_length (&message->header));
6590 _dbus_verbose_bytes_of_string (&message->body, 0,
6591 _dbus_string_get_length (&message->body));
6593 verify_test_message (message);
6595 copy = dbus_message_copy (message);
6597 _dbus_assert (message->client_serial == copy->client_serial);
6598 _dbus_assert (message->reply_serial == copy->reply_serial);
6599 _dbus_assert (message->header_padding == copy->header_padding);
6601 _dbus_assert (_dbus_string_get_length (&message->header) ==
6602 _dbus_string_get_length (©->header));
6604 _dbus_assert (_dbus_string_get_length (&message->body) ==
6605 _dbus_string_get_length (©->body));
6607 verify_test_message (copy);
6609 name1 = dbus_message_get_interface (message);
6610 name2 = dbus_message_get_interface (copy);
6612 _dbus_assert (strcmp (name1, name2) == 0);
6614 name1 = dbus_message_get_member (message);
6615 name2 = dbus_message_get_member (copy);
6617 _dbus_assert (strcmp (name1, name2) == 0);
6619 dbus_message_unref (message);
6620 dbus_message_unref (copy);
6622 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
6623 "/org/freedesktop/TestPath",
6624 "Foo.TestInterface",
6627 _dbus_message_set_serial (message, 1);
6628 dbus_message_set_reply_serial (message, 0x12345678);
6630 dbus_message_append_iter_init (message, &iter);
6631 dbus_message_iter_append_string (&iter, "Test string");
6632 dbus_message_iter_append_int32 (&iter, -0x12345678);
6633 dbus_message_iter_append_uint32 (&iter, 0xedd1e);
6634 dbus_message_iter_append_double (&iter, 3.14159);
6636 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE);
6637 dbus_message_iter_append_double (&child_iter, 1.5);
6638 dbus_message_iter_append_double (&child_iter, 2.5);
6641 dbus_message_iter_append_dict (&iter, &child_iter);
6642 dbus_message_iter_append_dict_key (&child_iter, "test");
6643 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
6645 /* array of array of int32 (in dict) */
6646 dbus_message_iter_append_dict_key (&child_iter, "array");
6647 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY);
6648 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
6649 dbus_message_iter_append_int32 (&child_iter3, 0x12345678);
6650 dbus_message_iter_append_int32 (&child_iter3, 0x23456781);
6651 _dbus_warn ("next call expected to fail with wrong array type\n");
6652 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32));
6653 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32);
6654 dbus_message_iter_append_int32 (&child_iter3, 0x34567812);
6655 dbus_message_iter_append_int32 (&child_iter3, 0x45678123);
6656 dbus_message_iter_append_int32 (&child_iter3, 0x56781234);
6658 dbus_message_iter_append_byte (&iter, 0xF0);
6660 dbus_message_iter_append_nil (&iter);
6662 dbus_message_iter_append_named (&iter, "named",
6665 message_iter_test (message);
6667 /* Message loader test */
6668 _dbus_message_lock (message);
6669 loader = _dbus_message_loader_new ();
6671 /* check ref/unref */
6672 _dbus_message_loader_ref (loader);
6673 _dbus_message_loader_unref (loader);
6675 /* Write the header data one byte at a time */
6676 data = _dbus_string_get_const_data (&message->header);
6677 for (i = 0; i < _dbus_string_get_length (&message->header); i++)
6681 _dbus_message_loader_get_buffer (loader, &buffer);
6682 _dbus_string_append_byte (buffer, data[i]);
6683 _dbus_message_loader_return_buffer (loader, buffer, 1);
6686 /* Write the body data one byte at a time */
6687 data = _dbus_string_get_const_data (&message->body);
6688 for (i = 0; i < _dbus_string_get_length (&message->body); i++)
6692 _dbus_message_loader_get_buffer (loader, &buffer);
6693 _dbus_string_append_byte (buffer, data[i]);
6694 _dbus_message_loader_return_buffer (loader, buffer, 1);
6697 dbus_message_unref (message);
6699 /* Now pop back the message */
6700 if (!_dbus_message_loader_queue_messages (loader))
6701 _dbus_assert_not_reached ("no memory to queue messages");
6703 if (_dbus_message_loader_get_is_corrupted (loader))
6704 _dbus_assert_not_reached ("message loader corrupted");
6706 message = _dbus_message_loader_pop_message (loader);
6708 _dbus_assert_not_reached ("received a NULL message");
6710 if (dbus_message_get_reply_serial (message) != 0x12345678)
6711 _dbus_assert_not_reached ("reply serial fields differ");
6713 message_iter_test (message);
6715 dbus_message_unref (message);
6716 _dbus_message_loader_unref (loader);
6718 /* Now load every message in test_data_dir if we have one */
6719 if (test_data_dir == NULL)
6722 return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
6723 (DBusForeachMessageFileFunc)
6724 dbus_internal_do_not_use_try_message_file,
6728 #endif /* DBUS_BUILD_TESTS */