src/json.c

changeset 996
333155f234c4
parent 976
d9063c14d3fb
child 1000
1aecddf7e209
--- a/src/json.c	Thu Nov 28 19:37:00 2024 +0100
+++ b/src/json.c	Thu Nov 28 20:53:56 2024 +0100
@@ -266,12 +266,12 @@
     return ret;
 }
 
-static cxmutstr unescape_string(const char *str, size_t len) {
+static cxmutstr unescape_string(const CxAllocator *a, const char *str, size_t len) {
     // TODO: support more escape sequences
     // we know that the unescaped string will be shorter by at least 2 chars
     cxmutstr result;
     result.length = 0;
-    result.ptr = malloc(len - 1);
+    result.ptr = cxMalloc(a, len - 1);
     if (result.ptr == NULL) {
         // TODO: check if this actually leads to correct error handling
         return result;
@@ -437,7 +437,7 @@
             }
             case CX_JSON_TOKEN_STRING: {
                 p->reader_type = CX_JSON_READER_STRING;
-                cxmutstr str = unescape_string(token.content, token.length);
+                cxmutstr str = unescape_string(p->allocator, token.content, token.length);
                 if (str.ptr) {
                     p->value_str = str.ptr;
                     p->value_str_len = str.length;
@@ -487,7 +487,7 @@
             if (token.tokentype != CX_JSON_TOKEN_STRING) return -1;
 
             if (p->value_name) free(p->value_name);
-            cxmutstr valname = unescape_string(token.content, token.length);
+            cxmutstr valname = unescape_string(p->allocator, token.content, token.length);
             p->value_name = valname.ptr;
             p->value_name_len = valname.length;
 
@@ -549,7 +549,8 @@
     if (!parent) {
         return -1; // shouldn't happen but who knows
     }
-
+    
+    CxArrayReallocator reallocator = cx_array_reallocator(p->allocator, NULL);
     if (parent->type == CX_JSON_OBJECT) {
         if (!p->value_name || p->value_name_len == 0) {
             return -1;
@@ -561,9 +562,21 @@
         newvalue.name = valuename;
         newvalue.value = v;
 
-        return cx_array_simple_add(parent->value.object.values, newvalue);
+        return cx_array_add(
+                &parent->value.object.values,
+                &parent->value.object.values_size,
+                &parent->value.object.values_capacity, 
+                sizeof(CxJsonObjValue),
+                &newvalue,
+                &reallocator);
     } else if (parent->type == CX_JSON_ARRAY) {
-        return cx_array_simple_add(parent->value.array.array, v);
+        return cx_array_add(
+                &parent->value.array.array,
+                &parent->value.array.array_size,
+                &parent->value.array.array_capacity, 
+                sizeof(CxJsonValue*),
+                &v,
+                &reallocator);
     } else {
         return -1; // should also never happen
     }
@@ -581,8 +594,13 @@
     return 0;
 }
 
-void cxJsonInit(CxJson *json) {
+void cxJsonInit(const CxAllocator *allocator, CxJson *json) {
+    if (allocator == NULL) {
+        allocator = cxDefaultAllocator;
+    }
+    
     memset(json, 0, sizeof(CxJson));
+    json->allocator = allocator;
     json->states = json->states_internal;
     json->states_alloc = cx_nmemb(json->states_internal);
     // TODO: find better way to configure the initial allocation size for arrays and objects
@@ -618,8 +636,9 @@
     while (p->readvalue_nelm > 0 || !p->read_value) {
         if (p->value_ready) {
             // value available without another read
-            CxJsonValue *v = calloc(1, sizeof(CxJsonValue));
+            CxJsonValue *v = cxCalloc(p->allocator, 1, sizeof(CxJsonValue));
             if (!v) return -1;
+            v->allocator = p->allocator;
 
             if (p->readvalue_nelm > 0) {
                 if (add_to_parent(p, p->readvalue_stack[p->readvalue_nelm - 1], v)) {
@@ -704,15 +723,14 @@
 void cxJsonValueFree(CxJsonValue *value) {
     if (value == NULL || value == &cx_json_value_nothing) return;
 
-    // TODO: discuss if we should keep freeing the stuff recursively
     switch (value->type) {
         case CX_JSON_OBJECT: {
             CxJsonObject obj = value->value.object;
             for (size_t i = 0; i < obj.values_size; i++) {
                 cxJsonValueFree(obj.values[i].value);
-                free(obj.values[i].name);
+                cxFree(value->allocator, obj.values[i].name);
             }
-            free(obj.values);
+            cxFree(value->allocator, obj.values);
             break;
         }
         case CX_JSON_ARRAY: {
@@ -720,18 +738,18 @@
             for (size_t i = 0; i < array.array_size; i++) {
                 cxJsonValueFree(array.array[i]);
             }
-            free(array.array);
+            cxFree(value->allocator, array.array);
             break;
         }
         case CX_JSON_STRING: {
-            free(value->value.string.ptr);
+            cxFree(value->allocator, value->value.string.ptr);
             break;
         }
         default: {
             break;
         }
     }
-    free(value);
+    cxFree(value->allocator, value);
 }
 
 CxJsonValue *cxJsonArrGet(CxJsonValue *value, size_t index) {

mercurial