1 /*****************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * In order to be useful for every potential user, curl and libcurl are
11 * dual-licensed under the MPL and the MIT/X-derivate licenses.
13 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
14 * copies of the Software, and permit persons to whom the Software is
15 * furnished to do so, under the terms of the MPL or the MIT/X-derivate
16 * licenses. You may pick one of these licenses.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
22 *****************************************************************************/
32 /* this must be the last include file */
38 curl_hash_str(const char *key, unsigned int key_length)
40 register unsigned long h = 0;
41 register unsigned long g;
42 register char *p = (char *) key;
43 register char *end = (char *) key + key_length;
47 if ((g = (h & 0xF0000000))) {
57 curl_hash_num(unsigned long key)
70 hash_element_dtor(void *u, void *ele)
72 curl_hash_element *e = (curl_hash_element *) ele;
73 curl_hash *h = (curl_hash *) u;
75 if (e->key.type == CURL_HASH_KEY_IS_STRING) {
76 free(e->key.value.str.val);
85 curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
93 h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
94 for (i = 0; i < h->slots; ++i) {
95 h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
100 curl_hash_alloc(int slots, curl_hash_dtor dtor)
104 h = (curl_hash *)malloc(sizeof(curl_hash));
108 curl_hash_init(h, slots, dtor);
113 #define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \
114 ((__s_key ? curl_hash_str(__s_key, __s_key_len) : curl_hash_num(__n_key)) % (__h)->slots)
116 #define KEY_CREATE(__k, __s_key, __s_key_len, __n_key, __dup) \
119 (__k)->value.str.val = (char *) malloc(__s_key_len); \
120 memcpy((__k)->value.str.val, __s_key, __s_key_len); \
122 (__k)->value.str.val = __s_key; \
124 (__k)->value.str.len = __s_key_len; \
125 (__k)->type = CURL_HASH_KEY_IS_STRING; \
127 (__k)->value.num = __n_key; \
128 (__k)->type = CURL_HASH_KEY_IS_NUM; \
131 #define MIN(a, b) (a > b ? b : a)
134 curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2)
136 if (key1->type == CURL_HASH_KEY_IS_NUM) {
137 if (key2->type == CURL_HASH_KEY_IS_STRING)
140 if (key1->value.num == key2->value.num)
143 if (key2->type == CURL_HASH_KEY_IS_NUM)
146 if (memcmp(key1->value.str.val, key2->value.str.val,
147 MIN(key1->value.str.len, key2->value.str.len)) == 0)
155 curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len,
156 unsigned long num_key, const void *p)
158 curl_hash_element *e;
161 curl_llist_element *le;
164 slot = FIND_SLOT(h, str_key, str_key_len, num_key);
166 KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
167 for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
168 if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
169 curl_hash_element *to_update = CURL_LLIST_VALP(le);
170 h->dtor(to_update->ptr);
171 to_update->ptr = (void *) p;
176 e = (curl_hash_element *) malloc(sizeof(curl_hash_element));
177 KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1);
180 if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) {
189 curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,
190 unsigned long num_key)
193 curl_llist_element *le;
197 slot = FIND_SLOT(h, str_key, str_key_len, num_key);
200 KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
201 for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
202 if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
203 curl_llist_remove(l, le, (void *) h);
213 curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
214 unsigned long num_key, void **p)
217 curl_llist_element *le;
221 slot = FIND_SLOT(h, str_key, str_key_len, num_key);
224 KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
225 for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
226 if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
227 *p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr;
236 curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *))
238 curl_llist_element *le;
241 for (i = 0; i < h->slots; ++i) {
242 for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) {
243 cb(user, (curl_hash_element *) CURL_LLIST_VALP(le));
249 curl_hash_clean(curl_hash *h)
253 for (i = 0; i < h->slots; ++i) {
254 curl_llist_destroy(h->table[i], (void *) h);
262 curl_hash_count(curl_hash *h)
268 curl_hash_destroy(curl_hash *h)
281 * eval: (load-file "../curl-mode.el")
284 * vim: et sw=2 ts=2 sts=2 tw=78