diff --git a/dse/clib/collections/hashlist.h b/dse/clib/collections/hashlist.h index 841aedd..8e4a044 100644 --- a/dse/clib/collections/hashlist.h +++ b/dse/clib/collections/hashlist.h @@ -6,6 +6,7 @@ #define DSE_CLIB_COLLECTIONS_HASHLIST_H_ #include +#include #include #include #include @@ -52,5 +53,25 @@ static __inline__ void* hashlist_at(HashList* h, uint32_t index) return hashmap_get(&h->hash_map, key); } +static __inline__ void* hashlist_ntl(HashList *h, size_t object_size, bool destroy) +{ + size_t count = hashlist_length(h); + void *object_array = calloc(count + 1, object_size); + + // Copy elements from the HashList to the object array. + for (uint32_t i = 0; i < count; i++) { + void *source_hashlist = hashlist_at(h, i); + if (source_hashlist != NULL) { + memcpy((void *)object_array + i * object_size, &source_hashlist, object_size); + } + } + + // Optionally destroy the original HashList. + if (destroy) { + hashlist_destroy(h); + } + + return object_array; +} #endif // DSE_CLIB_COLLECTIONS_HASHLIST_H_ diff --git a/tests/collections/__test__.c b/tests/collections/__test__.c index 724ed80..45ef67a 100644 --- a/tests/collections/__test__.c +++ b/tests/collections/__test__.c @@ -11,7 +11,7 @@ void test_hash_destroy_ext_mallocd_1(void** state); void test_hash_destroy_ext_with_callback(void** state); void test_set(void** state); void test_hashlist(void** state); - +void test_hashlist_ntl(void** state); int main() { @@ -22,6 +22,7 @@ int main() cmocka_unit_test(test_hash_destroy_ext_with_callback), cmocka_unit_test(test_set), cmocka_unit_test(test_hashlist), + cmocka_unit_test(test_hashlist_ntl), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/collections/test_hashlist.c b/tests/collections/test_hashlist.c index c896ce2..4b39c31 100644 --- a/tests/collections/test_hashlist.c +++ b/tests/collections/test_hashlist.c @@ -26,3 +26,30 @@ void test_hashlist(void** state) hashlist_destroy(&h); assert_int_equal(hashlist_length(&h), 0); } + +void test_hashlist_ntl(void** state) +{ + UNUSED(state); + + HashList h; + hashlist_init(&h, 2); + hashlist_append(&h, (void*)"foo"); + hashlist_append(&h, (void*)"bar"); + + + // Call hashlist_ntl to convert to NTL. + char** converted_array = (char**)hashlist_ntl(&h, sizeof(char*), false); + assert_int_equal(hashlist_length(&h), 2); + assert_string_equal(converted_array[0], "foo"); + assert_string_equal(converted_array[1], "bar"); + assert_null(converted_array[2]); + free(converted_array); + + // Call hashlist_ntl to convert to NTL AND DESTROY. + converted_array = (char**)hashlist_ntl(&h, sizeof(char*), true); + assert_int_equal(hashlist_length(&h), 0); + assert_string_equal(converted_array[0], "foo"); + assert_string_equal(converted_array[1], "bar"); + assert_null(converted_array[2]); + free(converted_array); +}