tor  0.4.0.0-alpha-dev
map.h
Go to the documentation of this file.
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 #ifndef TOR_MAP_H
7 #define TOR_MAP_H
8 
16 #include "lib/cc/torint.h"
17 
18 #include "ext/siphash.h"
19 
20 #define DECLARE_MAP_FNS(maptype, keytype, prefix) \
21  typedef struct maptype maptype; \
22  typedef struct prefix##entry_t *prefix##iter_t; \
23  MOCK_DECL(maptype*, prefix##new, (void)); \
24  void* prefix##set(maptype *map, keytype key, void *val); \
25  void* prefix##get(const maptype *map, keytype key); \
26  void* prefix##remove(maptype *map, keytype key); \
27  MOCK_DECL(void, prefix##free_, (maptype *map, void (*free_val)(void*))); \
28  int prefix##isempty(const maptype *map); \
29  int prefix##size(const maptype *map); \
30  prefix##iter_t *prefix##iter_init(maptype *map); \
31  prefix##iter_t *prefix##iter_next(maptype *map, prefix##iter_t *iter); \
32  prefix##iter_t *prefix##iter_next_rmv(maptype *map, prefix##iter_t *iter); \
33  void prefix##iter_get(prefix##iter_t *iter, keytype *keyp, void **valp); \
34  int prefix##iter_done(prefix##iter_t *iter); \
35  void prefix##assert_ok(const maptype *map)
36 
37 /* Map from const char * to void *. Implemented with a hash table. */
38 DECLARE_MAP_FNS(strmap_t, const char *, strmap_);
39 /* Map from const char[DIGEST_LEN] to void *. Implemented with a hash table. */
40 DECLARE_MAP_FNS(digestmap_t, const char *, digestmap_);
41 /* Map from const uint8_t[DIGEST256_LEN] to void *. Implemented with a hash
42  * table. */
43 DECLARE_MAP_FNS(digest256map_t, const uint8_t *, digest256map_);
44 
45 #define MAP_FREE_AND_NULL(maptype, map, fn) \
46  do { \
47  maptype ## _free_((map), (fn)); \
48  (map) = NULL; \
49  } while (0)
50 
51 #define strmap_free(map, fn) MAP_FREE_AND_NULL(strmap, (map), (fn))
52 #define digestmap_free(map, fn) MAP_FREE_AND_NULL(digestmap, (map), (fn))
53 #define digest256map_free(map, fn) MAP_FREE_AND_NULL(digest256map, (map), (fn))
54 
55 #undef DECLARE_MAP_FNS
56 
67 /* Unpacks to, approximately:
68  * {
69  * digestmap_iter_t *k_iter;
70  * for (k_iter = digestmap_iter_init(m); !digestmap_iter_done(k_iter);
71  * k_iter = digestmap_iter_next(m, k_iter)) {
72  * const char *k;
73  * void *r_voidp;
74  * routerinfo_t *r;
75  * digestmap_iter_get(k_iter, &k, &r_voidp);
76  * r = r_voidp;
77  * // use k and r
78  * }
79  * }
80  */
81 #define MAP_FOREACH(prefix, map, keytype, keyvar, valtype, valvar) \
82  STMT_BEGIN \
83  prefix##iter_t *keyvar##_iter; \
84  for (keyvar##_iter = prefix##iter_init(map); \
85  !prefix##iter_done(keyvar##_iter); \
86  keyvar##_iter = prefix##iter_next(map, keyvar##_iter)) { \
87  keytype keyvar; \
88  void *valvar##_voidp; \
89  valtype valvar; \
90  prefix##iter_get(keyvar##_iter, &keyvar, &valvar##_voidp); \
91  valvar = valvar##_voidp;
92 
102 /* Unpacks to, approximately:
103  * {
104  * digestmap_iter_t *k_iter;
105  * int k_del=0;
106  * for (k_iter = digestmap_iter_init(m); !digestmap_iter_done(k_iter);
107  * k_iter = k_del ? digestmap_iter_next(m, k_iter)
108  * : digestmap_iter_next_rmv(m, k_iter)) {
109  * const char *k;
110  * void *r_voidp;
111  * routerinfo_t *r;
112  * k_del=0;
113  * digestmap_iter_get(k_iter, &k, &r_voidp);
114  * r = r_voidp;
115  * if (is_very_old(r)) {
116  * k_del = 1;
117  * }
118  * }
119  * }
120  */
121 #define MAP_FOREACH_MODIFY(prefix, map, keytype, keyvar, valtype, valvar) \
122  STMT_BEGIN \
123  prefix##iter_t *keyvar##_iter; \
124  int keyvar##_del=0; \
125  for (keyvar##_iter = prefix##iter_init(map); \
126  !prefix##iter_done(keyvar##_iter); \
127  keyvar##_iter = keyvar##_del ? \
128  prefix##iter_next_rmv(map, keyvar##_iter) : \
129  prefix##iter_next(map, keyvar##_iter)) { \
130  keytype keyvar; \
131  void *valvar##_voidp; \
132  valtype valvar; \
133  keyvar##_del=0; \
134  prefix##iter_get(keyvar##_iter, &keyvar, &valvar##_voidp); \
135  valvar = valvar##_voidp;
136 
139 #define MAP_DEL_CURRENT(keyvar) \
140  STMT_BEGIN \
141  keyvar##_del = 1; \
142  STMT_END
143 
145 #define MAP_FOREACH_END } STMT_END ;
146 
153 #define DIGESTMAP_FOREACH(map, keyvar, valtype, valvar) \
154  MAP_FOREACH(digestmap_, map, const char *, keyvar, valtype, valvar)
155 
164 #define DIGESTMAP_FOREACH_MODIFY(map, keyvar, valtype, valvar) \
165  MAP_FOREACH_MODIFY(digestmap_, map, const char *, keyvar, valtype, valvar)
166 
167 #define DIGESTMAP_FOREACH_END MAP_FOREACH_END
168 
169 #define DIGEST256MAP_FOREACH(map, keyvar, valtype, valvar) \
170  MAP_FOREACH(digest256map_, map, const uint8_t *, keyvar, valtype, valvar)
171 #define DIGEST256MAP_FOREACH_MODIFY(map, keyvar, valtype, valvar) \
172  MAP_FOREACH_MODIFY(digest256map_, map, const uint8_t *, \
173  keyvar, valtype, valvar)
174 #define DIGEST256MAP_FOREACH_END MAP_FOREACH_END
175 
176 #define STRMAP_FOREACH(map, keyvar, valtype, valvar) \
177  MAP_FOREACH(strmap_, map, const char *, keyvar, valtype, valvar)
178 #define STRMAP_FOREACH_MODIFY(map, keyvar, valtype, valvar) \
179  MAP_FOREACH_MODIFY(strmap_, map, const char *, keyvar, valtype, valvar)
180 #define STRMAP_FOREACH_END MAP_FOREACH_END
181 
182 void* strmap_set_lc(strmap_t *map, const char *key, void *val);
183 void* strmap_get_lc(const strmap_t *map, const char *key);
184 void* strmap_remove_lc(strmap_t *map, const char *key);
185 
186 #define DECLARE_TYPED_DIGESTMAP_FNS(prefix, maptype, valtype) \
187  typedef struct maptype maptype; \
188  typedef struct prefix##iter_t *prefix##iter_t; \
189  ATTR_UNUSED static inline maptype* \
190  prefix##new(void) \
191  { \
192  return (maptype*)digestmap_new(); \
193  } \
194  ATTR_UNUSED static inline digestmap_t* \
195  prefix##to_digestmap(maptype *map) \
196  { \
197  return (digestmap_t*)map; \
198  } \
199  ATTR_UNUSED static inline valtype* \
200  prefix##get(maptype *map, const char *key) \
201  { \
202  return (valtype*)digestmap_get((digestmap_t*)map, key); \
203  } \
204  ATTR_UNUSED static inline valtype* \
205  prefix##set(maptype *map, const char *key, valtype *val) \
206  { \
207  return (valtype*)digestmap_set((digestmap_t*)map, key, val); \
208  } \
209  ATTR_UNUSED static inline valtype* \
210  prefix##remove(maptype *map, const char *key) \
211  { \
212  return (valtype*)digestmap_remove((digestmap_t*)map, key); \
213  } \
214  ATTR_UNUSED static inline void \
215  prefix##f##ree_(maptype *map, void (*free_val)(void*)) \
216  { \
217  digestmap_free_((digestmap_t*)map, free_val); \
218  } \
219  ATTR_UNUSED static inline int \
220  prefix##isempty(maptype *map) \
221  { \
222  return digestmap_isempty((digestmap_t*)map); \
223  } \
224  ATTR_UNUSED static inline int \
225  prefix##size(maptype *map) \
226  { \
227  return digestmap_size((digestmap_t*)map); \
228  } \
229  ATTR_UNUSED static inline \
230  prefix##iter_t *prefix##iter_init(maptype *map) \
231  { \
232  return (prefix##iter_t*) digestmap_iter_init((digestmap_t*)map); \
233  } \
234  ATTR_UNUSED static inline \
235  prefix##iter_t *prefix##iter_next(maptype *map, prefix##iter_t *iter) \
236  { \
237  return (prefix##iter_t*) digestmap_iter_next( \
238  (digestmap_t*)map, (digestmap_iter_t*)iter); \
239  } \
240  ATTR_UNUSED static inline prefix##iter_t* \
241  prefix##iter_next_rmv(maptype *map, prefix##iter_t *iter) \
242  { \
243  return (prefix##iter_t*) digestmap_iter_next_rmv( \
244  (digestmap_t*)map, (digestmap_iter_t*)iter); \
245  } \
246  ATTR_UNUSED static inline void \
247  prefix##iter_get(prefix##iter_t *iter, \
248  const char **keyp, \
249  valtype **valp) \
250  { \
251  void *v; \
252  digestmap_iter_get((digestmap_iter_t*) iter, keyp, &v); \
253  *valp = v; \
254  } \
255  ATTR_UNUSED static inline int \
256  prefix##iter_done(prefix##iter_t *iter) \
257  { \
258  return digestmap_iter_done((digestmap_iter_t*)iter); \
259  }
260 
261 #endif /* !defined(TOR_CONTAINER_H) */
void * strmap_set_lc(strmap_t *map, const char *key, void *val)
Definition: map.c:379
Integer definitions used throughout Tor.
void * strmap_remove_lc(strmap_t *map, const char *key)
Definition: map.c:405
void * strmap_get_lc(const strmap_t *map, const char *key)
Definition: map.c:393
Macros to implement mocking and selective exposure for the test code.