| 468 |
468 |
| 469 // initialize the value |
469 // initialize the value |
| 470 v->type = type; |
470 v->type = type; |
| 471 v->allocator = json->allocator; |
471 v->allocator = json->allocator; |
| 472 if (type == CX_JSON_ARRAY) { |
472 if (type == CX_JSON_ARRAY) { |
| 473 cx_array_initialize_a(json->allocator, v->array.array, 16); |
473 cx_array_initialize_a(json->allocator, v->array.data, 16); |
| 474 if (v->array.array == NULL) goto create_json_value_exit_error; // LCOV_EXCL_LINE |
474 if (v->array.data == NULL) goto create_json_value_exit_error; // LCOV_EXCL_LINE |
| 475 } else if (type == CX_JSON_OBJECT) { |
475 } else if (type == CX_JSON_OBJECT) { |
| 476 v->object = json_create_object_map(json->allocator); |
476 v->object = json_create_object_map(json->allocator); |
| 477 if (v->object == NULL) goto create_json_value_exit_error; // LCOV_EXCL_LINE |
477 if (v->object == NULL) goto create_json_value_exit_error; // LCOV_EXCL_LINE |
| 478 } |
478 } |
| 479 |
479 |
| 481 if (json->vbuf_size > 0) { |
481 if (json->vbuf_size > 0) { |
| 482 CxJsonValue *parent = json->vbuf[json->vbuf_size - 1]; |
482 CxJsonValue *parent = json->vbuf[json->vbuf_size - 1]; |
| 483 assert(parent != NULL); |
483 assert(parent != NULL); |
| 484 if (parent->type == CX_JSON_ARRAY) { |
484 if (parent->type == CX_JSON_ARRAY) { |
| 485 CxArrayReallocator value_realloc = cx_array_reallocator(json->allocator, NULL); |
485 CxArrayReallocator value_realloc = cx_array_reallocator(json->allocator, NULL); |
| 486 if (cx_array_simple_add_a(&value_realloc, parent->array.array, v)) { |
486 if (cx_array_simple_add_a(&value_realloc, parent->array.data, v)) { |
| 487 goto create_json_value_exit_error; // LCOV_EXCL_LINE |
487 goto create_json_value_exit_error; // LCOV_EXCL_LINE |
| 488 } |
488 } |
| 489 } else if (parent->type == CX_JSON_OBJECT) { |
489 } else if (parent->type == CX_JSON_OBJECT) { |
| 490 // the member was already created after parsing the name |
490 // the member was already created after parsing the name |
| 491 // store the pointer of the uncompleted value in the map |
491 // store the pointer of the uncompleted value in the map |
| 797 json_free_object_map(value->object); |
797 json_free_object_map(value->object); |
| 798 break; |
798 break; |
| 799 } |
799 } |
| 800 case CX_JSON_ARRAY: { |
800 case CX_JSON_ARRAY: { |
| 801 CxJsonArray array = value->array; |
801 CxJsonArray array = value->array; |
| 802 for (size_t i = 0; i < array.array_size; i++) { |
802 for (size_t i = 0; i < array.data_size; i++) { |
| 803 cxJsonValueFree(array.array[i]); |
803 cxJsonValueFree(array.data[i]); |
| 804 } |
804 } |
| 805 cxFree(value->allocator, array.array); |
805 cxFree(value->allocator, array.data); |
| 806 break; |
806 break; |
| 807 } |
807 } |
| 808 case CX_JSON_STRING: { |
808 case CX_JSON_STRING: { |
| 809 cxFree(value->allocator, value->string.ptr); |
809 cxFree(value->allocator, value->string.ptr); |
| 810 break; |
810 break; |
| 835 if (allocator == NULL) allocator = cxDefaultAllocator; |
835 if (allocator == NULL) allocator = cxDefaultAllocator; |
| 836 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
836 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
| 837 if (v == NULL) return NULL; |
837 if (v == NULL) return NULL; |
| 838 v->allocator = allocator; |
838 v->allocator = allocator; |
| 839 v->type = CX_JSON_ARRAY; |
839 v->type = CX_JSON_ARRAY; |
| 840 cx_array_initialize_a(allocator, v->array.array, 16); |
840 cx_array_initialize_a(allocator, v->array.data, 16); |
| 841 if (v->array.array == NULL) { cxFree(allocator, v); return NULL; } |
841 if (v->array.data == NULL) { cxFree(allocator, v); return NULL; } |
| 842 return v; |
842 return v; |
| 843 } |
843 } |
| 844 |
844 |
| 845 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num) { |
845 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num) { |
| 846 if (allocator == NULL) allocator = cxDefaultAllocator; |
846 if (allocator == NULL) allocator = cxDefaultAllocator; |
| 957 |
957 |
| 958 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { |
958 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { |
| 959 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); |
959 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); |
| 960 assert(arr->type == CX_JSON_ARRAY); |
960 assert(arr->type == CX_JSON_ARRAY); |
| 961 return cx_array_simple_copy_a(&value_realloc, |
961 return cx_array_simple_copy_a(&value_realloc, |
| 962 arr->array.array, |
962 arr->array.data, |
| 963 arr->array.array_size, |
963 arr->array.data_size, |
| 964 val, count |
964 val, count |
| 965 ); |
965 ); |
| 966 } |
966 } |
| 967 |
967 |
| 968 int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child) { |
968 int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child) { |
| 1010 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;} |
1010 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;} |
| 1011 return v; |
1011 return v; |
| 1012 } |
1012 } |
| 1013 |
1013 |
| 1014 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) { |
1014 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) { |
| 1015 if (index >= value->array.array_size) { |
1015 if (index >= value->array.data_size) { |
| 1016 return &cx_json_value_nothing; |
1016 return &cx_json_value_nothing; |
| 1017 } |
1017 } |
| 1018 return value->array.array[index]; |
1018 return value->array.data[index]; |
| 1019 } |
1019 } |
| 1020 |
1020 |
| 1021 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index) { |
1021 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index) { |
| 1022 if (index >= value->array.array_size) { |
1022 if (index >= value->array.data_size) { |
| 1023 return NULL; |
1023 return NULL; |
| 1024 } |
1024 } |
| 1025 CxJsonValue *ret = value->array.array[index]; |
1025 CxJsonValue *ret = value->array.data[index]; |
| 1026 // TODO: replace with a low level cx_array_remove() |
1026 // TODO: replace with a low level cx_array_remove() |
| 1027 size_t count = value->array.array_size - index - 1; |
1027 size_t count = value->array.data_size - index - 1; |
| 1028 if (count > 0) { |
1028 if (count > 0) { |
| 1029 memmove(value->array.array + index, value->array.array + index + 1, count * sizeof(CxJsonValue*)); |
1029 memmove(value->array.data + index, value->array.data + index + 1, count * sizeof(CxJsonValue*)); |
| 1030 } |
1030 } |
| 1031 value->array.array_size--; |
1031 value->array.data_size--; |
| 1032 return ret; |
1032 return ret; |
| 1033 } |
1033 } |
| 1034 |
1034 |
| 1035 char *cxJsonAsString(const CxJsonValue *value) { |
1035 char *cxJsonAsString(const CxJsonValue *value) { |
| 1036 return value->string.ptr; |
1036 return value->string.ptr; |
| 1060 } |
1060 } |
| 1061 } |
1061 } |
| 1062 |
1062 |
| 1063 CxIterator cxJsonArrIter(const CxJsonValue *value) { |
1063 CxIterator cxJsonArrIter(const CxJsonValue *value) { |
| 1064 return cxIteratorPtr( |
1064 return cxIteratorPtr( |
| 1065 value->array.array, |
1065 value->array.data, |
| 1066 value->array.array_size, |
1066 value->array.data_size, |
| 1067 true // arrays need to keep order |
1067 true // arrays need to keep order |
| 1068 ); |
1068 ); |
| 1069 } |
1069 } |
| 1070 |
1070 |
| 1071 CxMapIterator cxJsonObjIter(const CxJsonValue *value) { |
1071 CxMapIterator cxJsonObjIter(const CxJsonValue *value) { |