container.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. /* Copyright 2003-2004 Roger Dingledine; Copyright 2004 Nick Mathewson */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. const char container_c_id[] = "$Id$";
  5. #include "compat.h"
  6. #include "util.h"
  7. #include "log.h"
  8. #include "../or/tree.h"
  9. #include "container.h"
  10. #ifdef HAVE_CTYPE_H
  11. #include <ctype.h>
  12. #endif
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <assert.h>
  16. /* =====
  17. * smartlist_t: a simple resizeable array abstraction.
  18. * ===== */
  19. /* All newly allocated smartlists have this capacity.
  20. */
  21. #define SMARTLIST_DEFAULT_CAPACITY 32
  22. #ifndef FAST_SMARTLIST
  23. struct smartlist_t {
  24. /** <b>list</b> has enough capacity to store exactly <b>capacity</b> elements
  25. * before it needs to be resized. Only the first <b>num_used</b> (\<=
  26. * capacity) elements point to valid data.
  27. */
  28. void **list;
  29. int num_used;
  30. int capacity;
  31. };
  32. #endif
  33. /** Allocate and return an empty smartlist.
  34. */
  35. smartlist_t *smartlist_create() {
  36. smartlist_t *sl = tor_malloc(sizeof(smartlist_t));
  37. sl->num_used = 0;
  38. sl->capacity = SMARTLIST_DEFAULT_CAPACITY;
  39. sl->list = tor_malloc(sizeof(void *) * sl->capacity);
  40. return sl;
  41. }
  42. /** Deallocate a smartlist. Does not release storage associated with the
  43. * list's elements.
  44. */
  45. void smartlist_free(smartlist_t *sl) {
  46. free(sl->list);
  47. 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 smartlist_set_capacity(smartlist_t *sl, int n) {
  56. if (n < sl->num_used)
  57. n = sl->num_used;
  58. if (sl->capacity != n) {
  59. sl->capacity = n;
  60. sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
  61. }
  62. }
  63. /** Remove all elements from the list.
  64. */
  65. void smartlist_clear(smartlist_t *sl) {
  66. sl->num_used = 0;
  67. }
  68. /** Set the list's new length to <b>len</b> (which must be \<= the list's
  69. * current size). Remove the last smartlist_len(sl)-len elements from the
  70. * list.
  71. */
  72. void smartlist_truncate(smartlist_t *sl, int len)
  73. {
  74. tor_assert(len <= sl->num_used);
  75. sl->num_used = len;
  76. }
  77. /** Append element to the end of the list. */
  78. void smartlist_add(smartlist_t *sl, void *element) {
  79. if (sl->num_used >= sl->capacity) {
  80. sl->capacity *= 2;
  81. sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
  82. }
  83. sl->list[sl->num_used++] = element;
  84. }
  85. /** Append each element from S2 to the end of S1. */
  86. void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2)
  87. {
  88. SMARTLIST_FOREACH(s2, void *, element, smartlist_add(sl, element));
  89. }
  90. /** Remove all elements E from sl such that E==element. Does not preserve
  91. * the order of s1.
  92. */
  93. void smartlist_remove(smartlist_t *sl, void *element) {
  94. int i;
  95. if (element == NULL)
  96. return;
  97. for (i=0; i < sl->num_used; i++)
  98. if (sl->list[i] == element) {
  99. sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
  100. i--; /* so we process the new i'th element */
  101. }
  102. }
  103. /** Return true iff some element E of sl has E==element.
  104. */
  105. int smartlist_isin(const smartlist_t *sl, void *element) {
  106. int i;
  107. for (i=0; i < sl->num_used; i++)
  108. if (sl->list[i] == element)
  109. return 1;
  110. return 0;
  111. }
  112. int smartlist_string_isin(const smartlist_t *sl, const char *element) {
  113. int i;
  114. for (i=0; i < sl->num_used; i++)
  115. if (strcmp((const char*)sl->list[i],element)==0)
  116. return 1;
  117. return 0;
  118. }
  119. /** Return true iff some element E of sl2 has smartlist_isin(sl1,E).
  120. */
  121. int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2) {
  122. int i;
  123. for (i=0; i < sl2->num_used; i++)
  124. if (smartlist_isin(sl1, sl2->list[i]))
  125. return 1;
  126. return 0;
  127. }
  128. /** Remove every element E of sl1 such that !smartlist_isin(sl2,E).
  129. * Does not preserve the order of sl1.
  130. */
  131. void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2) {
  132. int i;
  133. for (i=0; i < sl1->num_used; i++)
  134. if (!smartlist_isin(sl2, sl1->list[i])) {
  135. sl1->list[i] = sl1->list[--sl1->num_used]; /* swap with the end */
  136. i--; /* so we process the new i'th element */
  137. }
  138. }
  139. /** Remove every element E of sl1 such that smartlist_isin(sl2,E).
  140. * Does not preserve the order of sl1.
  141. */
  142. void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2) {
  143. int i;
  144. for (i=0; i < sl2->num_used; i++)
  145. smartlist_remove(sl1, sl2->list[i]);
  146. }
  147. #ifndef FAST_SMARTLIST
  148. /** Return the <b>idx</b>th element of sl.
  149. */
  150. void *smartlist_get(const smartlist_t *sl, int idx)
  151. {
  152. tor_assert(sl);
  153. tor_assert(idx>=0);
  154. tor_assert(idx < sl->num_used);
  155. return sl->list[idx];
  156. }
  157. /** Change the value of the <b>idx</b>th element of sl to <b>val</b>; return the old
  158. * value of the <b>idx</b>th element.
  159. */
  160. void smartlist_set(smartlist_t *sl, int idx, void *val)
  161. {
  162. tor_assert(sl);
  163. tor_assert(idx>=0);
  164. tor_assert(idx < sl->num_used);
  165. sl->list[idx] = val;
  166. }
  167. /** Return the number of items in sl.
  168. */
  169. int smartlist_len(const smartlist_t *sl)
  170. {
  171. return sl->num_used;
  172. }
  173. #endif
  174. /** Remove the <b>idx</b>th element of sl; if idx is not the last
  175. * element, swap the last element of sl into the <b>idx</b>th space.
  176. * Return the old value of the <b>idx</b>th element.
  177. */
  178. void smartlist_del(smartlist_t *sl, int idx)
  179. {
  180. tor_assert(sl);
  181. tor_assert(idx>=0);
  182. tor_assert(idx < sl->num_used);
  183. sl->list[idx] = sl->list[--sl->num_used];
  184. }
  185. /** Remove the <b>idx</b>th element of sl; if idx is not the last element,
  186. * moving all subsequent elements back one space. Return the old value
  187. * of the <b>idx</b>th element.
  188. */
  189. void smartlist_del_keeporder(smartlist_t *sl, int idx)
  190. {
  191. tor_assert(sl);
  192. tor_assert(idx>=0);
  193. tor_assert(idx < sl->num_used);
  194. --sl->num_used;
  195. if (idx < sl->num_used)
  196. memmove(sl->list+idx, sl->list+idx+1, sizeof(void*)*(sl->num_used-idx));
  197. }
  198. /** Insert the value <b>val</b> as the new <b>idx</b>th element of
  199. * <b>sl</b>, moving all items previously at <b>idx</b> or later
  200. * forward one space.
  201. */
  202. void smartlist_insert(smartlist_t *sl, int idx, void *val)
  203. {
  204. tor_assert(sl);
  205. tor_assert(idx>=0);
  206. tor_assert(idx <= sl->num_used);
  207. if (idx == sl->num_used) {
  208. smartlist_add(sl, val);
  209. } else {
  210. /* Ensure sufficient capacity */
  211. if (sl->num_used >= sl->capacity) {
  212. sl->capacity *= 2;
  213. sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
  214. }
  215. /* Move other elements away */
  216. if (idx < sl->num_used)
  217. memmove(sl->list + idx + 1, sl->list + idx,
  218. sizeof(void*)*(sl->num_used-idx));
  219. sl->num_used++;
  220. sl->list[idx] = val;
  221. }
  222. }
  223. /**
  224. * Split a string <b>str</b> along all occurences of <b>sep</b>,
  225. * adding the split strings, in order, to <b>sl</b>. If
  226. * <b>flags</b>&amp;SPLIT_SKIP_SPACE is true, remove initial and
  227. * trailing space from each entry. If
  228. * <b>flags</b>&amp;SPLIT_IGNORE_BLANK is true, remove any entries of
  229. * length 0. If max>0, divide the string into no more than <b>max</b>
  230. * pieces.
  231. */
  232. int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
  233. int flags, int max)
  234. {
  235. const char *cp, *end, *next;
  236. int n = 0;
  237. tor_assert(sl);
  238. tor_assert(str);
  239. tor_assert(sep);
  240. cp = str;
  241. while (1) {
  242. if (flags&SPLIT_SKIP_SPACE) {
  243. while (isspace((int)*cp)) ++cp;
  244. }
  245. if (max>0 && n == max-1) {
  246. end = strchr(cp,'\0');
  247. } else {
  248. end = strstr(cp,sep);
  249. if (!end)
  250. end = strchr(cp,'\0');
  251. }
  252. if (!*end) {
  253. next = NULL;
  254. } else {
  255. next = end+strlen(sep);
  256. }
  257. if (flags&SPLIT_SKIP_SPACE) {
  258. while (end > cp && isspace((int)*(end-1)))
  259. --end;
  260. }
  261. if (end != cp || !(flags&SPLIT_IGNORE_BLANK)) {
  262. smartlist_add(sl, tor_strndup(cp, end-cp));
  263. ++n;
  264. }
  265. if (!next)
  266. break;
  267. cp = next;
  268. }
  269. return n;
  270. }
  271. /** Allocate and return a new string containing the concatenation of
  272. * the elements of <b>sl</b>, in order, separated by <b>join</b>. If
  273. * <b>terminate</b> is true, also terminate the string with <b>join</b>.
  274. * If <b>len_out</b> is not NULL, set <b>len_out</b> to the length of
  275. * the returned string. Requires that every element of <b>sl</b> is
  276. * NUL-terminated string.
  277. */
  278. char *smartlist_join_strings(smartlist_t *sl, const char *join,
  279. int terminate, size_t *len_out)
  280. {
  281. return smartlist_join_strings2(sl,join,strlen(join),terminate,len_out);
  282. }
  283. /** As smartlist_join_strings2, but instead of separating/terminated with a
  284. * NUL-terminated string <b>join</b>, uses the <b>join_len</b>-byte sequence
  285. * at <b>join</b>. (Useful for generating a sequence of NUL-terminated
  286. * strings.)
  287. */
  288. char *smartlist_join_strings2(smartlist_t *sl, const char *join,
  289. size_t join_len, int terminate, size_t *len_out)
  290. {
  291. int i;
  292. size_t n = 0;
  293. char *r = NULL, *dst, *src;
  294. tor_assert(sl);
  295. tor_assert(join);
  296. join_len = strlen(join);
  297. for (i = 0; i < sl->num_used; ++i) {
  298. n += strlen(sl->list[i]);
  299. n += join_len;
  300. }
  301. if (!terminate) n -= join_len;
  302. dst = r = tor_malloc(n+1);
  303. for (i = 0; i < sl->num_used; ) {
  304. for (src = sl->list[i]; *src; )
  305. *dst++ = *src++;
  306. if (++i < sl->num_used || terminate) {
  307. memcpy(dst, join, join_len);
  308. dst += join_len;
  309. }
  310. }
  311. *dst = '\0';
  312. if (len_out)
  313. *len_out = dst-r;
  314. return r;
  315. }
  316. /* Splay-tree implementation of string-to-void* map
  317. */
  318. struct strmap_entry_t {
  319. SPLAY_ENTRY(strmap_entry_t) node;
  320. char *key;
  321. void *val;
  322. };
  323. struct strmap_t {
  324. SPLAY_HEAD(strmap_tree, strmap_entry_t) head;
  325. };
  326. static int compare_strmap_entries(struct strmap_entry_t *a,
  327. struct strmap_entry_t *b)
  328. {
  329. return strcmp(a->key, b->key);
  330. }
  331. SPLAY_PROTOTYPE(strmap_tree, strmap_entry_t, node, compare_strmap_entries);
  332. SPLAY_GENERATE(strmap_tree, strmap_entry_t, node, compare_strmap_entries);
  333. /** Create a new empty map from strings to void*'s.
  334. */
  335. strmap_t* strmap_new(void)
  336. {
  337. strmap_t *result;
  338. result = tor_malloc(sizeof(strmap_t));
  339. SPLAY_INIT(&result->head);
  340. return result;
  341. }
  342. /** Set the current value for <b>key</b> to <b>val</b>. Returns the previous
  343. * value for <b>key</b> if one was set, or NULL if one was not.
  344. *
  345. * This function makes a copy of <b>key</b> if necessary, but not of <b>val</b>.
  346. */
  347. void* strmap_set(strmap_t *map, const char *key, void *val)
  348. {
  349. strmap_entry_t *resolve;
  350. strmap_entry_t search;
  351. void *oldval;
  352. tor_assert(map);
  353. tor_assert(key);
  354. tor_assert(val);
  355. search.key = (char*)key;
  356. resolve = SPLAY_FIND(strmap_tree, &map->head, &search);
  357. if (resolve) {
  358. oldval = resolve->val;
  359. resolve->val = val;
  360. return oldval;
  361. } else {
  362. resolve = tor_malloc_zero(sizeof(strmap_entry_t));
  363. resolve->key = tor_strdup(key);
  364. resolve->val = val;
  365. SPLAY_INSERT(strmap_tree, &map->head, resolve);
  366. return NULL;
  367. }
  368. }
  369. /** Return the current value associated with <b>key</b>, or NULL if no
  370. * value is set.
  371. */
  372. void* strmap_get(strmap_t *map, const char *key)
  373. {
  374. strmap_entry_t *resolve;
  375. strmap_entry_t search;
  376. tor_assert(map);
  377. tor_assert(key);
  378. search.key = (char*)key;
  379. resolve = SPLAY_FIND(strmap_tree, &map->head, &search);
  380. if (resolve) {
  381. return resolve->val;
  382. } else {
  383. return NULL;
  384. }
  385. }
  386. /** Remove the value currently associated with <b>key</b> from the map.
  387. * Return the value if one was set, or NULL if there was no entry for
  388. * <b>key</b>.
  389. *
  390. * Note: you must free any storage associated with the returned value.
  391. */
  392. void* strmap_remove(strmap_t *map, const char *key)
  393. {
  394. strmap_entry_t *resolve;
  395. strmap_entry_t search;
  396. void *oldval;
  397. tor_assert(map);
  398. tor_assert(key);
  399. search.key = (char*)key;
  400. resolve = SPLAY_FIND(strmap_tree, &map->head, &search);
  401. if (resolve) {
  402. oldval = resolve->val;
  403. SPLAY_REMOVE(strmap_tree, &map->head, resolve);
  404. tor_free(resolve->key);
  405. tor_free(resolve);
  406. return oldval;
  407. } else {
  408. return NULL;
  409. }
  410. }
  411. /** Same as strmap_set, but first converts <b>key</b> to lowercase. */
  412. void* strmap_set_lc(strmap_t *map, const char *key, void *val)
  413. {
  414. /* We could be a little faster by using strcasecmp instead, and a separate
  415. * type, but I don't think it matters. */
  416. void *v;
  417. char *lc_key = tor_strdup(key);
  418. tor_strlower(lc_key);
  419. v = strmap_set(map,lc_key,val);
  420. tor_free(lc_key);
  421. return v;
  422. }
  423. /** Same as strmap_get, but first converts <b>key</b> to lowercase. */
  424. void* strmap_get_lc(strmap_t *map, const char *key)
  425. {
  426. void *v;
  427. char *lc_key = tor_strdup(key);
  428. tor_strlower(lc_key);
  429. v = strmap_get(map,lc_key);
  430. tor_free(lc_key);
  431. return v;
  432. }
  433. /** Same as strmap_remove, but first converts <b>key</b> to lowercase */
  434. void* strmap_remove_lc(strmap_t *map, const char *key)
  435. {
  436. void *v;
  437. char *lc_key = tor_strdup(key);
  438. tor_strlower(lc_key);
  439. v = strmap_remove(map,lc_key);
  440. tor_free(lc_key);
  441. return v;
  442. }
  443. /** Invoke fn() on every entry of the map, in order. For every entry,
  444. * fn() is invoked with that entry's key, that entry's value, and the
  445. * value of <b>data</b> supplied to strmap_foreach. fn() must return a new
  446. * (possibly unmodified) value for each entry: if fn() returns NULL, the
  447. * entry is removed.
  448. *
  449. * Example:
  450. * \code
  451. * static void* upcase_and_remove_empty_vals(const char *key, void *val,
  452. * void* data) {
  453. * char *cp = (char*)val;
  454. * if (!*cp) { // val is an empty string.
  455. * free(val);
  456. * return NULL;
  457. * } else {
  458. * for (; *cp; cp++)
  459. * *cp = toupper(*cp);
  460. * }
  461. * return val;
  462. * }
  463. * }
  464. *
  465. * ...
  466. *
  467. * strmap_foreach(map, upcase_and_remove_empty_vals, NULL);
  468. * \endcode
  469. */
  470. void strmap_foreach(strmap_t *map,
  471. void* (*fn)(const char *key, void *val, void *data),
  472. void *data)
  473. {
  474. strmap_entry_t *ptr, *next;
  475. tor_assert(map);
  476. tor_assert(fn);
  477. for (ptr = SPLAY_MIN(strmap_tree, &map->head); ptr != NULL; ptr = next) {
  478. /* This remove-in-place usage is specifically blessed in tree(3). */
  479. next = SPLAY_NEXT(strmap_tree, &map->head, ptr);
  480. ptr->val = fn(ptr->key, ptr->val, data);
  481. if (!ptr->val) {
  482. SPLAY_REMOVE(strmap_tree, &map->head, ptr);
  483. tor_free(ptr->key);
  484. tor_free(ptr);
  485. }
  486. }
  487. }
  488. /** return an <b>iterator</b> pointer to the front of a map.
  489. *
  490. * Iterator example:
  491. *
  492. * \code
  493. * // uppercase values in "map", removing empty values.
  494. *
  495. * strmap_iter_t *iter;
  496. * const char *key;
  497. * void *val;
  498. * char *cp;
  499. *
  500. * for (iter = strmap_iter_init(map); !strmap_iter_done(iter); ) {
  501. * strmap_iter_get(iter, &key, &val);
  502. * cp = (char*)val;
  503. * if (!*cp) {
  504. * iter = strmap_iter_next_rmv(iter);
  505. * free(val);
  506. * } else {
  507. * for (;*cp;cp++) *cp = toupper(*cp);
  508. * iter = strmap_iter_next(iter);
  509. * }
  510. * }
  511. * \endcode
  512. *
  513. */
  514. strmap_iter_t *strmap_iter_init(strmap_t *map)
  515. {
  516. tor_assert(map);
  517. return SPLAY_MIN(strmap_tree, &map->head);
  518. }
  519. /** Advance the iterator <b>iter</b> for map a single step to the next entry.
  520. */
  521. strmap_iter_t *strmap_iter_next(strmap_t *map, strmap_iter_t *iter)
  522. {
  523. tor_assert(map);
  524. tor_assert(iter);
  525. return SPLAY_NEXT(strmap_tree, &map->head, iter);
  526. }
  527. /** Advance the iterator <b>iter</b> a single step to the next entry, removing
  528. * the current entry.
  529. */
  530. strmap_iter_t *strmap_iter_next_rmv(strmap_t *map, strmap_iter_t *iter)
  531. {
  532. strmap_iter_t *next;
  533. tor_assert(map);
  534. tor_assert(iter);
  535. next = SPLAY_NEXT(strmap_tree, &map->head, iter);
  536. SPLAY_REMOVE(strmap_tree, &map->head, iter);
  537. tor_free(iter->key);
  538. tor_free(iter);
  539. return next;
  540. }
  541. /** Set *keyp and *valp to the current entry pointed to by iter.
  542. */
  543. void strmap_iter_get(strmap_iter_t *iter, const char **keyp, void **valp)
  544. {
  545. tor_assert(iter);
  546. tor_assert(keyp);
  547. tor_assert(valp);
  548. *keyp = iter->key;
  549. *valp = iter->val;
  550. }
  551. /** Return true iff iter has advanced past the last entry of map.
  552. */
  553. int strmap_iter_done(strmap_iter_t *iter)
  554. {
  555. return iter == NULL;
  556. }
  557. /** Remove all entries from <b>map</b>, and deallocate storage for those entries.
  558. * If free_val is provided, it is invoked on every value in <b>map</b>.
  559. */
  560. void
  561. strmap_free(strmap_t *map, void (*free_val)(void*))
  562. {
  563. strmap_entry_t *ent, *next;
  564. for (ent = SPLAY_MIN(strmap_tree, &map->head); ent != NULL; ent = next) {
  565. next = SPLAY_NEXT(strmap_tree, &map->head, ent);
  566. SPLAY_REMOVE(strmap_tree, &map->head, ent);
  567. tor_free(ent->key);
  568. if (free_val)
  569. tor_free(ent->val);
  570. }
  571. tor_assert(SPLAY_EMPTY(&map->head));
  572. tor_free(map);
  573. }
  574. int strmap_isempty(strmap_t *map)
  575. {
  576. return SPLAY_EMPTY(&map->head);
  577. }