diff --git a/lib/generic/map.c b/lib/generic/map.c index fcf026b338c753a07161845e12c5860702db256f..73de090a39e09e227ccd431050ba40144afa9f3c 100644 --- a/lib/generic/map.c +++ b/lib/generic/map.c @@ -118,24 +118,8 @@ static cb_data_t *cbt_make_data(map_t *map, const uint8_t *str, size_t len, void return x; } -/*! Creates a new, empty critbit map */ -EXPORT map_t map_make(void) -{ - map_t map; - map.root = NULL; - map.malloc = &malloc_std; - map.free = &free_std; - map.baton = NULL; - return map; -} - -/*! Returns non-zero if map contains str */ -EXPORT int map_contains(map_t *map, const char *str) -{ - return map_get(map, str) != NULL; -} - -EXPORT void *map_get(map_t *map, const char *str) +/*! Like map_contains, but also set the value, if passed and found. */ +static int cbt_get(map_t *map, const char *str, void **value) { const uint8_t *ubytes = (void *)str; const size_t ulen = strlen(str); @@ -143,7 +127,7 @@ EXPORT void *map_get(map_t *map, const char *str) cb_data_t *x = NULL; if (p == NULL) { - return NULL; + return 0; } while (ref_is_internal(p)) { @@ -161,10 +145,37 @@ EXPORT void *map_get(map_t *map, const char *str) x = (cb_data_t *)p; if (strcmp(str, (const char *)x->key) == 0) { - return x->value; + if (value != NULL) { + *value = x->value; + } + return 1; } - return NULL; + return 0; +} + +/*! Creates a new, empty critbit map */ +EXPORT map_t map_make(void) +{ + map_t map; + map.root = NULL; + map.malloc = &malloc_std; + map.free = &free_std; + map.baton = NULL; + return map; +} + +/*! Returns non-zero if map contains str */ +EXPORT int map_contains(map_t *map, const char *str) +{ + return cbt_get(map, str, NULL); +} + +EXPORT void *map_get(map_t *map, const char *str) +{ + void *v = NULL; + cbt_get(map, str, &v); + return v; } /*! Inserts str into map, returns 0 on success */ diff --git a/lib/generic/map.h b/lib/generic/map.h index dc459f5ef9f271c9bff8bb2d1fd426aab16cc10a..9a4c3c08dea61db0089de85f4e73484b3d5a324a 100644 --- a/lib/generic/map.h +++ b/lib/generic/map.h @@ -76,7 +76,7 @@ map_t map_make(void); /** Returns non-zero if map contains str */ int map_contains(map_t *map, const char *str); -/** Returns value if map contains str */ +/** Returns value if map contains str. Note: NULL may mean two different things. */ void *map_get(map_t *map, const char *str); /** Inserts str into map, returns 0 on suceess */ diff --git a/tests/test_map.c b/tests/test_map.c index 6072ee169490103480d4b0d72b247e2f372bf962..baf16e967944f304578ea0cac9aa1acc75f10a4b 100644 --- a/tests/test_map.c +++ b/tests/test_map.c @@ -90,6 +90,17 @@ static void test_delete(void **state) assert_int_equal(map_del(tree, "most likely not in tree"), 1); } +/* Test null value existence */ +static void test_null_value(void **state) +{ + map_t *tree = *state; + char *key = "foo"; + + assert_int_equal(map_set(tree, key, (void *)0), 0); + assert_true(map_contains(tree, key)); + assert_int_equal(map_del(tree, key), 0); +} + static void test_init(void **state) { static map_t tree; @@ -112,8 +123,9 @@ int main(int argc, char **argv) unit_test(test_insert), unit_test(test_get), unit_test(test_delete), + unit_test(test_null_value), group_test_teardown(test_deinit) }; return run_group_tests(tests); -} \ No newline at end of file +}