container.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /* Copyright 2003-2004 Roger Dingledine
  2. Copyright 2004-2006 Roger Dingledine, Nick Mathewson */
  3. /* See LICENSE for licensing information */
  4. /* $Id$ */
  5. const char container_c_id[] =
  6. "$Id$";
  7. /**
  8. * \file container.c
  9. * \brief Implements a smartlist (a resizable array) along
  10. * with helper functions to use smartlists. Also includes
  11. * hash table implementations of a string-to-void* map, and of
  12. * a digest-to-void* map.
  13. **/
  14. #include "compat.h"
  15. #include "util.h"
  16. #include "log.h"
  17. #include "container.h"
  18. #include "crypto.h"
  19. #ifdef HAVE_CTYPE_H
  20. #include <ctype.h>
  21. #endif
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <assert.h>
  25. #include "ht.h"
  26. /* All newly allocated smartlists have this capacity.
  27. */
  28. #define SMARTLIST_DEFAULT_CAPACITY 32
  29. /** Allocate and return an empty smartlist.
  30. */
  31. smartlist_t *
  32. smartlist_create(void)
  33. {
  34. smartlist_t *sl = tor_malloc(sizeof(smartlist_t));
  35. sl->num_used = 0;
  36. sl->capacity = SMARTLIST_DEFAULT_CAPACITY;
  37. sl->list = tor_malloc(sizeof(void *) * sl->capacity);
  38. return sl;
  39. }
  40. /** Deallocate a smartlist. Does not release storage associated with the
  41. * list's elements.
  42. */
  43. void
  44. smartlist_free(smartlist_t *sl)
  45. {
  46. tor_free(sl->list);
  47. tor_free(sl);
  48. }
  49. /** Change the capacity of the smartlist to <b>n</b>, so that we can grow
  50. * the list up to <b>n</b> elements with no further reallocation or wasted
  51. * space. If <b>n</b> is less than or equal to the number of elements
  52. * currently in the list, reduce the list's capacity as much as
  53. * possible without losing elements.
  54. */
  55. void
  56. smartlist_set_capacity(smartlist_t *sl, int n)
  57. {
  58. if (n < sl->num_used)
  59. n = sl->num_used;
  60. if (sl->capacity != n) {
  61. sl->capacity = n;
  62. sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
  63. }
  64. }
  65. /** Remove all elements from the list.
  66. */
  67. void
  68. smartlist_clear(smartlist_t *sl)
  69. {
  70. sl->num_used = 0;
  71. }
  72. /** Make sure that <b>sl</b> can hold at least <b>size</b> entries. */
  73. static INLINE void
  74. smartlist_ensure_capacity(smartlist_t *sl, int size)
  75. {
  76. if (size > sl->capacity) {
  77. int higher = sl->capacity * 2;
  78. while (size > higher)
  79. higher *= 2;
  80. tor_assert(higher > sl->capacity); /* detect overflow */
  81. sl->capacity = higher;
  82. sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
  83. }
  84. }
  85. /** Append element to the end of the list. */
  86. void
  87. smartlist_add(smartlist_t *sl, void *element)
  88. {
  89. smartlist_ensure_capacity(sl, sl->num_used+1);
  90. sl->list[sl->num_used++] = element;
  91. }
  92. /** Append each element from S2 to the end of S1. */
  93. void
  94. smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
  95. {
  96. smartlist_ensure_capacity(s1, s1->num_used + s2->num_used);
  97. memcpy(s1->list + s1->num_used, s2->list, s2->num_used*sizeof(void*));
  98. s1->num_used += s2->num_used;
  99. }
  100. /** Remove all elements E from sl such that E==element. Preserve
  101. * the order of any elements before E, but elements after E can be
  102. * rearranged.
  103. */
  104. void
  105. smartlist_remove(smartlist_t *sl, const void *element)
  106. {
  107. int i;
  108. if (element == NULL)
  109. return;
  110. for (i=0; i < sl->num_used; i++)
  111. if (sl->list[i] == element) {
  112. sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
  113. i--; /* so we process the new i'th element */
  114. }
  115. }
  116. /** If there are any strings in sl equal to element, remove and free them.
  117. * Does not preserve order. */
  118. void
  119. smartlist_string_remove(smartlist_t *sl, const char *element)
  120. {
  121. int i;
  122. tor_assert(sl);
  123. tor_assert(element);
  124. for (i = 0; i < sl->num_used; ++i) {
  125. if (!strcmp(element, sl->list[i])) {
  126. tor_free(sl->list[i]);
  127. sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
  128. i--; /* so we process the new i'th element */
  129. }
  130. }
  131. }
  132. /** Return true iff some element E of sl has E==element.
  133. */
  134. int
  135. smartlist_isin(const smartlist_t *sl, const void *element)
  136. {
  137. int i;
  138. for (i=0; i < sl->num_used; i++)
  139. if (sl->list[i] == element)
  140. return 1;
  141. return 0;
  142. }
  143. /** Return true iff <b>sl</b> has some element E such that
  144. * !strcmp(E,<b>element</b>)
  145. */
  146. int
  147. smartlist_string_isin(const smartlist_t *sl, const char *element)
  148. {
  149. int i;
  150. if (!sl) return 0;
  151. for (i=0; i < sl->num_used; i++)
  152. if (strcmp((const char*)sl->list[i],element)==0)
  153. return 1;
  154. return 0;
  155. }
  156. /** Return true iff <b>sl</b> has some element E such that E is equal
  157. * to the decimal encoding of <b>num</b>.
  158. */
  159. int
  160. smartlist_string_num_isin(const smartlist_t *sl, int num)
  161. {
  162. char buf[16];
  163. tor_snprintf(buf,sizeof(buf),"%d", num);
  164. return smartlist_string_isin(sl, buf);
  165. }
  166. /** Return true iff some element E of sl2 has smartlist_isin(sl1,E).
  167. */
  168. int
  169. smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2)
  170. {
  171. int i;
  172. for (i=0; i < sl2->num_used; i++)
  173. if (smartlist_isin(sl1, sl2->list[i]))
  174. return 1;
  175. return 0;
  176. }
  177. /** Remove every element E of sl1 such that !smartlist_isin(sl2,E).
  178. * Does not preserve the order of sl1.
  179. */
  180. void
  181. smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2)
  182. {
  183. int i;
  184. for (i=0; i < sl1->num_used; i++)
  185. if (!smartlist_isin(sl2, sl1->list[i])) {
  186. sl1->list[i] = sl1->list[--sl1->num_used]; /* swap with the end */
  187. i--; /* so we process the new i'th element */
  188. }
  189. }
  190. /** Remove every element E of sl1 such that smartlist_isin(sl2,E).
  191. * Does not preserve the order of sl1.
  192. */
  193. void
  194. smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2)
  195. {
  196. int i;
  197. for (i=0; i < sl2->num_used; i++)
  198. smartlist_remove(sl1, sl2->list[i]);
  199. }
  200. /** Remove the <b>idx</b>th element of sl; if idx is not the last
  201. * element, swap the last element of sl into the <b>idx</b>th space.
  202. * Return the old value of the <b>idx</b>th element.
  203. */
  204. void
  205. smartlist_del(smartlist_t *sl, int idx)
  206. {
  207. tor_assert(sl);
  208. tor_assert(idx>=0);
  209. tor_assert(idx < sl->num_used);
  210. sl->list[idx] = sl->list[--sl->num_used];
  211. }
  212. /** Remove the <b>idx</b>th element of sl; if idx is not the last element,
  213. * moving all subsequent elements back one space. Return the old value
  214. * of the <b>idx</b>th element.
  215. */
  216. void
  217. smartlist_del_keeporder(smartlist_t *sl, int idx)
  218. {
  219. tor_assert(sl);
  220. tor_assert(idx>=0);
  221. tor_assert(idx < sl->num_used);
  222. --sl->num_used;
  223. if (idx < sl->num_used)
  224. memmove(sl->list+idx, sl->list+idx+1, sizeof(void*)*(sl->num_used-idx));
  225. }
  226. /** Insert the value <b>val</b> as the new <b>idx</b>th element of
  227. * <b>sl</b>, moving all items previously at <b>idx</b> or later
  228. * forward one space.
  229. */
  230. void
  231. smartlist_insert(smartlist_t *sl, int idx, void *val)
  232. {
  233. tor_assert(sl);
  234. tor_assert(idx>=0);
  235. tor_assert(idx <= sl->num_used);
  236. if (idx == sl->num_used) {
  237. smartlist_add(sl, val);
  238. } else {
  239. smartlist_ensure_capacity(sl, sl->num_used+1);
  240. /* Move other elements away */
  241. if (idx < sl->num_used)
  242. memmove(sl->list + idx + 1, sl->list + idx,
  243. sizeof(void*)*(sl->num_used-idx));
  244. sl->num_used++;
  245. sl->list[idx] = val;
  246. }
  247. }
  248. /**
  249. * Split a string <b>str</b> along all occurrences of <b>sep</b>,
  250. * adding the split strings, in order, to <b>sl</b>. If
  251. * <b>flags</b>&amp;SPLIT_SKIP_SPACE is true, remove initial and
  252. * trailing space from each entry. If
  253. * <b>flags</b>&amp;SPLIT_IGNORE_BLANK is true, remove any entries of
  254. * length 0. If max>0, divide the string into no more than <b>max</b>
  255. * pieces. If <b>sep</b> is NULL, split on any sequence of horizontal space.
  256. */
  257. int
  258. smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
  259. int flags, int max)
  260. {
  261. const char *cp, *end, *next;
  262. int n = 0;
  263. tor_assert(sl);
  264. tor_assert(str);
  265. cp = str;
  266. while (1) {
  267. if (flags&SPLIT_SKIP_SPACE) {
  268. while (TOR_ISSPACE(*cp)) ++cp;
  269. }
  270. if (max>0 && n == max-1) {
  271. end = strchr(cp,'\0');
  272. } else if (sep) {
  273. end = strstr(cp,sep);
  274. if (!end)
  275. end = strchr(cp,'\0');
  276. } else {
  277. for (end = cp; *end && *end != '\t' && *end != ' '; ++end)
  278. ;
  279. }
  280. if (!*end) {
  281. next = NULL;
  282. } else if (sep) {
  283. next = end+strlen(sep);
  284. } else {
  285. next = end+1;
  286. while (*next == '\t' || *next == ' ')
  287. ++next;
  288. }
  289. if (flags&SPLIT_SKIP_SPACE) {
  290. while (end > cp && TOR_ISSPACE(*(end-1)))
  291. --end;
  292. }
  293. if (end != cp || !(flags&SPLIT_IGNORE_BLANK)) {
  294. smartlist_add(sl, tor_strndup(cp, end-cp));
  295. ++n;
  296. }
  297. if (!next)
  298. break;
  299. cp = next;
  300. }
  301. return n;
  302. }
  303. /** Allocate and return a new string containing the concatenation of
  304. * the elements of <b>sl</b>, in order, separated by <b>join</b>. If
  305. * <b>terminate</b> is true, also terminate the string with <b>join</b>.
  306. * If <b>len_out</b> is not NULL, set <b>len_out</b> to the length of
  307. * the returned string. Requires that every element of <b>sl</b> is
  308. * NUL-terminated string.
  309. */
  310. char *
  311. smartlist_join_strings(smartlist_t *sl, const char *join,
  312. int terminate, size_t *len_out)
  313. {
  314. return smartlist_join_strings2(sl,join,strlen(join),terminate,len_out);
  315. }
  316. /** As smartlist_join_strings, but instead of separating/terminated with a
  317. * NUL-terminated string <b>join</b>, uses the <b>join_len</b>-byte sequence
  318. * at <b>join</b>. (Useful for generating a sequence of NUL-terminated
  319. * strings.)
  320. */
  321. char *
  322. smartlist_join_strings2(smartlist_t *sl, const char *join,
  323. size_t join_len, int terminate, size_t *len_out)
  324. {
  325. int i;
  326. size_t n = 0;
  327. char *r = NULL, *dst, *src;
  328. tor_assert(sl);
  329. tor_assert(join);
  330. if (terminate)
  331. n = join_len;
  332. for (i = 0; i < sl->num_used; ++i) {
  333. n += strlen(sl->list[i]);
  334. if (i+1 < sl->num_used) /* avoid double-counting the last one */
  335. n += join_len;
  336. }
  337. dst = r = tor_malloc(n+1);
  338. for (i = 0; i < sl->num_used; ) {
  339. for (src = sl->list[i]; *src; )
  340. *dst++ = *src++;
  341. if (++i < sl->num_used) {
  342. memcpy(dst, join, join_len);
  343. dst += join_len;
  344. }
  345. }
  346. if (terminate) {
  347. memcpy(dst, join, join_len);
  348. dst += join_len;
  349. }
  350. *dst = '\0';
  351. if (len_out)
  352. *len_out = dst-r;
  353. return r;
  354. }
  355. /** Sort the members of <b>sl</b> into an order defined by
  356. * the ordering function <b>compare</b>, which returns less then 0 if a
  357. * precedes b, greater than 0 if b precedes a, and 0 if a 'equals' b.
  358. */
  359. void
  360. smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b))
  361. {
  362. if (!sl->num_used)
  363. return;
  364. qsort(sl->list, sl->num_used, sizeof(void*),
  365. (int (*)(const void *,const void*))compare);
  366. }
  367. /** Assuming the members of <b>sl</b> are in order, return a pointer to the
  368. * member which matches <b>key</b>. Ordering and matching are defined by a
  369. * <b>compare</b> function, which returns 0 on a match; less than 0 if key is
  370. * less than member, and greater than 0 if key is greater then member.
  371. */
  372. void *
  373. smartlist_bsearch(smartlist_t *sl, const void *key,
  374. int (*compare)(const void *key, const void **member))
  375. {
  376. void ** r;
  377. if (!sl->num_used)
  378. return NULL;
  379. r = bsearch(key, sl->list, sl->num_used, sizeof(void*),
  380. (int (*)(const void *, const void *))compare);
  381. return r ? *r : NULL;
  382. }
  383. /** Helper: compare two const char **s. */
  384. static int
  385. _compare_string_ptrs(const void **_a, const void **_b)
  386. {
  387. return strcmp((const char*)*_a, (const char*)*_b);
  388. }
  389. /** Sort a smartlist <b>sl</b> containing strings into lexically ascending
  390. * order. */
  391. void
  392. smartlist_sort_strings(smartlist_t *sl)
  393. {
  394. smartlist_sort(sl, _compare_string_ptrs);
  395. }
  396. #define DEFINE_MAP_STRUCTS(maptype, keydecl, prefix) \
  397. typedef struct prefix ## entry_t { \
  398. HT_ENTRY(prefix ## entry_t) node; \
  399. void *val; \
  400. keydecl; \
  401. } prefix ## entry_t; \
  402. struct maptype { \
  403. HT_HEAD(prefix ## impl, prefix ## entry_t) head; \
  404. };
  405. DEFINE_MAP_STRUCTS(strmap_t, char *key, strmap_);
  406. DEFINE_MAP_STRUCTS(digestmap_t, char key[DIGEST_LEN], digestmap_);
  407. /** Helper: compare strmap_t_entry objects by key value. */
  408. static INLINE int
  409. strmap_entries_eq(strmap_entry_t *a, strmap_entry_t *b)
  410. {
  411. return !strcmp(a->key, b->key);
  412. }
  413. static INLINE unsigned int
  414. strmap_entry_hash(strmap_entry_t *a)
  415. {
  416. return ht_string_hash(a->key);
  417. }
  418. /** Helper: compare digestmap_entry_t objects by key value. */
  419. static INLINE int
  420. digestmap_entries_eq(digestmap_entry_t *a, digestmap_entry_t *b)
  421. {
  422. return !memcmp(a->key, b->key, DIGEST_LEN);
  423. }
  424. static INLINE unsigned int
  425. digestmap_entry_hash(digestmap_entry_t *a)
  426. {
  427. uint32_t *p = (uint32_t*)a->key;
  428. return ht_improve_hash(p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4]);
  429. }
  430. HT_PROTOTYPE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
  431. strmap_entries_eq);
  432. HT_GENERATE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
  433. strmap_entries_eq, 0.6, malloc, realloc, free);
  434. HT_PROTOTYPE(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
  435. digestmap_entries_eq);
  436. HT_GENERATE(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
  437. digestmap_entries_eq, 0.6, malloc, realloc, free);
  438. /** Constructor to create a new empty map from strings to void*'s.
  439. */
  440. strmap_t *
  441. strmap_new(void)
  442. {
  443. strmap_t *result;
  444. result = tor_malloc(sizeof(strmap_t));
  445. HT_INIT(&result->head);
  446. return result;
  447. }
  448. /** Constructor to create a new empty map from digests to void*'s.
  449. */
  450. digestmap_t *
  451. digestmap_new(void)
  452. {
  453. digestmap_t *result;
  454. result = tor_malloc(sizeof(digestmap_t));
  455. HT_INIT(&result->head);
  456. return result;
  457. }
  458. /** Set the current value for <b>key</b> to <b>val</b>. Returns the previous
  459. * value for <b>key</b> if one was set, or NULL if one was not.
  460. *
  461. * This function makes a copy of <b>key</b> if necessary, but not of
  462. * <b>val</b>.
  463. */
  464. void *
  465. strmap_set(strmap_t *map, const char *key, void *val)
  466. {
  467. strmap_entry_t *resolve;
  468. strmap_entry_t search;
  469. void *oldval;
  470. tor_assert(map);
  471. tor_assert(key);
  472. tor_assert(val);
  473. search.key = (char*)key;
  474. resolve = HT_FIND(strmap_impl, &map->head, &search);
  475. if (resolve) {
  476. oldval = resolve->val;
  477. resolve->val = val;
  478. return oldval;
  479. } else {
  480. resolve = tor_malloc_zero(sizeof(strmap_entry_t));
  481. resolve->key = tor_strdup(key);
  482. resolve->val = val;
  483. tor_assert(!HT_FIND(strmap_impl, &map->head, resolve));
  484. HT_INSERT(strmap_impl, &map->head, resolve);
  485. return NULL;
  486. }
  487. }
  488. /** Like strmap_set() above but for digestmaps. */
  489. void *
  490. digestmap_set(digestmap_t *map, const char *key, void *val)
  491. {
  492. digestmap_entry_t *resolve;
  493. digestmap_entry_t search;
  494. void *oldval;
  495. tor_assert(map);
  496. tor_assert(key);
  497. tor_assert(val);
  498. memcpy(&search.key, key, DIGEST_LEN);
  499. resolve = HT_FIND(digestmap_impl, &map->head, &search);
  500. if (resolve) {
  501. oldval = resolve->val;
  502. resolve->val = val;
  503. return oldval;
  504. } else {
  505. resolve = tor_malloc_zero(sizeof(digestmap_entry_t));
  506. memcpy(resolve->key, key, DIGEST_LEN);
  507. resolve->val = val;
  508. HT_INSERT(digestmap_impl, &map->head, resolve);
  509. return NULL;
  510. }
  511. }
  512. /** Return the current value associated with <b>key</b>, or NULL if no
  513. * value is set.
  514. */
  515. void *
  516. strmap_get(strmap_t *map, const char *key)
  517. {
  518. strmap_entry_t *resolve;
  519. strmap_entry_t search;
  520. tor_assert(map);
  521. tor_assert(key);
  522. search.key = (char*)key;
  523. resolve = HT_FIND(strmap_impl, &map->head, &search);
  524. if (resolve) {
  525. return resolve->val;
  526. } else {
  527. return NULL;
  528. }
  529. }
  530. /** Like strmap_get() above but for digestmaps. */
  531. void *
  532. digestmap_get(digestmap_t *map, const char *key)
  533. {
  534. digestmap_entry_t *resolve;
  535. digestmap_entry_t search;
  536. tor_assert(map);
  537. tor_assert(key);
  538. memcpy(&search.key, key, DIGEST_LEN);
  539. resolve = HT_FIND(digestmap_impl, &map->head, &search);
  540. if (resolve) {
  541. return resolve->val;
  542. } else {
  543. return NULL;
  544. }
  545. }
  546. /** Remove the value currently associated with <b>key</b> from the map.
  547. * Return the value if one was set, or NULL if there was no entry for
  548. * <b>key</b>.
  549. *
  550. * Note: you must free any storage associated with the returned value.
  551. */
  552. void *
  553. strmap_remove(strmap_t *map, const char *key)
  554. {
  555. strmap_entry_t *resolve;
  556. strmap_entry_t search;
  557. void *oldval;
  558. tor_assert(map);
  559. tor_assert(key);
  560. search.key = (char*)key;
  561. resolve = HT_REMOVE(strmap_impl, &map->head, &search);
  562. if (resolve) {
  563. oldval = resolve->val;
  564. tor_free(resolve->key);
  565. tor_free(resolve);
  566. return oldval;
  567. } else {
  568. return NULL;
  569. }
  570. }
  571. /** Like strmap_remove() above but for digestmaps. */
  572. void *
  573. digestmap_remove(digestmap_t *map, const char *key)
  574. {
  575. digestmap_entry_t *resolve;
  576. digestmap_entry_t search;
  577. void *oldval;
  578. tor_assert(map);
  579. tor_assert(key);
  580. memcpy(&search.key, key, DIGEST_LEN);
  581. resolve = HT_REMOVE(digestmap_impl, &map->head, &search);
  582. if (resolve) {
  583. oldval = resolve->val;
  584. tor_free(resolve);
  585. return oldval;
  586. } else {
  587. return NULL;
  588. }
  589. }
  590. /** Same as strmap_set, but first converts <b>key</b> to lowercase. */
  591. void *
  592. strmap_set_lc(strmap_t *map, const char *key, void *val)
  593. {
  594. /* We could be a little faster by using strcasecmp instead, and a separate
  595. * type, but I don't think it matters. */
  596. void *v;
  597. char *lc_key = tor_strdup(key);
  598. tor_strlower(lc_key);
  599. v = strmap_set(map,lc_key,val);
  600. tor_free(lc_key);
  601. return v;
  602. }
  603. /** Same as strmap_get, but first converts <b>key</b> to lowercase. */
  604. void *
  605. strmap_get_lc(strmap_t *map, const char *key)
  606. {
  607. void *v;
  608. char *lc_key = tor_strdup(key);
  609. tor_strlower(lc_key);
  610. v = strmap_get(map,lc_key);
  611. tor_free(lc_key);
  612. return v;
  613. }
  614. /** Same as strmap_remove, but first converts <b>key</b> to lowercase */
  615. void *
  616. strmap_remove_lc(strmap_t *map, const char *key)
  617. {
  618. void *v;
  619. char *lc_key = tor_strdup(key);
  620. tor_strlower(lc_key);
  621. v = strmap_remove(map,lc_key);
  622. tor_free(lc_key);
  623. return v;
  624. }
  625. /** return an <b>iterator</b> pointer to the front of a map.
  626. *
  627. * Iterator example:
  628. *
  629. * \code
  630. * // uppercase values in "map", removing empty values.
  631. *
  632. * strmap_iter_t *iter;
  633. * const char *key;
  634. * void *val;
  635. * char *cp;
  636. *
  637. * for (iter = strmap_iter_init(map); !strmap_iter_done(iter); ) {
  638. * strmap_iter_get(iter, &key, &val);
  639. * cp = (char*)val;
  640. * if (!*cp) {
  641. * iter = strmap_iter_next_rmv(iter);
  642. * free(val);
  643. * } else {
  644. * for (;*cp;cp++) *cp = toupper(*cp);
  645. * iter = strmap_iter_next(iter);
  646. * }
  647. * }
  648. * \endcode
  649. *
  650. */
  651. strmap_iter_t *
  652. strmap_iter_init(strmap_t *map)
  653. {
  654. tor_assert(map);
  655. return HT_START(strmap_impl, &map->head);
  656. }
  657. digestmap_iter_t *
  658. digestmap_iter_init(digestmap_t *map)
  659. {
  660. tor_assert(map);
  661. return HT_START(digestmap_impl, &map->head);
  662. }
  663. /** Advance the iterator <b>iter</b> for map a single step to the next entry.
  664. */
  665. strmap_iter_t *
  666. strmap_iter_next(strmap_t *map, strmap_iter_t *iter)
  667. {
  668. tor_assert(map);
  669. tor_assert(iter);
  670. return HT_NEXT(strmap_impl, &map->head, iter);
  671. }
  672. digestmap_iter_t *
  673. digestmap_iter_next(digestmap_t *map, digestmap_iter_t *iter)
  674. {
  675. tor_assert(map);
  676. tor_assert(iter);
  677. return HT_NEXT(digestmap_impl, &map->head, iter);
  678. }
  679. /** Advance the iterator <b>iter</b> a single step to the next entry, removing
  680. * the current entry.
  681. */
  682. strmap_iter_t *
  683. strmap_iter_next_rmv(strmap_t *map, strmap_iter_t *iter)
  684. {
  685. strmap_entry_t *rmv;
  686. tor_assert(map);
  687. tor_assert(iter);
  688. tor_assert(*iter);
  689. rmv = *iter;
  690. iter = HT_NEXT_RMV(strmap_impl, &map->head, iter);
  691. tor_free(rmv->key);
  692. tor_free(rmv);
  693. return iter;
  694. }
  695. digestmap_iter_t *
  696. digestmap_iter_next_rmv(digestmap_t *map, digestmap_iter_t *iter)
  697. {
  698. digestmap_entry_t *rmv;
  699. tor_assert(map);
  700. tor_assert(iter);
  701. tor_assert(*iter);
  702. rmv = *iter;
  703. iter = HT_NEXT_RMV(digestmap_impl, &map->head, iter);
  704. tor_free(rmv);
  705. return iter;
  706. }
  707. /** Set *keyp and *valp to the current entry pointed to by iter.
  708. */
  709. void
  710. strmap_iter_get(strmap_iter_t *iter, const char **keyp, void **valp)
  711. {
  712. tor_assert(iter);
  713. tor_assert(*iter);
  714. tor_assert(keyp);
  715. tor_assert(valp);
  716. *keyp = (*iter)->key;
  717. *valp = (*iter)->val;
  718. }
  719. void
  720. digestmap_iter_get(digestmap_iter_t *iter, const char **keyp, void **valp)
  721. {
  722. tor_assert(iter);
  723. tor_assert(*iter);
  724. tor_assert(keyp);
  725. tor_assert(valp);
  726. *keyp = (*iter)->key;
  727. *valp = (*iter)->val;
  728. }
  729. /** Return true iff iter has advanced past the last entry of map.
  730. */
  731. int
  732. strmap_iter_done(strmap_iter_t *iter)
  733. {
  734. return iter == NULL;
  735. }
  736. int
  737. digestmap_iter_done(digestmap_iter_t *iter)
  738. {
  739. return iter == NULL;
  740. }
  741. /** Remove all entries from <b>map</b>, and deallocate storage for those
  742. * entries. If free_val is provided, it is invoked on every value in
  743. * <b>map</b>.
  744. */
  745. void
  746. strmap_free(strmap_t *map, void (*free_val)(void*))
  747. {
  748. strmap_entry_t **ent, **next, *this;
  749. for (ent = HT_START(strmap_impl, &map->head); ent != NULL; ent = next) {
  750. this = *ent;
  751. next = HT_NEXT_RMV(strmap_impl, &map->head, ent);
  752. tor_free(this->key);
  753. if (free_val)
  754. free_val(this->val);
  755. tor_free(this);
  756. }
  757. tor_assert(HT_EMPTY(&map->head));
  758. HT_CLEAR(strmap_impl, &map->head);
  759. tor_free(map);
  760. }
  761. void
  762. digestmap_free(digestmap_t *map, void (*free_val)(void*))
  763. {
  764. digestmap_entry_t **ent, **next, *this;
  765. for (ent = HT_START(digestmap_impl, &map->head); ent != NULL; ent = next) {
  766. this = *ent;
  767. next = HT_NEXT_RMV(digestmap_impl, &map->head, ent);
  768. if (free_val)
  769. free_val(this->val);
  770. tor_free(this);
  771. }
  772. tor_assert(HT_EMPTY(&map->head));
  773. HT_CLEAR(digestmap_impl, &map->head);
  774. tor_free(map);
  775. }
  776. /** Return true iff <b>map</b> has no entries. */
  777. int
  778. strmap_isempty(strmap_t *map)
  779. {
  780. return HT_EMPTY(&map->head);
  781. }
  782. int
  783. digestmap_isempty(digestmap_t *map)
  784. {
  785. return HT_EMPTY(&map->head);
  786. }
  787. int
  788. strmap_size(strmap_t *map)
  789. {
  790. return HT_SIZE(&map->head);
  791. }
  792. int
  793. digestmap_size(digestmap_t *map)
  794. {
  795. return HT_SIZE(&map->head);
  796. }