From ee09dbf058bec7edd55deb2dbca67e7f0885b160 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 6 Mar 2003 23:11:49 +0000 Subject: 2003-03-07 Anders Carlsson * dbus/Makefile.am: Add dbus-dict.[ch] * dbus/dbus-dict.c: (dbus_dict_entry_free), (dbus_dict_new), (dbus_dict_ref), (dbus_dict_unref), (dbus_dict_contains), (dbus_dict_remove), (dbus_dict_get_value_type), (dbus_dict_get_keys), (dbus_dict_put_boolean), (dbus_dict_put_int32), (dbus_dict_put_uint32), (dbus_dict_put_double), (dbus_dict_put_string), (dbus_dict_put_boolean_array), (dbus_dict_put_int32_array), (dbus_dict_put_uint32_array), (dbus_dict_put_double_array), (dbus_dict_put_string_array), (dbus_dict_get_boolean), (dbus_dict_get_int32), (dbus_dict_get_uint32), (dbus_dict_get_double), (dbus_dict_get_string), (dbus_dict_get_boolean_array), (dbus_dict_get_int32_array), (dbus_dict_get_uint32_array), (dbus_dict_get_double_array), (dbus_dict_get_string_array), (_dbus_dict_test): * dbus/dbus-dict.h: Add DBusDict implementation * dbus/dbus-test.c: (dbus_internal_do_not_use_run_tests): * dbus/dbus-test.h: Add _dbus_dict_test. --- dbus/dbus-dict.c | 1172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1172 insertions(+) create mode 100644 dbus/dbus-dict.c (limited to 'dbus/dbus-dict.c') diff --git a/dbus/dbus-dict.c b/dbus/dbus-dict.c new file mode 100644 index 00000000..334a8742 --- /dev/null +++ b/dbus/dbus-dict.c @@ -0,0 +1,1172 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-dict.h Dict object for key-value data. + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * 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 + * + */ +#include "dbus-dict.h" +#include "dbus-hash.h" +#include "dbus-internals.h" +#include "dbus-protocol.h" + +/** + * @defgroup DBusDict DBusDict + * @ingroup DBus + * @brief key/value data structure. + * + * A DBusDict is a data structure that can store and lookup different + * values by name. + * + * @{ + */ + +struct DBusDict +{ + int refcount; + + DBusHashTable *table; +}; + +typedef struct +{ + int type; + union { + dbus_bool_t boolean_value; + dbus_int32_t int32_value; + dbus_uint32_t uint32_value; + double double_value; + char *string_value; + struct { + unsigned char *value; + int len; + } boolean_array; + struct { + dbus_int32_t *value; + int len; + } int32_array; + struct { + dbus_uint32_t *value; + int len; + } uint32_array; + struct { + double *value; + int len; + } double_array; + struct { + char **value; + int len; + } string_array; + } v; +} DBusDictEntry; + +static void +dbus_dict_entry_free (DBusDictEntry *entry) +{ + if (!entry) + return; + + switch (entry->type) + { + case DBUS_TYPE_INVALID: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + case DBUS_TYPE_DOUBLE: + break; + case DBUS_TYPE_STRING: + dbus_free (entry->v.string_value); + break; + case DBUS_TYPE_BOOLEAN_ARRAY: + dbus_free (entry->v.boolean_array.value); + break; + case DBUS_TYPE_INT32_ARRAY: + dbus_free (entry->v.int32_array.value); + break; + case DBUS_TYPE_UINT32_ARRAY: + dbus_free (entry->v.uint32_array.value); + break; + case DBUS_TYPE_DOUBLE_ARRAY: + dbus_free (entry->v.uint32_array.value); + break; + case DBUS_TYPE_STRING_ARRAY: + dbus_free_string_array (entry->v.string_array.value); + break; + default: + _dbus_assert_not_reached ("Unknown or invalid dict entry type\n"); + } + + dbus_free (entry); +} + +/** + * Constructs a new DBusDict. Returns #NULL if memory can't be + * allocated. + * + * @returns a new DBusDict or #NULL. + */ +DBusDict * +dbus_dict_new (void) +{ + DBusDict *dict; + + dict = dbus_new0 (DBusDict, 1); + + if (!dict) + return NULL; + + dict->table = _dbus_hash_table_new (DBUS_HASH_STRING, dbus_free, (DBusFreeFunction)dbus_dict_entry_free); + dict->refcount = 1; + + return dict; +} + +/** + * Increments the reference count of a DBusDict. + * + * @param dict the dict. + * @see dbus_dict_unref + */ +void +dbus_dict_ref (DBusDict *dict) +{ + dict->refcount += 1; + + _dbus_assert (dict->refcount > 1); +} + +/** + * Decrements the reference count of a DBusDict + * + * @param dict the dict + * @see dbus_dict_ref + */ +void +dbus_dict_unref (DBusDict *dict) +{ + dict->refcount -= 1; + + _dbus_assert (dict->refcount >= 0); + + if (dict->refcount == 0) + { + _dbus_hash_table_unref (dict->table); + dbus_free (dict); + } +} + +/** + * Checks if the dict contains the specified key. + * + * @param dict the dict. + * @param key the key + * @returns #TRUE if the dict contains the specified key. + */ +dbus_bool_t +dbus_dict_contains (DBusDict *dict, + const char *key) +{ + return (_dbus_hash_table_lookup_string (dict->table, key) != NULL); +} + +/** + * Removes the dict entry for the given key. If no dict entry for the + * key exists, this function does nothing. + * + * @param dict the dict + * @param key the key + * @returns #TRUE if the entry existed + */ +dbus_bool_t +dbus_dict_remove (DBusDict *dict, + const char *key) +{ + return _dbus_hash_table_remove_string (dict->table, key); +} + +/** + * Returns the type of the value in the dict entry specified by the key. + * + * @param dict the dict + * @param key the key + * @returns the value type or DBUS_TYPE_NIL if the key wasn't found. + */ +int +dbus_dict_get_value_type (DBusDict *dict, + const char *key) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry) + return DBUS_TYPE_NIL; + else + return entry->type; +} + +/** + * Returns the keys in the dict as a string array. + * + * @param dict the dict + * @param keys return location for string array + * @param len return location for string array length + * ®returns #TRUE on success + */ +dbus_bool_t +dbus_dict_get_keys (DBusDict *dict, + char ***keys, + int *len) +{ + int size, i; + char **tmp; + char *key; + DBusHashIter iter; + + size = _dbus_hash_table_get_n_entries (dict->table); + *len = size; + + if (size == 0) + { + *keys = NULL; + return TRUE; + } + + tmp = dbus_new0 (char *, size); + if (!tmp) + return FALSE; + + i = 0; + _dbus_hash_iter_init (dict->table, &iter); + + while (_dbus_hash_iter_next (&iter)) + { + key = _dbus_strdup (_dbus_hash_iter_get_string_key (&iter)); + + if (!key) + { + dbus_free_string_array (tmp); + return FALSE; + } + + tmp[i] = key; + i++; + } + + *keys = tmp; + + return TRUE; +} + +/** + * Adds a boolean value to the dict. If a value with the same key + * already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_boolean (DBusDict *dict, + const char *key, + dbus_bool_t value) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_BOOLEAN; + entry->v.boolean_value = value; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a 32 bit signed integer value to the dict. If a value with the + * same key already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_int32 (DBusDict *dict, + const char *key, + dbus_int32_t value) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_INT32; + entry->v.int32_value = value; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a 32 bit unsigned integer value to the dict. If a value with + * the same key already exists, then it will be replaced by the new + * value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_uint32 (DBusDict *dict, + const char *key, + dbus_uint32_t value) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_UINT32; + entry->v.uint32_value = value; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a 32 bit double value to the dict. If a value with the same + * key already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_double (DBusDict *dict, + const char *key, + double value) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_DOUBLE; + entry->v.double_value = value; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a string to the dict. If a value with the same key already + * exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_string (DBusDict *dict, + const char *key, + const char *value) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_STRING; + entry->v.string_value = _dbus_strdup (value); + + if (!entry->v.string_value) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a boolean array to the dict. If a value with the same key + * already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @param len the array length + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_boolean_array (DBusDict *dict, + const char *key, + unsigned const char *value, + int len) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_BOOLEAN_ARRAY; + + entry->v.boolean_array.value = dbus_malloc (len); + + if (!entry->v.boolean_array.value) + { + dbus_dict_entry_free (entry); + return FALSE; + } + memcpy (entry->v.boolean_array.value, value, len); + entry->v.boolean_array.len = len; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a 32 bit signed integer array to the dict. If a value with the + * same key already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @param len the array length + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_int32_array (DBusDict *dict, + const char *key, + const dbus_int32_t *value, + int len) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_INT32_ARRAY; + entry->v.int32_array.value = dbus_malloc (len * sizeof (dbus_int32_t)); + + if (!entry->v.int32_array.value) + { + dbus_dict_entry_free (entry); + return FALSE; + } + memcpy (entry->v.int32_array.value, value, len * sizeof (dbus_int32_t)); + entry->v.int32_array.len = len; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a 32 bit unsigned integer array to the dict. If a value with + * the same key already exists, then it will be replaced by the new + * value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @param len the array length + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_uint32_array (DBusDict *dict, + const char *key, + const dbus_uint32_t *value, + int len) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_UINT32_ARRAY; + entry->v.uint32_array.value = dbus_malloc (len * sizeof (dbus_uint32_t)); + + if (!entry->v.uint32_array.value) + { + dbus_dict_entry_free (entry); + return FALSE; + } + memcpy (entry->v.uint32_array.value, value, len * sizeof (dbus_uint32_t)); + entry->v.uint32_array.len = len; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a double array to the dict. If a value with the same key + * already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @param len the array length + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_double_array (DBusDict *dict, + const char *key, + const double *value, + int len) +{ + DBusDictEntry *entry; + char *tmp; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_DOUBLE_ARRAY; + entry->v.double_array.value = dbus_malloc (len * sizeof (double)); + + if (!entry->v.double_array.value) + { + dbus_dict_entry_free (entry); + return FALSE; + } + memcpy (entry->v.double_array.value, value, len * sizeof (double)); + entry->v.double_array.len = len; + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Adds a string array to the dict. If a value with the same key + * already exists, then it will be replaced by the new value. + * + * @param dict the dict + * @param key the key + * @param value the value + * @param len the array length + * @returns #TRUE on success + */ +dbus_bool_t +dbus_dict_put_string_array (DBusDict *dict, + const char *key, + const char **value, + int len) +{ + DBusDictEntry *entry; + char *tmp; + int i; + + entry = dbus_new0 (DBusDictEntry, 1); + + if (!entry) + return FALSE; + + entry->type = DBUS_TYPE_STRING_ARRAY; + entry->v.string_array.value = dbus_new0 (char *, len + 1); + + if (!entry->v.string_array.value) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + entry->v.string_array.len = len; + for (i = 0; i < len; i++) + { + entry->v.string_array.value[i] = _dbus_strdup (value[i]); + if (!entry->v.string_array.value[i]) + { + dbus_dict_entry_free (entry); + return FALSE; + } + } + + tmp = _dbus_strdup (key); + + if (!tmp) + { + dbus_dict_entry_free (entry); + return FALSE; + } + + if (!_dbus_hash_table_insert_string (dict->table, tmp, entry)) + { + dbus_free (tmp); + dbus_dict_entry_free (entry); + + return FALSE; + } + + return TRUE; +} + +/** + * Gets a boolean value from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_boolean (DBusDict *dict, + const char *key, + dbus_bool_t *value) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_BOOLEAN) + return FALSE; + + *value = entry->v.boolean_value; + + return TRUE; +} + +/** + * Gets a 32 bit signed integer value from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_int32 (DBusDict *dict, + const char *key, + dbus_int32_t *value) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_INT32) + return FALSE; + + *value = entry->v.int32_value; + + return TRUE; +} + +/** + * Gets a 32 bit unsigned integer value from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_uint32 (DBusDict *dict, + const char *key, + dbus_uint32_t *value) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_UINT32) + return FALSE; + + *value = entry->v.uint32_value; + + return TRUE; +} + +/** + * Gets a double value from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_double (DBusDict *dict, + const char *key, + double *value) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_DOUBLE) + return FALSE; + + *value = entry->v.double_value; + + return TRUE; +} + +/** + * Gets a string from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_string (DBusDict *dict, + const char *key, + const char **value) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_STRING) + return FALSE; + + *value = entry->v.string_value; + + return TRUE; +} + +/** + * Gets a boolean array from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @param len return location for the array length + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_boolean_array (DBusDict *dict, + const char *key, + unsigned const char **value, + int *len) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_BOOLEAN_ARRAY) + return FALSE; + + *value = entry->v.boolean_array.value; + *len = entry->v.boolean_array.len; + + return TRUE; +} + +/** + * Gets a 32 bit signed integer array from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @param len return location for the array length + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_int32_array (DBusDict *dict, + const char *key, + const dbus_int32_t **value, + int *len) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_INT32_ARRAY) + return FALSE; + + *value = entry->v.int32_array.value; + *len = entry->v.int32_array.len; + + return TRUE; +} + +/** + * Gets a 32 bit unsigned integer array from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @param len return location for the array length + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_uint32_array (DBusDict *dict, + const char *key, + const dbus_uint32_t **value, + int *len) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_UINT32_ARRAY) + return FALSE; + + *value = entry->v.uint32_array.value; + *len = entry->v.uint32_array.len; + + return TRUE; +} + +/** + * Gets a double array from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @param len return location for the array length + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_double_array (DBusDict *dict, + const char *key, + const double **value, + int *len) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_DOUBLE_ARRAY) + return FALSE; + + *value = entry->v.double_array.value; + *len = entry->v.double_array.len; + + return TRUE; +} + +/** + * Gets a string array from a dict using a key. + * + * @param dict the dict + * @param key the key + * @param value return location for the value + * @param len return location for the array length + * @returns #TRUE if the key exists and the value is of the correct + * type + */ +dbus_bool_t +dbus_dict_get_string_array (DBusDict *dict, + const char *key, + const char ***value, + int *len) +{ + DBusDictEntry *entry; + + entry = _dbus_hash_table_lookup_string (dict->table, key); + + if (!entry || entry->type != DBUS_TYPE_STRING_ARRAY) + return FALSE; + + *value = (const char **)entry->v.string_array.value; + *len = entry->v.string_array.len; + + return TRUE; +} + +/** @} */ + +#ifdef DBUS_BUILD_TESTS +#include "dbus-test.h" + +dbus_bool_t +_dbus_dict_test (void) +{ + DBusDict *dict; + dbus_bool_t our_bool; + dbus_int32_t our_int; + dbus_uint32_t our_uint; + double our_double; + const char *our_string; + const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE }; + const unsigned char *our_boolean_array; + const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e }; + const dbus_int32_t *our_int32_array; + const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff }; + const dbus_uint32_t *our_uint32_array; + const double double_array[] = { 3.14159, 1.2345, 6.7890 }; + const double *our_double_array; + const char *string_array[] = { "This", "Is", "A", "Test" }; + const char **our_string_array; + int i, len; + + /* We don't test much here since the hash table tests cover a great + deal of the functionality. */ + + dict = dbus_dict_new (); + + if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL) + _dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry"); + + if (!dbus_dict_put_boolean (dict, "boolean", TRUE)) + _dbus_assert_not_reached ("could not add boolean value"); + + if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) || + !our_bool) + _dbus_assert_not_reached ("could not get boolean value"); + + if (!dbus_dict_put_int32 (dict, "int32", 0x12345678)) + _dbus_assert_not_reached ("could not add int32 value"); + + if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678) + _dbus_assert_not_reached ("could not get int32 value or int32 values differ"); + + if (!dbus_dict_put_uint32 (dict, "uint32", 0x87654321)) + _dbus_assert_not_reached ("could not add uint32 value"); + + if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321) + _dbus_assert_not_reached ("could not get uint32 value or uint32 values differ"); + + if (!dbus_dict_put_double (dict, "double", 3.14159)) + _dbus_assert_not_reached ("could not add double value"); + + if (!dbus_dict_get_double (dict, "double", &our_double) || our_double != 3.14159) + _dbus_assert_not_reached ("could not get double value or double values differ"); + + if (!dbus_dict_put_string (dict, "string", "test string")) + _dbus_assert_not_reached ("could not add string value"); + + if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0) + _dbus_assert_not_reached ("could not get string value or string values differ"); + + if (!dbus_dict_put_boolean_array (dict, "boolean_array", boolean_array, 4)) + _dbus_assert_not_reached ("could not add boolean array"); + + if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) || + len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0) + _dbus_assert_not_reached ("could not get boolean array value or boolean array values differ"); + + if (!dbus_dict_put_int32_array (dict, "int32_array", int32_array, 5)) + _dbus_assert_not_reached ("could not add int32 array"); + + if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) || + len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0) + _dbus_assert_not_reached ("could not get int32 array value or int32 array values differ"); + + if (!dbus_dict_put_uint32_array (dict, "uint32_array", uint32_array, 5)) + _dbus_assert_not_reached ("could not add uint32 array"); + + if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) || + len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0) + _dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ"); + + if (!dbus_dict_put_double_array (dict, "double_array", double_array, 3)) + _dbus_assert_not_reached ("could not add double array"); + + if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) || + len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0) + _dbus_assert_not_reached ("could not get double array value or double array values differ"); + + if (!dbus_dict_put_string_array (dict, "string_array", string_array, 4)) + _dbus_assert_not_reached ("could not add string array"); + + if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len)) + _dbus_assert_not_reached ("could not get string array value"); + + if (len != 4) + _dbus_assert_not_reached ("string array lengths differ"); + + for (i = 0; i < len; i++) + { + if (strcmp (our_string_array[i], string_array[i]) != 0) + _dbus_assert_not_reached ("string array fields differ"); + } + + dbus_dict_unref (dict); + + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ -- cgit