diff options
Diffstat (limited to 'libs/libcurl/src/hash.c')
-rw-r--r-- | libs/libcurl/src/hash.c | 190 |
1 files changed, 72 insertions, 118 deletions
diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c index 4a12e1a7b9..c99b1b6994 100644 --- a/libs/libcurl/src/hash.c +++ b/libs/libcurl/src/hash.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -22,13 +22,12 @@ #include "curl_setup.h" +#include <curl/curl.h> + #include "hash.h" #include "llist.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - #include "curl_memory.h" + /* The last #include file should be: */ #include "memdebug.h" @@ -38,8 +37,6 @@ hash_element_dtor(void *user, void *element) struct curl_hash *h = (struct curl_hash *) user; struct curl_hash_element *e = (struct curl_hash_element *) element; - Curl_safefree(e->key); - if(e->ptr) { h->dtor(e->ptr); e->ptr = NULL; @@ -50,7 +47,12 @@ hash_element_dtor(void *user, void *element) free(e); } -/* return 1 on error, 0 is fine */ +/* Initializes a hash structure. + * Return 1 on error, 0 is fine. + * + * @unittest: 1602 + * @unittest: 1603 + */ int Curl_hash_init(struct curl_hash *h, int slots, @@ -70,92 +72,46 @@ Curl_hash_init(struct curl_hash *h, h->size = 0; h->slots = slots; - h->table = malloc(slots * sizeof(struct curl_llist *)); + h->table = malloc(slots * sizeof(struct curl_llist)); if(h->table) { - for(i = 0; i < slots; ++i) { - h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); - if(!h->table[i]) { - while(i--) { - Curl_llist_destroy(h->table[i], NULL); - h->table[i] = NULL; - } - free(h->table); - h->table = NULL; - h->slots = 0; - return 1; /* failure */ - } - } + for(i = 0; i < slots; ++i) + Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor); return 0; /* fine */ } - else { - h->slots = 0; - return 1; /* failure */ - } -} - -struct curl_hash * -Curl_hash_alloc(int slots, - hash_function hfunc, - comp_function comparator, - curl_hash_dtor dtor) -{ - struct curl_hash *h; - - if(!slots || !hfunc || !comparator ||!dtor) { - return NULL; /* failure */ - } - - h = malloc(sizeof(struct curl_hash)); - if(h) { - if(Curl_hash_init(h, slots, hfunc, comparator, dtor)) { - /* failure */ - free(h); - h = NULL; - } - } - - return h; + h->slots = 0; + return 1; /* failure */ } - - static struct curl_hash_element * mk_hash_element(const void *key, size_t key_len, const void *p) { - struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element)); - + /* allocate the struct plus memory after it to store the key */ + struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) + + key_len); if(he) { - void *dupkey = malloc(key_len); - if(dupkey) { - /* copy the key */ - memcpy(dupkey, key, key_len); - - he->key = dupkey; - he->key_len = key_len; - he->ptr = (void *) p; - } - else { - /* failed to duplicate the key, free memory and fail */ - free(he); - he = NULL; - } + /* copy the key */ + memcpy(he->key, key, key_len); + he->key_len = key_len; + he->ptr = (void *) p; } return he; } -#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)] +#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)] /* Insert the data in the hash. If there already was a match in the hash, * that data is replaced. * * @unittest: 1305 + * @unittest: 1602 + * @unittest: 1603 */ void * Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) { struct curl_hash_element *he; struct curl_llist_element *le; - struct curl_llist *l = FETCH_LIST (h, key, key_len); + struct curl_llist *l = FETCH_LIST(h, key, key_len); for(le = l->head; le; le = le->next) { he = (struct curl_hash_element *) le->ptr; @@ -168,24 +124,19 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) he = mk_hash_element(key, key_len, p); if(he) { - if(Curl_llist_insert_next(l, l->tail, he)) { - ++h->size; - return p; /* return the new entry */ - } - /* - * Couldn't insert it, destroy the 'he' element and the key again. We - * don't call hash_element_dtor() since that would also call the - * "destructor" for the actual data 'p'. When we fail, we shall not touch - * that data. - */ - free(he->key); - free(he); + Curl_llist_insert_next(l, l->tail, he, &he->list); + ++h->size; + return p; /* return the new entry */ } return NULL; /* failure */ } -/* remove the identified hash entry, returns non-zero on failure */ +/* Remove the identified hash entry. + * Returns non-zero on failure. + * + * @unittest: 1603 + */ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) { struct curl_llist_element *le; @@ -203,6 +154,10 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) return 1; } +/* Retrieves a hash element. + * + * @unittest: 1603 + */ void * Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) { @@ -242,14 +197,20 @@ Curl_hash_apply(curl_hash *h, void *user, } #endif +/* Destroys all the entries in the given hash and resets its attributes, + * prepping the given hash for [static|dynamic] deallocation. + * + * @unittest: 1305 + * @unittest: 1602 + * @unittest: 1603 + */ void -Curl_hash_clean(struct curl_hash *h) +Curl_hash_destroy(struct curl_hash *h) { int i; for(i = 0; i < h->slots; ++i) { - Curl_llist_destroy(h->table[i], (void *) h); - h->table[i] = NULL; + Curl_llist_destroy(&h->table[i], (void *) h); } Curl_safefree(h->table); @@ -257,6 +218,17 @@ Curl_hash_clean(struct curl_hash *h) h->slots = 0; } +/* Removes all the entries in the given hash. + * + * @unittest: 1602 + */ +void +Curl_hash_clean(struct curl_hash *h) +{ + Curl_hash_clean_with_criterium(h, NULL, NULL); +} + +/* Cleans all entries that pass the comp function criteria. */ void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, int (*comp)(void *, void *)) @@ -270,13 +242,13 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, return; for(i = 0; i < h->slots; ++i) { - list = h->table[i]; + list = &h->table[i]; le = list->head; /* get first list entry */ while(le) { struct curl_hash_element *he = le->ptr; lnext = le->next; /* ask the callback function if we shall remove this entry or not */ - if(comp(user, he->ptr)) { + if(comp == NULL || comp(user, he->ptr)) { Curl_llist_remove(list, le, (void *) h); --h->size; /* one less entry in the hash now */ } @@ -285,20 +257,9 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, } } -void -Curl_hash_destroy(struct curl_hash *h) +size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num) { - if(!h) - return; - - Curl_hash_clean(h); - - free(h); -} - -size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num) -{ - const char* key_str = (const char *) key; + const char *key_str = (const char *) key; const char *end = key_str + key_length; unsigned long h = 5381; @@ -310,16 +271,11 @@ size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num) return (h % slots_num); } -size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, size_t key2_len) +size_t Curl_str_key_compare(void *k1, size_t key1_len, + void *k2, size_t key2_len) { - char *key1 = (char *)k1; - char *key2 = (char *)k2; - - if(key1_len == key2_len && - *key1 == *key2 && - memcmp(key1, key2, key1_len) == 0) { + if((key1_len == key2_len) && !memcmp(k1, k2, key1_len)) return 1; - } return 0; } @@ -344,10 +300,10 @@ Curl_hash_next_element(struct curl_hash_iterator *iter) /* If we have reached the end of the list, find the next one */ if(!iter->current_element) { - for(i = iter->slot_index;i < h->slots;i++) { - if(h->table[i]->head) { - iter->current_element = h->table[i]->head; - iter->slot_index = i+1; + for(i = iter->slot_index; i < h->slots; i++) { + if(h->table[i].head) { + iter->current_element = h->table[i].head; + iter->slot_index = i + 1; break; } } @@ -357,10 +313,8 @@ Curl_hash_next_element(struct curl_hash_iterator *iter) struct curl_hash_element *he = iter->current_element->ptr; return he; } - else { - iter->current_element = NULL; - return NULL; - } + iter->current_element = NULL; + return NULL; } #if 0 /* useful function for debugging hashes and their contents */ |