ucx/cx/json.h

changeset 1016
ccde46662db7
parent 995
2f811eae2424
--- a/ucx/cx/json.h	Wed Dec 17 18:31:20 2025 +0100
+++ b/ucx/cx/json.h	Thu Dec 18 17:50:15 2025 +0100
@@ -43,8 +43,6 @@
 #include "array_list.h"
 #include "map.h"
 
-#include <string.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -185,10 +183,6 @@
 typedef struct cx_json_value_s CxJsonValue;
 
 /**
- * Type alias for the JSON array struct.
- */
-typedef struct cx_json_array_s CxJsonArray;
-/**
  * Type alias for the map representing a JSON object.
  * The map contains pointers of type @c CxJsonValue.
  */
@@ -211,16 +205,6 @@
 typedef enum cx_json_literal CxJsonLiteral;
 
 /**
- * JSON array structure.
- */
-struct cx_json_array_s {
-    /**
-     * The array data.
-     */
-    CX_ARRAY_DECLARE(CxJsonValue*, data);
-};
-
-/**
  * Structure for a JSON value.
  */
 struct cx_json_value_s {
@@ -243,7 +227,7 @@
         /**
          * The array data if the type is #CX_JSON_ARRAY.
          */
-        CxJsonArray array;
+        CX_ARRAY(CxJsonValue*, array);
         /**
          * The object data if the type is #CX_JSON_OBJECT.
          */
@@ -298,6 +282,7 @@
      * The allocator used for produced JSON values.
      */
     const CxAllocator *allocator;
+
     /**
      * The input buffer.
      */
@@ -327,12 +312,12 @@
     /**
      * State stack.
      */
-    CX_ARRAY_DECLARE_SIZED(int, states, unsigned);
+    CX_ARRAY(int, states);
 
     /**
      * Value buffer stack.
      */
-    CX_ARRAY_DECLARE_SIZED(CxJsonValue*, vbuf, unsigned);
+    CX_ARRAY(CxJsonValue*, vbuf);
 
     /**
      * Internally reserved memory for the state stack.
@@ -477,28 +462,28 @@
 /**
  * Produces a compact string representation of the specified JSON value.
  *
+ * @param allocator the allocator for the string
  * @param value the JSON value
- * @param allocator the allocator for the string
  * @return the produced string
  * @see cxJsonWrite()
  * @see cxJsonWriterCompact()
  * @see cxJsonToPrettyString()
  */
-cx_attr_nonnull_arg(1)
-CX_EXPORT cxmutstr cxJsonToString(CxJsonValue *value, const CxAllocator *allocator);
+cx_attr_nonnull_arg(2)
+CX_EXPORT cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value);
 
 /**
  * Produces a pretty string representation of the specified JSON value.
  *
+ * @param allocator the allocator for the string
  * @param value the JSON value
- * @param allocator the allocator for the string
  * @return the produced string
  * @see cxJsonWrite()
  * @see cxJsonWriterPretty()
  * @see cxJsonToString()
  */
-cx_attr_nonnull_arg(1)
-CX_EXPORT cxmutstr cxJsonToPrettyString(CxJsonValue *value, const CxAllocator *allocator);
+cx_attr_nonnull_arg(2)
+CX_EXPORT cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value);
 
 /**
  * Initializes the JSON interface.
@@ -628,13 +613,16 @@
 /**
  * Creates a new (empty) JSON array.
  *
+ * Optionally, this function already allocates memory with the given capacity.
+ *
  * @param allocator the allocator to use
+ * @param capacity optional capacity or zero if it's unknown how many elements the array will have
  * @return the new JSON array or @c NULL if allocation fails
  * @see cxJsonObjPutArr()
  * @see cxJsonArrAddValues()
  */
 cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator);
+CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity);
 
 /**
  * Creates a new JSON number value.
@@ -840,23 +828,25 @@
  *
  * @param obj the target JSON object
  * @param name the name of the new value
+ * @param capacity optional initial capacity
  * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateArr()
  */
 cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name);
+CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity);
 
 /**
  * Creates a new JSON array and adds it to an object.
  *
  * @param obj (@c CxJsonValue*) the target JSON object
  * @param name (any string) the name of the new value
+ * @param capacity (@c size_t) optional initial capacity
  * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateArr()
  */
-#define cxJsonObjPutArr(obj, name) cx_json_obj_put_arr(obj, cx_strcast(name))
+#define cxJsonObjPutArr(obj, name, capacity) cx_json_obj_put_arr(obj, cx_strcast(name), capacity)
 
 /**
  * Creates a new JSON number and adds it to an object.
@@ -1238,7 +1228,7 @@
  */
 cx_attr_nonnull
 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) {
-    return value->array.data_size;
+    return value->array.size;
 }
 
 /**
@@ -1366,6 +1356,66 @@
  */
 #define cxJsonObjRemove(value, name) cx_json_obj_remove(value, cx_strcast(name))
 
+/**
+ * Performs a deep comparison of two JSON values.
+ *
+ * The order of object members is ignored during comparison.
+ *
+ * @param json the JSON value
+ * @param other the other JSON value that the JSON value is compared to
+ * @retval zero the values are equal (except for ordering of object members)
+ * @retval non-zero the values differ
+ */
+CX_EXPORT int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other);
+
+
+/**
+ * Creates a deep copy of the specified JSON value.
+ *
+ * If you need a @c cx_clone_func compatible version, see cxJsonCloneFunc().
+ *
+ * @note when you are cloning @c NULL, you will get a pointer to a statically
+ * allocated value which represents nothing.
+ *
+ * @param value the value to be cloned
+ * @param allocator the allocator for the new value
+ * @return the new value or @c NULL if any allocation was unsuccessful
+ * @see cxJsonCloneFunc()
+ */
+cx_attr_nodiscard
+CX_EXPORT CxJsonValue* cxJsonClone(const CxJsonValue* value,
+        const CxAllocator* allocator);
+
+
+/**
+ * A @c cx_clone_func compatible version of cxJsonClone().
+ *
+ * Internal function - use cxJsonCloneFunc() to get a properly casted function pointer.
+ *
+ * @param target the target memory or @c NULL
+ * @param source the value to be cloned
+ * @param allocator the allocator for the new value
+ * @param data unused
+ * @return the new value or @c NULL if any allocation was unsuccessful
+ * @see cxJsonClone()
+ */
+cx_attr_nodiscard
+CX_EXPORT CxJsonValue* cx_json_clone_func(
+        CxJsonValue* target, const CxJsonValue* source,
+        const CxAllocator* allocator, void *data);
+
+/**
+ * A @c cx_clone_func compatible version of cxJsonClone().
+ *
+ * @param target (@c CxJsonValue*) the target memory or @c NULL
+ * @param source (@c CxJsonValue*) the value to be cloned
+ * @param allocator (@c CxAllocator*) the allocator for the new value
+ * @param data unused
+ * @return the new value or @c NULL if any allocation was unsuccessful
+ * @see cxJsonClone()
+ */
+#define cxJsonCloneFunc  ((cx_clone_func) cx_json_clone_func)
+
 #ifdef __cplusplus
 }
 #endif

mercurial