/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-message.c DBusMessage object
*
- * Copyright (C) 2002, 2003 Red Hat Inc.
+ * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
* Copyright (C) 2002, 2003 CodeFactory AB
*
* Licensed under the Academic Free License version 2.0
unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
-
- DBusString signature; /**< Signature */
};
enum {
message->header_padding = 0;
}
+#ifdef DBUS_DISABLE_CHECKS
+#define is_valid_error_name(x) TRUE
+#else
+static dbus_bool_t
+is_valid_error_name (const char *error_name)
+{
+ DBusString the_error_name;
+
+ if (error_name == NULL)
+ return FALSE;
+
+ _dbus_string_init_const (&the_error_name, error_name);
+ return _dbus_string_validate_error_name (&the_error_name, 0,
+ _dbus_string_get_length (&the_error_name));
+}
+#endif
+
static dbus_bool_t
append_header_padding (DBusMessage *message)
{
return FALSE;
}
-#define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 1 + 8)
+/** The maximum number of bytes of overhead to append to a string
+ * (fieldcode + typecode + alignment + length + nul + headerpadding)
+ */
+#define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 4 + 1 + 8)
+
static dbus_bool_t
-append_string_field (DBusMessage *message,
- int field,
- int type,
- const char *value)
+append_string_field_len (DBusMessage *message,
+ int field,
+ int type,
+ const char *value,
+ int value_len)
{
_dbus_assert (!message->locked);
message->header_fields[field].value_offset =
_dbus_string_get_length (&message->header);
- if (!_dbus_marshal_string (&message->header, message->byte_order,
- value))
+ if (!_dbus_marshal_string_len (&message->header, message->byte_order,
+ value, value_len))
goto failed;
if (!append_header_padding (message))
return FALSE;
}
+static dbus_bool_t
+append_string_field (DBusMessage *message,
+ int field,
+ int type,
+ const char *value)
+{
+ int value_len;
+
+ value_len = strlen (value);
+
+ return append_string_field_len (message, field, type, value, value_len);
+}
+
static int
get_type_alignment (int type)
{
const char *value)
{
int prealloc;
+ int value_len;
_dbus_assert (!message->locked);
+ value_len = value ? strlen (value) : 0;
+
/* the prealloc is so the append_string_field()
* below won't fail, leaving us in inconsistent state
*/
- prealloc = (value ? strlen (value) : 0) + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
+ prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
_dbus_verbose ("set_string_field() field %d prealloc %d\n",
field, prealloc);
if (value != NULL)
{
/* need to append the field */
- if (!append_string_field (message, field, type, value))
+ if (!append_string_field_len (message, field, type, value, value_len))
_dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
}
else
_dbus_list_free_link (link);
- _dbus_counter_adjust (counter, message->size_counter_delta);
+ _dbus_counter_adjust (counter, - message->size_counter_delta);
_dbus_counter_unref (counter);
}
_dbus_assert ((interface && member) ||
(error_name) ||
!(interface || member || error_name));
+ _dbus_assert (error_name == NULL || is_valid_error_name (error_name));
if (!_dbus_string_append_byte (&message->header, message->byte_order))
return FALSE;
if (service != NULL)
{
if (!append_string_field (message,
- DBUS_HEADER_FIELD_SERVICE,
+ DBUS_HEADER_FIELD_DESTINATION,
DBUS_TYPE_STRING,
service))
return FALSE;
error_name))
return FALSE;
}
+
+ /* @todo if we make signature optional when body is empty, we don't
+ * need to do this here.
+ */
+ if (!append_string_field (message,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ DBUS_TYPE_STRING,
+ ""))
+ return FALSE;
return TRUE;
}
*/
/**
+ * Sets the signature of the message, i.e. the arguments in the
+ * message payload. The signature includes only "in" arguments for
+ * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
+ * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
+ * what you might expect (it does not include the signature of the
+ * entire C++-style method).
+ *
+ * The signature is a string made up of type codes such
+ * as #DBUS_TYPE_STRING. The string is terminated with nul
+ * (nul is also the value of #DBUS_TYPE_INVALID).
+ *
+ * @param message the message
+ * @param signature the type signature or #NULL to unset
+ * @returns #FALSE if no memory
+ */
+static dbus_bool_t
+dbus_message_set_signature (DBusMessage *message,
+ const char *signature)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ return set_string_field (message,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ DBUS_TYPE_STRING,
+ signature);
+}
+
+/**
+ * Appends to the signature of the message.
+ * (currently a static function, maybe should be public?)
+ *
+ * @param message the message
+ * @param append_bytes nul-terminated bytes to append to the type signature
+ * @returns #FALSE if no memory
+ */
+static dbus_bool_t
+dbus_message_append_to_signature (DBusMessage *message,
+ const char *append_bytes)
+{
+ const char *signature;
+ DBusString append_str;
+ dbus_bool_t retval;
+
+ _dbus_return_val_if_fail (append_bytes != NULL, FALSE);
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ retval = FALSE;
+
+ /* FIXME Just really inefficient for the moment; later we could
+ * speed it up a lot by poking more directly at the header data
+ */
+ signature = dbus_message_get_signature (message);
+
+ if (!_dbus_string_init (&append_str))
+ return FALSE;
+
+ if (signature && !_dbus_string_append (&append_str, signature))
+ goto out;
+
+ if (!_dbus_string_append (&append_str, append_bytes))
+ goto out;
+
+ if (!set_string_field (message,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ DBUS_TYPE_STRING,
+ _dbus_string_get_const_data (&append_str)))
+ goto out;
+
+ retval = TRUE;
+
+ out:
+
+ _dbus_string_free (&append_str);
+
+ return retval;
+}
+
+/**
+ * Appends one byte to the signature of the message.
+ * Internal function.
+ *
+ * @param message the message
+ * @param append_byte the byte
+ * @returns #FALSE if no memory
+ */
+static dbus_bool_t
+_dbus_message_append_byte_to_signature (DBusMessage *message,
+ unsigned char append_byte)
+{
+ char buf[2];
+
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ buf[0] = append_byte;
+ buf[1] = '\0';
+
+ return dbus_message_append_to_signature (message, buf);
+}
+
+/**
+ * Removes the last byte from the signature of the message.
+ * Internal function.
+ *
+ * @param message the message
+ */
+static void
+_dbus_message_remove_byte_from_signature (DBusMessage *message)
+{
+ const char *signature;
+
+ _dbus_return_if_fail (message != NULL);
+ _dbus_return_if_fail (!message->locked);
+
+ signature = dbus_message_get_signature (message);
+
+ _dbus_return_if_fail (signature != NULL);
+
+ if (!delete_field (message,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ 0))
+ _dbus_assert_not_reached ("failed to delete signature field");
+
+ /* reappend one shorter (could this be any less efficient? the code will
+ * go away later anyhow)
+ */
+ if (!append_string_field_len (message, DBUS_HEADER_FIELD_SIGNATURE,
+ DBUS_TYPE_STRING, signature,
+ strlen (signature) - 1))
+ _dbus_assert_not_reached ("reappending shorter signature shouldn't have failed");
+}
+
+/**
* @typedef DBusMessage
*
* Opaque data type representing a message received from or to be
dbus_free (message);
return NULL;
}
-
- if (!_dbus_string_init_preallocated (&message->signature, 4))
- {
- _dbus_string_free (&message->header);
- _dbus_string_free (&message->body);
- dbus_free (message);
- return NULL;
- }
return message;
}
_dbus_return_val_if_fail (method_call != NULL, NULL);
sender = get_string_field (method_call,
- DBUS_HEADER_FIELD_SENDER_SERVICE,
+ DBUS_HEADER_FIELD_SENDER,
NULL);
/* sender is allowed to be null here in peer-to-peer case */
_dbus_return_val_if_fail (reply_to != NULL, NULL);
_dbus_return_val_if_fail (error_name != NULL, NULL);
+ _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
sender = get_string_field (reply_to,
- DBUS_HEADER_FIELD_SENDER_SERVICE,
+ DBUS_HEADER_FIELD_SENDER,
NULL);
/* sender may be NULL for non-message-bus case or
DBusString str;
DBusMessage *message;
+ _dbus_return_val_if_fail (reply_to != NULL, NULL);
+ _dbus_return_val_if_fail (error_name != NULL, NULL);
+ _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL);
+
if (!_dbus_string_init (&str))
return NULL;
dbus_free (retval);
return NULL;
}
-
- if (!_dbus_string_init_preallocated (&retval->signature,
- _dbus_string_get_length (&message->signature)))
- {
- _dbus_string_free (&retval->header);
- _dbus_string_free (&retval->body);
- dbus_free (retval);
- return NULL;
- }
if (!_dbus_string_copy (&message->header, 0,
&retval->header, 0))
if (!_dbus_string_copy (&message->body, 0,
&retval->body, 0))
goto failed_copy;
-
- if (!_dbus_string_copy (&message->signature, 0,
- &retval->signature, 0))
- goto failed_copy;
for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
{
failed_copy:
_dbus_string_free (&retval->header);
_dbus_string_free (&retval->body);
- _dbus_string_free (&retval->signature);
dbus_free (retval);
return NULL;
_dbus_string_free (&message->header);
_dbus_string_free (&message->body);
- _dbus_string_free (&message->signature);
dbus_free (message);
}
* emitted from (for DBUS_MESSAGE_TYPE_SIGNAL).
*
* @param message the message
- * @param object_path the path
+ * @param object_path the path or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
* (for DBUS_MESSAGE_TYPE_SIGNAL).
*
* @param message the message
- * @param interface the interface
+ * @param interface the interface or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
* The interface name is fully-qualified (namespaced).
*
* @param message the message
- * @param member the member
+ * @param member the member or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
* The name is fully-qualified (namespaced).
*
* @param message the message
- * @param error_name the name
+ * @param error_name the name or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
{
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_fail (!message->locked, FALSE);
-
+ _dbus_return_val_if_fail (error_name == NULL || is_valid_error_name (error_name), FALSE);
+
return set_string_field (message,
DBUS_HEADER_FIELD_ERROR_NAME,
DBUS_TYPE_STRING,
* Sets the message's destination service.
*
* @param message the message
- * @param destination the destination service name
+ * @param destination the destination service name or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
_dbus_return_val_if_fail (!message->locked, FALSE);
return set_string_field (message,
- DBUS_HEADER_FIELD_SERVICE,
+ DBUS_HEADER_FIELD_DESTINATION,
DBUS_TYPE_STRING,
destination);
}
_dbus_return_val_if_fail (message != NULL, NULL);
return get_string_field (message,
- DBUS_HEADER_FIELD_SERVICE,
+ DBUS_HEADER_FIELD_DESTINATION,
NULL);
}
}
/**
- * This function takes a va_list for use by language bindings.
- * It's otherwise the same as dbus_message_append_args().
+ * 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 #DBUS_TYPE_INVALID.
*
- * @todo: Shouldn't this function clean up the changes to the message
- * on failures? (Yes)
+ * @param message the message
+ * @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_bool_t retval;
+ va_list var_args;
+
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_error_is_set (error, FALSE);
- * @see dbus_message_append_args.
+ va_start (var_args, first_arg_type);
+ retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
+ va_end (var_args);
+
+ return retval;
+}
+
+/**
+ * This function takes a va_list for use by language bindings
+ *
+ * @todo We need to free the argument data when an error occurs.
+ *
+ * @see dbus_message_get_args
* @param message the message
- * @param first_arg_type type of first argument
- * @param var_args value of first argument, then list of type/value pairs
- * @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_args_valist (DBusMessage *message,
- int first_arg_type,
- va_list var_args)
+dbus_message_get_args_valist (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args)
{
- int type, old_len;
DBusMessageIter iter;
_dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_error_is_set (error, FALSE);
- old_len = _dbus_string_get_length (&message->body);
+ 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 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 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_iter_get_args (DBusMessageIter *iter,
+ DBusError *error,
+ int first_arg_type,
+ ...)
+{
+ dbus_bool_t retval;
+ va_list var_args;
+
+ _dbus_return_val_if_fail (iter != NULL, FALSE);
+ _dbus_return_val_if_error_is_set (error, FALSE);
- type = first_arg_type;
+ va_start (var_args, first_arg_type);
+ retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
+ va_end (var_args);
- dbus_message_append_iter_init (message, &iter);
-
- while (type != DBUS_TYPE_INVALID)
- {
- switch (type)
- {
- case DBUS_TYPE_NIL:
- if (!dbus_message_iter_append_nil (&iter))
- goto errorout;
- break;
- case DBUS_TYPE_BYTE:
- if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, unsigned char)))
- goto errorout;
- break;
- case DBUS_TYPE_BOOLEAN:
- if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
- goto errorout;
- break;
- case DBUS_TYPE_INT32:
- if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
- goto errorout;
- break;
- case DBUS_TYPE_UINT32:
- if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
- goto errorout;
- break;
-#ifdef DBUS_HAVE_INT64
- case DBUS_TYPE_INT64:
- if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
- goto errorout;
- break;
- case DBUS_TYPE_UINT64:
- if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
- goto errorout;
- break;
-#endif /* DBUS_HAVE_INT64 */
- case DBUS_TYPE_DOUBLE:
- if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
- goto errorout;
- break;
- case DBUS_TYPE_STRING:
- if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
- goto errorout;
- break;
- case DBUS_TYPE_OBJECT_PATH:
- if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*)))
- goto errorout;
- break;
- case DBUS_TYPE_CUSTOM:
- {
- const char *name;
- unsigned char *data;
- int len;
-
- name = va_arg (var_args, const char *);
- data = va_arg (var_args, unsigned char *);
- len = va_arg (var_args, int);
-
- if (!dbus_message_iter_append_custom (&iter, name, data, len))
- goto errorout;
- break;
- }
- case DBUS_TYPE_ARRAY:
- {
- void *data;
- int len, type;
-
- type = va_arg (var_args, int);
- data = va_arg (var_args, void *);
- len = va_arg (var_args, int);
-
- 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;
-#ifdef DBUS_HAVE_INT64
- case DBUS_TYPE_INT64:
- if (!dbus_message_iter_append_int64_array (&iter, (dbus_int64_t *)data, len))
- goto errorout;
- break;
- case DBUS_TYPE_UINT64:
- if (!dbus_message_iter_append_uint64_array (&iter, (dbus_uint64_t *)data, len))
- goto errorout;
- break;
-#endif /* DBUS_HAVE_INT64 */
- 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_OBJECT_PATH:
- if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len))
- goto errorout;
- break;
- case DBUS_TYPE_NIL:
- case DBUS_TYPE_ARRAY:
- case DBUS_TYPE_CUSTOM:
- 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:
- _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);
- }
-
- return TRUE;
-
- errorout:
- return FALSE;
-}
-
-
-/**
- * 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 #DBUS_TYPE_INVALID.
- *
- * @param message the message
- * @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_bool_t retval;
- va_list var_args;
-
- _dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_error_is_set (error, FALSE);
-
- va_start (var_args, first_arg_type);
- retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
- va_end (var_args);
-
- return retval;
-}
-
-/**
- * This function takes a va_list for use by language bindings
- *
- * @todo We need to free the argument data when an error occurs.
- *
- * @see dbus_message_get_args
- * @param message the message
- * @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)
-{
- DBusMessageIter iter;
-
- _dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_error_is_set (error, FALSE);
-
- 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 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 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_iter_get_args (DBusMessageIter *iter,
- DBusError *error,
- int first_arg_type,
- ...)
-{
- dbus_bool_t retval;
- va_list var_args;
-
- _dbus_return_val_if_fail (iter != NULL, FALSE);
- _dbus_return_val_if_error_is_set (error, FALSE);
-
- va_start (var_args, first_arg_type);
- retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
- va_end (var_args);
-
- return retval;
-}
-
-/**
- * This function takes a va_list for use by language bindings
- *
- * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64
- * only if #DBUS_HAVE_INT64 is defined.
- *
- * @todo this function (or some lower-level non-convenience function)
- * needs better error handling; should allow the application to
- * distinguish between out of memory, and bad data from the remote
- * app. It also needs to not leak a bunch of args when it gets
- * to the arg that's bad, as that would be a security hole
- * (allow one app to force another to leak memory)
- *
- * @todo We need to free the argument data when an error occurs.
- *
- * @see dbus_message_get_args
- * @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_iter_get_args_valist (DBusMessageIter *iter,
- DBusError *error,
- int first_arg_type,
- va_list var_args)
-{
- int spec_type, msg_type, i;
- dbus_bool_t retval;
-
- _dbus_return_val_if_fail (iter != NULL, FALSE);
- _dbus_return_val_if_error_is_set (error, FALSE);
-
- retval = FALSE;
-
- spec_type = first_arg_type;
- i = 0;
-
- while (spec_type != 0)
- {
- msg_type = dbus_message_iter_get_arg_type (iter);
-
- if (msg_type != spec_type)
- {
- dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
- "Argument %d is specified to be of type \"%s\", but "
- "is actually of type \"%s\"\n", i,
- _dbus_type_to_string (spec_type),
- _dbus_type_to_string (msg_type));
-
- goto out;
- }
-
- switch (spec_type)
- {
- 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;
-
- ptr = va_arg (var_args, dbus_bool_t *);
-
- *ptr = dbus_message_iter_get_boolean (iter);
- break;
- }
- case DBUS_TYPE_INT32:
- {
- dbus_int32_t *ptr;
-
- ptr = va_arg (var_args, dbus_int32_t *);
-
- *ptr = dbus_message_iter_get_int32 (iter);
- break;
- }
- case DBUS_TYPE_UINT32:
- {
- dbus_uint32_t *ptr;
-
- ptr = va_arg (var_args, dbus_uint32_t *);
-
- *ptr = dbus_message_iter_get_uint32 (iter);
- break;
- }
-#ifdef DBUS_HAVE_INT64
- case DBUS_TYPE_INT64:
- {
- dbus_int64_t *ptr;
-
- ptr = va_arg (var_args, dbus_int64_t *);
-
- *ptr = dbus_message_iter_get_int64 (iter);
- break;
- }
- case DBUS_TYPE_UINT64:
- {
- dbus_uint64_t *ptr;
-
- ptr = va_arg (var_args, dbus_uint64_t *);
-
- *ptr = dbus_message_iter_get_uint64 (iter);
- break;
- }
-#endif /* DBUS_HAVE_INT64 */
-
- case DBUS_TYPE_DOUBLE:
- {
- double *ptr;
-
- ptr = va_arg (var_args, double *);
-
- *ptr = dbus_message_iter_get_double (iter);
- break;
- }
-
- case DBUS_TYPE_STRING:
- {
- char **ptr;
-
- ptr = va_arg (var_args, char **);
-
- *ptr = dbus_message_iter_get_string (iter);
-
- if (!*ptr)
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
-
- break;
- }
-
- case DBUS_TYPE_CUSTOM:
- {
- char **name;
- unsigned char **data;
- int *len;
-
- name = va_arg (var_args, char **);
- data = va_arg (var_args, unsigned char **);
- len = va_arg (var_args, int *);
-
- if (!dbus_message_iter_get_custom (iter, name, data, len))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- }
- break;
- case DBUS_TYPE_ARRAY:
- {
- void **data;
- int *len, type;
- dbus_bool_t err = FALSE;
-
- type = va_arg (var_args, int);
- data = va_arg (var_args, void *);
- len = va_arg (var_args, int *);
-
- _dbus_return_val_if_fail (data != NULL, FALSE);
- _dbus_return_val_if_fail (len != NULL, FALSE);
-
- 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;
- }
-
- switch (type)
- {
- case DBUS_TYPE_BYTE:
- err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
- break;
- case DBUS_TYPE_BOOLEAN:
- err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
- break;
- case DBUS_TYPE_INT32:
- err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
- break;
- case DBUS_TYPE_UINT32:
- err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
- break;
-#ifdef DBUS_HAVE_INT64
- case DBUS_TYPE_INT64:
- err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
- break;
- case DBUS_TYPE_UINT64:
- err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
- break;
-#endif /* DBUS_HAVE_INT64 */
- case DBUS_TYPE_DOUBLE:
- err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
- break;
- case DBUS_TYPE_STRING:
- err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
- break;
- case DBUS_TYPE_NIL:
- case DBUS_TYPE_ARRAY:
- case DBUS_TYPE_CUSTOM:
- 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;
- }
- if (err)
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto out;
- }
- }
- break;
- case DBUS_TYPE_DICT:
- _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);
- if (spec_type != 0 && !dbus_message_iter_next (iter))
- {
- dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
- "Message has only %d arguments, but more were expected", i);
- goto out;
- }
-
- i++;
- }
-
- retval = TRUE;
-
- out:
-
- return retval;
-}
-
-
-/**
- * Initializes a DBusMessageIter representing the arguments of the
- * message passed in.
- *
- * @param message the message
- * @param iter pointer to an iterator to initialize
- * @returns #FALSE if the message has no arguments
- */
-dbus_bool_t
-dbus_message_iter_init (DBusMessage *message,
- DBusMessageIter *iter)
-{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_fail (iter != NULL, FALSE);
+ return retval;
+}
+
+/**
+ * Initializes a DBusMessageIter representing the arguments of the
+ * message passed in.
+ *
+ * @param message the message
+ * @param iter pointer to an iterator to initialize
+ * @returns #FALSE if the message has no arguments
+ */
+dbus_bool_t
+dbus_message_iter_init (DBusMessage *message,
+ DBusMessageIter *iter)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (iter != NULL, FALSE);
_dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
int type, pos;
char *_name;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+ _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+
+ pos = dbus_message_iter_get_data_start (real, &type);
+
+ _dbus_assert (type == DBUS_TYPE_CUSTOM);
+
+ _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
+ pos, &pos);
+
+ if (_name == NULL)
+ return FALSE;
+
+ if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
+ pos, NULL, value, len))
+ {
+ dbus_free (_name);
+ return FALSE;
+ }
+
+ *name = _name;
+
+ return TRUE;
+}
+
+static void
+_dbus_message_iter_get_basic_type (DBusMessageIter *iter,
+ char type,
+ void *value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int item_type, pos;
+
+ _dbus_return_if_fail (dbus_message_iter_check (real));
+
+ pos = dbus_message_iter_get_data_start (real, &item_type);
+
+ _dbus_assert (type == item_type);
+
+ _dbus_demarshal_basic_type (&real->message->body,
+ type, value,
+ real->message->byte_order,
+ &pos);
+}
+
+
+/**
+ * This function takes a va_list for use by language bindings
+ *
+ * This function supports #DBUS_TYPE_INT64 and #DBUS_TYPE_UINT64
+ * only if #DBUS_HAVE_INT64 is defined.
+ *
+ * @todo this function (or some lower-level non-convenience function)
+ * needs better error handling; should allow the application to
+ * distinguish between out of memory, and bad data from the remote
+ * app. It also needs to not leak a bunch of args when it gets
+ * to the arg that's bad, as that would be a security hole
+ * (allow one app to force another to leak memory)
+ *
+ * @todo We need to free the argument data when an error occurs.
+ *
+ * @see dbus_message_get_args
+ * @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_iter_get_args_valist (DBusMessageIter *iter,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args)
+{
+ int spec_type, msg_type, i;
+ dbus_bool_t retval;
+
+ _dbus_return_val_if_fail (iter != NULL, FALSE);
+ _dbus_return_val_if_error_is_set (error, FALSE);
+
+ retval = FALSE;
+
+ spec_type = first_arg_type;
+ i = 0;
+
+ while (spec_type != DBUS_TYPE_INVALID)
+ {
+ msg_type = dbus_message_iter_get_arg_type (iter);
+
+ if (msg_type != spec_type)
+ {
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Argument %d is specified to be of type \"%s\", but "
+ "is actually of type \"%s\"\n", i,
+ _dbus_type_to_string (spec_type),
+ _dbus_type_to_string (msg_type));
+
+ goto out;
+ }
+
+ switch (spec_type)
+ {
+ case DBUS_TYPE_NIL:
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_bool_t *ptr;
+
+ ptr = va_arg (var_args, dbus_bool_t *);
+
+ *ptr = dbus_message_iter_get_boolean (iter);
+ break;
+ }
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+#ifdef DBUS_HAVE_INT64
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+#endif /* DBUS_HAVE_INT64 */
+ case DBUS_TYPE_DOUBLE:
+ {
+ void *ptr = va_arg (var_args, void *);
+ _dbus_message_iter_get_basic_type (iter, spec_type, ptr);
+ break;
+ }
+
+ case DBUS_TYPE_STRING:
+ {
+ char **ptr;
+
+ ptr = va_arg (var_args, char **);
+
+ *ptr = dbus_message_iter_get_string (iter);
+
+ if (!*ptr)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ break;
+ }
+
+ case DBUS_TYPE_OBJECT_PATH:
+ {
+ char **ptr;
+
+ ptr = va_arg (var_args, char **);
+
+ *ptr = dbus_message_iter_get_object_path (iter);
+
+ if (!*ptr)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ break;
+ }
+
+ case DBUS_TYPE_CUSTOM:
+ {
+ char **name;
+ unsigned char **data;
+ int *len;
+
+ name = va_arg (var_args, char **);
+ data = va_arg (var_args, unsigned char **);
+ len = va_arg (var_args, int *);
+
+ if (!dbus_message_iter_get_custom (iter, name, data, len))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ }
+ break;
+ case DBUS_TYPE_ARRAY:
+ {
+ void **data;
+ int *len, type;
+ dbus_bool_t err = FALSE;
+
+ type = va_arg (var_args, int);
+ data = va_arg (var_args, void *);
+ len = va_arg (var_args, int *);
+
+ _dbus_return_val_if_fail (data != NULL, FALSE);
+ _dbus_return_val_if_fail (len != NULL, FALSE);
+
+ 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;
+ }
+
+ switch (type)
+ {
+ case DBUS_TYPE_BYTE:
+ err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
+ break;
+ case DBUS_TYPE_INT32:
+ err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
+ break;
+ case DBUS_TYPE_UINT32:
+ err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
+ break;
+#ifdef DBUS_HAVE_INT64
+ case DBUS_TYPE_INT64:
+ err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
+ break;
+ case DBUS_TYPE_UINT64:
+ err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
+ break;
+#endif /* DBUS_HAVE_INT64 */
+ case DBUS_TYPE_DOUBLE:
+ err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
+ break;
+ case DBUS_TYPE_STRING:
+ err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len);
+ break;
+
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_CUSTOM:
+ 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;
+ }
+ if (err)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+ }
+ break;
+ case DBUS_TYPE_DICT:
+ _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;
+ }
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_CUSTOM);
-
- _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order,
- pos, &pos);
+ spec_type = va_arg (var_args, int);
+ if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID)
+ {
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Message has only %d arguments, but more were expected", i);
+ goto out;
+ }
- if (_name == NULL)
- return FALSE;
-
- if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- {
- dbus_free (_name);
- return FALSE;
+ i++;
}
-
- *name = _name;
- return TRUE;
+ retval = TRUE;
+
+ out:
+
+ return retval;
}
/**
unsigned char
dbus_message_iter_get_byte (DBusMessageIter *iter)
{
- unsigned char value;
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
+ unsigned char value = 0;
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_BYTE);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value);
- 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
dbus_bool_t
dbus_message_iter_get_boolean (DBusMessageIter *iter)
{
- unsigned char value;
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+ unsigned char value = 0;
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_BOOLEAN);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value);
- value = _dbus_string_get_byte (&real->message->body, pos);
-
- return value;
+ return (value != FALSE);
}
/**
dbus_int32_t
dbus_message_iter_get_int32 (DBusMessageIter *iter)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
+ dbus_int32_t value = 0;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value);
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_INT32);
-
- return _dbus_demarshal_int32 (&real->message->body, real->message->byte_order,
- pos, NULL);
+ return value;
}
/**
dbus_uint32_t
dbus_message_iter_get_uint32 (DBusMessageIter *iter)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
+ dbus_int32_t value = 0;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value);
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_UINT32);
-
- return _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order,
- pos, NULL);
+ return value;
}
#ifdef DBUS_HAVE_INT64
dbus_int64_t
dbus_message_iter_get_int64 (DBusMessageIter *iter)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
+ dbus_int64_t value = 0;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value);
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_INT64);
-
- return _dbus_demarshal_int64 (&real->message->body, real->message->byte_order,
- pos, NULL);
+ return value;
}
/**
dbus_uint64_t
dbus_message_iter_get_uint64 (DBusMessageIter *iter)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
+ dbus_uint64_t value = 0;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), 0);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value);
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_UINT64);
-
- return _dbus_demarshal_uint64 (&real->message->body, real->message->byte_order,
- pos, NULL);
+ return value;
}
#endif /* DBUS_HAVE_INT64 */
double
dbus_message_iter_get_double (DBusMessageIter *iter)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
+ double value = 0.0;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), 0.0);
+ _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value);
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_DOUBLE);
-
- return _dbus_demarshal_double (&real->message->body, real->message->byte_order,
- pos, NULL);
+ return value;
}
/**
return len > 0;
}
+static dbus_bool_t
+_dbus_message_iter_get_basic_type_array (DBusMessageIter *iter,
+ char type,
+ void **array,
+ int *array_len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int item_type, pos;
+
+ _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+
+ pos = dbus_message_iter_get_data_start (real, &item_type);
+
+ _dbus_assert (item_type == DBUS_TYPE_ARRAY);
+
+ item_type = iter_get_array_type (real, NULL);
+
+ _dbus_assert (type == item_type);
+
+ return _dbus_demarshal_basic_type_array (&real->message->body,
+ item_type, array, array_len,
+ real->message->byte_order, &pos);
+}
+
/**
* Returns the byte array that the iterator may point to.
* Note that you need to check that the iterator points
unsigned char **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
-
- _dbus_assert (type == DBUS_TYPE_BYTE);
-
- if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE,
+ (void **) value, len);
}
/**
unsigned char **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
-
- _dbus_assert (type == DBUS_TYPE_BOOLEAN);
-
- if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN,
+ (void **) value, len);
}
/**
dbus_int32_t **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
-
- _dbus_assert (type == DBUS_TYPE_INT32);
-
- if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32,
+ (void **) value, len);
}
/**
dbus_uint32_t **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
- _dbus_assert (type == DBUS_TYPE_UINT32);
-
- if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32,
+ (void **) value, len);
}
#ifdef DBUS_HAVE_INT64
dbus_int64_t **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
-
- _dbus_assert (type == DBUS_TYPE_INT64);
-
- if (!_dbus_demarshal_int64_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64,
+ (void **) value, len);
}
/**
dbus_uint64_t **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
- _dbus_assert (type == DBUS_TYPE_UINT64);
-
- if (!_dbus_demarshal_uint64_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64,
+ (void **) value, len);
}
#endif /* DBUS_HAVE_INT64 */
double **value,
int *len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int type, pos;
-
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
-
- pos = dbus_message_iter_get_data_start (real, &type);
-
- _dbus_assert (type == DBUS_TYPE_ARRAY);
-
- type = iter_get_array_type (real, NULL);
- _dbus_assert (type == DBUS_TYPE_DOUBLE);
-
- if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order,
- pos, NULL, value, len))
- return FALSE;
- else
- return TRUE;
+ return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE,
+ (void **) value, len);
}
/**
int type)
{
const char *data;
+
switch (iter->type)
{
case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
- if (!_dbus_string_append_byte (&iter->message->signature, type))
- return FALSE;
-
if (!_dbus_string_append_byte (&iter->message->body, type))
+ return FALSE;
+
+ if (!_dbus_message_append_byte_to_signature (iter->message, type))
{
- _dbus_string_shorten (&iter->message->signature, 1);
+ _dbus_string_shorten (&iter->message->body, 1);
return FALSE;
}
break;
return TRUE;
}
+static dbus_bool_t
+dbus_message_iter_append_basic (DBusMessageIter *iter,
+ char type,
+ void *value)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
+
+ if (!dbus_message_iter_append_type (real, type))
+ return FALSE;
+
+ if (!_dbus_marshal_basic_type (&real->message->body,
+ type, value,
+ real->message->byte_order))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
/**
* Appends a boolean value to the message
*
dbus_message_iter_append_boolean (DBusMessageIter *iter,
dbus_bool_t value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- 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;
+ unsigned char val = (value != FALSE);
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &val);
}
/**
dbus_message_iter_append_byte (DBusMessageIter *iter,
unsigned char value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!dbus_message_iter_append_type (real, DBUS_TYPE_BYTE))
- 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;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &value);
}
-
/**
* Appends a 32 bit signed integer to the message.
*
dbus_message_iter_append_int32 (DBusMessageIter *iter,
dbus_int32_t value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- 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;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &value);
}
/**
dbus_message_iter_append_uint32 (DBusMessageIter *iter,
dbus_uint32_t value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- 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;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &value);
}
#ifdef DBUS_HAVE_INT64
dbus_message_iter_append_int64 (DBusMessageIter *iter,
dbus_int64_t value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!dbus_message_iter_append_type (real, DBUS_TYPE_INT64))
- return FALSE;
-
- if (!_dbus_marshal_int64 (&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;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value);
}
/**
dbus_message_iter_append_uint64 (DBusMessageIter *iter,
dbus_uint64_t value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!dbus_message_iter_append_type (real, DBUS_TYPE_UINT64))
- return FALSE;
-
- if (!_dbus_marshal_uint64 (&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;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value);
}
#endif /* DBUS_HAVE_INT64 */
dbus_message_iter_append_double (DBusMessageIter *iter,
double value)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- 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;
+ return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &value);
}
/**
*array_type_pos = _dbus_string_get_length (&real->message->body);
- if (!_dbus_string_append_byte (&real->message->signature, element_type))
+ if (!_dbus_message_append_byte_to_signature (real->message, element_type))
{
_dbus_string_set_length (&real->message->body, real->pos);
return FALSE;
/* Append element type */
if (!_dbus_string_append_byte (&real->message->body, element_type))
{
- _dbus_string_shorten (&real->message->signature, 1);
+ _dbus_message_remove_byte_from_signature (real->message);
_dbus_string_set_length (&real->message->body, real->pos);
return FALSE;
}
if (element_type != DBUS_TYPE_ARRAY &&
!array_iter_type_mark_done (real))
{
- _dbus_string_shorten (&real->message->signature, 1);
+ _dbus_message_remove_byte_from_signature (real->message);
return FALSE;
- }
+ }
}
return TRUE;
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 dict_iter pointer to an iter that will be initialized
- * @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;
+/**
+ * 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 dict_iter pointer to an iter that will be initialized
+ * @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_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
+
+ 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_start = dict_real->pos;
+ dict_real->container_length_pos = len_pos;
+ dict_real->wrote_dict_key = 0;
+
+ dbus_message_iter_append_done (dict_real);
+
+ real->wrote_dict_key = FALSE;
+
+ return TRUE;
+}
+
+static dbus_bool_t
+_dbus_message_iter_append_basic_array (DBusMessageIter *iter,
+ char type,
+ const void *value,
+ int len)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+
+ _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
+
+ if (!append_array_type (real, type, NULL, NULL))
+ return FALSE;
+
+ if (!_dbus_marshal_basic_type_array (&real->message->body,
+ type, value, len,
+ real->message->byte_order))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
+
+ dbus_message_iter_append_done (real);
+
+ return TRUE;
+}
+
+
+/**
+ * This function takes a va_list for use by language bindings.
+ * It's otherwise the same as dbus_message_append_args().
+ *
+ * @todo: Shouldn't this function clean up the changes to the message
+ * on failures? (Yes)
+
+ * @see dbus_message_append_args.
+ * @param message the message
+ * @param first_arg_type type of first argument
+ * @param var_args value of first argument, then list of type/value pairs
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_append_args_valist (DBusMessage *message,
+ int first_arg_type,
+ va_list var_args)
+{
+ int type, old_len;
+ DBusMessageIter iter;
+
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+
+ old_len = _dbus_string_get_length (&message->body);
+
+ type = first_arg_type;
+
+ dbus_message_append_iter_init (message, &iter);
+
+ while (type != DBUS_TYPE_INVALID)
+ {
+ switch (type)
+ {
+ case DBUS_TYPE_NIL:
+ if (!dbus_message_iter_append_nil (&iter))
+ goto errorout;
+ break;
+ case DBUS_TYPE_BYTE:
+ /* FIXME if you pass an unsigned char to varargs it gets promoted to int,
+ * so probably we should read an int here.
+ */
+ if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, unsigned char)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_INT32:
+ /* FIXME this is probably wrong, because an int passed in probably gets
+ * converted to plain "int" not necessarily 32-bit.
+ */
+ if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_UINT32:
+ /* FIXME this is probably wrong, because an int passed in probably gets
+ * converted to plain "int" not necessarily 32-bit.
+ */
+ if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t)))
+ goto errorout;
+ break;
+#ifdef DBUS_HAVE_INT64
+ case DBUS_TYPE_INT64:
+ if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_UINT64:
+ if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t)))
+ goto errorout;
+ break;
+#endif /* DBUS_HAVE_INT64 */
+ case DBUS_TYPE_DOUBLE:
+ if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_STRING:
+ if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*)))
+ goto errorout;
+ break;
+ case DBUS_TYPE_CUSTOM:
+ {
+ const char *name;
+ unsigned char *data;
+ int len;
+
+ name = va_arg (var_args, const char *);
+ data = va_arg (var_args, unsigned char *);
+ len = va_arg (var_args, int);
+
+ if (!dbus_message_iter_append_custom (&iter, name, data, len))
+ goto errorout;
+ break;
+ }
+ case DBUS_TYPE_ARRAY:
+ {
+ void *data;
+ int len, type;
+
+ type = va_arg (var_args, int);
+ data = va_arg (var_args, void *);
+ len = va_arg (var_args, int);
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- 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));
+ switch (type)
+ {
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+#ifdef DBUS_HAVE_INT64
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+#endif /* DBUS_HAVE_INT64 */
+ case DBUS_TYPE_DOUBLE:
+ if (!_dbus_message_iter_append_basic_array (&iter, type, 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_OBJECT_PATH:
+ if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len))
+ goto errorout;
+ break;
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_CUSTOM:
+ 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:
+ _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;
+ }
- /* 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;
+ type = va_arg (var_args, int);
}
-
- 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_start = dict_real->pos;
- dict_real->container_length_pos = len_pos;
- dict_real->wrote_dict_key = 0;
- dbus_message_iter_append_done (dict_real);
-
- real->wrote_dict_key = FALSE;
-
return TRUE;
-}
+ errorout:
+ return FALSE;
+}
/**
* Appends a boolean array to the message.
unsigned const char *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL))
- 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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN,
+ value, len);
}
/**
const dbus_int32_t *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL))
- 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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32,
+ value, len);
}
/**
const dbus_uint32_t *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL))
- 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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32,
+ value, len);
}
#ifdef DBUS_HAVE_INT64
const dbus_int64_t *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_INT64, NULL, NULL))
- return FALSE;
-
- if (!_dbus_marshal_int64_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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64,
+ value, len);
}
/**
const dbus_uint64_t *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_UINT64, NULL, NULL))
- return FALSE;
-
- if (!_dbus_marshal_uint64_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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64,
+ value, len);
}
#endif /* DBUS_HAVE_INT64 */
const double *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL))
- 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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE,
+ value, len);
}
/**
unsigned const char *value,
int len)
{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
-
- _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
- if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL))
- 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;
+ return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE,
+ value, len);
}
/**
* Sets the message sender.
*
* @param message the message
- * @param sender the sender
+ * @param sender the sender or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
_dbus_return_val_if_fail (!message->locked, FALSE);
return set_string_field (message,
- DBUS_HEADER_FIELD_SENDER_SERVICE,
+ DBUS_HEADER_FIELD_SENDER,
DBUS_TYPE_STRING,
sender);
}
_dbus_return_val_if_fail (message != NULL, NULL);
return get_string_field (message,
- DBUS_HEADER_FIELD_SENDER_SERVICE,
+ DBUS_HEADER_FIELD_SENDER,
NULL);
}
dbus_message_get_signature (DBusMessage *message)
{
_dbus_return_val_if_fail (message != NULL, NULL);
-
- return _dbus_string_get_const_data (&message->signature);
+
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL);
}
static dbus_bool_t
*/
dbus_bool_t
dbus_message_is_error (DBusMessage *message,
- const char *error_name)
+ const char *error_name)
{
const char *n;
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_fail (error_name != NULL, FALSE);
-
+ _dbus_return_val_if_fail (is_valid_error_name (error_name), FALSE);
+
if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
return FALSE;
dbus_message_has_signature (DBusMessage *message,
const char *signature)
{
+ const char *s;
+
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_fail (signature != NULL, FALSE);
+
+ s = dbus_message_get_signature (message);
- return _dbus_string_equal_c_str (&message->signature, signature);
+ if (s && strcmp (s, signature) == 0)
+ return TRUE;
+ else
+ return FALSE;
}
/**
_dbus_string_init_const (field_data,
_dbus_string_get_const_data (data) + string_data_pos);
- header_field->name_offset = pos;
+ header_field->name_offset = pos - 2;
header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
#if 0
int i;
int field;
int type;
+ dbus_bool_t signature_required;
if (header_len < 16)
{
switch (field)
{
- case DBUS_HEADER_FIELD_SERVICE:
+ case DBUS_HEADER_FIELD_DESTINATION:
if (!decode_string_field (data, field, &fields[field],
&field_data, pos, type))
return FALSE;
}
break;
- case DBUS_HEADER_FIELD_SENDER_SERVICE:
+ case DBUS_HEADER_FIELD_SENDER:
if (!decode_string_field (data, field, &fields[field],
&field_data, pos, type))
return FALSE;
return FALSE;
}
- fields[field].name_offset = pos;
+ fields[field].name_offset = pos - 2;
fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
/* No forging signals from the local path */
return FALSE;
}
- fields[field].name_offset = pos;
+ fields[field].name_offset = pos - 2;
fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
_dbus_verbose ("Found reply serial %u at offset %d\n",
fields[field].value_offset);
break;
+ case DBUS_HEADER_FIELD_SIGNATURE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
+ return FALSE;
+
+#if 0
+ /* FIXME */
+ if (!_dbus_string_validate_signature (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("signature field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
+#endif
+ break;
+
default:
_dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
field, pos);
}
/* Depending on message type, enforce presence of certain fields. */
+ signature_required = TRUE;
+
switch (message_type)
{
case DBUS_MESSAGE_TYPE_SIGNAL:
break;
default:
/* An unknown type, spec requires us to ignore it */
+ signature_required = FALSE;
break;
}
+
+ /* FIXME allow omitting signature field for a message with no arguments? */
+ if (signature_required)
+ {
+ if (fields[DBUS_HEADER_FIELD_SIGNATURE].value_offset < 0)
+ {
+ _dbus_verbose ("No signature field provided\n");
+ return FALSE;
+ }
+ }
if (message_padding)
*message_padding = header_len - pos;
loader->corrupted = TRUE;
goto failed;
}
-
- /* Fill in signature (FIXME should do this during validation,
- * but I didn't want to spend time on it since we want to change
- * the wire format to contain the signature anyway)
- */
- {
- DBusMessageIter iter;
-
- dbus_message_iter_init (message, &iter);
-
- do
- {
- int t;
-
- t = dbus_message_iter_get_arg_type (&iter);
- if (t == DBUS_TYPE_INVALID)
- break;
-
- if (!_dbus_string_append_byte (&message->signature,
- t))
- {
- _dbus_verbose ("failed to append type byte to signature\n");
- oom = TRUE;
- goto failed;
- }
-
- if (t == DBUS_TYPE_ARRAY)
- {
- DBusMessageIter child_iter;
- int array_type = t;
-
- child_iter = iter;
-
- while (array_type == DBUS_TYPE_ARRAY)
- {
- DBusMessageIter parent_iter = child_iter;
- dbus_message_iter_init_array_iterator (&parent_iter,
- &child_iter,
- &array_type);
-
- if (!_dbus_string_append_byte (&message->signature,
- array_type))
- {
- _dbus_verbose ("failed to append array type byte to signature\n");
-
- oom = TRUE;
- goto failed;
- }
- }
- }
- }
- while (dbus_message_iter_next (&iter));
- }
-
+
_dbus_verbose ("Loaded message %p\n", message);
_dbus_assert (!oom);
_dbus_assert_not_reached ("bool array had wrong values");
dbus_free (our_boolean_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");
_dbus_assert (_dbus_string_get_length (&message->body) ==
_dbus_string_get_length (©->body));
-
- _dbus_assert (_dbus_string_get_length (&message->signature) ==
- _dbus_string_get_length (©->signature));
verify_test_message (copy);