/* Insert the data in the hash. If there already was a match in the hash, * that data is replaced. * * @unittest: 1305 */ 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); for(le = l->head; le; le = le->next) { he = (struct curl_hash_element *) le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *)h); --h->size; break; } } 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); } return NULL; /* failure */ }
void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, int (*comp)(void*, void*)) { struct curl_llist_element *le; struct curl_llist_element *lnext; struct curl_llist *list; int i; for (i = 0; i < h->slots; ++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)) { Curl_llist_remove(list, le, (void*) h); --h->size; /* one less entry in the hash now */ } le = lnext; } } }
void Curl_llist_destroy( curl_llist *list, void *user ) { if ( list ) { while ( list->size > 0 ) Curl_llist_remove( list, list->tail, user ); free( list ); } }
/* remove the identified hash entry, returns non-zero on failure */ int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len) { struct curl_llist_element *le; struct curl_hash_element *he; struct curl_llist *l = FETCH_LIST(h, key, key_len); for (le = l->head; le; le = le->next) { he = le->ptr; if (hash_key_compare(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); return 0; } } return 1; }
/* Remove a connection from a bundle */ static int bundle_remove_conn(struct connectbundle *cb_ptr, struct connectdata *conn) { struct curl_llist_element *curr; curr = cb_ptr->conn_list->head; while(curr) { if(curr->ptr == conn) { Curl_llist_remove(cb_ptr->conn_list, curr, NULL); cb_ptr->num_connections--; conn->bundle = NULL; return 1; /* we removed a handle */ } curr = curr->next; } return 0; }
/* altsvc_flush() removes all alternatives for this source origin from the list */ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, const char *srchost, unsigned short srcport) { struct curl_llist_element *e; struct curl_llist_element *n; for(e = asi->list.head; e; e = n) { struct altsvc *as = e->ptr; n = e->next; if((srcalpnid == as->srcalpnid) && (srcport == as->srcport) && strcasecompare(srchost, as->srchost)) { Curl_llist_remove(&asi->list, e, NULL); altsvc_free(as); asi->num--; } } }
int Curl_llist_remove_prev(curl_llist *list, curl_llist_element *e, void *user) { return Curl_llist_remove(list, e->prev, user); }
int Curl_llist_remove_next(curl_llist *list, curl_llist_element *e, void *user) { return Curl_llist_remove(list, e->next, user); }