add implementation for creating new json values

Wed, 25 Dec 2024 19:33:04 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 25 Dec 2024 19:33:04 +0100
changeset 1054
fb1076ead56f
parent 1053
2e86cf779135
child 1055
221e2e2f2c06

add implementation for creating new json values

relates to #527

src/cx/json.h file | annotate | diff | comparison | revisions
src/json.c file | annotate | diff | comparison | revisions
--- a/src/cx/json.h	Mon Dec 23 18:32:25 2024 +0100
+++ b/src/cx/json.h	Wed Dec 25 19:33:04 2024 +0100
@@ -295,7 +295,9 @@
 };
 
 /**
- * Structure for a parsed token.
+ * Internally used structure for a parsed token.
+ * 
+ * You should never need to use this in your code.
  */
 struct cx_json_token_s {
     /**
@@ -549,6 +551,78 @@
 }
 #endif
 
+cx_attr_nodiscard
+CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
+
+cx_attr_nodiscard
+CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator);
+
+cx_attr_nodiscard
+CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
+
+cx_attr_nodiscard
+CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
+
+cx_attr_nodiscard
+cx_attr_nonnull_arg(2)
+cx_attr_cstr_arg(2)
+CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char *str);
+
+cx_attr_nodiscard
+CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str);
+
+cx_attr_nodiscard
+CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
+
+cx_attr_nonnull
+cx_attr_access_r(2, 3)
+int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
+
+cx_attr_nonnull
+cx_attr_access_r(2, 3)
+int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
+
+cx_attr_nonnull
+cx_attr_access_r(2, 3)
+int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
+
+cx_attr_nonnull
+cx_attr_access_r(2, 3)
+int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
+
+cx_attr_nonnull
+cx_attr_access_r(2, 3)
+int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
+
+cx_attr_nonnull
+cx_attr_access_r(2, 3)
+int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
+
+cx_attr_nonnull
+int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child);
+
+cx_attr_nonnull
+CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name);
+
+cx_attr_nonnull
+CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name);
+
+cx_attr_nonnull
+CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num);
+
+cx_attr_nonnull
+CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num);
+
+cx_attr_nonnull
+cx_attr_cstr_arg(3)
+CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str);
+
+cx_attr_nonnull
+CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str);
+
+cx_attr_nonnull
+CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
+
 /**
  * Recursively deallocates the memory of a JSON value.
  *
--- a/src/json.c	Mon Dec 23 18:32:25 2024 +0100
+++ b/src/json.c	Wed Dec 25 19:33:04 2024 +0100
@@ -665,6 +665,203 @@
     cxFree(value->allocator, value);
 }
 
+CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator) {
+    CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
+    if (v == NULL) return NULL;
+    v->allocator = allocator;
+    v->type = CX_JSON_OBJECT;
+    cx_array_initialize_a(allocator, v->value.object.values, 16);
+    if (v->value.object.values == NULL) { cxFree(allocator, v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator) {
+    CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
+    if (v == NULL) return NULL;
+    v->allocator = allocator;
+    v->type = CX_JSON_ARRAY;
+    cx_array_initialize_a(allocator, v->value.array.array, 16);
+    if (v->value.array.array == NULL) { cxFree(allocator, v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num) {
+    CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
+    if (v == NULL) return NULL;
+    v->allocator = allocator;
+    v->type = CX_JSON_NUMBER;
+    v->value.number = num;
+    return v;
+}
+
+CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num) {
+    CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
+    if (v == NULL) return NULL;
+    v->allocator = allocator;
+    v->type = CX_JSON_INTEGER;
+    v->value.integer = num;
+    return v;
+}
+
+CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char* str) {
+    return cxJsonCreateCxString(allocator, cx_str(str));
+}
+
+CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str) {
+    CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
+    if (v == NULL) return NULL;
+    v->allocator = allocator;
+    v->type = CX_JSON_STRING;
+    cxmutstr s = cx_strdup_a(allocator, str);
+    if (s.ptr == NULL) { cxFree(allocator, v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit) {
+    CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
+    if (v == NULL) return NULL;
+    v->allocator = allocator;
+    v->type = CX_JSON_LITERAL;
+    v->value.literal = lit;
+    return v;
+}
+
+static void cx_json_arr_free_temp(CxJsonValue** values, size_t count) {
+    for (size_t i = 0; i < count; i++) {
+        if (values[i] == NULL) break;
+        cxJsonValueFree(values[i]);
+    }
+    free(values);
+}
+
+int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) {
+    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    if (values == NULL) return -1;
+    for (size_t i = 0; i < count; i++) {
+        values[i] = cxJsonCreateNumber(arr->allocator, num[i]);
+        if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; }
+    }
+    int ret = cxJsonArrAddValues(arr, values, count);
+    free(values);
+    return ret;
+}
+
+int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) {
+    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    if (values == NULL) return -1;
+    for (size_t i = 0; i < count; i++) {
+        values[i] = cxJsonCreateInteger(arr->allocator, num[i]);
+        if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; }
+    }
+    int ret = cxJsonArrAddValues(arr, values, count);
+    free(values);
+    return ret;
+}
+
+int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) {
+    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    if (values == NULL) return -1;
+    for (size_t i = 0; i < count; i++) {
+        values[i] = cxJsonCreateString(arr->allocator, str[i]);
+        if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; }
+    }
+    int ret = cxJsonArrAddValues(arr, values, count);
+    free(values);
+    return ret;
+}
+
+int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) {
+    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    if (values == NULL) return -1;
+    for (size_t i = 0; i < count; i++) {
+        values[i] = cxJsonCreateCxString(arr->allocator, str[i]);
+        if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; }
+    }
+    int ret = cxJsonArrAddValues(arr, values, count);
+    free(values);
+    return ret;
+}
+
+int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) {
+    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    if (values == NULL) return -1;
+    for (size_t i = 0; i < count; i++) {
+        values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]);
+        if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; }
+    }
+    int ret = cxJsonArrAddValues(arr, values, count);
+    free(values);
+    return ret;
+}
+
+int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) {
+    CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL);
+    assert(arr->type == CX_JSON_ARRAY);
+    return cx_array_simple_copy_a(&value_realloc,
+            arr->value.array.array,
+            arr->value.array.array_size,
+            val, count
+    );
+}
+
+int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child) {
+    CxArrayReallocator value_realloc = cx_array_reallocator(obj->allocator, NULL);
+    assert(obj->type == CX_JSON_OBJECT);
+    cxmutstr k = cx_strdup_a(obj->allocator, name);
+    if (k.ptr == NULL) return -1;
+    CxJsonObjValue kv = {k, child};
+    return cx_array_simple_add_a(&value_realloc, obj->value.object.values, kv);
+}
+
+CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name) {
+    CxJsonValue* v = cxJsonCreateObj(obj->allocator);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name) {
+    CxJsonValue* v = cxJsonCreateArr(obj->allocator);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num) {
+    CxJsonValue* v = cxJsonCreateNumber(obj->allocator, num);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num) {
+    CxJsonValue* v = cxJsonCreateInteger(obj->allocator, num);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str) {
+    CxJsonValue* v = cxJsonCreateString(obj->allocator, str);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str) {
+    CxJsonValue* v = cxJsonCreateCxString(obj->allocator, str);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
+    return v;
+}
+
+CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit) {
+    CxJsonValue* v = cxJsonCreateLiteral(obj->allocator, lit);
+    if (v == NULL) return NULL;
+    if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;}
+    return v;
+}
+
 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) {
     if (index >= value->value.array.array_size) {
         return &cx_json_value_nothing;

mercurial