diff options
author | Christian Dywan <christian.dywan@lanedo.com> | 2010-09-23 19:22:53 +0200 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2015-05-13 18:44:42 +0100 |
commit | 8e83c6e4d5478085c7571bf5d2ea44a6ebce26c9 (patch) | |
tree | b81452ad34c371094b8ffb3232ce8d16442c647d | |
parent | ae56222048a633248a50408b41a05b560125f138 (diff) | |
download | dbus-8e83c6e4d5478085c7571bf5d2ea44a6ebce26c9.tar.gz |
Implement dbus_message_iter_get_element_count
According unit tests are added to _dbus_message_test.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=30350
Reviewed-by: Havoc Pennington <hp@pobox.com>
-rw-r--r-- | dbus/dbus-message-util.c | 56 | ||||
-rw-r--r-- | dbus/dbus-message.c | 49 | ||||
-rw-r--r-- | dbus/dbus-message.h | 3 |
3 files changed, 101 insertions, 7 deletions
diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 0c0ab7cc..ded72036 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -1208,6 +1208,16 @@ _dbus_message_test (const char *test_data_dir) char **decomposed; DBusInitialFDs *initial_fds; dbus_bool_t ok; + char basic_types[] = DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BOOLEAN_AS_STRING \ + DBUS_TYPE_INT16_AS_STRING \ + DBUS_TYPE_INT32_AS_STRING \ + DBUS_TYPE_INT64_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_UINT64_AS_STRING \ + DBUS_TYPE_DOUBLE_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING; initial_fds = _dbus_check_fdleaks_enter (); @@ -1598,6 +1608,52 @@ _dbus_message_test (const char *test_data_dir) _dbus_check_fdleaks_leave (initial_fds); initial_fds = _dbus_check_fdleaks_enter (); + /* Test enumeration of array elements */ + for (i = strlen (basic_types) - 1; i > 0; i--) + { + int some; + char* signature = _dbus_strdup ("?"); + signature[0] = basic_types[i]; + s = "SomeThingToSay"; + message = dbus_message_new_method_call ("de.ende.test", + "/de/ende/test", "de.ende.Test", "ArtistName"); + _dbus_assert (message != NULL); + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, + signature, &array_iter); + for (some = 0; some < 3; some++) + { + if (basic_types[i] == DBUS_TYPE_STRING) + dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &s); + else + dbus_message_iter_append_basic (&array_iter, basic_types[i], &some); + } + dbus_message_iter_close_container (&iter, &array_iter); + dbus_message_iter_init (message, &iter); + _dbus_assert (dbus_message_iter_get_element_count (&iter) == some); + dbus_message_unref (message); + dbus_free (signature); + } + /* Array of structs */ + message = dbus_message_new_method_call ("de.ende.test", + "/de/ende/test", "de.ende.Test", "ArtistName"); + _dbus_assert (message != NULL); + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING, &array_iter); + dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, + NULL, &struct_iter); + s = "SpamAndEggs"; + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); + dbus_message_iter_close_container (&array_iter, &struct_iter); + dbus_message_iter_close_container (&iter, &array_iter); + dbus_message_iter_init (message, &iter); + _dbus_assert (dbus_message_iter_get_element_count (&iter) == 1); + dbus_message_unref (message); + check_memleaks (); + /* Check that we can abandon a container */ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index d6fec0bd..e14c2645 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -2325,20 +2325,55 @@ dbus_message_iter_get_basic (DBusMessageIter *iter, } /** + * Returns the number of elements in the array-typed value pointed + * to by the iterator. + * Note that this function is O(1) for arrays of fixed-size types + * but O(n) for arrays of variable-length types such as strings, + * so it may be a bad idea to use it. + * + * @param iter the iterator + * @returns the number of elements in the array + */ +int dbus_message_iter_get_element_count (DBusMessageIter* iter) +{ + DBusMessageRealIter *real = (DBusMessageRealIter *)iter; + DBusTypeReader array; + int element_type; + int n_elements = 0; + + _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0); + _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader) + == DBUS_TYPE_ARRAY, 0); + + element_type = _dbus_type_reader_get_element_type (&real->u.reader); + _dbus_type_reader_recurse (&real->u.reader, &array); + if (dbus_type_is_fixed (element_type)) + { + int alignment = _dbus_type_get_alignment (element_type); + int total_len = _dbus_type_reader_get_array_length (&array); + n_elements = total_len / alignment; + } + else + { + while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID) + { + ++n_elements; + _dbus_type_reader_next (&array); + } + } + + return n_elements; +} + +/** * 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. + * in the wire protocol? Use dbus_message_iter_get_element_count() instead. * - * @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 bytes in the array */ diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index baa7d7b5..3e33eb7b 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -226,6 +226,9 @@ void dbus_message_iter_recurse (DBusMessageIter *iter, DBUS_EXPORT void dbus_message_iter_get_basic (DBusMessageIter *iter, void *value); +DBUS_EXPORT +int dbus_message_iter_get_element_count(DBusMessageIter *iter); + #ifndef DBUS_DISABLE_DEPRECATED /* This function returns the wire protocol size of the array in bytes, * you do not want to know that probably |