ucx/json.c

branch
dav-2
changeset 886
da79af4baec8
parent 854
1c8401ece69e
child 889
42cdbf9bbd49
--- a/ucx/json.c	Tue Sep 09 16:01:30 2025 +0200
+++ b/ucx/json.c	Tue Sep 09 20:56:47 2025 +0200
@@ -46,22 +46,17 @@
     return cx_strcmp(cx_strcast(left->name), cx_strcast(right->name));
 }
 
-static CxJsonObjValue *json_find_objvalue(const CxJsonValue *obj, cxstring name) {
+static size_t json_find_objvalue(const CxJsonValue *obj, cxstring name) {
     assert(obj->type == CX_JSON_OBJECT);
     CxJsonObjValue kv_dummy;
     kv_dummy.name = cx_mutstrn((char*) name.ptr, name.length);
-    size_t index = cx_array_binary_search(
+    return cx_array_binary_search(
             obj->value.object.values,
             obj->value.object.values_size,
             sizeof(CxJsonObjValue),
             &kv_dummy,
             json_cmp_objvalue
     );
-    if (index == obj->value.object.values_size) {
-        return NULL;
-    } else {
-        return &obj->value.object.values[index];
-    }
 }
 
 static int json_add_objvalue(CxJsonValue *objv, CxJsonObjValue member) {
@@ -500,7 +495,7 @@
 
         if (all_printable && escape) {
             size_t capa = str.length + 32;
-            char *space = malloc(capa);
+            char *space = cxMallocDefault(capa);
             if (space == NULL) return cx_mutstrn(NULL, 0);
             cxBufferInit(&buf, space, capa, NULL, CX_BUFFER_AUTO_EXTEND);
             cxBufferWrite(str.ptr, 1, i, &buf);
@@ -631,10 +626,10 @@
 void cxJsonDestroy(CxJson *json) {
     cxBufferDestroy(&json->buffer);
     if (json->states != json->states_internal) {
-        free(json->states);
+        cxFreeDefault(json->states);
     }
     if (json->vbuf != json->vbuf_internal) {
-        free(json->vbuf);
+        cxFreeDefault(json->vbuf);
     }
     cxJsonValueFree(json->parsed);
     json->parsed = NULL;
@@ -984,67 +979,67 @@
         if (values[i] == NULL) break;
         cxJsonValueFree(values[i]);
     }
-    free(values);
+    cxFreeDefault(values);
 }
 // LCOV_EXCL_STOP
 
 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) {
-    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    CxJsonValue** values = cxCallocDefault(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) { json_arr_free_temp(values, count); return -1; }
     }
     int ret = cxJsonArrAddValues(arr, values, count);
-    free(values);
+    cxFreeDefault(values);
     return ret;
 }
 
 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) {
-    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    CxJsonValue** values = cxCallocDefault(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) { json_arr_free_temp(values, count); return -1; }
     }
     int ret = cxJsonArrAddValues(arr, values, count);
-    free(values);
+    cxFreeDefault(values);
     return ret;
 }
 
 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) {
-    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    CxJsonValue** values = cxCallocDefault(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) { json_arr_free_temp(values, count); return -1; }
     }
     int ret = cxJsonArrAddValues(arr, values, count);
-    free(values);
+    cxFreeDefault(values);
     return ret;
 }
 
 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) {
-    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    CxJsonValue** values = cxCallocDefault(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) { json_arr_free_temp(values, count); return -1; }
     }
     int ret = cxJsonArrAddValues(arr, values, count);
-    free(values);
+    cxFreeDefault(values);
     return ret;
 }
 
 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) {
-    CxJsonValue** values = calloc(count, sizeof(CxJsonValue*));
+    CxJsonValue** values = cxCallocDefault(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) { json_arr_free_temp(values, count); return -1; }
     }
     int ret = cxJsonArrAddValues(arr, values, count);
-    free(values);
+    cxFreeDefault(values);
     return ret;
 }
 
@@ -1126,6 +1121,20 @@
     return value->value.array.array[index];
 }
 
+CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index) {
+    if (index >= value->value.array.array_size) {
+        return NULL;
+    }
+    CxJsonValue *ret = value->value.array.array[index];
+    // TODO: replace with a low level cx_array_remove()
+    size_t count = value->value.array.array_size - index - 1;
+    if (count > 0) {
+        memmove(value->value.array.array + index, value->value.array.array + index + 1, count * sizeof(CxJsonValue*));
+    }
+    value->value.array.array_size--;
+    return ret;
+}
+
 CxIterator cxJsonArrIter(const CxJsonValue *value) {
     return cxIteratorPtr(
         value->value.array.array,
@@ -1142,11 +1151,25 @@
 }
 
 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) {
-    CxJsonObjValue *member = json_find_objvalue(value, name);
-    if (member == NULL) {
+    size_t index = json_find_objvalue(value, name);
+    if (index >= value->value.object.values_size) {
         return &cx_json_value_nothing;
     } else {
-        return member->value;
+        return value->value.object.values[index].value;
+    }
+}
+
+CxJsonValue *cx_json_obj_remove_cxstr(CxJsonValue *value, cxstring name) {
+    size_t index = json_find_objvalue(value, name);
+    if (index >= value->value.object.values_size) {
+        return NULL;
+    } else {
+        CxJsonObjValue kv = value->value.object.values[index];
+        cx_strfree_a(value->allocator, &kv.name);
+        // TODO: replace with cx_array_remove()
+        value->value.object.values_size--;
+        memmove(value->value.object.values + index, value->value.object.values + index + 1, (value->value.object.values_size - index) * sizeof(CxJsonObjValue));
+        return kv.value;
     }
 }
 

mercurial