summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-message.c
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/dbus-message.c')
-rw-r--r--dbus/dbus-message.c655
1 files changed, 397 insertions, 258 deletions
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index aa6f65bd..7e53ce12 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -579,18 +579,229 @@ dbus_message_cache_or_finalize (DBusMessage *message)
dbus_message_finalize (message);
}
+/**
+ * Implementation of the varargs arg-getting functions.
+ * dbus_message_get_args() is the place to go for complete
+ * documentation.
+ *
+ * @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)
+{
+ DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+ int spec_type, msg_type, i;
+ dbus_bool_t retval;
+
+ _dbus_assert (_dbus_message_iter_check (real));
+
+ 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;
+ }
+
+ if (dbus_type_is_basic (spec_type))
+ {
+ DBusBasicValue *ptr;
+
+ ptr = va_arg (var_args, DBusBasicValue*);
+
+ _dbus_assert (ptr != NULL);
+
+ _dbus_type_reader_read_basic (&real->u.reader,
+ ptr);
+ }
+ else if (spec_type == DBUS_TYPE_ARRAY)
+ {
+ int element_type;
+ int spec_element_type;
+ const DBusBasicValue **ptr;
+ int *n_elements_p;
+ DBusTypeReader array;
+
+ spec_element_type = va_arg (var_args, int);
+ element_type = _dbus_type_reader_get_element_type (&real->u.reader);
+
+ if (spec_element_type != element_type)
+ {
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Argument %d is specified to be an array of \"%s\", but "
+ "is actually an array of \"%s\"\n",
+ i,
+ _dbus_type_to_string (spec_element_type),
+ _dbus_type_to_string (element_type));
+
+ goto out;
+ }
+
+ if (dbus_type_is_fixed (spec_element_type))
+ {
+ ptr = va_arg (var_args, const DBusBasicValue**);
+ n_elements_p = va_arg (var_args, int*);
+
+ _dbus_assert (ptr != NULL);
+ _dbus_assert (n_elements_p != NULL);
+
+ _dbus_type_reader_recurse (&real->u.reader, &array);
+
+ _dbus_type_reader_read_fixed_multi (&array,
+ ptr, n_elements_p);
+ }
+ else if (spec_element_type == DBUS_TYPE_STRING ||
+ spec_element_type == DBUS_TYPE_SIGNATURE ||
+ spec_element_type == DBUS_TYPE_OBJECT_PATH)
+ {
+ char ***str_array_p;
+ int n_elements;
+ char **str_array;
+
+ str_array_p = va_arg (var_args, char***);
+ n_elements_p = va_arg (var_args, int*);
+
+ _dbus_assert (str_array_p != NULL);
+ _dbus_assert (n_elements_p != NULL);
+
+ /* Count elements in the array */
+ _dbus_type_reader_recurse (&real->u.reader, &array);
+
+ n_elements = 0;
+ while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
+ {
+ ++n_elements;
+ _dbus_type_reader_next (&array);
+ }
+
+ str_array = dbus_new0 (char*, n_elements + 1);
+ if (str_array == NULL)
+ {
+ _DBUS_SET_OOM (error);
+ goto out;
+ }
+
+ /* Now go through and dup each string */
+ _dbus_type_reader_recurse (&real->u.reader, &array);
+
+ i = 0;
+ while (i < n_elements)
+ {
+ const char *s;
+ _dbus_type_reader_read_basic (&array,
+ &s);
+
+ str_array[i] = _dbus_strdup (s);
+ if (str_array[i] == NULL)
+ {
+ dbus_free_string_array (str_array);
+ _DBUS_SET_OOM (error);
+ goto out;
+ }
+
+ ++i;
+
+ if (!_dbus_type_reader_next (&array))
+ _dbus_assert (i == n_elements);
+ }
+
+ _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
+ _dbus_assert (i == n_elements);
+ _dbus_assert (str_array[i] == NULL);
+
+ *str_array_p = str_array;
+ *n_elements_p = n_elements;
+ }
+#ifndef DBUS_DISABLE_CHECKS
+ else
+ {
+ _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
+ _DBUS_FUNCTION_NAME);
+ goto out;
+ }
+#endif
+ }
+#ifndef DBUS_DISABLE_CHECKS
+ else
+ {
+ _dbus_warn ("you can only read arrays and basic types with %s for now\n",
+ _DBUS_FUNCTION_NAME);
+ goto out;
+ }
+#endif
+
+ spec_type = va_arg (var_args, int);
+ if (!_dbus_type_reader_next (&real->u.reader) && 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;
+ }
+
+ i++;
+ }
+
+ retval = TRUE;
+
+ out:
+
+ return retval;
+}
+
/** @} */
/**
* @defgroup DBusMessage DBusMessage
* @ingroup DBus
- * @brief Message to be sent or received over a DBusConnection.
+ * @brief Message to be sent or received over a #DBusConnection.
*
* A DBusMessage is the most basic unit of communication over a
* DBusConnection. A DBusConnection represents a stream of messages
* received from a remote application, and a stream of messages
* sent to a remote application.
*
+ * A message has a message type, returned from
+ * dbus_message_get_type(). This indicates whether the message is a
+ * method call, a reply to a method call, a signal, or an error reply.
+ *
+ * A message has header fields such as the sender, destination, method
+ * or signal name, and so forth. DBusMessage has accessor functions for
+ * these, such as dbus_message_get_member().
+ *
+ * Convenience functions dbus_message_is_method_call(), dbus_message_is_signal(),
+ * and dbus_message_is_error() check several header fields at once and are
+ * slightly more efficient than checking the header fields with individual
+ * accessor functions.
+ *
+ * Finally, a message has arguments. The number and types of arguments
+ * are in the message's signature header field (accessed with
+ * dbus_message_get_signature()). Simple argument values are usually
+ * retrieved with dbus_message_get_args() but more complex values such
+ * as structs may require the use of #DBusMessageIter.
+ *
+ * The D-Bus specification goes into some more detail about header fields and
+ * message types.
+ *
* @{
*/
@@ -604,12 +815,16 @@ dbus_message_cache_or_finalize (DBusMessage *message)
/**
* Returns the serial of a message or 0 if none has been specified.
* The message's serial number is provided by the application sending
- * the message and is used to identify replies to this message. All
- * messages received on a connection will have a serial, but messages
- * you haven't sent yet may return 0.
+ * the message and is used to identify replies to this message.
+ *
+ * All messages received on a connection will have a serial provided
+ * by the remote application.
+ *
+ * For messages you're sending, dbus_connection_send() will assign a
+ * serial and return it to you.
*
* @param message the message
- * @returns the client serial
+ * @returns the serial
*/
dbus_uint32_t
dbus_message_get_serial (DBusMessage *message)
@@ -620,11 +835,11 @@ dbus_message_get_serial (DBusMessage *message)
}
/**
- * Sets the reply serial of a message (the client serial
- * of the message this is a reply to).
+ * Sets the reply serial of a message (the serial of the message this
+ * is a reply to).
*
* @param message the message
- * @param reply_serial the client serial
+ * @param reply_serial the serial we're replying to
* @returns #FALSE if not enough memory
*/
dbus_bool_t
@@ -748,8 +963,12 @@ dbus_message_new_empty_header (void)
* Types include #DBUS_MESSAGE_TYPE_METHOD_CALL,
* #DBUS_MESSAGE_TYPE_SIGNAL, and so forth.
*
+ * Usually you want to use dbus_message_new_method_call(),
+ * dbus_message_new_method_return(), dbus_message_new_signal(),
+ * or dbus_message_new_error() instead.
+ *
* @param message_type type of message
- * @returns new message or #NULL If no memory
+ * @returns new message or #NULL if no memory
*/
DBusMessage*
dbus_message_new (int message_type)
@@ -781,14 +1000,18 @@ dbus_message_new (int message_type)
* context (no message bus). The interface may be #NULL, which means
* that if multiple methods with the given name exist it is undefined
* which one will be invoked.
- *
+ *
+ * The path and method names may not be #NULL.
+ *
+ * Destination, path, interface, and method name can't contain
+ * any invalid characters (see the D-Bus specification).
+ *
* @param destination name that the message should be sent to or #NULL
* @param path object path the message should be sent to
- * @param interface interface to invoke method on
+ * @param interface interface to invoke method on, or #NULL
* @param method method to invoke
*
* @returns a new DBusMessage, free with dbus_message_unref()
- * @see dbus_message_unref()
*/
DBusMessage*
dbus_message_new_method_call (const char *destination,
@@ -826,10 +1049,8 @@ dbus_message_new_method_call (const char *destination,
* Constructs a message that is a reply to a method call. Returns
* #NULL if memory can't be allocated for the message.
*
- * @param method_call the message which the created
- * message is a reply to.
+ * @param method_call the message being replied to
* @returns a new DBusMessage, free with dbus_message_unref()
- * @see dbus_message_new_method_call(), dbus_message_unref()
*/
DBusMessage*
dbus_message_new_method_return (DBusMessage *method_call)
@@ -870,14 +1091,16 @@ dbus_message_new_method_return (DBusMessage *method_call)
/**
* Constructs a new message representing a signal emission. Returns
* #NULL if memory can't be allocated for the message. A signal is
- * identified by its originating interface, and the name of the
- * signal.
+ * identified by its originating object path, interface, and the name
+ * of the signal.
*
+ * Path, interface, and signal name must all be valid (the D-Bus
+ * specification defines the syntax of these fields).
+ *
* @param path the path to the object emitting the signal
* @param interface the interface the signal is emitted from
* @param name name of the signal
* @returns a new DBusMessage, free with dbus_message_unref()
- * @see dbus_message_unref()
*/
DBusMessage*
dbus_message_new_signal (const char *path,
@@ -911,13 +1134,18 @@ dbus_message_new_signal (const char *path,
}
/**
- * Creates a new message that is an error reply to a certain message.
- * Error replies are possible in response to method calls primarily.
+ * Creates a new message that is an error reply to another message.
+ * Error replies are most common in response to method calls, but
+ * can be returned in reply to any message.
*
- * @param reply_to the original message
+ * The error name must be a valid error name according to the syntax
+ * given in the D-Bus specification. If you don't want to make
+ * up an error name just use #DBUS_ERROR_FAILED.
+ *
+ * @param reply_to the message we're replying to
* @param error_name the error name
- * @param error_message the error message string or #NULL for none
- * @returns a new error message
+ * @param error_message the error message string (or #NULL for none, but please give a message)
+ * @returns a new error message object, free with dbus_message_unref()
*/
DBusMessage*
dbus_message_new_error (DBusMessage *reply_to,
@@ -975,8 +1203,11 @@ dbus_message_new_error (DBusMessage *reply_to,
}
/**
- * Creates a new message that is an error reply to a certain message.
- * Error replies are possible in response to method calls primarily.
+ * Creates a new message that is an error reply to another message, allowing
+ * you to use printf formatting.
+ *
+ * See dbus_message_new_error() for details - this function is the same
+ * aside from the printf formatting.
*
* @param reply_to the original message
* @param error_name the error name
@@ -1024,8 +1255,8 @@ dbus_message_new_error_printf (DBusMessage *reply_to,
* outgoing message queue and thus not modifiable) the new message
* will not be locked.
*
- * @param message the message.
- * @returns the new message.
+ * @param message the message
+ * @returns the new message.or #NULL if not enough memory
*/
DBusMessage *
dbus_message_copy (const DBusMessage *message)
@@ -1077,7 +1308,7 @@ dbus_message_copy (const DBusMessage *message)
/**
* Increments the reference count of a DBusMessage.
*
- * @param message The message
+ * @param message the message
* @returns the message
* @see dbus_message_unref
*/
@@ -1097,9 +1328,10 @@ dbus_message_ref (DBusMessage *message)
}
/**
- * Decrements the reference count of a DBusMessage.
+ * Decrements the reference count of a DBusMessage, freeing the
+ * message if the count reaches 0.
*
- * @param message The message
+ * @param message the message
* @see dbus_message_ref
*/
void
@@ -1127,8 +1359,7 @@ dbus_message_unref (DBusMessage *message)
* #DBUS_MESSAGE_TYPE_METHOD_CALL, #DBUS_MESSAGE_TYPE_METHOD_RETURN,
* #DBUS_MESSAGE_TYPE_ERROR, #DBUS_MESSAGE_TYPE_SIGNAL, but other
* types are allowed and all code must silently ignore messages of
- * unknown type. #DBUS_MESSAGE_TYPE_INVALID will never be returned,
- * however.
+ * unknown type. #DBUS_MESSAGE_TYPE_INVALID will never be returned.
*
* @param message the message
* @returns the type of the message
@@ -1156,8 +1387,10 @@ dbus_message_get_type (DBusMessage *message)
*
* dbus_int32_t v_INT32 = 42;
* const char *v_STRING = "Hello World";
- * DBUS_TYPE_INT32, &v_INT32,
- * DBUS_TYPE_STRING, &v_STRING,
+ * dbus_message_append_args (message,
+ * DBUS_TYPE_INT32, &v_INT32,
+ * DBUS_TYPE_STRING, &v_STRING,
+ * DBUS_TYPE_INVALID);
* @endcode
*
* To append an array of fixed-length basic types, pass in the
@@ -1167,7 +1400,9 @@ dbus_message_get_type (DBusMessage *message)
* @code
* const dbus_int32_t array[] = { 1, 2, 3 };
* const dbus_int32_t *v_ARRAY = array;
- * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3
+ * dbus_message_append_args (message,
+ * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3,
+ * DBUS_TYPE_INVALID);
* @endcode
*
* @warning in C, given "int array[]", "&array == array" (the
@@ -1178,7 +1413,8 @@ dbus_message_get_type (DBusMessage *message)
* const char *array = "Hello" and then use &array though.
*
* The last argument to this function must be #DBUS_TYPE_INVALID,
- * marking the end of the argument list.
+ * marking the end of the argument list. If you don't do this
+ * then libdbus won't know to stop and will read invalid memory.
*
* String/signature/path arrays should be passed in as "const char***
* address_of_array" and "int n_elements"
@@ -1213,8 +1449,7 @@ dbus_message_append_args (DBusMessage *message,
}
/**
- * This function takes a va_list for use by language bindings.
- * It's otherwise the same as dbus_message_append_args().
+ * Like dbus_message_append_args() but takes a va_list for use by language bindings.
*
* @todo for now, if this function fails due to OOM it will leave
* the message half-written and you have to discard the message
@@ -1353,12 +1588,15 @@ dbus_message_append_args_valist (DBusMessage *message,
* followed by a pointer to where the value should be stored. The list
* is terminated with #DBUS_TYPE_INVALID.
*
- * The returned values are constant; do not free them. They point
- * into the #DBusMessage.
+ * Except for string arrays, the returned values are constant; do not
+ * free them. They point into the #DBusMessage.
*
* If the requested arguments are not present, or do not have the
* requested types, then an error will be set.
*
+ * If more arguments than requested are present, the requested
+ * arguments are returned and the extra arguments are ignored.
+ *
* @todo support DBUS_TYPE_STRUCT and DBUS_TYPE_VARIANT and complex arrays
*
* @param message the message
@@ -1387,8 +1625,7 @@ dbus_message_get_args (DBusMessage *message,
}
/**
- * This function takes a va_list for use by language bindings. It is
- * otherwise the same as dbus_message_get_args().
+ * Like dbus_message_get_args but takes a va_list for use by language bindings.
*
* @see dbus_message_get_args
* @param message the message
@@ -1434,6 +1671,20 @@ _dbus_message_iter_init_common (DBusMessage *message,
* Initializes a #DBusMessageIter for reading the arguments of the
* message passed in.
*
+ * When possible, dbus_message_get_args() is much more convenient.
+ * Some types of argument can only be read with #DBusMessageIter
+ * however.
+ *
+ * The easiest way to iterate is like this:
+ * @code
+ * dbus_message_iter_init (&iter);
+ * while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
+ * dbus_message_iter_next (&iter);
+ * @endcode
+ *
+ * #DBusMessageIter contains no allocated memory; it need not be
+ * freed, and can be copied by assignment or memcpy().
+ *
* @param message the message
* @param iter pointer to an iterator to initialize
* @returns #FALSE if the message has no arguments
@@ -1469,7 +1720,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
{
if (iter == NULL)
{
- _dbus_warn ("dbus message iterator is NULL\n");
+ _dbus_warn_check_failed ("dbus message iterator is NULL\n");
return FALSE;
}
@@ -1477,7 +1728,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
{
if (iter->u.reader.byte_order != iter->message->byte_order)
{
- _dbus_warn ("dbus message changed byte order since iterator was created\n");
+ _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n");
return FALSE;
}
/* because we swap the message into compiler order when you init an iter */
@@ -1487,7 +1738,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
{
if (iter->u.writer.byte_order != iter->message->byte_order)
{
- _dbus_warn ("dbus message changed byte order since append iterator was created\n");
+ _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n");
return FALSE;
}
/* because we swap the message into compiler order when you init an iter */
@@ -1495,13 +1746,13 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
}
else
{
- _dbus_warn ("dbus message iterator looks uninitialized or corrupted\n");
+ _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n");
return FALSE;
}
if (iter->changed_stamp != iter->message->changed_stamp)
{
- _dbus_warn ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
+ _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n");
return FALSE;
}
@@ -1513,8 +1764,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
* Checks if an iterator has any more fields.
*
* @param iter the message iter
- * @returns #TRUE if there are more fields
- * following
+ * @returns #TRUE if there are more fields following
*/
dbus_bool_t
dbus_message_iter_has_next (DBusMessageIter *iter)
@@ -1626,6 +1876,8 @@ dbus_message_iter_recurse (DBusMessageIter *iter,
* recurse into a variant and determine the signature of
* the variant's value.
*
+ * The returned string must be freed with dbus_free().
+ *
* @param iter the message iterator
* @returns the contained signature, or NULL if out of memory
*/
@@ -1677,10 +1929,12 @@ dbus_message_iter_get_signature (DBusMessageIter *iter)
* #endif
* @endcode
*
- * To avoid the #DBUS_HAVE_INT64 conditional, create a struct or
- * something that occupies at least 8 bytes, e.g. you could use a
- * struct with two int32 values in it. dbus_uint64_t is just one
- * example of a type that's large enough to hold any possible value.
+ * You can skip the #DBUS_HAVE_INT64 conditional unless you care about
+ * some sort of really obscure platform. If you do know about such a
+ * platform and want your code to work on it, create a struct
+ * that occupies at least 8 bytes. dbus_uint64_t is just
+ * one example of a type that's large enough to hold any possible
+ * value.
*
* Be sure you have somehow checked that
* dbus_message_iter_get_arg_type() matches the type you are
@@ -1704,10 +1958,22 @@ dbus_message_iter_get_basic (DBusMessageIter *iter,
}
/**
- * Returns the number of elements in the array;
+ * Returns the number of bytes in the array as marshaled in the wire
+ * protocol. The iterator must currently be inside an array-typed
+ * value.
+ *
+ * This function is deprecated on the grounds that it is stupid. Why
+ * would you want to know how many bytes are in the array as marshaled
+ * in the wire protocol? For now, use the n_elements returned from
+ * dbus_message_iter_get_fixed_array() instead, or iterate over the
+ * array values and count them.
*
+ * @todo introduce a variant of this get_n_elements that returns
+ * the number of elements, though with a non-fixed array it will not
+ * be very efficient, so maybe it's not good.
+ *
* @param iter the iterator
- * @returns the number of elements in the array
+ * @returns the number of bytes in the array
*/
int
dbus_message_iter_get_array_len (DBusMessageIter *iter)
@@ -1725,13 +1991,17 @@ dbus_message_iter_get_array_len (DBusMessageIter *iter)
* such as integers, bool, double. The block read will be from the
* current position in the array until the end of the array.
*
- * This function should only be used if #dbus_type_is_fixed returns
+ * This function should only be used if dbus_type_is_fixed() returns
* #TRUE for the element type.
*
* The value argument should be the address of a location to store the
* returned array. So for int32 it should be a "const dbus_int32_t**"
* The returned value is by reference and should not be freed.
*
+ * Because the array is not copied, this function runs in
+ * constant time and is fast; it's much preferred over walking the
+ * entire array with an iterator.
+ *
* @param iter the iterator
* @param value location to store the block
* @param n_elements number of elements in the block
@@ -1754,202 +2024,12 @@ dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
}
/**
- * This function takes a va_list for use by language bindings and is
- * otherwise the same as dbus_message_iter_get_args().
- * dbus_message_get_args() is the place to go for complete
- * documentation.
- *
- * @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)
-{
- DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int spec_type, msg_type, i;
- dbus_bool_t retval;
-
- _dbus_assert (_dbus_message_iter_check (real));
-
- 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;
- }
-
- if (dbus_type_is_basic (spec_type))
- {
- DBusBasicValue *ptr;
-
- ptr = va_arg (var_args, DBusBasicValue*);
-
- _dbus_assert (ptr != NULL);
-
- _dbus_type_reader_read_basic (&real->u.reader,
- ptr);
- }
- else if (spec_type == DBUS_TYPE_ARRAY)
- {
- int element_type;
- int spec_element_type;
- const DBusBasicValue **ptr;
- int *n_elements_p;
- DBusTypeReader array;
-
- spec_element_type = va_arg (var_args, int);
- element_type = _dbus_type_reader_get_element_type (&real->u.reader);
-
- if (spec_element_type != element_type)
- {
- dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
- "Argument %d is specified to be an array of \"%s\", but "
- "is actually an array of \"%s\"\n",
- i,
- _dbus_type_to_string (spec_element_type),
- _dbus_type_to_string (element_type));
-
- goto out;
- }
-
- if (dbus_type_is_fixed (spec_element_type))
- {
- ptr = va_arg (var_args, const DBusBasicValue**);
- n_elements_p = va_arg (var_args, int*);
-
- _dbus_assert (ptr != NULL);
- _dbus_assert (n_elements_p != NULL);
-
- _dbus_type_reader_recurse (&real->u.reader, &array);
-
- _dbus_type_reader_read_fixed_multi (&array,
- ptr, n_elements_p);
- }
- else if (spec_element_type == DBUS_TYPE_STRING ||
- spec_element_type == DBUS_TYPE_SIGNATURE ||
- spec_element_type == DBUS_TYPE_OBJECT_PATH)
- {
- char ***str_array_p;
- int n_elements;
- char **str_array;
-
- str_array_p = va_arg (var_args, char***);
- n_elements_p = va_arg (var_args, int*);
-
- _dbus_assert (str_array_p != NULL);
- _dbus_assert (n_elements_p != NULL);
-
- /* Count elements in the array */
- _dbus_type_reader_recurse (&real->u.reader, &array);
-
- n_elements = 0;
- while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
- {
- ++n_elements;
- _dbus_type_reader_next (&array);
- }
-
- str_array = dbus_new0 (char*, n_elements + 1);
- if (str_array == NULL)
- {
- _DBUS_SET_OOM (error);
- goto out;
- }
-
- /* Now go through and dup each string */
- _dbus_type_reader_recurse (&real->u.reader, &array);
-
- i = 0;
- while (i < n_elements)
- {
- const char *s;
- _dbus_type_reader_read_basic (&array,
- &s);
-
- str_array[i] = _dbus_strdup (s);
- if (str_array[i] == NULL)
- {
- dbus_free_string_array (str_array);
- _DBUS_SET_OOM (error);
- goto out;
- }
-
- ++i;
-
- if (!_dbus_type_reader_next (&array))
- _dbus_assert (i == n_elements);
- }
-
- _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
- _dbus_assert (i == n_elements);
- _dbus_assert (str_array[i] == NULL);
-
- *str_array_p = str_array;
- *n_elements_p = n_elements;
- }
-#ifndef DBUS_DISABLE_CHECKS
- else
- {
- _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n",
- _DBUS_FUNCTION_NAME);
- goto out;
- }
-#endif
- }
-#ifndef DBUS_DISABLE_CHECKS
- else
- {
- _dbus_warn ("you can only read arrays and basic types with %s for now\n",
- _DBUS_FUNCTION_NAME);
- goto out;
- }
-#endif
-
- spec_type = va_arg (var_args, int);
- if (!_dbus_type_reader_next (&real->u.reader) && 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;
- }
-
- i++;
- }
-
- retval = TRUE;
-
- out:
-
- return retval;
-}
-
-/**
* Initializes a #DBusMessageIter for appending arguments to the end
* of a message.
*
* @todo If appending any of the arguments fails due to lack of
- * memory, generally the message is hosed and you have to start over
- * building the whole message.
+ * memory, the message is hosed and you have to start over building
+ * the whole message.
*
* @param message the message
* @param iter pointer to an iterator to initialize
@@ -2099,7 +2179,7 @@ _dbus_message_iter_append_check (DBusMessageRealIter *iter)
if (iter->message->locked)
{
- _dbus_warn ("dbus append iterator can't be used: message is locked (has already been sent)\n");
+ _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n");
return FALSE;
}
@@ -2322,6 +2402,11 @@ dbus_message_iter_close_container (DBusMessageIter *iter,
* message successfully arrived at the remote end. Normally you know a
* message was received when you receive the reply to it.
*
+ * The flag is #FALSE by default, that is by default the other end is
+ * required to reply.
+ *
+ * On the protocol level this toggles #DBUS_HEADER_FLAG_NO_REPLY_EXPECTED
+ *
* @param message the message
* @param no_reply #TRUE if no reply is desired
*/
@@ -2360,6 +2445,10 @@ dbus_message_get_no_reply (DBusMessage *message)
* starting up, or fails to start up. In case of failure, the reply
* will be an error.
*
+ * The flag is set to #TRUE by default, i.e. auto starting is the default.
+ *
+ * On the protocol level this toggles #DBUS_HEADER_FLAG_NO_AUTO_START
+ *
* @param message the message
* @param auto_start #TRUE if auto-starting is desired
*/
@@ -2397,6 +2486,9 @@ dbus_message_get_auto_start (DBusMessage *message)
* DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a signal is being
* emitted from (for DBUS_MESSAGE_TYPE_SIGNAL).
*
+ * The path must contain only valid characters as defined
+ * in the D-Bus specification.
+ *
* @param message the message
* @param object_path the path or #NULL to unset
* @returns #FALSE if not enough memory
@@ -2422,6 +2514,11 @@ dbus_message_set_path (DBusMessage *message,
* DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted from (for
* DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none.
*
+ * See also dbus_message_get_path_decomposed().
+ *
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the path (should not be freed) or #NULL
*/
@@ -2441,7 +2538,9 @@ dbus_message_get_path (DBusMessage *message)
}
/**
- * Checks if the message has a path
+ * Checks if the message has a particular object path. The object
+ * path is the destination object for a method call or the emitting
+ * object for a signal.
*
* @param message the message
* @param path the path name
@@ -2482,6 +2581,8 @@ dbus_message_has_path (DBusMessage *message,
* So the path "/foo/bar" becomes { "foo", "bar", NULL }
* and the path "/" becomes { NULL }.
*
+ * See also dbus_message_get_path().
+ *
* @todo this could be optimized by using the len from the message
* instead of calling strlen() again
*
@@ -2516,6 +2617,9 @@ dbus_message_get_path_decomposed (DBusMessage *message,
* the interface a signal is being emitted from
* (for DBUS_MESSAGE_TYPE_SIGNAL).
*
+ * The interface name must contain only valid characters as defined
+ * in the D-Bus specification.
+ *
* @param message the message
* @param interface the interface or #NULL to unset
* @returns #FALSE if not enough memory
@@ -2543,6 +2647,9 @@ dbus_message_set_interface (DBusMessage *message,
* The interface name is fully-qualified (namespaced).
* Returns #NULL if none.
*
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the message interface (should not be freed) or #NULL
*/
@@ -2566,7 +2673,7 @@ dbus_message_get_interface (DBusMessage *message)
*
* @param message the message
* @param interface the interface name
- * @returns #TRUE if there is a interface field in the header
+ * @returns #TRUE if the interface field in the header matches
*/
dbus_bool_t
dbus_message_has_interface (DBusMessage *message,
@@ -2597,7 +2704,9 @@ dbus_message_has_interface (DBusMessage *message,
* Sets the interface member being invoked
* (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
* (DBUS_MESSAGE_TYPE_SIGNAL).
- * The interface name is fully-qualified (namespaced).
+ *
+ * The member name must contain only valid characters as defined
+ * in the D-Bus specification.
*
* @param message the message
* @param member the member or #NULL to unset
@@ -2624,6 +2733,9 @@ dbus_message_set_member (DBusMessage *message,
* (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
* (DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none.
*
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the member name (should not be freed) or #NULL
*/
@@ -2678,6 +2790,9 @@ dbus_message_has_member (DBusMessage *message,
* Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
* The name is fully-qualified (namespaced).
*
+ * The error name must contain only valid characters as defined
+ * in the D-Bus specification.
+ *
* @param message the message
* @param error_name the name or #NULL to unset
* @returns #FALSE if not enough memory
@@ -2702,6 +2817,9 @@ dbus_message_set_error_name (DBusMessage *message,
* Gets the error name (DBUS_MESSAGE_TYPE_ERROR only)
* or #NULL if none.
*
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the error name (should not be freed) or #NULL
*/
@@ -2726,6 +2844,9 @@ dbus_message_get_error_name (DBusMessage *message)
* assigned by the bus to each connection, or a well-known name
* specified in advance.
*
+ * The destination name must contain only valid characters as defined
+ * in the D-Bus specification.
+ *
* @param message the message
* @param destination the destination name or #NULL to unset
* @returns #FALSE if not enough memory
@@ -2749,6 +2870,9 @@ dbus_message_set_destination (DBusMessage *message,
/**
* Gets the destination of a message or #NULL if there is none set.
*
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the message destination (should not be freed) or #NULL
*/
@@ -2770,6 +2894,13 @@ dbus_message_get_destination (DBusMessage *message)
/**
* Sets the message sender.
*
+ * The sender must be a valid bus name as defined in the D-Bus
+ * specification.
+ *
+ * Usually you don't want to call this. The message bus daemon will
+ * call it to set the origin of each message. If you aren't implementing
+ * a message bus daemon you shouldn't need to set the sender.
+ *
* @param message the message
* @param sender the sender or #NULL to unset
* @returns #FALSE if not enough memory
@@ -2795,6 +2926,13 @@ dbus_message_set_sender (DBusMessage *message,
* message, or #NULL if unknown or inapplicable. The sender is filled
* in by the message bus.
*
+ * Note, the returned sender is always the unique bus name.
+ * Connections may own multiple other bus names, but those
+ * are not found in the sender field.
+ *
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the unique name of the sender or #NULL
*/
@@ -2818,13 +2956,16 @@ dbus_message_get_sender (DBusMessage *message)
* 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
+ * what you might expect (that is, 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_INT32. The string is terminated with nul (nul is also
* the value of #DBUS_TYPE_INVALID).
*
+ * The returned string becomes invalid if the message is
+ * modified, since it points into the wire-marshaled message data.
+ *
* @param message the message
* @returns the type signature
*/
@@ -2907,9 +3048,7 @@ dbus_message_is_method_call (DBusMessage *message,
/**
* Checks whether the message is a signal with the given interface and
* member fields. If the message is not #DBUS_MESSAGE_TYPE_SIGNAL, or
- * has a different interface or member field, returns #FALSE. If the
- * interface field in the message is missing, it is assumed to match
- * any interface you pass in to this function.
+ * has a different interface or member field, returns #FALSE.
*
* @param message the message
* @param interface the name to check (must not be #NULL)
@@ -3064,7 +3203,7 @@ dbus_message_has_signature (DBusMessage *message,
/**
* Sets a #DBusError based on the contents of the given
* message. The error is only set if the message
- * is an error message, as in DBUS_MESSAGE_TYPE_ERROR.
+ * is an error message, as in #DBUS_MESSAGE_TYPE_ERROR.
* The name of the error is set to the name of the message,
* and the error message is set to the first argument
* if the argument exists and is a string.
@@ -3081,7 +3220,7 @@ dbus_message_has_signature (DBusMessage *message,
*
* @param error the error to set
* @param message the message to set it from
- * @returns #TRUE if dbus_message_get_is_error() returns #TRUE for the message
+ * @returns #TRUE if the message had type #DBUS_MESSAGE_TYPE_ERROR
*/
dbus_bool_t
dbus_set_error_from_message (DBusError *error,