diff --git a/ChangeLog b/ChangeLog index e001541c75..c3cb6084c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-06-16 Dan Williams + + * libnm-util/Makefile.am + * libnm-util/dbus-dict-helpers.[ch] + - Add some helpers to take the pain out of using dict types in + dbus. + + * test/libnm-util/Makefile.am + * test/libnm-util/test-dbus-dict-helpers.c + - Test cases for the dict helper functions + 2006-06-15 Robert Love * gnome/applet/nm-gconf-wso-wpa-eap.c: Don't set the set unless there diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 8dc994034d..7d227f1bf8 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -34,7 +34,9 @@ libnm_util_la_SOURCES= \ sha1.c \ sha1.h \ dbus-method-dispatcher.c \ - dbus-method-dispatcher.h + dbus-method-dispatcher.h \ + dbus-dict-helpers.c \ + dbus-dict-helpers.h if !WITH_GCRYPT libnm_util_la_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h diff --git a/libnm-util/dbus-dict-helpers.c b/libnm-util/dbus-dict-helpers.c new file mode 100644 index 0000000000..5232b8d93a --- /dev/null +++ b/libnm-util/dbus-dict-helpers.c @@ -0,0 +1,533 @@ +/* NetworkManager -- Network link manager + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2006 Red Hat, Inc. + */ + +#include +#include +#include + +#include "dbus-dict-helpers.h" + + +/** + * Start a dict in a dbus message. Should be paired with a call to + * {@link nmu_dbus_dict_close_write}. + * + * @param iter A valid dbus message iterator + * @param iter_dict (out) A dict iterator to pass to further dict functions + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_open_write (DBusMessageIter *iter, DBusMessageIter *iter_dict) +{ + if (!iter || !iter_dict) + return 0; + + return dbus_message_iter_open_container (iter, + DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + iter_dict); +} + + +/** + * End a dict element in a dbus message. Should be paired with + * a call to {@link nmu_dbus_dict_open_write}. + * + * @param iter valid dbus message iterator, same as passed to + * nmu_dbus_dict_open_write() + * @param iter_dict a dbus dict iterator returned from {@link nmu_dbus_dict_open_write} + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_close_write (DBusMessageIter *iter, DBusMessageIter *iter_dict) +{ + if (!iter || !iter_dict) + return 0; + + return dbus_message_iter_close_container (iter, iter_dict); +} + + +static const char * +_nmu_get_type_as_string_from_type (const int type) +{ + switch (type) + { + case DBUS_TYPE_BYTE: + return DBUS_TYPE_BYTE_AS_STRING; + case DBUS_TYPE_BOOLEAN: + return DBUS_TYPE_BOOLEAN_AS_STRING; + case DBUS_TYPE_INT16: + return DBUS_TYPE_INT16_AS_STRING; + case DBUS_TYPE_UINT16: + return DBUS_TYPE_UINT16_AS_STRING; + case DBUS_TYPE_INT32: + return DBUS_TYPE_INT32_AS_STRING; + case DBUS_TYPE_UINT32: + return DBUS_TYPE_UINT32_AS_STRING; + case DBUS_TYPE_INT64: + return DBUS_TYPE_INT64_AS_STRING; + case DBUS_TYPE_UINT64: + return DBUS_TYPE_UINT64_AS_STRING; + case DBUS_TYPE_DOUBLE: + return DBUS_TYPE_DOUBLE_AS_STRING; + case DBUS_TYPE_STRING: + return DBUS_TYPE_STRING_AS_STRING; + case DBUS_TYPE_OBJECT_PATH: + return DBUS_TYPE_OBJECT_PATH_AS_STRING; + default: + return NULL; + } + return NULL; +} + + +static dbus_bool_t +_nmu_dbus_add_dict_entry (DBusMessageIter *iter_dict, + const char *key, + const int value_type, + const void *value) +{ + DBusMessageIter iter_dict_entry, iter_dict_val; + const char * type_as_string = NULL; + + type_as_string = _nmu_get_type_as_string_from_type (value_type); + if (!type_as_string) + return 0; + + if (!dbus_message_iter_open_container (iter_dict, + DBUS_TYPE_DICT_ENTRY, + NULL, + &iter_dict_entry)) + return 0; + + if (!dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &key)) + return 0; + + if (!dbus_message_iter_open_container (&iter_dict_entry, + DBUS_TYPE_VARIANT, + type_as_string, + &iter_dict_val)) + return 0; + + if (!dbus_message_iter_append_basic (&iter_dict_val, value_type, value)) + return 0; + + if (!dbus_message_iter_close_container (&iter_dict_entry, &iter_dict_val)) + return 0; + if (!dbus_message_iter_close_container (iter_dict, &iter_dict_entry)) + return 0; + + return 1; +} + + +/** + * Add a string entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The string value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_string (DBusMessageIter *iter_dict, + const char * key, + const char * value) +{ + if (!key || !value) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_STRING, &value); +} + +/** + * Add a byte entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The byte value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_byte (DBusMessageIter *iter_dict, + const char * key, + const char value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_BYTE, &value); +} + +/** + * Add a boolean entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The boolean value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_bool (DBusMessageIter *iter_dict, + const char * key, + const dbus_bool_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_BOOLEAN, &value); +} + +/** + * Add a 16-bit signed integer entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The 16-bit signed integer value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_int16 (DBusMessageIter *iter_dict, + const char * key, + const dbus_int16_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_INT16, &value); +} + +/** + * Add a 16-bit unsigned integer entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The 16-bit unsigned integer value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_uint16 (DBusMessageIter *iter_dict, + const char * key, + const dbus_uint16_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_UINT16, &value); +} + +/** + * Add a 32-bit signed integer to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The 32-bit signed integer value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_int32 (DBusMessageIter *iter_dict, + const char * key, + const dbus_int32_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_INT32, &value); +} + +/** + * Add a 32-bit unsigned integer entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The 32-bit unsigned integer value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_uint32 (DBusMessageIter *iter_dict, + const char * key, + const dbus_uint32_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_UINT32, &value); +} + +/** + * Add a 64-bit integer entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The 64-bit integer value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_int64 (DBusMessageIter *iter_dict, + const char * key, + const dbus_int64_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_INT64, &value); +} + +/** + * Add a 64-bit unsigned integer entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The 64-bit unsigned integer value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_uint64 (DBusMessageIter *iter_dict, + const char * key, + const dbus_uint64_t value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_UINT64, &value); +} + +/** + * Add a double-precision floating point entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The double-precision floating point value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_double (DBusMessageIter *iter_dict, + const char * key, + const double value) +{ + if (!key) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_DOUBLE, &value); +} + +/** + * Add a DBus object path entry to the dict. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_write} + * @param key The key of the dict item + * @param value The DBus object path value + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_append_object_path (DBusMessageIter *iter_dict, + const char * key, + const char * value) +{ + if (!key || !value) return 0; + return _nmu_dbus_add_dict_entry (iter_dict, key, DBUS_TYPE_OBJECT_PATH, &value); +} + + +/*****************************************************/ +/* Stuff for reading dicts */ +/*****************************************************/ + +/** + * Start reading from a dbus dict. + * + * @param iter A valid DBusMessageIter pointing to the start of the dict + * @param iter_dict (out) A DBusMessageIter to be passed to {@link nmu_dbus_dict_read_next_entry} + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_open_read (DBusMessageIter *iter, + DBusMessageIter *iter_dict) +{ + if (!iter || !iter_dict) return FALSE; + + if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type (iter) != DBUS_TYPE_DICT_ENTRY) + return FALSE; + + dbus_message_iter_recurse (iter, iter_dict); + return TRUE; +} + +static dbus_bool_t +_nmu_dbus_dict_fill_value_from_variant (NMUDictEntry *entry, + DBusMessageIter *iter_dict_val) +{ + dbus_bool_t success = TRUE; + + switch (entry->type) + { + case DBUS_TYPE_STRING: + { + const char *v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->str_value = v; + break; + } + case DBUS_TYPE_BOOLEAN: + { + dbus_bool_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->bool_value = v; + break; + } + case DBUS_TYPE_BYTE: + { + char v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->byte_value = v; + break; + } + case DBUS_TYPE_INT16: + { + dbus_int16_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->int16_value = v; + break; + } + case DBUS_TYPE_UINT16: + { + dbus_uint16_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->uint16_value = v; + break; + } + case DBUS_TYPE_INT32: + { + dbus_int32_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->int32_value = v; + break; + } + case DBUS_TYPE_UINT32: + { + dbus_uint32_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->uint32_value = v; + break; + } + case DBUS_TYPE_INT64: + { + dbus_int64_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->int64_value = v; + break; + } + case DBUS_TYPE_UINT64: + { + dbus_uint64_t v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->uint64_value = v; + break; + } + case DBUS_TYPE_DOUBLE: + { + double v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->double_value = v; + break; + } + case DBUS_TYPE_OBJECT_PATH: + { + const char *v; + dbus_message_iter_get_basic (iter_dict_val, &v); + entry->str_value = v; + break; + } + default: + success = FALSE; + break; + } + + return success; +} + + +/** + * Read the current key/value entry from the dict. Entries and their data + * are owned by the dbus message and should not be freed or modified. You must + * copy the data if you wish to keep it around after the DBusMessage has been + * freed. + * + * The returned entry object will be filled with the type and value of the next + * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error occurred. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_read} + * @param entry A valid dict entry object into which the dict key and value will be placed + * @return TRUE on success, FALSE on failure + * + */ +dbus_bool_t +nmu_dbus_dict_get_entry (DBusMessageIter *iter_dict, + NMUDictEntry * entry) +{ + DBusMessageIter iter_dict_entry, iter_dict_val; + const char *key; + + if (!iter_dict || !entry) + goto error; + + if (dbus_message_iter_get_arg_type (iter_dict) != DBUS_TYPE_DICT_ENTRY) + goto error; + + dbus_message_iter_recurse (iter_dict, &iter_dict_entry); + dbus_message_iter_get_basic (&iter_dict_entry, &key); + entry->key = key; + + if (!dbus_message_iter_next (&iter_dict_entry)) + goto error; + + dbus_message_iter_recurse (&iter_dict_entry, &iter_dict_val); + entry->type = dbus_message_iter_get_arg_type (&iter_dict_val); + if(!_nmu_dbus_dict_fill_value_from_variant (entry, &iter_dict_val)) + goto error; + + dbus_message_iter_next (iter_dict); + return TRUE; + +error: + memset (entry, 0, sizeof (NMUDictEntry)); + entry->type = DBUS_TYPE_INVALID; + return FALSE; +} + + +/** + * Return whether or not there are additional dictionary entries. + * + * @param iter_dict A valid DBusMessageIter returned from {@link nmu_dbus_dict_open_read} + * @return TRUE if more dict entries exists, FALSE if no more dict entries exist + * + */ +dbus_bool_t +nmu_dbus_dict_has_dict_entry (DBusMessageIter *iter_dict) +{ + if (!iter_dict) + { + fprintf (stderr, "nmu_dbus_dict_has_dict_entry() called with invalid " + "arguments; this is an error in the program.\n"); + return FALSE; + } + return dbus_message_iter_get_arg_type (iter_dict) == DBUS_TYPE_DICT_ENTRY; +} diff --git a/libnm-util/dbus-dict-helpers.h b/libnm-util/dbus-dict-helpers.h new file mode 100644 index 0000000000..d7b7511094 --- /dev/null +++ b/libnm-util/dbus-dict-helpers.h @@ -0,0 +1,135 @@ +/* NetworkManager -- Network link manager + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2006 Red Hat, Inc. + */ + +#ifndef DBUS_DICT_HELPERS_H +#define DBUS_DICT_HELPERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Adding a dict to a DBusMessage + */ + +dbus_bool_t +nmu_dbus_dict_open_write (DBusMessageIter *iter, + DBusMessageIter *iter_dict); + +dbus_bool_t +nmu_dbus_dict_close_write (DBusMessageIter *iter, + DBusMessageIter *iter_dict); + +dbus_bool_t +nmu_dbus_dict_append_string (DBusMessageIter *iter_dict, + const char * key, + const char * value); + +dbus_bool_t +nmu_dbus_dict_append_byte (DBusMessageIter *iter_dict, + const char * key, + const char value); + +dbus_bool_t +nmu_dbus_dict_append_bool (DBusMessageIter *iter_dict, + const char * key, + const dbus_bool_t value); + +dbus_bool_t +nmu_dbus_dict_append_int16 (DBusMessageIter *iter_dict, + const char * key, + const dbus_int16_t value); + +dbus_bool_t +nmu_dbus_dict_append_uint16 (DBusMessageIter *iter_dict, + const char * key, + const dbus_uint16_t value); + +dbus_bool_t +nmu_dbus_dict_append_int32 (DBusMessageIter *iter_dict, + const char * key, + const dbus_int32_t value); + +dbus_bool_t +nmu_dbus_dict_append_uint32 (DBusMessageIter *iter_dict, + const char * key, + const dbus_uint32_t value); + +dbus_bool_t +nmu_dbus_dict_append_int64 (DBusMessageIter *iter_dict, + const char * key, + const dbus_int64_t value); + +dbus_bool_t +nmu_dbus_dict_append_uint64 (DBusMessageIter *iter_dict, + const char * key, + const dbus_uint64_t value); + +dbus_bool_t +nmu_dbus_dict_append_double (DBusMessageIter *iter_dict, + const char * key, + const double value); + +dbus_bool_t +nmu_dbus_dict_append_object_path (DBusMessageIter *iter_dict, + const char * key, + const char * value); + + +/* + * Reading a dict from a DBusMessage + */ + +typedef struct NMUDictEntry { + int type; + const char *key; + + /** Possible values of the property */ + union { + const char *str_value; + char byte_value; + dbus_bool_t bool_value; + dbus_int16_t int16_value; + dbus_uint16_t uint16_value; + dbus_int32_t int32_value; + dbus_uint32_t uint32_value; + dbus_int64_t int64_value; + dbus_uint64_t uint64_value; + double double_value; + }; +} NMUDictEntry; + +dbus_bool_t +nmu_dbus_dict_open_read (DBusMessageIter *iter, + DBusMessageIter *iter_dict); + +dbus_bool_t +nmu_dbus_dict_get_entry (DBusMessageIter *iter_dict, + NMUDictEntry * entry); + +dbus_bool_t +nmu_dbus_dict_has_dict_entry (DBusMessageIter *iter_dict); + +#ifdef __cplusplus +} +#endif + +#endif /* DBUS_DICT_HELPERS_H */ diff --git a/test/libnm-util/Makefile.am b/test/libnm-util/Makefile.am index 63f32cbad6..971802ca6a 100644 --- a/test/libnm-util/Makefile.am +++ b/test/libnm-util/Makefile.am @@ -5,7 +5,7 @@ INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/test \ -I${top_srcdir}/test/test-common -noinst_PROGRAMS = test-ciphers test-dbus-helpers +noinst_PROGRAMS = test-ciphers test-dbus-helpers test-dbus-dict-helpers test_ciphers_SOURCES = test-ciphers.c test-inputs.h @@ -22,6 +22,7 @@ test_ciphers_LDADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/test/test-common/libtest-common.la + test_dbus_helpers_SOURCES = test-dbus-helpers.c test-inputs.h test_dbus_helpers_CPPFLAGS = \ @@ -36,3 +37,17 @@ test_dbus_helpers_LDADD = \ $(GLIB_LIBS) \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/test/test-common/libtest-common.la + + +test_dbus_dict_helpers_SOURCES = test-dbus-dict-helpers.c + +test_dbus_dict_helpers_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + -DDBUS_API_SUBJECT_TO_CHANGE \ + -DBINDIR=\"$(bindir)\" \ + -DDATADIR=\"$(datadir)\" + +test_dbus_dict_helpers_LDADD = \ + $(DBUS_LIBS) \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/test/test-common/libtest-common.la diff --git a/test/libnm-util/test-dbus-dict-helpers.c b/test/libnm-util/test-dbus-dict-helpers.c new file mode 100644 index 0000000000..ef102c7975 --- /dev/null +++ b/test/libnm-util/test-dbus-dict-helpers.c @@ -0,0 +1,226 @@ +/* NetworkManager -- Forget about your network + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2006 Red Hat, Inc. + */ + +#include +#include +#include +#include + +#include "test-common.h" +#include "dbus-dict-helpers.h" + +static char *progname = NULL; + + +struct DictEntries +{ + const char * key_string; const char * val_string; dbus_bool_t string_found; + const char * key_byte; const char val_byte; dbus_bool_t byte_found; + const char * key_bool; const dbus_bool_t val_bool; dbus_bool_t bool_found; + const char * key_int16; const dbus_int16_t val_int16; dbus_bool_t int16_found; + const char * key_uint16; const dbus_uint16_t val_uint16; dbus_bool_t uint16_found; + const char * key_int32; const dbus_int32_t val_int32; dbus_bool_t int32_found; + const char * key_uint32; const dbus_uint32_t val_uint32; dbus_bool_t uint32_found; + const char * key_int64; const dbus_int64_t val_int64; dbus_bool_t int64_found; + const char * key_uint64; const dbus_uint64_t val_uint64; dbus_bool_t uint64_found; + const char * key_double; const double val_double; dbus_bool_t double_found; + const char * key_op; const char * val_op; dbus_bool_t op_found; +}; + +#define TEST_KEY_STRING "String" +#define TEST_KEY_BYTE "Byte" +#define TEST_KEY_BOOL "Bool" +#define TEST_KEY_INT16 "Int16" +#define TEST_KEY_UINT16 "UInt16" +#define TEST_KEY_INT32 "Int32" +#define TEST_KEY_UINT32 "UInt32" +#define TEST_KEY_INT64 "Int64" +#define TEST_KEY_UINT64 "UInt64" +#define TEST_KEY_DOUBLE "Double" +#define TEST_KEY_OP "ObjectPath" + +struct DictEntries entries = { + TEST_KEY_STRING, "foobar22", FALSE, + TEST_KEY_BYTE, 0x78, FALSE, + TEST_KEY_BOOL, TRUE, FALSE, + TEST_KEY_INT16, -28567, FALSE, + TEST_KEY_UINT16, 12345, FALSE, + TEST_KEY_INT32, -5987654, FALSE, + TEST_KEY_UINT32, 45678912, FALSE, + TEST_KEY_INT64, -12491340761ll, FALSE, + TEST_KEY_UINT64, 8899223582883ll, FALSE, + TEST_KEY_DOUBLE, 54.3355632f, FALSE, + TEST_KEY_OP, "/com/it/foobar", FALSE +}; + + +static void +test_write_dict (DBusMessage *message) +{ + TestResult result = TEST_FAIL; + DBusMessageIter iter, iter_dict; + char * err_string = "failure"; + + fprintf (stdout, "\n\n---- START: WRITE DICT ---------------------------------------------\n"); + + dbus_message_iter_init_append (message, &iter); + if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) { + err_string = "failed on open_write"; + goto done; + } + if (!nmu_dbus_dict_append_string (&iter_dict, entries.key_string, entries.val_string)) { + err_string = "failed to append string entry"; + goto done; + } + if (!nmu_dbus_dict_append_byte (&iter_dict, entries.key_byte, entries.val_byte)) { + err_string = "failed to append byte entry"; + goto done; + } + if (!nmu_dbus_dict_append_bool (&iter_dict, entries.key_bool, entries.val_bool)) { + err_string = "failed to append boolean entry"; + goto done; + } + if (!nmu_dbus_dict_append_int16 (&iter_dict, entries.key_int16, entries.val_int16)) { + err_string = "failed to append int16 entry"; + goto done; + } + if (!nmu_dbus_dict_append_uint16 (&iter_dict, entries.key_uint16, entries.val_uint16)) { + err_string = "failed to append uint16 entry"; + goto done; + } + if (!nmu_dbus_dict_append_int32 (&iter_dict, entries.key_int32, entries.val_int32)) { + err_string = "failed to append int32 entry"; + goto done; + } + if (!nmu_dbus_dict_append_uint32 (&iter_dict, entries.key_uint32, entries.val_uint32)) { + err_string = "failed to append uint32 entry"; + goto done; + } + if (!nmu_dbus_dict_append_int64 (&iter_dict, entries.key_int64, entries.val_int64)) { + err_string = "failed to append int64 entry"; + goto done; + } + if (!nmu_dbus_dict_append_uint64 (&iter_dict, entries.key_uint64, entries.val_uint64)) { + err_string = "failed to append uint64 entry"; + goto done; + } + if (!nmu_dbus_dict_append_double (&iter_dict, entries.key_double, entries.val_double)) { + err_string = "failed to append double entry"; + goto done; + } + if (!nmu_dbus_dict_append_object_path (&iter_dict, entries.key_op, entries.val_op)) { + err_string = "failed to append object path entry"; + goto done; + } + if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) { + err_string = "failed to close dictionary"; + goto done; + } + + result = TEST_SUCCEED; + err_string = "success"; + +done: + test_result (progname, "Dict Write", result, err_string); +} + +#define TEST_CASE(test_key, found_var, comparison) \ + if (!strcmp (entry.key, test_key)) { \ + fprintf (stderr, "Testing type " test_key ".\n"); \ + if (!(comparison)) { \ + err_string = "Test item " test_key " was unexpected value."; \ + goto done; \ + } \ + found_var = TRUE; \ + goto next; \ + } + +static void +test_read_dict (DBusMessage *message) +{ + TestResult result = TEST_FAIL; + NMUDictEntry entry = { .type = DBUS_TYPE_STRING }; + DBusMessageIter iter, iter_dict; + char * err_string = "failure"; + + dbus_message_iter_init (message, &iter); + + if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) { + err_string = "failure on open_read"; + goto done; + } + + while (nmu_dbus_dict_has_dict_entry (&iter_dict)) + { + if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) { + err_string = "failure reading dict entry"; + goto done; + } + + TEST_CASE (TEST_KEY_STRING, entries.string_found, !strcmp (entry.str_value, entries.val_string)) + TEST_CASE (TEST_KEY_BYTE, entries.byte_found, entry.byte_value == entries.val_byte) + TEST_CASE (TEST_KEY_BOOL, entries.bool_found, entry.bool_value == entries.val_bool) + TEST_CASE (TEST_KEY_INT16, entries.int16_found, entry.int16_value == entries.val_int16) + TEST_CASE (TEST_KEY_UINT16, entries.uint16_found, entry.uint16_value == entries.val_uint16) + TEST_CASE (TEST_KEY_INT32, entries.int32_found, entry.int32_value == entries.val_int32) + TEST_CASE (TEST_KEY_UINT32, entries.uint32_found, entry.uint32_value == entries.val_uint32) + TEST_CASE (TEST_KEY_INT64, entries.int64_found, entry.int64_value == entries.val_int64) + TEST_CASE (TEST_KEY_UINT64, entries.uint64_found, entry.uint64_value == entries.val_uint64) + TEST_CASE (TEST_KEY_DOUBLE, entries.double_found, !memcmp (&entry.double_value, &entries.val_double, sizeof (double))) + TEST_CASE (TEST_KEY_OP, entries.op_found, !strcmp (entry.str_value, entries.val_op)) + + err_string = "Unknown dict entry encountered."; + goto done; + + next: + continue; + } + + if (!entries.string_found || !entries.byte_found || !entries.bool_found || !entries.int16_found + || !entries.uint16_found || !entries.int32_found || !entries.uint32_found + || !entries.int64_found || !entries.uint64_found || !entries.double_found + || !entries.op_found) { + err_string = "A required entry was not found in the dict."; + goto done; + } + + result = TEST_SUCCEED; + err_string = ""; + +done: + test_result (progname, "Dict Read", result, err_string); +} + + +int main (int argc, char **argv) +{ + DBusMessage * message; + progname = argv[0]; + + message = dbus_message_new_method_call ("com.it", "/com/it", + "com.it", "someMethod"); + test_write_dict (message); + test_read_dict (message); + + fprintf (stderr, "\n\n------ DONE\n"); + + return 0; +}