2003-03-13 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-dict.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-dict.h Dict object for key-value data.
3  * 
4  * Copyright (C) 2003  CodeFactory AB
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23 #include "dbus-dict.h"
24 #include "dbus-hash.h"
25 #include "dbus-internals.h"
26 #include "dbus-protocol.h"
27
28 /**
29  * @defgroup DBusDict DBusDict
30  * @ingroup DBus
31  * @brief key/value data structure.
32  *
33  * A DBusDict is a data structure that can store and lookup different
34  * values by name.
35  *
36  * @{
37  */
38
39 struct DBusDict
40 {
41   int refcount;
42
43   DBusHashTable *table;
44 };
45
46 typedef struct
47 {
48   int type;
49   union {
50     dbus_bool_t boolean_value;
51     dbus_int32_t int32_value;
52     dbus_uint32_t uint32_value;
53     double double_value;
54     char *string_value;
55     struct {
56       unsigned char *value;
57       int len;
58     } boolean_array;
59     struct {
60       dbus_int32_t *value;
61       int len;
62     } int32_array;
63     struct {
64       dbus_uint32_t *value;
65       int len;
66     } uint32_array;
67     struct {
68       double *value;
69       int len;
70     } double_array;
71     struct {
72       char **value;
73       int len;
74     } string_array;
75   } v;
76 } DBusDictEntry;
77
78 static void
79 dbus_dict_entry_free (DBusDictEntry *entry)
80 {
81   if (!entry)
82     return;
83   
84   switch (entry->type)
85     {
86     case DBUS_TYPE_INVALID:
87     case DBUS_TYPE_BOOLEAN:
88     case DBUS_TYPE_INT32:
89     case DBUS_TYPE_UINT32:
90     case DBUS_TYPE_DOUBLE:
91       break;
92     case DBUS_TYPE_STRING:
93       dbus_free (entry->v.string_value);
94       break;
95     case DBUS_TYPE_BOOLEAN_ARRAY:
96       dbus_free (entry->v.boolean_array.value);
97       break;
98     case DBUS_TYPE_INT32_ARRAY:
99       dbus_free (entry->v.int32_array.value);
100       break;
101     case DBUS_TYPE_UINT32_ARRAY:
102       dbus_free (entry->v.uint32_array.value);
103       break;
104     case DBUS_TYPE_DOUBLE_ARRAY:
105       dbus_free (entry->v.uint32_array.value);
106       break;
107     case DBUS_TYPE_STRING_ARRAY:
108       dbus_free_string_array (entry->v.string_array.value);
109       break;
110     default:
111       _dbus_assert_not_reached ("Unknown or invalid dict entry type\n");
112     }
113
114   dbus_free (entry);
115 }
116
117 /**
118  * Constructs a new DBusDict. Returns #NULL if memory can't be
119  * allocated.
120  *
121  * @returns a new DBusDict or #NULL.
122  */
123 DBusDict *
124 dbus_dict_new (void)
125 {
126   DBusDict *dict;
127
128   dict = dbus_new0 (DBusDict, 1);
129
130   if (!dict)
131     return NULL;
132
133   dict->table = _dbus_hash_table_new (DBUS_HASH_STRING, dbus_free, (DBusFreeFunction)dbus_dict_entry_free);
134
135   if (!dict->table)
136     {
137       dbus_free (dict);
138       return NULL;
139     }
140   
141   dict->refcount = 1;
142   
143   return dict;
144 }
145
146 /**
147  * Increments the reference count of a DBusDict.
148  *
149  * @param dict the dict.
150  * @see dbus_dict_unref
151  */
152 void
153 dbus_dict_ref (DBusDict *dict)
154 {
155   dict->refcount += 1;
156   
157   _dbus_assert (dict->refcount > 1);
158 }
159
160 /**
161  * Decrements the reference count of a DBusDict
162  *
163  * @param dict the dict
164  * @see dbus_dict_ref
165  */
166 void
167 dbus_dict_unref (DBusDict *dict)
168 {
169   dict->refcount -= 1;
170
171   _dbus_assert (dict->refcount >= 0);
172
173   if (dict->refcount == 0)
174     {
175       _dbus_hash_table_unref (dict->table);
176       dbus_free (dict);
177     }
178 }
179
180 /**
181  * Checks if the dict contains the specified key.
182  *
183  * @param dict the dict.
184  * @param key the key
185  * @returns #TRUE if the dict contains the specified key.
186  */
187 dbus_bool_t
188 dbus_dict_contains (DBusDict   *dict,
189                     const char *key)
190 {
191   return (_dbus_hash_table_lookup_string (dict->table, key) != NULL);
192 }
193
194 /**
195  * Removes the dict entry for the given key. If no dict entry for the
196  * key exists, this function does nothing.
197  *
198  * @param dict the dict
199  * @param key the key
200  * @returns #TRUE if the entry existed
201  */
202 dbus_bool_t
203 dbus_dict_remove (DBusDict   *dict,
204                   const char *key)
205 {
206   return _dbus_hash_table_remove_string (dict->table, key);
207 }
208
209 /**
210  * Returns the type of the value in the dict entry specified by the key.
211  *
212  * @param dict the dict
213  * @param key the key
214  * @returns the value type or DBUS_TYPE_NIL if the key wasn't found.
215  */
216 int
217 dbus_dict_get_value_type (DBusDict   *dict,
218                           const char *key)
219 {
220   DBusDictEntry *entry;
221
222   entry = _dbus_hash_table_lookup_string (dict->table, key);
223
224   if (!entry)
225     return DBUS_TYPE_NIL;
226   else
227     return entry->type;
228 }
229
230 /**
231  * Returns the keys in the dict as a string array.
232  *
233  * @param dict the dict
234  * @param keys return location for string array
235  * @param len return location for string array length
236  * Â®returns #TRUE on success
237  */
238 dbus_bool_t
239 dbus_dict_get_keys (DBusDict *dict,
240                     char   ***keys,
241                     int      *len)
242 {
243   int size, i;
244   char **tmp;
245   char *key;
246   DBusHashIter iter;
247   
248   size = _dbus_hash_table_get_n_entries (dict->table);
249   *len = size;
250   
251   if (size == 0)
252     {
253       *keys = NULL;
254       return TRUE;
255     }
256
257   tmp = dbus_new0 (char *, size + 1);
258   if (!tmp)
259     return FALSE;
260
261   
262   i = 0;
263   _dbus_hash_iter_init (dict->table, &iter);
264
265   while (_dbus_hash_iter_next (&iter))
266     {
267       key = _dbus_strdup (_dbus_hash_iter_get_string_key (&iter));
268
269       if (!key)
270         {
271           dbus_free_string_array (tmp);
272           return FALSE;
273         }
274
275       tmp[i] = key;
276       i++;
277     }
278
279   *keys = tmp;
280
281   return TRUE;
282 }
283
284 static dbus_bool_t
285 insert_entry (DBusDict *dict, 
286               const char *key,
287               DBusDictEntry **entry)
288 {
289   char *tmp;
290
291   tmp = _dbus_strdup (key);
292
293   if (!tmp)
294     return FALSE;
295   
296   *entry = dbus_new0 (DBusDictEntry, 1);
297   
298   if (!*entry)
299     {
300       dbus_free (tmp);
301       return FALSE;
302     }
303
304   if (!_dbus_hash_table_insert_string (dict->table, tmp, *entry))
305     {
306       dbus_free (tmp);
307       dbus_dict_entry_free (*entry);
308
309       return FALSE;
310     }
311
312   return TRUE;
313 }
314               
315 /**
316  * Adds a boolean value to the dict. If a value with the same key
317  * already exists, then it will be replaced by the new value.
318  *
319  * @param dict the dict
320  * @param key the key
321  * @param value the value
322  * @returns #TRUE on success
323  */
324 dbus_bool_t
325 dbus_dict_set_boolean (DBusDict    *dict,
326                        const char  *key,
327                        dbus_bool_t  value)
328 {
329   DBusDictEntry *entry;
330
331   if (insert_entry (dict, key, &entry))
332     {
333       entry->type = DBUS_TYPE_BOOLEAN;
334       entry->v.boolean_value = value;
335
336       return TRUE;
337     }
338   else
339     return FALSE;
340 }
341
342 /**
343  * Adds a 32 bit signed integer value to the dict. If a value with the
344  * same key already exists, then it will be replaced by the new value.
345  *
346  * @param dict the dict
347  * @param key the key
348  * @param value the value
349  * @returns #TRUE on success
350  */
351 dbus_bool_t
352 dbus_dict_set_int32 (DBusDict     *dict,
353                      const char   *key,
354                      dbus_int32_t  value)
355 {
356   DBusDictEntry *entry;
357
358   if (insert_entry (dict, key, &entry))
359     {
360       entry->type = DBUS_TYPE_INT32;
361       entry->v.int32_value = value;
362
363       return TRUE;
364     }
365   else
366     return FALSE;
367 }
368
369 /**
370  * Adds a 32 bit unsigned integer value to the dict. If a value with
371  * the same key already exists, then it will be replaced by the new
372  * value.
373  *
374  * @param dict the dict
375  * @param key the key
376  * @param value the value
377  * @returns #TRUE on success
378  */
379 dbus_bool_t
380 dbus_dict_set_uint32 (DBusDict      *dict,
381                       const char    *key,
382                       dbus_uint32_t  value)
383 {
384   DBusDictEntry *entry;
385
386   if (insert_entry (dict, key, &entry))
387     {
388       entry->type = DBUS_TYPE_UINT32;
389       entry->v.uint32_value = value;
390
391       return TRUE;
392     }
393   else
394     return FALSE;
395 }
396
397 /**
398  * Adds a 32 bit double value to the dict. If a value with the same
399  * key already exists, then it will be replaced by the new value.
400  *
401  * @param dict the dict
402  * @param key the key
403  * @param value the value
404  * @returns #TRUE on success
405  */
406 dbus_bool_t
407 dbus_dict_set_double (DBusDict   *dict,
408                       const char *key,
409                       double      value)
410 {
411   DBusDictEntry *entry;
412
413   if (insert_entry (dict, key, &entry))
414     {
415       entry->type = DBUS_TYPE_DOUBLE;
416       entry->v.double_value = value;
417
418       return TRUE;
419     }
420   else
421     return FALSE;
422 }
423
424 /**
425  * Adds a string to the dict. If a value with the same key already
426  * exists, then it will be replaced by the new value.
427  *
428  * @param dict the dict
429  * @param key the key
430  * @param value the value
431  * @returns #TRUE on success
432  */
433 dbus_bool_t
434 dbus_dict_set_string (DBusDict   *dict,
435                       const char *key,
436                       const char *value)
437 {
438   DBusDictEntry *entry;
439   char *tmp;
440
441   tmp = _dbus_strdup (value);
442
443   if (!tmp)
444     return FALSE;
445   
446   if (insert_entry (dict, key, &entry))
447     {
448       entry->type = DBUS_TYPE_STRING;
449       entry->v.string_value = tmp;
450
451       return TRUE;
452     }
453   else
454     return FALSE;
455 }
456
457 /**
458  * Adds a boolean array to the dict. If a value with the same key
459  * already exists, then it will be replaced by the new value.
460  *
461  * @param dict the dict
462  * @param key the key
463  * @param value the value
464  * @param len the array length
465  * @returns #TRUE on success
466  */
467 dbus_bool_t
468 dbus_dict_set_boolean_array (DBusDict            *dict,
469                              const char          *key,
470                              unsigned const char *value,
471                              int                  len)
472 {
473   DBusDictEntry *entry;
474   unsigned char *tmp;
475
476   tmp = dbus_malloc (len);
477   
478   if (!tmp)
479     return FALSE;
480
481   memcpy (tmp, value, len);
482   
483   if (insert_entry (dict, key, &entry))
484     {
485       entry->type = DBUS_TYPE_BOOLEAN_ARRAY;
486       entry->v.boolean_array.value = tmp;
487       entry->v.boolean_array.len = len;
488       
489       return TRUE;
490     }
491   else
492     return FALSE;
493 }
494
495 /**
496  * Adds a 32 bit signed integer array to the dict. If a value with the
497  * same key already exists, then it will be replaced by the new value.
498  *
499  * @param dict the dict
500  * @param key the key
501  * @param value the value
502  * @param len the array length
503  * @returns #TRUE on success
504  */
505 dbus_bool_t
506 dbus_dict_set_int32_array (DBusDict           *dict,
507                            const char         *key,
508                            const dbus_int32_t *value,
509                            int                 len)
510 {
511   DBusDictEntry *entry;
512   dbus_int32_t *tmp;
513
514   tmp = dbus_new (dbus_int32_t, len);
515
516   if (!tmp)
517     return FALSE;
518
519   memcpy (tmp, value, len * sizeof (dbus_int32_t));
520   
521   if (insert_entry (dict, key, &entry))
522     {
523       entry->type = DBUS_TYPE_INT32_ARRAY;
524       entry->v.int32_array.value = tmp;
525       entry->v.int32_array.len = len;
526       
527       return TRUE;
528     }
529   else
530     return FALSE;
531 }
532
533 /**
534  * Adds a 32 bit unsigned integer array to the dict. If a value with
535  * the same key already exists, then it will be replaced by the new
536  * value.
537  *
538  * @param dict the dict
539  * @param key the key
540  * @param value the value
541  * @param len the array length
542  * @returns #TRUE on success
543  */
544 dbus_bool_t
545 dbus_dict_set_uint32_array (DBusDict             *dict,
546                             const char           *key,
547                             const dbus_uint32_t  *value,
548                             int                   len)
549 {
550   DBusDictEntry *entry;
551   dbus_uint32_t *tmp;
552
553   tmp = dbus_new (dbus_uint32_t, len);
554
555   if (!tmp)
556     return FALSE;
557
558   memcpy (tmp, value, len * sizeof (dbus_uint32_t));
559   
560   if (insert_entry (dict, key, &entry))
561     {
562       entry->type = DBUS_TYPE_UINT32_ARRAY;
563       entry->v.uint32_array.value = tmp;
564       entry->v.int32_array.len = len;
565
566       return TRUE;
567     }
568   else
569     return FALSE;
570 }
571
572 /**
573  * Adds a double array to the dict. If a value with the same key
574  * already exists, then it will be replaced by the new value.
575  *
576  * @param dict the dict
577  * @param key the key
578  * @param value the value
579  * @param len the array length
580  * @returns #TRUE on success
581  */
582 dbus_bool_t
583 dbus_dict_set_double_array (DBusDict     *dict,
584                             const char   *key,
585                             const double *value,
586                             int           len)
587 {
588   DBusDictEntry *entry;
589   double *tmp;
590
591   tmp = dbus_new (double, len);
592
593   if (!tmp)
594     return FALSE;
595
596   memcpy (tmp, value, len * sizeof (double));
597   
598   if (insert_entry (dict, key, &entry))
599     {
600       entry->type = DBUS_TYPE_DOUBLE_ARRAY;
601       entry->v.double_array.value = tmp;
602       entry->v.double_array.len = len;
603
604       return TRUE;
605     }
606   else
607     return FALSE;
608 }
609
610 /**
611  * Adds a string array to the dict. If a value with the same key
612  * already exists, then it will be replaced by the new value.
613  *
614  * @param dict the dict
615  * @param key the key
616  * @param value the value
617  * @param len the array length
618  * @returns #TRUE on success
619  */
620 dbus_bool_t
621 dbus_dict_set_string_array (DBusDict    *dict,
622                             const char  *key,
623                             const char **value,
624                             int          len)
625 {
626   DBusDictEntry *entry;
627   char **tmp;
628   int i;
629
630   tmp = dbus_new0 (char *, len + 1);
631   if (!tmp)
632     return FALSE;
633
634   for (i = 0; i < len; i++)
635     {
636       tmp[i] = _dbus_strdup (value[i]);
637       if (!tmp[i])
638         {
639           dbus_free_string_array (tmp);
640           return FALSE;
641         }
642     }
643
644   if (insert_entry (dict, key, &entry))
645     {
646       entry->type = DBUS_TYPE_STRING_ARRAY;
647       entry->v.string_array.value = tmp;
648       entry->v.string_array.len = len;
649       
650       return TRUE;
651     }
652   else
653     return FALSE;
654 }
655
656 /**
657  * Gets a boolean value from a dict using a key.
658  *
659  * @param dict the dict
660  * @param key the key
661  * @param value return location for the value
662  * @returns #TRUE if the key exists and the value is of the correct
663  * type
664  */
665 dbus_bool_t
666 dbus_dict_get_boolean (DBusDict    *dict,
667                        const char  *key,
668                        dbus_bool_t *value)
669 {
670   DBusDictEntry *entry;
671
672   entry = _dbus_hash_table_lookup_string (dict->table, key);
673
674   if (!entry || entry->type != DBUS_TYPE_BOOLEAN)
675     return FALSE;
676
677   *value = entry->v.boolean_value;
678
679   return TRUE;
680 }
681
682 /**
683  * Gets a 32 bit signed integer value from a dict using a key.
684  *
685  * @param dict the dict
686  * @param key the key
687  * @param value return location for the value
688  * @returns #TRUE if the key exists and the value is of the correct
689  * type
690  */
691 dbus_bool_t
692 dbus_dict_get_int32 (DBusDict     *dict,
693                      const char   *key,
694                      dbus_int32_t *value)
695 {
696   DBusDictEntry *entry;
697
698   entry = _dbus_hash_table_lookup_string (dict->table, key);
699
700   if (!entry || entry->type != DBUS_TYPE_INT32)
701     return FALSE;
702
703   *value = entry->v.int32_value;
704
705   return TRUE;
706 }
707
708 /**
709  * Gets a 32 bit unsigned integer value from a dict using a key.
710  *
711  * @param dict the dict
712  * @param key the key
713  * @param value return location for the value
714  * @returns #TRUE if the key exists and the value is of the correct
715  * type
716  */
717 dbus_bool_t
718 dbus_dict_get_uint32 (DBusDict      *dict,
719                       const char    *key,
720                       dbus_uint32_t *value)
721 {
722   DBusDictEntry *entry;
723
724   entry = _dbus_hash_table_lookup_string (dict->table, key);
725
726   if (!entry || entry->type != DBUS_TYPE_UINT32)
727     return FALSE;
728
729   *value = entry->v.uint32_value;
730
731   return TRUE;
732 }
733
734 /**
735  * Gets a double value from a dict using a key.
736  *
737  * @param dict the dict
738  * @param key the key
739  * @param value return location for the value
740  * @returns #TRUE if the key exists and the value is of the correct
741  * type
742  */
743 dbus_bool_t
744 dbus_dict_get_double (DBusDict   *dict,
745                       const char *key,
746                       double     *value)
747 {
748   DBusDictEntry *entry;
749
750   entry = _dbus_hash_table_lookup_string (dict->table, key);
751
752   if (!entry || entry->type != DBUS_TYPE_DOUBLE)
753     return FALSE;
754
755   *value = entry->v.double_value;
756
757   return TRUE;
758 }
759
760 /**
761  * Gets a string from a dict using a key.
762  *
763  * @param dict the dict
764  * @param key the key
765  * @param value return location for the value
766  * @returns #TRUE if the key exists and the value is of the correct
767  * type
768  */
769 dbus_bool_t
770 dbus_dict_get_string (DBusDict    *dict,
771                       const char  *key,
772                       const char **value)
773 {
774   DBusDictEntry *entry;
775   
776   entry = _dbus_hash_table_lookup_string (dict->table, key);
777   
778   if (!entry || entry->type != DBUS_TYPE_STRING)
779     return FALSE;
780
781   *value = entry->v.string_value;
782
783   return TRUE;
784 }
785
786 /**
787  * Gets a boolean array from a dict using a key.
788  *
789  * @param dict the dict
790  * @param key the key
791  * @param value return location for the value
792  * @param len return location for the array length
793  * @returns #TRUE if the key exists and the value is of the correct
794  * type
795  */
796 dbus_bool_t
797 dbus_dict_get_boolean_array (DBusDict             *dict,
798                              const char           *key,
799                              unsigned const char **value,
800                              int                  *len)
801 {
802   DBusDictEntry *entry;
803   
804   entry = _dbus_hash_table_lookup_string (dict->table, key);
805   
806   if (!entry || entry->type != DBUS_TYPE_BOOLEAN_ARRAY)
807     return FALSE;
808
809   *value = entry->v.boolean_array.value;
810   *len = entry->v.boolean_array.len;
811   
812   return TRUE;
813 }
814
815 /**
816  * Gets a 32 bit signed integer array from a dict using a key.
817  *
818  * @param dict the dict
819  * @param key the key
820  * @param value return location for the value
821  * @param len return location for the array length
822  * @returns #TRUE if the key exists and the value is of the correct
823  * type
824  */
825 dbus_bool_t
826 dbus_dict_get_int32_array (DBusDict            *dict,
827                            const char          *key,
828                            const dbus_int32_t **value,
829                            int                 *len)
830 {
831   DBusDictEntry *entry;
832   
833   entry = _dbus_hash_table_lookup_string (dict->table, key);
834   
835   if (!entry || entry->type != DBUS_TYPE_INT32_ARRAY)
836     return FALSE;
837
838   *value = entry->v.int32_array.value;
839   *len = entry->v.int32_array.len;
840   
841   return TRUE;
842 }
843
844 /**
845  * Gets a 32 bit unsigned integer array from a dict using a key.
846  *
847  * @param dict the dict
848  * @param key the key
849  * @param value return location for the value
850  * @param len return location for the array length
851  * @returns #TRUE if the key exists and the value is of the correct
852  * type
853  */
854 dbus_bool_t
855 dbus_dict_get_uint32_array (DBusDict             *dict,
856                             const char           *key,
857                             const dbus_uint32_t **value,
858                             int                  *len)
859 {
860   DBusDictEntry *entry;
861   
862   entry = _dbus_hash_table_lookup_string (dict->table, key);
863   
864   if (!entry || entry->type != DBUS_TYPE_UINT32_ARRAY)
865     return FALSE;
866
867   *value = entry->v.uint32_array.value;
868   *len = entry->v.uint32_array.len;
869   
870   return TRUE;
871 }
872
873 /**
874  * Gets a double array from a dict using a key.
875  *
876  * @param dict the dict
877  * @param key the key
878  * @param value return location for the value
879  * @param len return location for the array length
880  * @returns #TRUE if the key exists and the value is of the correct
881  * type
882  */
883 dbus_bool_t
884 dbus_dict_get_double_array (DBusDict      *dict,
885                             const char    *key,
886                             const double **value,
887                             int           *len)
888 {
889   DBusDictEntry *entry;
890   
891   entry = _dbus_hash_table_lookup_string (dict->table, key);
892   
893   if (!entry || entry->type != DBUS_TYPE_DOUBLE_ARRAY)
894     return FALSE;
895
896   *value = entry->v.double_array.value;
897   *len = entry->v.double_array.len;
898   
899   return TRUE;
900 }
901
902 /**
903  * Gets a string array from a dict using a key.
904  *
905  * @param dict the dict
906  * @param key the key
907  * @param value return location for the value
908  * @param len return location for the array length
909  * @returns #TRUE if the key exists and the value is of the correct
910  * type
911  */
912 dbus_bool_t
913 dbus_dict_get_string_array (DBusDict     *dict,
914                             const char   *key,
915                             const char ***value,
916                             int           *len)
917 {
918   DBusDictEntry *entry;
919   
920   entry = _dbus_hash_table_lookup_string (dict->table, key);
921   
922   if (!entry || entry->type != DBUS_TYPE_STRING_ARRAY)
923     return FALSE;
924
925   *value = (const char **)entry->v.string_array.value;
926   *len = entry->v.string_array.len;
927   
928   return TRUE;
929 }
930
931 /** @} */
932
933 #ifdef DBUS_BUILD_TESTS
934 #include "dbus-test.h"
935
936 dbus_bool_t
937 _dbus_dict_test (void)
938 {
939   DBusDict *dict;
940   dbus_bool_t our_bool;
941   dbus_int32_t our_int;
942   dbus_uint32_t our_uint;
943   double our_double;
944   const char *our_string;
945   const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE };
946   const unsigned char *our_boolean_array;
947   const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e };
948   const dbus_int32_t *our_int32_array;
949   const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff };
950   const dbus_uint32_t *our_uint32_array;
951   const double double_array[] = { 3.14159, 1.2345, 6.7890 };
952   const double *our_double_array;
953   const char *string_array[] = { "This", "Is", "A", "Test" };
954   const char **our_string_array;
955   int i, len;
956
957   /* We don't test much here since the hash table tests cover a great
958      deal of the functionality. */
959
960   dict = dbus_dict_new ();
961
962   if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL)
963     _dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry");
964
965   if (!dbus_dict_set_boolean (dict, "boolean", TRUE))
966     _dbus_assert_not_reached ("could not add boolean value");
967
968   if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) ||
969       !our_bool)
970     _dbus_assert_not_reached ("could not get boolean value");
971
972   if (!dbus_dict_set_int32 (dict, "int32", 0x12345678))
973     _dbus_assert_not_reached ("could not add int32 value");
974
975   if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678)
976     _dbus_assert_not_reached ("could not get int32 value or int32 values differ");
977   
978   if (!dbus_dict_set_uint32 (dict, "uint32", 0x87654321))
979     _dbus_assert_not_reached ("could not add uint32 value");
980
981   if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321)
982     _dbus_assert_not_reached ("could not get uint32 value or uint32 values differ");
983
984   if (!dbus_dict_set_double (dict, "double", 3.14159))
985     _dbus_assert_not_reached ("could not add double value");
986
987   if (!dbus_dict_get_double (dict, "double", &our_double) || our_double != 3.14159)
988     _dbus_assert_not_reached ("could not get double value or double values differ");
989
990   if (!dbus_dict_set_string (dict, "string", "test string"))
991     _dbus_assert_not_reached ("could not add string value");
992
993   if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0)
994     _dbus_assert_not_reached ("could not get string value or string values differ");
995
996   if (!dbus_dict_set_boolean_array (dict, "boolean_array", boolean_array, 4))
997     _dbus_assert_not_reached ("could not add boolean array");
998
999   if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) ||
1000       len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0)
1001     _dbus_assert_not_reached ("could not get boolean array value or boolean array values differ");
1002
1003   if (!dbus_dict_set_int32_array (dict, "int32_array", int32_array, 5))
1004     _dbus_assert_not_reached ("could not add int32 array");
1005
1006   if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) ||
1007       len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0)
1008     _dbus_assert_not_reached ("could not get int32 array value or int32 array values differ");
1009
1010   if (!dbus_dict_set_uint32_array (dict, "uint32_array", uint32_array, 5))
1011     _dbus_assert_not_reached ("could not add uint32 array");
1012
1013   if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) ||
1014       len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0)
1015     _dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ");
1016
1017   if (!dbus_dict_set_double_array (dict, "double_array", double_array, 3))
1018     _dbus_assert_not_reached ("could not add double array");
1019
1020   if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) ||
1021       len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0)
1022     _dbus_assert_not_reached ("could not get double array value or double array values differ");
1023
1024   if (!dbus_dict_set_string_array (dict, "string_array", string_array, 4))
1025     _dbus_assert_not_reached ("could not add string array");
1026
1027   if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len))
1028     _dbus_assert_not_reached ("could not get string array value");
1029
1030   if (len != 4)
1031     _dbus_assert_not_reached ("string array lengths differ");
1032
1033   for (i = 0; i < len; i++)
1034     {
1035       if (strcmp (our_string_array[i], string_array[i]) != 0)
1036         _dbus_assert_not_reached ("string array fields differ");
1037     }
1038
1039   dbus_dict_unref (dict);
1040
1041   return TRUE;
1042 }
1043 #endif /* DBUS_BUILD_TESTS */