From afa4ffbd852686633086569cd34942917c5c49af Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 21 Oct 2006 17:08:08 +0000 Subject: 2006-10-21 Havoc Pennington * dbus/dbus-message.h: put #ifndef DBUS_DISABLE_DEPRECATED around dbus_message_iter_get_array_len(). * throughout: documentation improvements. --- dbus/dbus-message.c | 655 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 397 insertions(+), 258 deletions(-) (limited to 'dbus/dbus-message.c') 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 @@ -1753,203 +2023,13 @@ dbus_message_iter_get_fixed_array (DBusMessageIter *iter, value, n_elements); } -/** - * 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, -- cgit