ucx/json.c

branch
dav-2
changeset 886
da79af4baec8
parent 854
1c8401ece69e
child 889
42cdbf9bbd49
equal deleted inserted replaced
885:591377a27fa3 886:da79af4baec8
44 const CxJsonObjValue *left = l; 44 const CxJsonObjValue *left = l;
45 const CxJsonObjValue *right = r; 45 const CxJsonObjValue *right = r;
46 return cx_strcmp(cx_strcast(left->name), cx_strcast(right->name)); 46 return cx_strcmp(cx_strcast(left->name), cx_strcast(right->name));
47 } 47 }
48 48
49 static CxJsonObjValue *json_find_objvalue(const CxJsonValue *obj, cxstring name) { 49 static size_t json_find_objvalue(const CxJsonValue *obj, cxstring name) {
50 assert(obj->type == CX_JSON_OBJECT); 50 assert(obj->type == CX_JSON_OBJECT);
51 CxJsonObjValue kv_dummy; 51 CxJsonObjValue kv_dummy;
52 kv_dummy.name = cx_mutstrn((char*) name.ptr, name.length); 52 kv_dummy.name = cx_mutstrn((char*) name.ptr, name.length);
53 size_t index = cx_array_binary_search( 53 return cx_array_binary_search(
54 obj->value.object.values, 54 obj->value.object.values,
55 obj->value.object.values_size, 55 obj->value.object.values_size,
56 sizeof(CxJsonObjValue), 56 sizeof(CxJsonObjValue),
57 &kv_dummy, 57 &kv_dummy,
58 json_cmp_objvalue 58 json_cmp_objvalue
59 ); 59 );
60 if (index == obj->value.object.values_size) {
61 return NULL;
62 } else {
63 return &obj->value.object.values[index];
64 }
65 } 60 }
66 61
67 static int json_add_objvalue(CxJsonValue *objv, CxJsonObjValue member) { 62 static int json_add_objvalue(CxJsonValue *objv, CxJsonObjValue member) {
68 assert(objv->type == CX_JSON_OBJECT); 63 assert(objv->type == CX_JSON_OBJECT);
69 const CxAllocator * const al = objv->allocator; 64 const CxAllocator * const al = objv->allocator;
498 bool escape = c < 0x20 || c == '\\' || c == '"' 493 bool escape = c < 0x20 || c == '\\' || c == '"'
499 || (escape_slash && c == '/'); 494 || (escape_slash && c == '/');
500 495
501 if (all_printable && escape) { 496 if (all_printable && escape) {
502 size_t capa = str.length + 32; 497 size_t capa = str.length + 32;
503 char *space = malloc(capa); 498 char *space = cxMallocDefault(capa);
504 if (space == NULL) return cx_mutstrn(NULL, 0); 499 if (space == NULL) return cx_mutstrn(NULL, 0);
505 cxBufferInit(&buf, space, capa, NULL, CX_BUFFER_AUTO_EXTEND); 500 cxBufferInit(&buf, space, capa, NULL, CX_BUFFER_AUTO_EXTEND);
506 cxBufferWrite(str.ptr, 1, i, &buf); 501 cxBufferWrite(str.ptr, 1, i, &buf);
507 all_printable = false; 502 all_printable = false;
508 } 503 }
629 } 624 }
630 625
631 void cxJsonDestroy(CxJson *json) { 626 void cxJsonDestroy(CxJson *json) {
632 cxBufferDestroy(&json->buffer); 627 cxBufferDestroy(&json->buffer);
633 if (json->states != json->states_internal) { 628 if (json->states != json->states_internal) {
634 free(json->states); 629 cxFreeDefault(json->states);
635 } 630 }
636 if (json->vbuf != json->vbuf_internal) { 631 if (json->vbuf != json->vbuf_internal) {
637 free(json->vbuf); 632 cxFreeDefault(json->vbuf);
638 } 633 }
639 cxJsonValueFree(json->parsed); 634 cxJsonValueFree(json->parsed);
640 json->parsed = NULL; 635 json->parsed = NULL;
641 if (json->uncompleted_member.name.ptr != NULL) { 636 if (json->uncompleted_member.name.ptr != NULL) {
642 cx_strfree_a(json->allocator, &json->uncompleted_member.name); 637 cx_strfree_a(json->allocator, &json->uncompleted_member.name);
982 static void json_arr_free_temp(CxJsonValue** values, size_t count) { 977 static void json_arr_free_temp(CxJsonValue** values, size_t count) {
983 for (size_t i = 0; i < count; i++) { 978 for (size_t i = 0; i < count; i++) {
984 if (values[i] == NULL) break; 979 if (values[i] == NULL) break;
985 cxJsonValueFree(values[i]); 980 cxJsonValueFree(values[i]);
986 } 981 }
987 free(values); 982 cxFreeDefault(values);
988 } 983 }
989 // LCOV_EXCL_STOP 984 // LCOV_EXCL_STOP
990 985
991 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) { 986 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) {
992 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); 987 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
993 if (values == NULL) return -1; 988 if (values == NULL) return -1;
994 for (size_t i = 0; i < count; i++) { 989 for (size_t i = 0; i < count; i++) {
995 values[i] = cxJsonCreateNumber(arr->allocator, num[i]); 990 values[i] = cxJsonCreateNumber(arr->allocator, num[i]);
996 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } 991 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
997 } 992 }
998 int ret = cxJsonArrAddValues(arr, values, count); 993 int ret = cxJsonArrAddValues(arr, values, count);
999 free(values); 994 cxFreeDefault(values);
1000 return ret; 995 return ret;
1001 } 996 }
1002 997
1003 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) { 998 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) {
1004 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); 999 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
1005 if (values == NULL) return -1; 1000 if (values == NULL) return -1;
1006 for (size_t i = 0; i < count; i++) { 1001 for (size_t i = 0; i < count; i++) {
1007 values[i] = cxJsonCreateInteger(arr->allocator, num[i]); 1002 values[i] = cxJsonCreateInteger(arr->allocator, num[i]);
1008 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } 1003 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
1009 } 1004 }
1010 int ret = cxJsonArrAddValues(arr, values, count); 1005 int ret = cxJsonArrAddValues(arr, values, count);
1011 free(values); 1006 cxFreeDefault(values);
1012 return ret; 1007 return ret;
1013 } 1008 }
1014 1009
1015 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) { 1010 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) {
1016 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); 1011 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
1017 if (values == NULL) return -1; 1012 if (values == NULL) return -1;
1018 for (size_t i = 0; i < count; i++) { 1013 for (size_t i = 0; i < count; i++) {
1019 values[i] = cxJsonCreateString(arr->allocator, str[i]); 1014 values[i] = cxJsonCreateString(arr->allocator, str[i]);
1020 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } 1015 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
1021 } 1016 }
1022 int ret = cxJsonArrAddValues(arr, values, count); 1017 int ret = cxJsonArrAddValues(arr, values, count);
1023 free(values); 1018 cxFreeDefault(values);
1024 return ret; 1019 return ret;
1025 } 1020 }
1026 1021
1027 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) { 1022 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) {
1028 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); 1023 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
1029 if (values == NULL) return -1; 1024 if (values == NULL) return -1;
1030 for (size_t i = 0; i < count; i++) { 1025 for (size_t i = 0; i < count; i++) {
1031 values[i] = cxJsonCreateCxString(arr->allocator, str[i]); 1026 values[i] = cxJsonCreateCxString(arr->allocator, str[i]);
1032 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } 1027 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
1033 } 1028 }
1034 int ret = cxJsonArrAddValues(arr, values, count); 1029 int ret = cxJsonArrAddValues(arr, values, count);
1035 free(values); 1030 cxFreeDefault(values);
1036 return ret; 1031 return ret;
1037 } 1032 }
1038 1033
1039 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) { 1034 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) {
1040 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); 1035 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
1041 if (values == NULL) return -1; 1036 if (values == NULL) return -1;
1042 for (size_t i = 0; i < count; i++) { 1037 for (size_t i = 0; i < count; i++) {
1043 values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]); 1038 values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]);
1044 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } 1039 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
1045 } 1040 }
1046 int ret = cxJsonArrAddValues(arr, values, count); 1041 int ret = cxJsonArrAddValues(arr, values, count);
1047 free(values); 1042 cxFreeDefault(values);
1048 return ret; 1043 return ret;
1049 } 1044 }
1050 1045
1051 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { 1046 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) {
1052 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); 1047 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL);
1124 return &cx_json_value_nothing; 1119 return &cx_json_value_nothing;
1125 } 1120 }
1126 return value->value.array.array[index]; 1121 return value->value.array.array[index];
1127 } 1122 }
1128 1123
1124 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index) {
1125 if (index >= value->value.array.array_size) {
1126 return NULL;
1127 }
1128 CxJsonValue *ret = value->value.array.array[index];
1129 // TODO: replace with a low level cx_array_remove()
1130 size_t count = value->value.array.array_size - index - 1;
1131 if (count > 0) {
1132 memmove(value->value.array.array + index, value->value.array.array + index + 1, count * sizeof(CxJsonValue*));
1133 }
1134 value->value.array.array_size--;
1135 return ret;
1136 }
1137
1129 CxIterator cxJsonArrIter(const CxJsonValue *value) { 1138 CxIterator cxJsonArrIter(const CxJsonValue *value) {
1130 return cxIteratorPtr( 1139 return cxIteratorPtr(
1131 value->value.array.array, 1140 value->value.array.array,
1132 value->value.array.array_size 1141 value->value.array.array_size
1133 ); 1142 );
1140 value->value.object.values_size 1149 value->value.object.values_size
1141 ); 1150 );
1142 } 1151 }
1143 1152
1144 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) { 1153 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) {
1145 CxJsonObjValue *member = json_find_objvalue(value, name); 1154 size_t index = json_find_objvalue(value, name);
1146 if (member == NULL) { 1155 if (index >= value->value.object.values_size) {
1147 return &cx_json_value_nothing; 1156 return &cx_json_value_nothing;
1148 } else { 1157 } else {
1149 return member->value; 1158 return value->value.object.values[index].value;
1159 }
1160 }
1161
1162 CxJsonValue *cx_json_obj_remove_cxstr(CxJsonValue *value, cxstring name) {
1163 size_t index = json_find_objvalue(value, name);
1164 if (index >= value->value.object.values_size) {
1165 return NULL;
1166 } else {
1167 CxJsonObjValue kv = value->value.object.values[index];
1168 cx_strfree_a(value->allocator, &kv.name);
1169 // TODO: replace with cx_array_remove()
1170 value->value.object.values_size--;
1171 memmove(value->value.object.values + index, value->value.object.values + index + 1, (value->value.object.values_size - index) * sizeof(CxJsonObjValue));
1172 return kv.value;
1150 } 1173 }
1151 } 1174 }
1152 1175
1153 CxJsonWriter cxJsonWriterCompact(void) { 1176 CxJsonWriter cxJsonWriterCompact(void) {
1154 return (CxJsonWriter) { 1177 return (CxJsonWriter) {

mercurial