diff options
-rw-r--r-- | p11-kit/hash.c | 20 | ||||
-rw-r--r-- | tests/hash-test.c | 39 |
2 files changed, 49 insertions, 10 deletions
diff --git a/p11-kit/hash.c b/p11-kit/hash.c index 9be1c32..cfa6bf7 100644 --- a/p11-kit/hash.c +++ b/p11-kit/hash.c @@ -152,6 +152,7 @@ hash_free (hash_t* ht) ht->key_destroy_func (hi.ths->key); if (ht->value_destroy_func) ht->value_destroy_func (hi.ths->val); + free (hi.ths); } if (ht->array) @@ -231,7 +232,7 @@ expand_array (hash_t* ht) */ static hash_entry_t** -find_entry (hash_t* ht, const void* key, void* val) +find_entry (hash_t* ht, const void* key, int create) { hash_entry_t** hep; hash_entry_t* he; @@ -247,7 +248,7 @@ find_entry (hash_t* ht, const void* key, void* val) break; } - if(he || !val) + if(he || !create) return hep; /* add a new entry for non-NULL val */ @@ -257,7 +258,7 @@ find_entry (hash_t* ht, const void* key, void* val) he->key = (void*)key; he->next = NULL; he->hash = hash; - he->val = val; + he->val = NULL; *hep = he; ht->count++; @@ -269,7 +270,7 @@ find_entry (hash_t* ht, const void* key, void* val) void* hash_get (hash_t* ht, const void *key) { - hash_entry_t** he = find_entry (ht, key, NULL); + hash_entry_t** he = find_entry (ht, key, 0); if (he && *he) return (void*)((*he)->val); else @@ -279,8 +280,11 @@ hash_get (hash_t* ht, const void *key) int hash_set (hash_t* ht, void* key, void* val) { - hash_entry_t** hep = find_entry (ht, key, val); + hash_entry_t** hep = find_entry (ht, key, 1); if(hep && *hep) { + if ((*hep)->val && ht->value_destroy_func) + ht->value_destroy_func ((*hep)->val); + /* replace entry */ (*hep)->val = val; @@ -299,7 +303,7 @@ hash_set (hash_t* ht, void* key, void* val) int hash_remove (hash_t* ht, const void* key) { - hash_entry_t** hep = find_entry (ht, key, NULL); + hash_entry_t** hep = find_entry (ht, key, 0); if (hep && *hep) { hash_entry_t* old = *hep; @@ -428,7 +432,7 @@ unsigned int hash_intptr_hash (const void *to_int) { assert (to_int); - return (unsigned int)*((unsigned long*)to_int); + return (unsigned int)*((int*)to_int); } int @@ -436,7 +440,7 @@ hash_intptr_equal (const void *int_one, const void *int_two) { assert (int_one); assert (int_two); - return *((unsigned long*)int_one) == *((unsigned long*)int_two); + return *((int*)int_one) == *((int*)int_two); } unsigned int diff --git a/tests/hash-test.c b/tests/hash-test.c index 2efa5a9..3349c26 100644 --- a/tests/hash-test.c +++ b/tests/hash-test.c @@ -223,6 +223,38 @@ test_hash_remove_destroys (CuTest *tc) } static void +test_hash_set_destroys (CuTest *tc) +{ + hash_t *ht; + int key = 0; + int value = 0; + int value2 = 0; + int ret; + + ht = hash_create (hash_direct_hash, hash_direct_equal, destroy_key, destroy_value); + CuAssertPtrNotNull (tc, ht); + if (!hash_set (ht, &key, &value)) + CuFail (tc, "should not be reached"); + + ret = hash_set (ht, &key, &value2); + CuAssertIntEquals (tc, ret, 1); + CuAssertIntEquals (tc, 0, key); + CuAssertIntEquals (tc, 2, value); + CuAssertIntEquals (tc, 0, value2); + + key = 0; + value = 0; + value2 = 0; + + hash_free (ht); + + CuAssertIntEquals (tc, 1, key); + CuAssertIntEquals (tc, 0, value); + CuAssertIntEquals (tc, 2, value2); +} + + +static void test_hash_clear_destroys (CuTest *tc) { hash_t *ht; @@ -260,7 +292,7 @@ static unsigned int test_hash_intptr_with_collisions (const void *data) { /* lots and lots of collisions, only returns 100 values */ - return (unsigned int)(*((unsigned long*)data) % 100); + return (unsigned int)(*((int*)data) % 100); } static void @@ -330,7 +362,7 @@ test_hash_ulongptr (CuTest *tc) ht = hash_create (hash_ulongptr_hash, hash_ulongptr_equal, NULL, free); for (i = 0; i < 20000; ++i) { - value = malloc (sizeof (int)); + value = malloc (sizeof (unsigned long)); *value = i; if (!hash_set (ht, value, value)) CuFail (tc, "should not be reached"); @@ -357,6 +389,7 @@ main (void) SUITE_ADD_TEST (suite, test_hash_set_get_remove); SUITE_ADD_TEST (suite, test_hash_remove_destroys); SUITE_ADD_TEST (suite, test_hash_set_get_clear); + SUITE_ADD_TEST (suite, test_hash_set_destroys); SUITE_ADD_TEST (suite, test_hash_clear_destroys); SUITE_ADD_TEST (suite, test_hash_free_null); SUITE_ADD_TEST (suite, test_hash_free_destroys); @@ -371,6 +404,8 @@ main (void) printf ("%s\n", output->buffer); ret = suite->failCount; CuSuiteDelete (suite); + CuStringDelete (output); + return ret; } |