src/json.c

changeset 1513
4d641c6a2f82
parent 1429
6e0c3a8a914a
equal deleted inserted replaced
1512:0dc866c7863b 1513:4d641c6a2f82
92 92
93 // check the new capacity, if we need to realloc the index array 93 // check the new capacity, if we need to realloc the index array
94 size_t newcap = obj->values_capacity; 94 size_t newcap = obj->values_capacity;
95 if (newcap > oldcap) { 95 if (newcap > oldcap) {
96 if (cxReallocateArray(al, &obj->indices, newcap, sizeof(size_t))) { 96 if (cxReallocateArray(al, &obj->indices, newcap, sizeof(size_t))) {
97 return 1; 97 return 1; // LCOV_EXCL_LINE
98 } 98 }
99 } 99 }
100 100
101 // check if append or insert 101 // check if append or insert
102 if (index < obj->values_size) { 102 if (index < obj->values_size) {
435 } else if (c == 'b') { 435 } else if (c == 'b') {
436 c = '\b'; 436 c = '\b';
437 } else if (c == 'u') { 437 } else if (c == 'u') {
438 char utf8buf[4]; 438 char utf8buf[4];
439 unsigned utf8len = unescape_unicode_string( 439 unsigned utf8len = unescape_unicode_string(
440 cx_strn(str.ptr + i - 1, str.length + 1 - i), 440 cx_strn(str.ptr + i - 1, str.length - i),
441 utf8buf 441 utf8buf
442 ); 442 );
443 if(utf8len > 0) { 443 if(utf8len > 0) {
444 i += utf8len < 4 ? 4 : 10; 444 i += utf8len < 4 ? 4 : 10;
445 // add all bytes from utf8buf except the last char 445 // add all bytes from utf8buf except the last char
454 result.ptr[result.length++] = '\\'; 454 result.ptr[result.length++] = '\\';
455 } 455 }
456 } else { 456 } else {
457 // TODO: discuss the behavior for unrecognized escape sequences 457 // TODO: discuss the behavior for unrecognized escape sequences
458 // most parsers throw an error here - we just ignore it 458 // most parsers throw an error here - we just ignore it
459 result.ptr[result.length++] = '\\'; 459 result.ptr[result.length++] = '\\'; // LCOV_EXCL_LINE
460 } 460 }
461 461
462 result.ptr[result.length++] = c; 462 result.ptr[result.length++] = c;
463 } else { 463 } else {
464 if (c == '\\') { 464 if (c == '\\') {
638 638
639 int cxJsonFilln(CxJson *json, const char *buf, size_t size) { 639 int cxJsonFilln(CxJson *json, const char *buf, size_t size) {
640 if (cxBufferEof(&json->buffer)) { 640 if (cxBufferEof(&json->buffer)) {
641 // reinitialize the buffer 641 // reinitialize the buffer
642 cxBufferDestroy(&json->buffer); 642 cxBufferDestroy(&json->buffer);
643 if (buf == NULL) buf = ""; // buffer must not be initialized with NULL
643 cxBufferInit(&json->buffer, (char*) buf, size, 644 cxBufferInit(&json->buffer, (char*) buf, size,
644 NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_COPY_ON_WRITE); 645 NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_COPY_ON_WRITE);
645 json->buffer.size = size; 646 json->buffer.size = size;
646 return 0; 647 return 0;
647 } else { 648 } else {
732 if (cx_strtoi64(token.content, &vbuf->value.integer, 10)) { 733 if (cx_strtoi64(token.content, &vbuf->value.integer, 10)) {
733 return_rec(CX_JSON_FORMAT_ERROR_NUMBER); 734 return_rec(CX_JSON_FORMAT_ERROR_NUMBER);
734 } 735 }
735 } else { 736 } else {
736 if (cx_strtod(token.content, &vbuf->value.number)) { 737 if (cx_strtod(token.content, &vbuf->value.number)) {
737 return_rec(CX_JSON_FORMAT_ERROR_NUMBER); 738 // TODO: at the moment this is unreachable, because the tokenizer is already stricter than cx_strtod()
739 return_rec(CX_JSON_FORMAT_ERROR_NUMBER); // LCOV_EXCL_LINE
738 } 740 }
739 } 741 }
740 return_rec(CX_JSON_NO_ERROR); 742 return_rec(CX_JSON_NO_ERROR);
741 } 743 }
742 case CX_JSON_TOKEN_LITERAL: { 744 case CX_JSON_TOKEN_LITERAL: {
813 return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); 815 return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN);
814 } 816 }
815 } else { 817 } else {
816 // should be unreachable 818 // should be unreachable
817 assert(false); 819 assert(false);
818 return_rec(-1); 820 return_rec(-1); // LCOV_EXCL_LINE
819 } 821 }
820 } 822 }
821 823
822 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value) { 824 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value) {
823 // check if buffer has been filled 825 // initialize output value
826 *value = &cx_json_value_nothing;
827
828 // check if the buffer has been filled
824 if (json->buffer.space == NULL) { 829 if (json->buffer.space == NULL) {
825 return CX_JSON_NULL_DATA; 830 return CX_JSON_NULL_DATA;
826 } 831 }
827
828 // initialize output value
829 *value = &cx_json_value_nothing;
830 832
831 // parse data 833 // parse data
832 CxJsonStatus result; 834 CxJsonStatus result;
833 do { 835 do {
834 result = json_parse(json); 836 result = json_parse(json);
941 v->type = CX_JSON_INTEGER; 943 v->type = CX_JSON_INTEGER;
942 v->value.integer = num; 944 v->value.integer = num;
943 return v; 945 return v;
944 } 946 }
945 947
946 CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char* str) { 948 CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str) {
947 return cxJsonCreateCxString(allocator, cx_str(str));
948 }
949
950 CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str) {
951 if (allocator == NULL) allocator = cxDefaultAllocator; 949 if (allocator == NULL) allocator = cxDefaultAllocator;
952 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); 950 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue));
953 if (v == NULL) return NULL; 951 if (v == NULL) return NULL;
954 v->allocator = allocator; 952 v->allocator = allocator;
955 v->type = CX_JSON_STRING; 953 v->type = CX_JSON_STRING;
1018 1016
1019 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) { 1017 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) {
1020 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); 1018 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*));
1021 if (values == NULL) return -1; 1019 if (values == NULL) return -1;
1022 for (size_t i = 0; i < count; i++) { 1020 for (size_t i = 0; i < count; i++) {
1023 values[i] = cxJsonCreateCxString(arr->allocator, str[i]); 1021 values[i] = cxJsonCreateString(arr->allocator, str[i]);
1024 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } 1022 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; }
1025 } 1023 }
1026 int ret = cxJsonArrAddValues(arr, values, count); 1024 int ret = cxJsonArrAddValues(arr, values, count);
1027 cxFreeDefault(values); 1025 cxFreeDefault(values);
1028 return ret; 1026 return ret;
1048 arr->value.array.array_size, 1046 arr->value.array.array_size,
1049 val, count 1047 val, count
1050 ); 1048 );
1051 } 1049 }
1052 1050
1053 int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child) { 1051 int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child) {
1054 cxmutstr k = cx_strdup_a(obj->allocator, name); 1052 cxmutstr k = cx_strdup_a(obj->allocator, name);
1055 if (k.ptr == NULL) return -1; 1053 if (k.ptr == NULL) return -1;
1056 CxJsonObjValue kv = {k, child}; 1054 CxJsonObjValue kv = {k, child};
1057 if (json_add_objvalue(obj, kv)) { 1055 if (json_add_objvalue(obj, kv)) {
1056 // LCOV_EXCL_START
1058 cx_strfree_a(obj->allocator, &k); 1057 cx_strfree_a(obj->allocator, &k);
1059 return 1; 1058 return 1;
1059 // LCOV_EXCL_STOP
1060 } else { 1060 } else {
1061 return 0; 1061 return 0;
1062 } 1062 }
1063 } 1063 }
1064 1064
1065 CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name) { 1065 CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name) {
1066 CxJsonValue* v = cxJsonCreateObj(obj->allocator); 1066 CxJsonValue* v = cxJsonCreateObj(obj->allocator);
1067 if (v == NULL) return NULL; 1067 if (v == NULL) return NULL;
1068 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } 1068 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
1069 return v; 1069 return v;
1070 } 1070 }
1071 1071
1072 CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name) { 1072 CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name) {
1073 CxJsonValue* v = cxJsonCreateArr(obj->allocator); 1073 CxJsonValue* v = cxJsonCreateArr(obj->allocator);
1074 if (v == NULL) return NULL; 1074 if (v == NULL) return NULL;
1075 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } 1075 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
1076 return v; 1076 return v;
1077 } 1077 }
1078 1078
1079 CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num) { 1079 CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num) {
1080 CxJsonValue* v = cxJsonCreateNumber(obj->allocator, num); 1080 CxJsonValue* v = cxJsonCreateNumber(obj->allocator, num);
1081 if (v == NULL) return NULL; 1081 if (v == NULL) return NULL;
1082 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } 1082 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
1083 return v; 1083 return v;
1084 } 1084 }
1085 1085
1086 CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num) { 1086 CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num) {
1087 CxJsonValue* v = cxJsonCreateInteger(obj->allocator, num); 1087 CxJsonValue* v = cxJsonCreateInteger(obj->allocator, num);
1088 if (v == NULL) return NULL; 1088 if (v == NULL) return NULL;
1089 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } 1089 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
1090 return v; 1090 return v;
1091 } 1091 }
1092 1092
1093 CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str) { 1093 CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str) {
1094 CxJsonValue* v = cxJsonCreateString(obj->allocator, str); 1094 CxJsonValue* v = cxJsonCreateString(obj->allocator, str);
1095 if (v == NULL) return NULL; 1095 if (v == NULL) return NULL;
1096 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } 1096 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
1097 return v; 1097 return v;
1098 } 1098 }
1099 1099
1100 CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str) { 1100 CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit) {
1101 CxJsonValue* v = cxJsonCreateCxString(obj->allocator, str);
1102 if (v == NULL) return NULL;
1103 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; }
1104 return v;
1105 }
1106
1107 CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit) {
1108 CxJsonValue* v = cxJsonCreateLiteral(obj->allocator, lit); 1101 CxJsonValue* v = cxJsonCreateLiteral(obj->allocator, lit);
1109 if (v == NULL) return NULL; 1102 if (v == NULL) return NULL;
1110 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;} 1103 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;}
1111 return v; 1104 return v;
1112 } 1105 }
1284 // get the member either via index array or directly 1277 // get the member either via index array or directly
1285 size_t elem_idx = settings->sort_members 1278 size_t elem_idx = settings->sort_members
1286 ? look_idx 1279 ? look_idx
1287 : value->value.object.indices[look_idx]; 1280 : value->value.object.indices[look_idx];
1288 CxJsonObjValue *member = &value->value.object.values[elem_idx]; 1281 CxJsonObjValue *member = &value->value.object.values[elem_idx];
1289 if (settings->sort_members) {
1290 depth++;depth--;
1291 }
1292 1282
1293 // possible indentation 1283 // possible indentation
1294 if (settings->pretty) { 1284 if (settings->pretty) {
1295 if (cx_json_writer_indent(target, wfunc, settings, depth)) { 1285 if (cx_json_writer_indent(target, wfunc, settings, depth)) {
1296 return 1; // LCOV_EXCL_LINE 1286 return 1; // LCOV_EXCL_LINE
1348 CxIterator iter = cxJsonArrIter(value); 1338 CxIterator iter = cxJsonArrIter(value);
1349 cx_foreach(CxJsonValue*, element, iter) { 1339 cx_foreach(CxJsonValue*, element, iter) {
1350 if (cx_json_write_rec( 1340 if (cx_json_write_rec(
1351 target, element, 1341 target, element,
1352 wfunc, settings, depth) 1342 wfunc, settings, depth)
1353 ) return 1; 1343 ) {
1344 return 1; // LCOV_EXCL_LINE
1345 }
1354 1346
1355 if (iter.index < iter.elem_count - 1) { 1347 if (iter.index < iter.elem_count - 1) {
1356 const char *arr_value_sep = ", "; 1348 const char *arr_value_sep = ", ";
1357 if (settings->pretty) { 1349 if (settings->pretty) {
1358 actual += wfunc(arr_value_sep, 1, 2, target); 1350 actual += wfunc(arr_value_sep, 1, 2, target);

mercurial