add cxKvListGetKey()

Thu, 25 Sep 2025 14:30:28 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 25 Sep 2025 14:30:28 +0200
changeset 1394
7b23c6db9500
parent 1393
461d256e32c6
child 1395
395ad9f8da44

add cxKvListGetKey()

resolves #461

docs/Writerside/topics/kv_list.h.md file | annotate | diff | comparison | revisions
src/cx/kv_list.h file | annotate | diff | comparison | revisions
src/kv_list.c file | annotate | diff | comparison | revisions
tests/test_kv_list.c file | annotate | diff | comparison | revisions
--- a/docs/Writerside/topics/kv_list.h.md	Wed Sep 24 23:52:36 2025 +0200
+++ b/docs/Writerside/topics/kv_list.h.md	Thu Sep 25 14:30:28 2025 +0200
@@ -58,6 +58,8 @@
 
 int cxKvListRemoveKey(CxList *list, size_t index);
 
+const CxHashKey *cxKvListGetKey(CxList *list, size_t index);
+
 int cxKvListAdd(CxList *list, KeyType key, void *value);
 
 int cxKvListInsert(CxList *list, size_t index,
@@ -73,6 +75,8 @@
 They return zero on success and non-zero on failure.
 A failure can happen when the index is out of bounds or when a memory allocation failed.
 The `cxKvListSetKey()` function also returns non-zero if the key already exists for _another_ element.
+With `cxKvListGetKey()`, you can retrieve the key of an element.
+This function returns `NULL` when an element has no key assigned or the index is out of bounds.
 
 With the `cxKvListAdd()` and `cxKvListInsert()` functions, you can add a new element to the list and immediately assign a key to it.
 The `cxKvListAdd()` function will add the element at the end of the list,
--- a/src/cx/kv_list.h	Wed Sep 24 23:52:36 2025 +0200
+++ b/src/cx/kv_list.h	Thu Sep 25 14:30:28 2025 +0200
@@ -283,6 +283,17 @@
 int cxKvListRemoveKey(CxList *list, size_t index);
 
 /**
+ * Returns the key of a list item.
+ *
+ * @param list the list
+ * @param index the index of the element in the list
+ * @return a pointer to the key or @c NULL when the index is out of bounds or the item does not have a key
+ */
+cx_attr_nonnull
+cx_attr_export
+const CxHashKey *cxKvListGetKey(CxList *list, size_t index);
+
+/**
  * Inserts an item into the list at the specified index and associates it with the specified key.
  *
  * @param list (@c CxList*) the list
--- a/src/kv_list.c	Wed Sep 24 23:52:36 2025 +0200
+++ b/src/kv_list.c	Thu Sep 25 14:30:28 2025 +0200
@@ -649,6 +649,19 @@
     return 0;
 }
 
+const CxHashKey *cxKvListGetKey(CxList *list, size_t index) {
+    cx_kv_list *kv_list = (cx_kv_list*)list;
+    void *node_data = kv_list->list_methods->at(list, index);
+    if (node_data == NULL) {
+        return NULL;
+    }
+    CxHashKey *key = cx_kv_list_loc_key(kv_list, node_data);
+    if (key->hash == 0) {
+        return NULL;
+    }
+    return key;
+}
+
 int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) {
     // assume we are losing the sorted property
     list->collection.sorted = false;
--- a/tests/test_kv_list.c	Wed Sep 24 23:52:36 2025 +0200
+++ b/tests/test_kv_list.c	Thu Sep 25 14:30:28 2025 +0200
@@ -542,6 +542,40 @@
     cxListFree(list);
 }
 
+CX_TEST(test_kv_list_get_key) {
+    CxList *list = cxKvListCreateSimple(sizeof(int));
+    int x;
+    CX_TEST_DO {
+        CxMap *map = cxKvListAsMap(list);
+
+        x = 47;
+        cxMapPut(map, "xyz", &x);
+        x = 11;
+        cxMapPut(map, "abc", &x);
+        x = 1337;
+        cxMapPut(map, "efg", &x);
+        CX_TEST_ASSERT(cxMapSize(map) == 3);
+
+        const CxHashKey *key = cxKvListGetKey(list, 1);
+        int *y = cxMapGet(map, *key);
+        CX_TEST_ASSERT(y != NULL);
+        CX_TEST_ASSERT(*y == 11);
+
+        // removing the element
+        CX_TEST_ASSERT(0 == cxMapRemove(map, cx_strn(key->data, key->len)));
+        key = cxKvListGetKey(list, 1);
+        CX_TEST_ASSERT(0 == cx_strcmp(CX_STR("efg"), cx_strn(key->data, key->len)));
+
+        // remove the key of element
+        CX_TEST_ASSERT(0 == cxKvListRemoveKey(list, 1));
+        CX_TEST_ASSERT(NULL == cxKvListGetKey(list, 1));
+
+        // index out of bounds:
+        CX_TEST_ASSERT(NULL == cxKvListGetKey(list, 3));
+    }
+    cxListFree(list);
+}
+
 CX_TEST(test_kv_list_insert_with_key) {
     CxList *list = cxKvListCreateSimple(sizeof(int));
     int x;
@@ -993,6 +1027,7 @@
     cx_test_register(suite, test_kv_list_set_key_already_exists);
     cx_test_register(suite, test_kv_list_set_key_again);
     cx_test_register(suite, test_kv_list_remove_key);
+    cx_test_register(suite, test_kv_list_get_key);
     cx_test_register(suite, test_kv_list_insert_with_key);
     cx_test_register(suite, test_kv_list_insert_ptr_with_key);
     cx_test_register(suite, test_kv_list_insert_array_and_set_keys);

mercurial