add cxJsonCompare()

Sat, 13 Dec 2025 13:24:02 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 13 Dec 2025 13:24:02 +0100
changeset 1583
97fc8c55aeea
parent 1582
32b82c424252
child 1584
7a14af59d356

add cxJsonCompare()

resolves #781 except for the tests

CHANGELOG file | annotate | diff | comparison | revisions
docs/Writerside/topics/about.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/json.h.md file | annotate | diff | comparison | revisions
src/json.c file | annotate | diff | comparison | revisions
--- a/CHANGELOG	Sat Dec 13 12:54:56 2025 +0100
+++ b/CHANGELOG	Sat Dec 13 13:24:02 2025 +0100
@@ -3,6 +3,7 @@
 
  * adds cx_system_page_size() to allocator.h
  * adds cxJsonFromString(), cxJsonToString(), and cxJsonToPrettyString()
+ * adds cxJsonCompare()
  * adds cxMapCompare()
  * adds line continuation support to CxProperties / CxPropertiesConfig
  * adds cxBufferMaximumCapacity()
--- a/docs/Writerside/topics/about.md	Sat Dec 13 12:54:56 2025 +0100
+++ b/docs/Writerside/topics/about.md	Sat Dec 13 13:24:02 2025 +0100
@@ -30,6 +30,7 @@
 
 * adds cx_system_page_size() to allocator.h
 * adds cxJsonFromString(), cxJsonToString(), and cxJsonToPrettyString()
+* adds cxJsonCompare()
 * adds cxMapCompare()
 * adds line continuation support to CxProperties / CxPropertiesConfig
 * adds cxBufferMaximumCapacity()
--- a/docs/Writerside/topics/json.h.md	Sat Dec 13 12:54:56 2025 +0100
+++ b/docs/Writerside/topics/json.h.md	Sat Dec 13 13:24:02 2025 +0100
@@ -166,6 +166,19 @@
 > If you don't have full control over the JSON data, you should always check the datatype of a value first before accessing it.
 >{style="note"}
 
+## Compare Values
+
+```C
+#include <cx/json.h>
+
+int cxJsonCompare(const CxJsonValue *value,
+        const CxJsonValue *other);
+```
+
+The function `cxJsonCompare()` performs a deep comparison of two JSON values.
+It returns zero if both values are equal except for the order of object members.
+When the values are not equal, the return-value is an unspecified non-zero value.
+
 ## Deallocate Memory
 
 ```C
--- a/src/json.c	Sat Dec 13 12:54:56 2025 +0100
+++ b/src/json.c	Sat Dec 13 13:24:02 2025 +0100
@@ -453,9 +453,10 @@
 }
 
 static CxJsonObject json_create_object_map(const CxAllocator *allocator) {
-    // TODO: we might want to add a comparator that is sorting the elements by their key
     CxMap *map = cxKvListCreateAsMap(allocator, NULL, CX_STORE_POINTERS);
     if (map == NULL) return NULL; // LCOV_EXCL_LINE
+    // TODO: fix the specification of the compare function
+    map->collection.cmpfunc = (cx_compare_func) cxJsonCompare;
     cxDefineDestructor(map, cxJsonValueFree);
     return map;
 }
@@ -1441,3 +1442,36 @@
     CxJsonWriter writer = cxJsonWriterPretty(true);
     return cx_json_to_string(value, allocator, &writer);
 }
+
+int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other) {
+    if (json == NULL && other == NULL) return 0;
+    if (json == NULL || other == NULL) return -1;
+    if (json->type != other->type) return -1;
+    switch (json->type) {
+        case CX_JSON_NOTHING:
+            return 0;
+        case CX_JSON_OBJECT:
+            return cxMapCompare(json->object, other->object);
+        case CX_JSON_ARRAY:
+            if (json->array.data_size != other->array.data_size) return -1;
+            for (size_t i = 0; i < json->array.data_size; i++) {
+                const int d = cxJsonCompare(json->array.data[i], other->array.data[i]);
+                if (d != 0) return d;
+            }
+            return 0;
+        case CX_JSON_STRING:
+            return cx_strcmp(json->string, other->string);
+        case CX_JSON_INTEGER:
+            return cx_vcmp_int64(json->integer, other->integer);
+        case CX_JSON_NUMBER:
+            return cx_vcmp_double(json->number, other->number);
+        case CX_JSON_LITERAL:
+            return json->literal == other->literal ? 0 : -1;
+        default:
+            // LCOV_EXCL_START
+            // unreachable
+            assert(false);
+            return -1;
+            // LCOV_EXCL_STOP
+    }
+}

mercurial