summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-message.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2003-04-08 15:52:51 +0000
committerAlexander Larsson <alexl@redhat.com>2003-04-08 15:52:51 +0000
commitc5020ac870c5990a36c3576453cc23431213e8bf (patch)
tree8b5c4c5b884e9481d1ce17b9a24d9c1bbe094428 /dbus/dbus-message.c
parenta162febe6746269f51b3a16db5f6fb240001f828 (diff)
2003-04-08 Alexander Larsson <alexl@redhat.com>
Implemented recursive types, named types and new-style iters * bus/driver.c: * glib/test-thread-client.c: (thread_func): * glib/test-thread-server.c: (handle_test_message): * test/test-service.c: (handle_echo): Update to new api * dbus/Makefile.am: * dbus/dbus-dict.c: * dbus/dbus-dict.h: * dbus/dbus.h Remove DBusDict * dbus/dbus-internals.c: (_dbus_type_to_string): Update for new types. * dbus/dbus-marshal.[ch]: Implement recursive types and the new marshalling format. Remove hardcoded dict marshalling. Marshal named types. * dbus/dbus-message-builder.c: Add BYTE_ARRAY. Remove references to old types * dbus/dbus-message.[ch]: New non-refcounted iter API that supports recursive iters. Use iters for appending, including support for recursive iters. Add byte and named type support. Update everything to new marshalling formats. Add tests for new API. * dbus/dbus-protocol.h: Remove old array types. Add types: BYTE, ARRAY, DICT, NAMED * dbus/dbus-string.c: * dbus/dbus-sysdeps.c: Make parse_double locale safe. * dbus/dbus-test-main.c: Call setlocale. * dbus/dbus-test.c: Kill dict test * doc/dbus-specification.sgml: Update spec * test/data/incomplete-messages/missing-body.message: * test/data/invalid-messages/bad-boolean.message: * test/data/invalid-messages/bad-boolean-array.message: * test/data/invalid-messages/boolean-array-length-too-long.message-raw: * test/data/invalid-messages/boolean-has-no-value.message-raw: * test/data/invalid-messages/too-short-dict.message: * test/data/valid-messages/dict-simple.message: * test/data/valid-messages/dict.message: * test/data/valid-messages/emptiness.message: * test/data/valid-messages/lots-of-arguments.message: * test/data/valid-messages/no-padding.message: * test/data/valid-messages/recursive-types.message: Add missing NAME fields Fix up dicts & arrays * test/data/invalid-messages/dict-with-nil-value.message: Removed, this is not invalid anymore. * test/data/valid-messages/recursive-types.message: Add new test for deeply recursive types.
Diffstat (limited to 'dbus/dbus-message.c')
-rw-r--r--dbus/dbus-message.c2542
1 files changed, 1760 insertions, 782 deletions
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 46c4c406..994e160d 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -103,22 +103,40 @@ struct DBusMessage
DBusCounter *size_counter; /**< Counter for the size of the message, or #NULL */
long size_counter_delta; /**< Size we incremented the size counter by. */
+
+ dbus_uint32_t changed_stamp;
unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
};
+enum {
+ DBUS_MESSAGE_ITER_TYPE_MESSAGE,
+ DBUS_MESSAGE_ITER_TYPE_ARRAY,
+ DBUS_MESSAGE_ITER_TYPE_DICT
+};
+
+typedef struct DBusMessageRealIter DBusMessageRealIter;
+
/**
* @brief Internals of DBusMessageIter
*
* Object representing a position in a message. All fields are internal.
*/
-struct DBusMessageIter
+struct DBusMessageRealIter
{
- int refcount; /**< Reference count */
-
- int pos; /**< Current position in the string */
-
+ DBusMessageRealIter *parent_iter; /**< parent iter, or NULL */
DBusMessage *message; /**< Message used */
+ dbus_uint32_t changed_stamp; /**< stamp to detect invalid iters */
+
+ /* This is an int instead of an enum to get a guaranteed size for the dummy: */
+ int type; /**< type of iter */
+
+ int pos; /**< Current position in the string */
+ int end; /**< position right after the container */
+ int container_type; /**< type of the items in the container (used for arrays) */
+ int container_start; /**< offset of the start of the container */
+ int container_length_pos; /**< offset of the length of the container */
+ int wrote_dict_key; /**< whether we wrote the dict key for the current dict element */
};
/**
@@ -861,6 +879,7 @@ dbus_message_new_error_reply (DBusMessage *original_message,
{
DBusMessage *message;
const char *sender;
+ DBusMessageIter iter;
sender = get_string_field (original_message,
FIELD_SENDER, NULL);
@@ -879,7 +898,8 @@ dbus_message_new_error_reply (DBusMessage *original_message,
return NULL;
}
- if (!dbus_message_append_string (message, error_message))
+ dbus_message_append_iter_init (message, &iter);
+ if (!dbus_message_iter_append_string (&iter, error_message))
{
dbus_message_unref (message);
return NULL;
@@ -1034,10 +1054,12 @@ dbus_message_get_service (DBusMessage *message)
/**
* Appends fields to a message given a variable argument
* list. The variable argument list should contain the type
- * of the argument followed by the value to add. Array values
- * are specified by a pointer to the array followed by an int
- * giving the length of the array. The list is terminated
- * with 0.
+ * of the argument followed by the value to add.
+ * Array values are specified by a int typecode followed by a pointer
+ * to the array followed by an int giving the length of the array.
+ * The argument list must be terminated with 0.
+ *
+ * This function doesn't support dicts or non-fundamental arrays.
*
* @param message the message
* @param first_arg_type type of the first argument
@@ -1064,6 +1086,9 @@ dbus_message_append_args (DBusMessage *message,
/**
* This function takes a va_list for use by language bindings
*
+ * @todo: Shouldn't this function clean up the changes to the message
+ * on failures?
+
* @see dbus_message_append_args.
* @param message the message
* @param first_arg_type type of first argument
@@ -1076,122 +1101,110 @@ dbus_message_append_args_valist (DBusMessage *message,
va_list var_args)
{
int type, old_len;
+ DBusMessageIter iter;
old_len = _dbus_string_get_length (&message->body);
type = first_arg_type;
+ dbus_message_append_iter_init (message, &iter);
+
while (type != 0)
{
switch (type)
{
case DBUS_TYPE_NIL:
- if (!dbus_message_append_nil (message))
- goto enomem;
+ if (!dbus_message_iter_append_nil (&iter))
+ goto errorout;
+ break;
case DBUS_TYPE_BOOLEAN:
- if (!dbus_message_append_boolean (message, va_arg (var_args, dbus_bool_t)))
- goto enomem;
+ if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
+ goto errorout;
break;
case DBUS_TYPE_INT32:
- if (!dbus_message_append_int32 (message, va_arg (var_args, dbus_int32_t)))
- goto enomem;
+ if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
+ goto errorout;
break;
case DBUS_TYPE_UINT32:
- if (!dbus_message_append_uint32 (message, va_arg (var_args, dbus_uint32_t)))
- goto enomem;
+ if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
+ goto errorout;
break;
case DBUS_TYPE_DOUBLE:
- if (!dbus_message_append_double (message, va_arg (var_args, double)))
- goto enomem;
+ if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
+ goto errorout;
break;
case DBUS_TYPE_STRING:
- if (!dbus_message_append_string (message, va_arg (var_args, const char *)))
- goto enomem;
+ if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
+ goto errorout;
break;
- case DBUS_TYPE_BOOLEAN_ARRAY:
+ case DBUS_TYPE_NAMED:
{
- int len;
+ const char *name;
unsigned char *data;
-
- data = va_arg (var_args, unsigned char *);
- len = va_arg (var_args, int);
-
- if (!dbus_message_append_boolean_array (message, data, len))
- goto enomem;
- }
- break;
- case DBUS_TYPE_INT32_ARRAY:
- {
- int len;
- dbus_int32_t *data;
-
- data = va_arg (var_args, dbus_int32_t *);
- len = va_arg (var_args, int);
-
- if (!dbus_message_append_int32_array (message, data, len))
- goto enomem;
- }
- break;
- case DBUS_TYPE_UINT32_ARRAY:
- {
int len;
- dbus_uint32_t *data;
-
- data = va_arg (var_args, dbus_uint32_t *);
- len = va_arg (var_args, int);
-
- if (!dbus_message_append_uint32_array (message, data, len))
- goto enomem;
- }
- break;
- case DBUS_TYPE_DOUBLE_ARRAY:
- {
- int len;
- double *data;
-
- data = va_arg (var_args, double *);
- len = va_arg (var_args, int);
-
- if (!dbus_message_append_double_array (message, data, len))
- goto enomem;
- }
- break;
- case DBUS_TYPE_BYTE_ARRAY:
- {
- int len;
- unsigned char *data;
-
+
+ name = va_arg (var_args, const char *);
data = va_arg (var_args, unsigned char *);
len = va_arg (var_args, int);
- if (!dbus_message_append_byte_array (message, data, len))
- goto enomem;
+ if (!dbus_message_iter_append_named (&iter, name, data, len))
+ goto errorout;
+ break;
}
- break;
- case DBUS_TYPE_STRING_ARRAY:
+ case DBUS_TYPE_ARRAY:
{
- int len;
- const char **data;
-
- data = va_arg (var_args, const char **);
+ void *data;
+ int len, type;
+
+ type = va_arg (var_args, int);
+ data = va_arg (var_args, void *);
len = va_arg (var_args, int);
- if (!dbus_message_append_string_array (message, data, len))
- goto enomem;
+ switch (type)
+ {
+ case DBUS_TYPE_BYTE:
+ if (!dbus_message_iter_append_byte_array (&iter, (unsigned char *)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ if (!dbus_message_iter_append_boolean_array (&iter, (unsigned char *)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_INT32:
+ if (!dbus_message_iter_append_int32_array (&iter, (dbus_int32_t *)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_UINT32:
+ if (!dbus_message_iter_append_uint32_array (&iter, (dbus_uint32_t *)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_DOUBLE:
+ if (!dbus_message_iter_append_double_array (&iter, (double *)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_STRING:
+ if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_NAMED:
+ case DBUS_TYPE_DICT:
+ _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n");
+ goto errorout;
+ default:
+ _dbus_warn ("Unknown field type %d\n", type);
+ goto errorout;
+ }
}
break;
+
case DBUS_TYPE_DICT:
- {
- DBusDict *dict;
-
- dict = va_arg (var_args, DBusDict *);
-
- if (!dbus_message_append_dict (message, dict))
- goto enomem;
- break;
- }
+ _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n");
+ goto errorout;
default:
_dbus_warn ("Unknown field type %d\n", type);
+ goto errorout;
}
type = va_arg (var_args, int);
@@ -1199,360 +1212,82 @@ dbus_message_append_args_valist (DBusMessage *message,
return TRUE;
- enomem:
+ errorout:
return FALSE;
}
-/**
- * Appends a nil value to the message
- *
- * @param message the message
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_nil (DBusMessage *message)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_NIL))
- return FALSE;
- else
- return TRUE;
-}
-
-/**
- * Appends a boolean value to the message
- *
- * @param message the message
- * @param value the boolean value
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_boolean (DBusMessage *message,
- dbus_bool_t value)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_BOOLEAN))
- return FALSE;
-
- if (!_dbus_string_append_byte (&message->body, (value != FALSE)))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a 32 bit signed integer to the message.
- *
- * @param message the message
- * @param value the integer value
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_int32 (DBusMessage *message,
- dbus_int32_t value)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_INT32))
- return FALSE;
-
- if (!_dbus_marshal_int32 (&message->body, message->byte_order, value))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
/**
- * Appends a 32 bit unsigned integer to the message.
- *
- * @param message the message
- * @param value the integer value
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_uint32 (DBusMessage *message,
- dbus_uint32_t value)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_UINT32))
- return FALSE;
-
- if (!_dbus_marshal_uint32 (&message->body, message->byte_order, value))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a double value to the message.
- *
- * @param message the message
- * @param value the double value
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_double (DBusMessage *message,
- double value)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DOUBLE))
- return FALSE;
-
- if (!_dbus_marshal_double (&message->body, message->byte_order, value))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a UTF-8 string to the message.
+ * Gets arguments from a message given a variable argument list.
+ * The variable argument list should contain the type of the
+ * argumen followed by a pointer to where the value should be
+ * stored. The list is terminated with 0.
*
* @param message the message
- * @param value the string
- * @returns #TRUE on success
+ * @param error error to be filled in on failure
+ * @param first_arg_type the first argument type
+ * @param ... location for first argument value, then list of type-location pairs
+ * @returns #FALSE if the error was set
*/
dbus_bool_t
-dbus_message_append_string (DBusMessage *message,
- const char *value)
+dbus_message_get_args (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ ...)
{
- _dbus_assert (!message->locked);
+ dbus_bool_t retval;
+ va_list var_args;
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING))
- return FALSE;
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (!_dbus_marshal_string (&message->body, message->byte_order, value))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a boolean array to the message.
- *
- * @param message the message
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_boolean_array (DBusMessage *message,
- unsigned const char *value,
- int len)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_BOOLEAN_ARRAY))
- return FALSE;
-
- if (!_dbus_marshal_byte_array (&message->body, message->byte_order, value, len))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a 32 bit signed integer array to the message.
- *
- * @param message the message
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_int32_array (DBusMessage *message,
- const dbus_int32_t *value,
- int len)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_INT32_ARRAY))
- return FALSE;
-
- if (!_dbus_marshal_int32_array (&message->body, message->byte_order,
- value, len))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a 32 bit unsigned integer array to the message.
- *
- * @param message the message
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_uint32_array (DBusMessage *message,
- const dbus_uint32_t *value,
- int len)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_UINT32_ARRAY))
- return FALSE;
-
- if (!_dbus_marshal_uint32_array (&message->body, message->byte_order,
- value, len))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a double array to the message.
- *
- * @param message the message
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_double_array (DBusMessage *message,
- const double *value,
- int len)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DOUBLE_ARRAY))
- return FALSE;
-
- if (!_dbus_marshal_double_array (&message->body, message->byte_order,
- value, len))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a byte array to the message.
- *
- * @param message the message
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_byte_array (DBusMessage *message,
- unsigned const char *value,
- int len)
-{
- _dbus_assert (!message->locked);
+ va_start (var_args, first_arg_type);
+ retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
+ va_end (var_args);
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_BYTE_ARRAY))
- return FALSE;
-
- if (!_dbus_marshal_byte_array (&message->body, message->byte_order, value, len))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
+ return retval;
}
/**
- * Appends a string array to the message.
+ * This function takes a va_list for use by language bindings
*
- * @param message the message
- * @param value the array
- * @param len the length of the array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_append_string_array (DBusMessage *message,
- const char **value,
- int len)
-{
- _dbus_assert (!message->locked);
-
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING_ARRAY))
- return FALSE;
-
- if (!_dbus_marshal_string_array (&message->body, message->byte_order,
- (const char **)value, len))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Appends a dict to the message.
+ * @todo We need to free the argument data when an error occurs.
*
+ * @see dbus_message_get_args
* @param message the message
- * @param dict the dict
- * @returns #TRUE on success
+ * @param error error to be filled in
+ * @param first_arg_type type of the first argument
+ * @param var_args return location for first argument, followed by list of type/location pairs
+ * @returns #FALSE if error was set
*/
dbus_bool_t
-dbus_message_append_dict (DBusMessage *message,
- DBusDict *dict)
+dbus_message_get_args_valist (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args)
{
- _dbus_assert (!message->locked);
+ DBusMessageIter iter;
- if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DICT))
- return FALSE;
-
- if (!_dbus_marshal_dict (&message->body, message->byte_order, dict))
- {
- _dbus_string_shorten (&message->body, 1);
- return FALSE;
- }
-
- return TRUE;
+ dbus_message_iter_init (message, &iter);
+ return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
}
/**
- * Gets arguments from a message given a variable argument list.
+ * Gets arguments from a message iterator given a variable argument list.
* The variable argument list should contain the type of the
* argumen followed by a pointer to where the value should be
* stored. The list is terminated with 0.
*
- * @param message the message
+ * @param iter the message iterator
* @param error error to be filled in on failure
* @param first_arg_type the first argument type
* @param ... location for first argument value, then list of type-location pairs
* @returns #FALSE if the error was set
*/
dbus_bool_t
-dbus_message_get_args (DBusMessage *message,
- DBusError *error,
- int first_arg_type,
- ...)
+dbus_message_iter_get_args (DBusMessageIter *iter,
+ DBusError *error,
+ int first_arg_type,
+ ...)
{
dbus_bool_t retval;
va_list var_args;
@@ -1560,7 +1295,7 @@ dbus_message_get_args (DBusMessage *message,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
va_start (var_args, first_arg_type);
- retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
+ retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
va_end (var_args);
return retval;
@@ -1579,31 +1314,22 @@ dbus_message_get_args (DBusMessage *message,
* @todo We need to free the argument data when an error occurs.
*
* @see dbus_message_get_args
- * @param message the message
+ * @param iter the message iter
* @param error error to be filled in
* @param first_arg_type type of the first argument
* @param var_args return location for first argument, followed by list of type/location pairs
* @returns #FALSE if error was set
*/
dbus_bool_t
-dbus_message_get_args_valist (DBusMessage *message,
- DBusError *error,
- int first_arg_type,
- va_list var_args)
+dbus_message_iter_get_args_valist (DBusMessageIter *iter,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args)
{
int spec_type, msg_type, i;
- DBusMessageIter *iter;
dbus_bool_t retval;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- iter = dbus_message_get_args_iter (message);
-
- if (iter == NULL)
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- return FALSE;
- }
retval = FALSE;
@@ -1629,6 +1355,15 @@ dbus_message_get_args_valist (DBusMessage *message,
{
case DBUS_TYPE_NIL:
break;
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char *ptr;
+
+ ptr = va_arg (var_args, unsigned char *);
+
+ *ptr = dbus_message_iter_get_byte (iter);
+ break;
+ }
case DBUS_TYPE_BOOLEAN:
{
dbus_bool_t *ptr;
@@ -1684,117 +1419,109 @@ dbus_message_get_args_valist (DBusMessage *message,
break;
}
- case DBUS_TYPE_BOOLEAN_ARRAY:
+ case DBUS_TYPE_NAMED:
{
- unsigned char **ptr;
+ char **name;
+ unsigned char **data;
int *len;
-
- ptr = va_arg (var_args, unsigned char **);
+
+ name = va_arg (var_args, char **);
+ data = va_arg (var_args, unsigned char **);
len = va_arg (var_args, int *);
- if (!dbus_message_iter_get_boolean_array (iter, ptr, len))
- {
+ *name = dbus_message_iter_get_named (iter, data, len);
+ if (*name == NULL)
+ {
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- break;
+ goto out;
+ }
}
-
- case DBUS_TYPE_INT32_ARRAY:
- {
- dbus_int32_t **ptr;
- int *len;
-
- ptr = va_arg (var_args, dbus_int32_t **);
- len = va_arg (var_args, int *);
-
- if (!dbus_message_iter_get_int32_array (iter, ptr, len))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
-
- break;
- }
-
- case DBUS_TYPE_UINT32_ARRAY:
+ break;
+ case DBUS_TYPE_ARRAY:
{
- dbus_uint32_t **ptr;
- int *len;
-
- ptr = va_arg (var_args, dbus_uint32_t **);
+ void **data;
+ int *len, type;
+
+ type = va_arg (var_args, int);
+ data = va_arg (var_args, void *);
len = va_arg (var_args, int *);
- if (!dbus_message_iter_get_uint32_array (iter, ptr, len))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
+ if (dbus_message_iter_get_array_type (iter) != type)
+ {
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Argument %d is specified to be of type \"array of %s\", but "
+ "is actually of type \"array of %s\"\n", i,
+ _dbus_type_to_string (type),
+ _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
+ goto out;
+ }
- break;
- }
-
- case DBUS_TYPE_DOUBLE_ARRAY:
- {
- double **ptr;
- int *len;
-
- ptr = va_arg (var_args, double **);
- len = va_arg (var_args, int *);
-
- if (!dbus_message_iter_get_double_array (iter, ptr, len))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- break;
- }
-
- case DBUS_TYPE_BYTE_ARRAY:
- {
- unsigned char **ptr;
- int *len;
-
- ptr = va_arg (var_args, unsigned char **);
- len = va_arg (var_args, int *);
-
- if (!dbus_message_iter_get_byte_array (iter, ptr, len))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- break;
- }
- case DBUS_TYPE_STRING_ARRAY:
- {
- char ***ptr;
- int *len;
-
- ptr = va_arg (var_args, char ***);
- len = va_arg (var_args, int *);
-
- if (!dbus_message_iter_get_string_array (iter, ptr, len))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- break;
+ switch (type)
+ {
+ case DBUS_TYPE_BYTE:
+ if (!dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ if (!dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ break;
+ case DBUS_TYPE_INT32:
+ if (!dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ break;
+ case DBUS_TYPE_UINT32:
+ if (!dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ break;
+ case DBUS_TYPE_DOUBLE:
+ if (!dbus_message_iter_get_double_array (iter, (double **)data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ break;
+ case DBUS_TYPE_STRING:
+ if (!dbus_message_iter_get_string_array (iter, (char ***)data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ break;
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_NAMED:
+ case DBUS_TYPE_DICT:
+ _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
+ dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
+ goto out;
+ default:
+ _dbus_warn ("Unknown field type %d\n", type);
+ dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
+ goto out;
+ }
}
+ break;
case DBUS_TYPE_DICT:
- {
- DBusDict **dict;
-
- dict = va_arg (var_args, DBusDict **);
-
- if (!dbus_message_iter_get_dict (iter, dict))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- break;
- }
+ _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
+ dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
+ goto out;
default:
+ dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
_dbus_warn ("Unknown field type %d\n", spec_type);
+ goto out;
}
spec_type = va_arg (var_args, int);
@@ -1811,81 +1538,92 @@ dbus_message_get_args_valist (DBusMessage *message,
retval = TRUE;
out:
- dbus_message_iter_unref (iter);
+
return retval;
}
+
/**
- * Returns a DBusMessageIter representing the arguments of the
+ * Initializes a DBusMessageIter representing the arguments of the
* message passed in.
*
- * @todo IMO the message iter should follow the GtkTextIter pattern,
- * a static object with a "stamp" value used to detect invalid
- * iter uses (uninitialized or after changing the message).
- * ref/unref is kind of annoying to deal with, and slower too.
- * This implies not ref'ing the message from the iter.
- *
- * @todo I'd also name this dbus_message_iter_new() or
- * for the static object dbus_message_iter_init() rather
- * than making it a method on the message
- *
* @param message the message
- * @returns a new iter.
+ * @param _iter pointer to an iterator to initialize
*/
-DBusMessageIter *
-dbus_message_get_args_iter (DBusMessage *message)
+void
+dbus_message_iter_init (DBusMessage *message,
+ DBusMessageIter *iter)
{
- DBusMessageIter *iter;
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- iter = dbus_new (DBusMessageIter, 1);
-
- if (iter != NULL)
- {
- dbus_message_ref (message);
+ real->message = message;
+ real->parent_iter = NULL;
+ real->changed_stamp = message->changed_stamp;
- iter->refcount = 1;
- iter->message = message;
- iter->pos = 0;
- }
+ real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
+ real->pos = 0;
+ real->end = _dbus_string_get_length (&message->body);
- return iter;
+ real->container_type = 0;
+ real->container_start = 0;
+ real->container_length_pos = 0;
+ real->wrote_dict_key = 0;
}
-/**
- * Increments the reference count of a DBusMessageIter.
- *
- * @param iter the message iter
- * @see dbus_message_iter_unref
- */
-void
-dbus_message_iter_ref (DBusMessageIter *iter)
+static void
+dbus_message_iter_check (DBusMessageRealIter *iter)
{
- _dbus_assert (iter->refcount > 0);
-
- iter->refcount += 1;
+ if (iter->changed_stamp != iter->message->changed_stamp)
+ _dbus_warn ("dbus iterator check failed: invalid iterator\n");
+ if (iter->pos < 0 || iter->pos > iter->end)
+ _dbus_warn ("dbus iterator check failed: invalid position\n");
}
-/**
- * Decrements the reference count of a DBusMessageIter.
- *
- * @param iter The message iter
- * @see dbus_message_iter_ref
- */
-void
-dbus_message_iter_unref (DBusMessageIter *iter)
+static int
+dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
{
- _dbus_assert (iter->refcount > 0);
-
- iter->refcount -= 1;
-
- if (iter->refcount == 0)
+ const char *data;
+ int pos, len;
+
+ switch (iter->type)
{
- dbus_message_unref (iter->message);
-
- dbus_free (iter);
+ case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
+ data = _dbus_string_get_const_data_len (&iter->message->body,
+ iter->pos, 1);
+ if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ *type = *data;
+ else
+ *type = DBUS_TYPE_INVALID;
+
+ return iter->pos + 1;
+
+ case DBUS_MESSAGE_ITER_TYPE_ARRAY:
+ *type = iter->container_type;
+ return iter->pos;
+
+
+ case DBUS_MESSAGE_ITER_TYPE_DICT:
+ /* Get the length of the string */
+ len = _dbus_demarshal_uint32 (&iter->message->body,
+ iter->message->byte_order,
+ iter->pos, &pos);
+ pos = pos + len + 1;
+ data = _dbus_string_get_const_data_len (&iter->message->body,
+ pos, 1);
+ if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ *type = *data;
+ else
+ *type = DBUS_TYPE_INVALID;
+ return pos + 1;
+ default:
+ _dbus_assert_not_reached ("Invalid iter type");
+ break;
}
+ *type = DBUS_TYPE_INVALID;
+ return iter->pos;
}
+
/**
* Checks if an iterator has any more fields.
*
@@ -1896,39 +1634,54 @@ dbus_message_iter_unref (DBusMessageIter *iter)
dbus_bool_t
dbus_message_iter_has_next (DBusMessageIter *iter)
{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
int end_pos;
-
- if (!_dbus_marshal_get_arg_end_pos (&iter->message->body,
- iter->message->byte_order,
- iter->pos, &end_pos))
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ if (real->pos >= real->end)
return FALSE;
- if (end_pos >= _dbus_string_get_length (&iter->message->body))
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
+ real->message->byte_order,
+ type, pos, &end_pos))
return FALSE;
+ if (end_pos >= real->end)
+ return FALSE;
+
return TRUE;
}
/**
* Moves the iterator to the next field.
*
- * @param iter The message iter
+ * @param _iter The message iter
* @returns #TRUE if the iterator was moved to the next field
*/
dbus_bool_t
dbus_message_iter_next (DBusMessageIter *iter)
{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
int end_pos;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
- if (!_dbus_marshal_get_arg_end_pos (&iter->message->body,
- iter->message->byte_order,
- iter->pos, &end_pos))
+ if (!_dbus_marshal_get_arg_end_pos (&real->message->body,
+ real->message->byte_order,
+ type, pos, &end_pos))
return FALSE;
- if (end_pos >= _dbus_string_get_length (&iter->message->body))
+ if (end_pos >= real->end)
return FALSE;
- iter->pos = end_pos;
+ real->pos = end_pos;
return TRUE;
}
@@ -1943,19 +1696,54 @@ dbus_message_iter_next (DBusMessageIter *iter)
int
dbus_message_iter_get_arg_type (DBusMessageIter *iter)
{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ if (real->pos >= real->end)
+ return DBUS_TYPE_INVALID;
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ return type;
+}
+
+/**
+ * Returns the element type of the array that the
+ * message iterator points at. Note that you need
+ * to check that the iterator points to an array
+ * prior to using this function.
+ *
+ * @param iter the message iter
+ * @returns the field type
+ */
+int
+dbus_message_iter_get_array_type (DBusMessageIter *iter)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
const char *data;
- if (iter->pos >= _dbus_string_get_length (&iter->message->body))
+ dbus_message_iter_check (real);
+
+ if (real->pos >= real->end)
return DBUS_TYPE_INVALID;
- data = _dbus_string_get_const_data_len (&iter->message->body, iter->pos, 1);
+ pos = dbus_message_iter_get_data_start (real, &type);
- if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_DICT)
- return *data;
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+ if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ return *data;
+
return DBUS_TYPE_INVALID;
}
+
/**
* Returns the string value that an iterator may point to.
* Note that you need to check that the iterator points to
@@ -1968,29 +1756,114 @@ dbus_message_iter_get_arg_type (DBusMessageIter *iter)
char *
dbus_message_iter_get_string (DBusMessageIter *iter)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_STRING);
+
+ return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
+ pos, NULL);
+}
+
+/**
+ * Returns the name and data from a named type that an
+ * iterator may point to.Note that you need to check that
+ * the iterator points to a named type before using this
+ * function.
+ *
+ * @see dbus_message_iter_get_arg_type
+ * @param iter the message iter
+ * @param value return location for data
+ * @param len return location for length of data
+ * @returns the named type name as a string
+ *
+ */
+char *
+dbus_message_iter_get_named (DBusMessageIter *iter,
+ unsigned char **value,
+ int *len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ char *name;
- return _dbus_demarshal_string (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL);
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_NAMED);
+
+ name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
+ pos, &pos);
+
+ if (name == NULL)
+ return NULL;
+
+ if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
+ {
+ dbus_free (name);
+ return NULL;
+ }
+ else
+ return name;
}
/**
+ * Returns the byte value that an iterator may point to.
+ * Note that you need to check that the iterator points to
+ * a byte value before using this function.
+ *
+ * @see dbus_message_iter_get_arg_type
+ * @param iter the message iter
+ * @returns the byte value
+ */
+unsigned char
+dbus_message_iter_get_byte (DBusMessageIter *iter)
+{
+ unsigned char value;
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_BYTE);
+
+ value = _dbus_string_get_byte (&real->message->body, pos);
+
+ return value;
+}
+
+
+/**
* Returns the boolean value that an iterator may point to.
* Note that you need to check that the iterator points to
* a boolean value before using this function.
*
* @see dbus_message_iter_get_arg_type
* @param iter the message iter
- * @returns the string
+ * @returns the boolean value
*/
dbus_bool_t
dbus_message_iter_get_boolean (DBusMessageIter *iter)
{
unsigned char value;
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN);
+ _dbus_assert (type == DBUS_TYPE_BOOLEAN);
- value = _dbus_string_get_byte (&iter->message->body, iter->pos + 1);
+ value = _dbus_string_get_byte (&real->message->body, pos);
return value;
}
@@ -2004,13 +1877,20 @@ dbus_message_iter_get_boolean (DBusMessageIter *iter)
* @param iter the message iter
* @returns the integer
*/
-int
+dbus_int32_t
dbus_message_iter_get_int32 (DBusMessageIter *iter)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_INT32);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_INT32);
- return _dbus_demarshal_int32 (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL);
+ return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order,
+ pos, NULL);
}
/**
@@ -2022,13 +1902,20 @@ dbus_message_iter_get_int32 (DBusMessageIter *iter)
* @param iter the message iter
* @returns the integer
*/
-int
+dbus_uint32_t
dbus_message_iter_get_uint32 (DBusMessageIter *iter)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UINT32);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
- return _dbus_demarshal_uint32 (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL);
+ _dbus_assert (type == DBUS_TYPE_UINT32);
+
+ return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
+ pos, NULL);
}
/**
@@ -2043,10 +1930,160 @@ dbus_message_iter_get_uint32 (DBusMessageIter *iter)
double
dbus_message_iter_get_double (DBusMessageIter *iter)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DOUBLE);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_DOUBLE);
- return _dbus_demarshal_double (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL);
+ return _dbus_demarshal_double (&real->message->body, real->message->byte_order,
+ pos, NULL);
+}
+
+/**
+ * Initializes an iterator for the array that the iterator
+ * may point to. Note that you need to check that the iterator
+ * points to an array prior to using this function.
+ *
+ * The array element type is returned in array_type, and the array
+ * iterator can only be used to get that type of data.
+ *
+ * @param iter the iterator
+ * @param array_iter pointer to an iterator to initialize
+ * @param array_type gets set to the type of the array elements
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
+ DBusMessageIter *array_iter,
+ int *array_type)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
+ int type, pos, len_pos, len;
+ int _array_type;
+ const char *data;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+ if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ _array_type = *data;
+ else
+ return FALSE;
+
+ len_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t));
+ len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
+ pos + 1, &pos);
+
+ array_real->parent_iter = real;
+ array_real->message = real->message;
+ array_real->changed_stamp = real->message->changed_stamp;
+
+ array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
+ array_real->pos = pos;
+ array_real->end = pos + len;
+
+ array_real->container_type = _array_type;
+ array_real->container_start = pos;
+ array_real->container_length_pos = len_pos;
+ array_real->wrote_dict_key = 0;
+
+ if (array_type != NULL)
+ *array_type = _array_type;
+
+ return TRUE;
+}
+
+
+/**
+ * Initializes an iterator for the dict that the iterator
+ * may point to. Note that you need to check that the iterator
+ * points to a dict prior to using this function.
+ *
+ * @param iter the iterator
+ * @param dict_iter pointer to an iterator to initialize
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
+ DBusMessageIter *dict_iter)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
+ int type, pos, len_pos, len;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_DICT);
+
+ len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
+ len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
+ pos, &pos);
+
+ dict_real->parent_iter = real;
+ dict_real->message = real->message;
+ dict_real->changed_stamp = real->message->changed_stamp;
+
+ dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
+ dict_real->pos = pos;
+ dict_real->end = pos + len;
+
+ dict_real->container_type = 0;
+ dict_real->container_start = pos;
+ dict_real->container_length_pos = len_pos;
+ dict_real->wrote_dict_key = 0;
+
+ return TRUE;
+}
+
+/**
+ * Returns the byte array that the iterator may point to.
+ * Note that you need to check that the iterator points
+ * to a byte array prior to using this function.
+ *
+ * @param iter the iterator
+ * @param value return location for array values
+ * @param len return location for length of byte array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_get_byte_array (DBusMessageIter *iter,
+ unsigned char **value,
+ int *len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ const char *data;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+
+ _dbus_assert (*data == DBUS_TYPE_BYTE);
+
+ if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
+ return FALSE;
+ else
+ return TRUE;
}
/**
@@ -2064,10 +2101,24 @@ dbus_message_iter_get_boolean_array (DBusMessageIter *iter,
unsigned char **value,
int *len)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN_ARRAY);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ const char *data;
+
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
- if (!_dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, value, len))
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+
+ _dbus_assert (*data == DBUS_TYPE_BOOLEAN);
+
+ if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
return FALSE;
else
return TRUE;
@@ -2088,10 +2139,24 @@ dbus_message_iter_get_int32_array (DBusMessageIter *iter,
dbus_int32_t **value,
int *len)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_INT32_ARRAY);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ const char *data;
- if (!_dbus_demarshal_int32_array (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, value, len))
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+
+ _dbus_assert (*data == DBUS_TYPE_INT32);
+
+ if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
return FALSE;
else
return TRUE;
@@ -2112,10 +2177,24 @@ dbus_message_iter_get_uint32_array (DBusMessageIter *iter,
dbus_uint32_t **value,
int *len)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UINT32_ARRAY);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ const char *data;
- if (!_dbus_demarshal_uint32_array (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, value, len))
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+
+ _dbus_assert (*data == DBUS_TYPE_UINT32);
+
+ if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
return FALSE;
else
return TRUE;
@@ -2136,34 +2215,24 @@ dbus_message_iter_get_double_array (DBusMessageIter *iter,
double **value,
int *len)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DOUBLE_ARRAY);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ const char *data;
- if (!_dbus_demarshal_double_array (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, value, len))
- return FALSE;
- else
- return TRUE;
-}
+ dbus_message_iter_check (real);
-/**
- * Returns the byte array that the iterator may point to.
- * Note that you need to check that the iterator points
- * to a byte array prior to using this function.
- *
- * @param iter the iterator
- * @param value return location for array values
- * @param len return location for length of byte array
- * @returns #TRUE on success
- */
-dbus_bool_t
-dbus_message_iter_get_byte_array (DBusMessageIter *iter,
- unsigned char **value,
- int *len)
-{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE_ARRAY);
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
- if (!_dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, value, len))
+ _dbus_assert (*data == DBUS_TYPE_DOUBLE);
+
+ if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
return FALSE;
else
return TRUE;
@@ -2189,35 +2258,756 @@ dbus_message_iter_get_string_array (DBusMessageIter *iter,
char ***value,
int *len)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING_ARRAY);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int type, pos;
+ const char *data;
- if (!_dbus_demarshal_string_array (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, value, len))
+ dbus_message_iter_check (real);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+ data = _dbus_string_get_const_data_len (&real->message->body,
+ pos,
+ 1);
+
+ _dbus_assert (*data == DBUS_TYPE_STRING);
+
+ if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order,
+ pos + 1, NULL, value, len))
return FALSE;
else
return TRUE;
}
/**
- * Returns the dict that the iterator may point to.
- * Note that you need to check that the iterator points
- * to a dict prior to using this function.
+ * Returns the key name fot the dict entry that an iterator
+ * may point to. Note that you need to check that the iterator
+ * points to a dict entry before using this function.
*
- * @param iter the iterator
- * @param dict return location for dict
+ * @see dbus_message_iter_init_dict_iterator
+ * @param iter the message iter
+ * @returns the key name
+ */
+char *
+dbus_message_iter_get_dict_key (DBusMessageIter *iter)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_check (real);
+
+ _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
+
+ return _dbus_demarshal_string (&real->message->body, real->message->byte_order,
+ real->pos, NULL);
+}
+
+/**
+ * Initializes a DBusMessageIter pointing to the end of the
+ * message. This iterator can be used to append data to the
+ * message.
+ *
+ * @param message the message
+ * @param _iter pointer to an iterator to initialize
+ */
+void
+dbus_message_append_iter_init (DBusMessage *message,
+ DBusMessageIter *iter)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ real->message = message;
+ real->parent_iter = NULL;
+ real->changed_stamp = message->changed_stamp;
+
+ real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE;
+ real->end = _dbus_string_get_length (&real->message->body);
+ real->pos = real->end;
+
+ real->container_type = 0;
+ real->container_length_pos = 0;
+ real->wrote_dict_key = 0;
+}
+
+static void
+dbus_message_iter_append_check (DBusMessageRealIter *iter)
+{
+ _dbus_assert (!iter->message->locked);
+
+ if (iter->changed_stamp != iter->message->changed_stamp)
+ _dbus_warn ("dbus iterator check failed: invalid iterator");
+
+ if (iter->pos != iter->end)
+ _dbus_warn ("dbus iterator check failed: can only append at end of message");
+
+ if (iter->pos != _dbus_string_get_length (&iter->message->body))
+ _dbus_warn ("dbus iterator check failed: append pos not at end of message string");
+}
+
+static dbus_bool_t
+dbus_message_iter_append_type (DBusMessageRealIter *iter,
+ int type)
+{
+ switch (iter->type)
+ {
+ case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
+ if (!_dbus_string_append_byte (&iter->message->body, type))
+ return FALSE;
+ break;
+
+ case DBUS_MESSAGE_ITER_TYPE_ARRAY:
+ if (type != iter->container_type)
+ {
+ _dbus_warn ("Appended element of wrong type for array\n");
+ return FALSE;
+ }
+ break;
+
+ case DBUS_MESSAGE_ITER_TYPE_DICT:
+ if (!iter->wrote_dict_key)
+ {
+ _dbus_warn ("Appending dict data before key name\n");
+ return FALSE;
+ }
+
+ if (!_dbus_string_append_byte (&iter->message->body, type))
+ return FALSE;
+
+ break;
+
+ default:
+ _dbus_assert_not_reached ("Invalid iter type");
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+dbus_message_iter_update_after_change (DBusMessageRealIter *iter)
+{
+ iter->changed_stamp = iter->message->changed_stamp;
+
+ /* Set new end of iter */
+ iter->end = _dbus_string_get_length (&iter->message->body);
+ iter->pos = iter->end;
+
+ /* Set container length */
+ if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT ||
+ iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY)
+ _dbus_marshal_set_uint32 (&iter->message->body,
+ iter->message->byte_order,
+ iter->container_length_pos,
+ iter->end - iter->container_start);
+
+ if (iter->parent_iter)
+ dbus_message_iter_update_after_change (iter->parent_iter);
+}
+
+static void
+dbus_message_iter_append_done (DBusMessageRealIter *iter)
+{
+ iter->message->changed_stamp++;
+ dbus_message_iter_update_after_change (iter);
+ iter->wrote_dict_key = FALSE;
+}
+
+/**
+ * Appends a nil value to the message
+ *
+ * @param iter an iterator pointing to the end of the message
* @returns #TRUE on success
*/
dbus_bool_t
-dbus_message_iter_get_dict (DBusMessageIter *iter,
- DBusDict **dict)
+dbus_message_iter_append_nil (DBusMessageIter *iter)
{
- _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DICT);
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
- if (!_dbus_demarshal_dict (&iter->message->body, iter->message->byte_order,
- iter->pos + 1, NULL, dict))
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL))
return FALSE;
- else
- return TRUE;
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a boolean value to the message
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the boolean value
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_boolean (DBusMessageIter *iter,
+ dbus_bool_t value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, (value != FALSE)))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a byte to the message
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the byte value
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_byte (DBusMessageIter *iter,
+ unsigned char value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_BOOLEAN))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, value))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+
+/**
+ * Appends a 32 bit signed integer to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the integer value
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_int32 (DBusMessageIter *iter,
+ dbus_int32_t value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT32))
+ return FALSE;
+
+ if (!_dbus_marshal_int32 (&real->message->body, real->message->byte_order, value))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a 32 bit unsigned integer to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the integer value
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_uint32 (DBusMessageIter *iter,
+ dbus_uint32_t value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT32))
+ return FALSE;
+
+ if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, value))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a double value to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the double value
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_double (DBusMessageIter *iter,
+ double value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_DOUBLE))
+ return FALSE;
+
+ if (!_dbus_marshal_double (&real->message->body, real->message->byte_order, value))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a UTF-8 string to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the string
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_string (DBusMessageIter *iter,
+ const char *value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
+ return FALSE;
+
+ if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a named type data chunk to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param name the name of the type
+ * @parame
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_named (DBusMessageIter *iter,
+ const char *name,
+ const unsigned char *data,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_NAMED))
+ return FALSE;
+
+ if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, data))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+
+/**
+ * Appends a dict key name to the message. The iterator used
+ * must point to a dict.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the string
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_dict_key (DBusMessageIter *iter,
+ const char *value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+ _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT);
+
+ if (real->wrote_dict_key)
+ {
+ _dbus_warn ("Appendinging multiple dict key names\n");
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value))
+ {
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+ real->wrote_dict_key = TRUE;
+
+ return TRUE;
+}
+
+/**
+ * Appends an array to the message and initializes an iterator that
+ * can be used to append to the array.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param array_iter pointer to an iter that will be initialized
+ * @param element_type the type of the array elements
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_array (DBusMessageIter *iter,
+ DBusMessageIter *array_iter,
+ int element_type)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;
+ int len_pos;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, element_type))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
+
+ /* Empty length for now, backfill later */
+ if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ array_real->parent_iter = real;
+ array_real->message = real->message;
+ array_real->changed_stamp = real->message->changed_stamp;
+
+ array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY;
+ array_real->pos = _dbus_string_get_length (&real->message->body);
+ array_real->end = array_real->end;
+
+ array_real->container_type = element_type;
+ array_real->container_start = array_real->pos;
+ array_real->container_length_pos = len_pos;
+ array_real->wrote_dict_key = 0;
+
+ dbus_message_iter_append_done (array_real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a dict to the message and initializes an iterator that
+ * can be used to append to the dict.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param array_iter pointer to an iter that will be initialized
+ * @param element_type the type of the array elements
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_dict (DBusMessageIter *iter,
+ DBusMessageIter *dict_iter)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
+ int len_pos;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
+ return FALSE;
+
+ len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
+
+ /* Empty length for now, backfill later */
+ if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dict_real->parent_iter = real;
+ dict_real->message = real->message;
+ dict_real->changed_stamp = real->message->changed_stamp;
+
+ dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT;
+ dict_real->pos = _dbus_string_get_length (&real->message->body);
+ dict_real->end = dict_real->end;
+
+ dict_real->container_type = 0;
+ dict_real->container_start = dict_real->pos;
+ dict_real->container_length_pos = len_pos;
+ dict_real->wrote_dict_key = 0;
+
+ dbus_message_iter_append_done (dict_real);
+
+ return TRUE;
+}
+
+
+/**
+ * Appends a boolean array to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the array
+ * @param len the length of the array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_boolean_array (DBusMessageIter *iter,
+ unsigned const char *value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_BOOLEAN))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a 32 bit signed integer array to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the array
+ * @param len the length of the array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_int32_array (DBusMessageIter *iter,
+ const dbus_int32_t *value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_INT32))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a 32 bit unsigned integer array to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the array
+ * @param len the length of the array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_uint32_array (DBusMessageIter *iter,
+ const dbus_uint32_t *value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_UINT32))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a double array to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the array
+ * @param len the length of the array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_double_array (DBusMessageIter *iter,
+ const double *value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_DOUBLE))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a byte array to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the array
+ * @param len the length of the array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_byte_array (DBusMessageIter *iter,
+ unsigned const char *value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_BYTE))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+/**
+ * Appends a string array to the message.
+ *
+ * @param iter an iterator pointing to the end of the message
+ * @param value the array
+ * @param len the length of the array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_append_string_array (DBusMessageIter *iter,
+ const char **value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ dbus_message_iter_append_check (real);
+
+ if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY))
+ return FALSE;
+
+ if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_BYTE))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
}
/**
@@ -2621,6 +3411,7 @@ decode_header_data (const DBusString *data,
const char *field;
int pos, new_pos;
int i;
+ int type;
if (header_len < 16)
return FALSE;
@@ -2723,7 +3514,13 @@ decode_header_data (const DBusString *data,
field[0], field[1], field[2], field[3], pos);
}
- if (!_dbus_marshal_validate_arg (data, byte_order, pos, &new_pos))
+ if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
+ {
+ _dbus_verbose ("Failed to validate type of named header field\n");
+ return FALSE;
+ }
+
+ if (!_dbus_marshal_validate_arg (data, byte_order, type, pos, &new_pos))
{
_dbus_verbose ("Failed to validate argument to named header field\n");
return FALSE;
@@ -2891,13 +3688,24 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
next_arg = header_len;
while (next_arg < (header_len + body_len))
{
+ int type;
int prev = next_arg;
+ if (!_dbus_marshal_validate_type (&loader->data, next_arg,
+ &type, &next_arg))
+ {
+ _dbus_verbose ("invalid typecode at offset %d\n", prev);
+ loader->corrupted = TRUE;
+ return TRUE;
+ }
+
if (!_dbus_marshal_validate_arg (&loader->data,
byte_order,
+ type,
next_arg,
&next_arg))
{
+ _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg);
loader->corrupted = TRUE;
return TRUE;
}
@@ -3078,66 +3886,245 @@ _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
static void
message_iter_test (DBusMessage *message)
{
- DBusMessageIter *iter;
+ DBusMessageIter iter, dict, array;
char *str;
- iter = dbus_message_get_args_iter (message);
+ dbus_message_iter_init (message, &iter);
/* String tests */
- if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRING)
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
_dbus_assert_not_reached ("Argument type isn't string");
- str = dbus_message_iter_get_string (iter);
+ str = dbus_message_iter_get_string (&iter);
if (strcmp (str, "Test string") != 0)
_dbus_assert_not_reached ("Strings differ");
dbus_free (str);
- if (!dbus_message_iter_next (iter))
+ if (!dbus_message_iter_next (&iter))
_dbus_assert_not_reached ("Reached end of arguments");
/* Signed integer tests */
- if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_INT32)
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32)
_dbus_assert_not_reached ("Argument type isn't int32");
- if (dbus_message_iter_get_int32 (iter) != -0x12345678)
+ if (dbus_message_iter_get_int32 (&iter) != -0x12345678)
_dbus_assert_not_reached ("Signed integers differ");
- if (!dbus_message_iter_next (iter))
+ if (!dbus_message_iter_next (&iter))
_dbus_assert_not_reached ("Reached end of fields");
/* Unsigned integer tests */
- if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_UINT32)
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
_dbus_assert_not_reached ("Argument type isn't int32");
- if (dbus_message_iter_get_uint32 (iter) != 0xedd1e)
+ if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e)
_dbus_assert_not_reached ("Unsigned integers differ");
- if (!dbus_message_iter_next (iter))
+ if (!dbus_message_iter_next (&iter))
_dbus_assert_not_reached ("Reached end of arguments");
/* Double tests */
- if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_DOUBLE)
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE)
_dbus_assert_not_reached ("Argument type isn't double");
- if (dbus_message_iter_get_double (iter) != 3.14159)
+ if (dbus_message_iter_get_double (&iter) != 3.14159)
_dbus_assert_not_reached ("Doubles differ");
- if (dbus_message_iter_next (iter))
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
+ _dbus_assert_not_reached ("Argument type not an array");
+
+ if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("Array type not uint32");
+
+
+ if (!dbus_message_iter_init_array_iterator (&iter, &array, NULL))
+ _dbus_assert_not_reached ("Array init failed");
+
+ if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("Argument type isn't int32");
+
+ if (dbus_message_iter_get_uint32 (&array) != 0x12345678)
+ _dbus_assert_not_reached ("Unsigned integers differ");
+
+ if (!dbus_message_iter_next (&array))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("Argument type isn't int32");
+
+ if (dbus_message_iter_get_uint32 (&array) != 0x23456781)
+ _dbus_assert_not_reached ("Unsigned integers differ");
+
+ if (dbus_message_iter_next (&array))
_dbus_assert_not_reached ("Didn't reach end of arguments");
- dbus_message_iter_unref (iter);
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
+ _dbus_assert_not_reached ("not dict type");
+
+ if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
+ _dbus_assert_not_reached ("dict iter failed");
+
+ str = dbus_message_iter_get_dict_key (&dict);
+ if (str == NULL || strcmp (str, "test") != 0)
+ _dbus_assert_not_reached ("wrong dict key");
+ dbus_free (str);
+
+ if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("wrong dict entry type");
+
+ if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
+ _dbus_assert_not_reached ("wrong dict entry value");
+
+ if (dbus_message_iter_next (&dict))
+ _dbus_assert_not_reached ("Didn't reach end of dict");
+
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("wrong type after dict");
+
+ if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
+ _dbus_assert_not_reached ("wrong value after dict");
+
+ if (dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Didn't reach end of arguments");
}
+
+static dbus_bool_t
+check_message_handling_type (DBusMessageIter *iter,
+ int type)
+{
+ DBusMessageIter child_iter;
+
+ switch (type)
+ {
+ case DBUS_TYPE_NIL:
+ break;
+ case DBUS_TYPE_BYTE:
+ dbus_message_iter_get_byte (iter);
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ dbus_message_iter_get_boolean (iter);
+ break;
+ case DBUS_TYPE_INT32:
+ dbus_message_iter_get_int32 (iter);
+ break;
+ case DBUS_TYPE_UINT32:
+ dbus_message_iter_get_uint32 (iter);
+ break;
+ case DBUS_TYPE_DOUBLE:
+ dbus_message_iter_get_double (iter);
+ break;
+ case DBUS_TYPE_STRING:
+ {
+ char *str;
+ str = dbus_message_iter_get_string (iter);
+ if (str == NULL)
+ {
+ _dbus_warn ("NULL string int message\n");
+ return FALSE;
+ }
+ dbus_free (str);
+ }
+ break;
+ case DBUS_TYPE_NAMED:
+ {
+ char *name;
+ unsigned char *data;
+ int len;
+
+ name = dbus_message_iter_get_named (iter, &data, &len);
+ if (name == NULL)
+ {
+ _dbus_warn ("error reading name from named type\n");
+ return FALSE;
+ }
+ dbus_free (data);
+ dbus_free (name);
+ }
+ break;
+ case DBUS_TYPE_ARRAY:
+ {
+ int array_type;
+
+ if (!dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type))
+ {
+ _dbus_warn ("Failed to init array iterator\n");
+ return FALSE;
+ }
+
+ while (dbus_message_iter_has_next (&child_iter))
+ {
+ if (!check_message_handling_type (&child_iter, array_type))
+ {
+ _dbus_warn ("error in array element\n");
+ return FALSE;
+ }
+
+ if (!dbus_message_iter_next (&child_iter))
+ break;
+ }
+ }
+ break;
+ case DBUS_TYPE_DICT:
+ {
+ int entry_type;
+ char *key;
+
+ if (!dbus_message_iter_init_dict_iterator (iter, &child_iter))
+ {
+ _dbus_warn ("Failed to init dict iterator\n");
+ return FALSE;
+ }
+
+ while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
+ {
+ key = dbus_message_iter_get_dict_key (&child_iter);
+ if (key == NULL)
+ {
+ _dbus_warn ("error reading dict key\n");
+ return FALSE;
+ }
+ dbus_free (key);
+
+ if (!check_message_handling_type (&child_iter, entry_type))
+ {
+ _dbus_warn ("error in dict value\n");
+ return FALSE;
+ }
+
+ if (!dbus_message_iter_next (&child_iter))
+ break;
+ }
+ }
+ break;
+
+ default:
+ _dbus_warn ("unknown type %d\n", type);
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+
static dbus_bool_t
check_message_handling (DBusMessage *message)
{
- DBusMessageIter *iter;
+ DBusMessageIter iter;
int type;
dbus_bool_t retval;
dbus_int32_t client_serial;
retval = FALSE;
- iter = NULL;
client_serial = dbus_message_get_serial (message);
@@ -3155,109 +4142,20 @@ check_message_handling (DBusMessage *message)
* then we would want to test it here
*/
- iter = dbus_message_get_args_iter (message);
- while ((type = dbus_message_iter_get_arg_type (iter)) != DBUS_TYPE_INVALID)
+ dbus_message_iter_init (message, &iter);
+ while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
{
- switch (type)
- {
- case DBUS_TYPE_NIL:
- break;
- case DBUS_TYPE_INT32:
- dbus_message_iter_get_int32 (iter);
- break;
- case DBUS_TYPE_UINT32:
- dbus_message_iter_get_uint32 (iter);
- break;
- case DBUS_TYPE_DOUBLE:
- dbus_message_iter_get_double (iter);
- break;
- case DBUS_TYPE_STRING:
- {
- char *str;
- str = dbus_message_iter_get_string (iter);
- dbus_free (str);
- }
- break;
- case DBUS_TYPE_BOOLEAN_ARRAY:
- {
- unsigned char *values;
- int len;
-
- if (!dbus_message_iter_get_boolean_array (iter, &values, &len))
- return FALSE;
- dbus_free (values);
- }
- break;
- case DBUS_TYPE_INT32_ARRAY:
- {
- dbus_int32_t *values;
- int len;
-
- if (!dbus_message_iter_get_int32_array (iter, &values, &len))
- return FALSE;
-
- dbus_free (values);
- }
- break;
- case DBUS_TYPE_UINT32_ARRAY:
- {
- dbus_uint32_t *values;
- int len;
-
- if (!dbus_message_iter_get_uint32_array (iter, &values, &len))
- return FALSE;
-
- dbus_free (values);
- }
- break;
- case DBUS_TYPE_DOUBLE_ARRAY:
- {
- double *values;
- int len;
-
- if (!dbus_message_iter_get_double_array (iter, &values, &len))
- return FALSE;
-
- dbus_free (values);
- }
- break;
- case DBUS_TYPE_STRING_ARRAY:
- {
- char **values;
- int len;
-
- if (!dbus_message_iter_get_string_array (iter, &values, &len))
- return FALSE;
-
- dbus_free_string_array (values);
- }
- break;
-
- case DBUS_TYPE_DICT:
- {
- DBusDict *dict;
-
- if (!dbus_message_iter_get_dict (iter, &dict))
- return FALSE;
- dbus_dict_unref (dict);
- }
- break;
+ if (!check_message_handling_type (&iter, type))
+ goto failed;
- default:
- break;
- }
-
- if (!dbus_message_iter_next (iter))
+ if (!dbus_message_iter_next (&iter))
break;
}
-
+
retval = TRUE;
failed:
- if (iter)
- dbus_message_iter_unref (iter);
-
return retval;
}
@@ -3408,6 +4306,7 @@ dbus_internal_do_not_use_load_message_file (const DBusString *filename,
{
DBusError error;
+ _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
dbus_error_init (&error);
if (!_dbus_file_get_contents (data, filename, &error))
{
@@ -3733,14 +4632,25 @@ verify_test_message (DBusMessage *message)
char *our_str;
double our_double;
dbus_bool_t our_bool;
-
- if (!dbus_message_get_args (message, NULL,
- DBUS_TYPE_INT32, &our_int,
- DBUS_TYPE_STRING, &our_str,
- DBUS_TYPE_DOUBLE, &our_double,
- DBUS_TYPE_BOOLEAN, &our_bool,
- 0))
- _dbus_assert_not_reached ("Could not get arguments");
+ dbus_int32_t *our_int_array;
+ int our_int_array_len;
+ DBusMessageIter iter, dict;
+ DBusError error;
+
+ dbus_message_iter_init (message, &iter);
+
+ dbus_error_init (&error);
+ if (!dbus_message_iter_get_args (&iter, &error,
+ DBUS_TYPE_INT32, &our_int,
+ DBUS_TYPE_STRING, &our_str,
+ DBUS_TYPE_DOUBLE, &our_double,
+ DBUS_TYPE_BOOLEAN, &our_bool,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &our_int_array, &our_int_array_len,
+ 0))
+ {
+ _dbus_verbose ("error: %s - %s\n", error.name, (error.message != NULL)?error.message: "no message");
+ _dbus_assert_not_reached ("Could not get arguments");
+ }
if (our_int != -0x12345678)
_dbus_assert_not_reached ("integers differ!");
@@ -3750,11 +4660,56 @@ verify_test_message (DBusMessage *message)
if (strcmp (our_str, "Test string") != 0)
_dbus_assert_not_reached ("strings differ!");
+ dbus_free (our_str);
if (!our_bool)
_dbus_assert_not_reached ("booleans differ");
-
+
+ if (our_int_array_len != 4 ||
+ our_int_array[0] != 0x12345678 ||
+ our_int_array[1] != 0x23456781 ||
+ our_int_array[2] != 0x34567812 ||
+ our_int_array[3] != 0x45678123)
+ _dbus_assert_not_reached ("array differ");
+ dbus_free (our_int_array);
+
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
+ _dbus_assert_not_reached ("not dict type");
+
+ if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
+ _dbus_assert_not_reached ("dict iter failed");
+
+ our_str = dbus_message_iter_get_dict_key (&dict);
+ if (our_str == NULL || strcmp (our_str, "test") != 0)
+ _dbus_assert_not_reached ("wrong dict key");
dbus_free (our_str);
+
+ if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32)
+ {
+ _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict));
+ _dbus_assert_not_reached ("wrong dict entry type");
+ }
+
+ if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)
+ _dbus_assert_not_reached ("wrong dict entry value");
+
+ if (dbus_message_iter_next (&dict))
+ _dbus_assert_not_reached ("Didn't reach end of dict");
+
+ if (!dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Reached end of arguments");
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32)
+ _dbus_assert_not_reached ("wrong type after dict");
+
+ if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)
+ _dbus_assert_not_reached ("wrong value after dict");
+
+ if (dbus_message_iter_next (&iter))
+ _dbus_assert_not_reached ("Didn't reach end of arguments");
}
/**
@@ -3768,12 +4723,17 @@ _dbus_message_test (const char *test_data_dir)
{
DBusMessage *message;
DBusMessageLoader *loader;
+ DBusMessageIter iter, child_iter;
int i;
const char *data;
DBusMessage *copy;
const char *name1;
const char *name2;
-
+ const dbus_uint32_t our_int32_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
+
+
+ _dbus_assert (sizeof (DBusMessageRealIter) == sizeof (DBusMessageIter));
+
/* Test the vararg functions */
message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
_dbus_message_set_serial (message, 1);
@@ -3782,7 +4742,15 @@ _dbus_message_test (const char *test_data_dir)
DBUS_TYPE_STRING, "Test string",
DBUS_TYPE_DOUBLE, 3.14159,
DBUS_TYPE_BOOLEAN, TRUE,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_int32_array, 4,
0);
+
+ dbus_message_append_iter_init (message, &iter);
+ dbus_message_iter_append_dict (&iter, &child_iter);
+ dbus_message_iter_append_dict_key (&child_iter, "test");
+ dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
+ dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
+
_dbus_verbose_bytes_of_string (&message->header, 0,
_dbus_string_get_length (&message->header));
_dbus_verbose_bytes_of_string (&message->body, 0,
@@ -3816,11 +4784,21 @@ _dbus_message_test (const char *test_data_dir)
_dbus_message_set_serial (message, 1);
dbus_message_set_reply_serial (message, 0x12345678);
- dbus_message_append_string (message, "Test string");
- dbus_message_append_int32 (message, -0x12345678);
- dbus_message_append_uint32 (message, 0xedd1e);
- dbus_message_append_double (message, 3.14159);
+ dbus_message_append_iter_init (message, &iter);
+ dbus_message_iter_append_string (&iter, "Test string");
+ dbus_message_iter_append_int32 (&iter, -0x12345678);
+ dbus_message_iter_append_uint32 (&iter, 0xedd1e);
+ dbus_message_iter_append_double (&iter, 3.14159);
+ dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_UINT32);
+ dbus_message_iter_append_uint32 (&child_iter, 0x12345678);
+ dbus_message_iter_append_uint32 (&child_iter, 0x23456781);
+
+ dbus_message_iter_append_dict (&iter, &child_iter);
+ dbus_message_iter_append_dict_key (&child_iter, "test");
+ dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
+ dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
+
message_iter_test (message);
/* Message loader test */