kv-list: fix support for CX_STORE_POINTERS when using the map interface

Thu, 11 Sep 2025 20:09:33 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 11 Sep 2025 20:09:33 +0200
changeset 1370
607f822c79fe
parent 1369
a9989e16f7df
child 1371
37dcaeebe5ca

kv-list: fix support for CX_STORE_POINTERS when using the map interface

relates to #461

src/kv_list.c file | annotate | diff | comparison | revisions
tests/test_kv_list.c file | annotate | diff | comparison | revisions
--- a/src/kv_list.c	Thu Sep 11 19:59:49 2025 +0200
+++ b/src/kv_list.c	Thu Sep 11 20:09:33 2025 +0200
@@ -238,16 +238,19 @@
     kv_list->list.base.collection.sorted = false;
     // TODO: use the same trick as above to increase the element size temporarily to add the key to the data
     void *node_data = kv_list->list_methods->insert_element(
-        &kv_list->list.base, kv_list->list.base.collection.size, value);
+        &kv_list->list.base, kv_list->list.base.collection.size,
+        kv_list->list.base.collection.store_pointer ? &value : value);
     if (node_data == NULL) return NULL; // LCOV_EXCL_LINE
     // then insert the key into the map, referring to the node data
-    // TODO: check if we still get a correct pointer when the list is storing pointers
     return kv_list->map_methods->put(map, key, node_data);
 }
 
 void *cx_kvl_map_get(const CxMap *map, CxHashKey key) {
     cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
-    return kv_list->map_methods->get(map, key);
+    void *node_data = kv_list->map_methods->get(map, key);
+    if (node_data == NULL) return NULL; // LCOV_EXCL_LINE
+    // return the node data
+    return kv_list->list.base.collection.store_pointer ? *(void**)node_data : node_data;
 }
 
 int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) {
--- a/tests/test_kv_list.c	Thu Sep 11 19:59:49 2025 +0200
+++ b/tests/test_kv_list.c	Thu Sep 11 20:09:33 2025 +0200
@@ -92,6 +92,20 @@
     cxListFree(list);
 }
 
+CX_TEST(test_kv_list_map_put_ptr) {
+    CxList *list = cxKvListCreateSimple(CX_STORE_POINTERS);
+    int x;
+    CX_TEST_DO {
+        CxMap *map = cxKvListAsMap(list);
+        x = 13;
+        CX_TEST_ASSERT(0 == cxMapPut(map, "xyz", &x));
+        x = 37;
+        CX_TEST_ASSERT((int*)cxListAt(list, 0) == &x);
+        CX_TEST_ASSERT((int*)cxMapGet(map, "xyz") == &x);
+    }
+    cxListFree(list);
+}
+
 CX_TEST(test_kv_list_map_remove) {
     CxList *list = cxKvListCreateSimple(sizeof(int));
     int x;
@@ -273,6 +287,21 @@
     cxMapFree(map);
 }
 
+CX_TEST(test_kv_list_destr_ptr) {
+    CxMap *map = cxKvListCreateAsMapSimple(CX_STORE_POINTERS);
+    cxDefineDestructor(map, kv_list_test_destr);
+    int x;
+    CX_TEST_DO {
+        x = 0xabcd;
+        CX_TEST_ASSERT(0 == cxMapPut(map, "xyz", &x));
+        x = 0xef89;
+        kv_list_test_destr_val = 0;
+        CX_TEST_ASSERT(0 == cxMapRemove(map, "xyz"));
+        CX_TEST_ASSERT(kv_list_test_destr_val == 0xef89);
+    }
+    cxMapFree(map);
+}
+
 CxTestSuite *cx_test_suite_kv_list_specifics(void) {
     CxTestSuite *suite = cx_test_suite_new("kv_list specifics");
 
@@ -280,6 +309,7 @@
     cx_test_register(suite, test_kv_list_free_as_map);
     cx_test_register(suite, test_kv_list_free_as_list);
     cx_test_register(suite, test_kv_list_map_put);
+    cx_test_register(suite, test_kv_list_map_put_ptr);
     cx_test_register(suite, test_kv_list_map_remove);
     cx_test_register(suite, test_kv_list_set_key);
     cx_test_register(suite, test_kv_list_list_remove_destr_in_list);
@@ -290,6 +320,7 @@
     cx_test_register(suite, test_kv_list_list_clear_destr_in_map);
     cx_test_register(suite, test_kv_list_map_clear_destr_in_list);
     cx_test_register(suite, test_kv_list_map_clear_destr_in_map);
+    cx_test_register(suite, test_kv_list_destr_ptr);
 
     return suite;
 }

mercurial