1/* Copyright (C) 2011 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10** GNU General Public License for more details.
11*/
12#ifndef _ANDROID_UTILS_INTMAP_H
13#define _ANDROID_UTILS_INTMAP_H
14
15#include "android/utils/compiler.h"
16
17ANDROID_BEGIN_HEADER
18
19/* A simple container that can hold a simple mapping from integers to
20 * references. I.e. a dictionary where keys are integers, and values
21 * are liberal pointer values (NULL is allowed).
22 */
23
24typedef struct AIntMap  AIntMap;
25
26/* Create new integer map */
27AIntMap*  aintMap_new(void);
28
29/* Returns the number of keys stored in the map */
30int       aintmap_getCount( AIntMap* map );
31
32/* Returns TRUE if the map has a value for the 'key'. Necessary because
33 * NULL is a valid value for the map.
34 */
35int       aintmap_has( AIntMap*  map, int key );
36
37/* Get the value associated with a 'key', or NULL if not in map */
38void*     aintMap_get( AIntMap*  map, int  key );
39
40/* Get the value associated with a 'key', or 'def' if not in map */
41void*     aintMap_getWithDefault( AIntMap*  map, int key, void*  def );
42
43/* Set the value associated to a 'key', return the old value, if any, or NULL */
44void*     aintMap_set( AIntMap* map, int key, void* value );
45
46/* Delete a given value associated to a 'key', return the old value, or NULL */
47void*     aintMap_del( AIntMap* map, int key );
48
49/* Destroy a given integer map */
50void      aintMap_free( AIntMap*  map );
51
52/* Integer map iterator. First call aintMapIterator_init(), then call
53 * aintMapIterator_next() until it returns 0. Then finish with
54 * aintMapIterator_done().
55 *
56 * Example:
57 *    AIntMapIterator  iter[1];
58 *    aintMapIterator_init(iter, map);
59 *    while (aintMapIterator_next(iter, &key, &value)) {
60 *        // do something
61 *    }
62 *    aintMapIterator_done(iter);
63 */
64typedef struct AIntMapIterator {
65    int    key;
66    void*  value;
67    void*  magic[4];
68} AIntMapIterator;
69
70/* Initialize iterator. Returns -1 if the map is empty, or 0 otherwise
71 * On success, the first (key,value) pair can be read from the iterator
72 * directly.
73 */
74void aintMapIterator_init( AIntMapIterator* iter, AIntMap* map );
75
76/* Read the next (key,value) pair with an iterator, returns -1 when
77 * there isn't anything more, or 0 otherwise. On success, the key and
78 * value can be read directly from the iterator.
79 */
80int  aintMapIterator_next( AIntMapIterator* iter );
81
82/* Finalize an iterator. This only needs to be called if you stop
83 * the iteration before aintMapIterator_init() or aintMapIterator_next()
84 * return -1.
85 */
86void aintMapIterator_done( AIntMapIterator* iter );
87
88#define AINTMAP_FOREACH_KEY(map, keyvarname, stmnt) \
89    do { \
90        AIntMapIterator  __aintmap_foreach_iter[1]; \
91        aintMapIterator_init(__aintmap_foreach_iter, (map)); \
92        while (aintMapIterator_next(__aintmap_foreach_iter)) { \
93            int keyvarname = __aintmap_foreach_iter->key; \
94            stmnt; \
95        } \
96        aintMapIterator_done(__aintmap_foreach_iter); \
97    } while (0)
98
99#define AINTMAP_FOREACH_VALUE(map, valvarname, stmnt) \
100    do { \
101        AIntMapIterator  __aintmap_foreach_iter[1]; \
102        aintMapIterator_init(__aintmap_foreach_iter, (map)); \
103        while (aintMapIterator_next(__aintmap_foreach_iter)) { \
104            void* valvarname = __aintmap_foreach_iter->value; \
105            stmnt; \
106        } \
107        aintMapIterator_done(__aintmap_foreach_iter); \
108    } while (0)
109
110ANDROID_END_HEADER
111
112#endif /* _ANDROID_UTILS_INTMAP_H */
113