Fri, 23 May 2025 12:44:24 +0200
make test-compile depend on both static and shared
the shared lib is not needed for the tests,
but when run with coverage, gcov will be confused
when outdated line information is available from
a previous shared build
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1 | /* |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
3 | * |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
4 | * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
5 | * |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
8 | * |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
11 | * |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
15 | * |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
27 | */ |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
28 | |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1037
diff
changeset
|
29 | #include "cx/json.h" |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1037
diff
changeset
|
30 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
31 | #include <string.h> |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
32 | #include <assert.h> |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
33 | #include <stdio.h> |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
34 | #include <inttypes.h> |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
35 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
36 | /* |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
37 | * RFC 8259 |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
38 | * https://tools.ietf.org/html/rfc8259 |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
39 | */ |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
40 | |
944
c26299cc9897
make both gcc and clang happy with how cx_json_value_nothing is initialized
Mike Becker <universe@uap-core.de>
parents:
943
diff
changeset
|
41 | static CxJsonValue cx_json_value_nothing = {.type = CX_JSON_NOTHING}; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
42 | |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
43 | static int json_cmp_objvalue(const void *l, const void *r) { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
44 | const CxJsonObjValue *left = l; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
45 | const CxJsonObjValue *right = r; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
46 | return cx_strcmp(cx_strcast(left->name), cx_strcast(right->name)); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
47 | } |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
48 | |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
49 | static CxJsonObjValue *json_find_objvalue(const CxJsonValue *obj, cxstring name) { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
50 | assert(obj->type == CX_JSON_OBJECT); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
51 | CxJsonObjValue kv_dummy; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
52 | kv_dummy.name = cx_mutstrn((char*) name.ptr, name.length); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
53 | size_t index = cx_array_binary_search( |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
54 | obj->value.object.values, |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
55 | obj->value.object.values_size, |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
56 | sizeof(CxJsonObjValue), |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
57 | &kv_dummy, |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
58 | json_cmp_objvalue |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
59 | ); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
60 | if (index == obj->value.object.values_size) { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
61 | return NULL; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
62 | } else { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
63 | return &obj->value.object.values[index]; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
64 | } |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
65 | } |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
66 | |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
67 | static int json_add_objvalue(CxJsonValue *objv, CxJsonObjValue member) { |
1083 | 68 | assert(objv->type == CX_JSON_OBJECT); |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
69 | const CxAllocator * const al = objv->allocator; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
70 | CxJsonObject *obj = &(objv->value.object); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
71 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
72 | // determine the index where we need to insert the new member |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
73 | size_t index = cx_array_binary_search_sup( |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
74 | obj->values, |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
75 | obj->values_size, |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
76 | sizeof(CxJsonObjValue), |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
77 | &member, json_cmp_objvalue |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
78 | ); |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
79 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
80 | // is the name already present? |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
81 | if (index < obj->values_size && 0 == json_cmp_objvalue(&member, &obj->values[index])) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
82 | // free the original value |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
83 | cx_strfree_a(al, &obj->values[index].name); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
84 | cxJsonValueFree(obj->values[index].value); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
85 | // replace the item |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
86 | obj->values[index] = member; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
87 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
88 | // nothing more to do |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
89 | return 0; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
90 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
91 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
92 | // determine the old capacity and reserve for one more element |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
93 | CxArrayReallocator arealloc = cx_array_reallocator(al, NULL); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
94 | size_t oldcap = obj->values_capacity; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
95 | if (cx_array_simple_reserve_a(&arealloc, obj->values, 1)) return 1; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
96 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
97 | // check the new capacity, if we need to realloc the index array |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
98 | size_t newcap = obj->values_capacity; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
99 | if (newcap > oldcap) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
100 | if (cxReallocateArray(al, &obj->indices, newcap, sizeof(size_t))) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
101 | return 1; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
102 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
103 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
104 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
105 | // check if append or insert |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
106 | if (index < obj->values_size) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
107 | // move the other elements |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
108 | memmove( |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
109 | &obj->values[index+1], |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
110 | &obj->values[index], |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
111 | (obj->values_size - index) * sizeof(CxJsonObjValue) |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
112 | ); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
113 | // increase indices for the moved elements |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
114 | for (size_t i = 0; i < obj->values_size ; i++) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
115 | if (obj->indices[i] >= index) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
116 | obj->indices[i]++; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
117 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
118 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
119 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
120 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
121 | // insert the element and set the index |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
122 | obj->values[index] = member; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
123 | obj->indices[obj->values_size] = index; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
124 | obj->values_size++; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
125 | |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
126 | return 0; |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
127 | } |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
128 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
129 | static void token_destroy(CxJsonToken *token) { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
130 | if (token->allocated) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
131 | cx_strfree(&token->content); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
132 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
133 | } |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
134 | |
1132
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
135 | static bool json_isdigit(char c) { |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
136 | // TODO: remove once UCX has public API for this |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
137 | return c >= '0' && c <= '9'; |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
138 | } |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
139 | |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
140 | static bool json_isspace(char c) { |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
141 | // TODO: remove once UCX has public API for this |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
142 | return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'; |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
143 | } |
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
144 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
145 | static int num_isexp(const char *content, size_t length, size_t pos) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
146 | if (pos >= length) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
147 | return 0; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
148 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
149 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
150 | int ok = 0; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
151 | for (size_t i = pos; i < length; i++) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
152 | char c = content[i]; |
1132
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
153 | if (json_isdigit(c)) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
154 | ok = 1; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
155 | } else if (i == pos) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
156 | if (!(c == '+' || c == '-')) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
157 | return 0; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
158 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
159 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
160 | return 0; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
161 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
162 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
163 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
164 | return ok; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
165 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
166 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
167 | static CxJsonTokenType token_numbertype(const char *content, size_t length) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
168 | if (length == 0) return CX_JSON_TOKEN_ERROR; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
169 | |
1132
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
170 | if (content[0] != '-' && !json_isdigit(content[0])) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
171 | return CX_JSON_TOKEN_ERROR; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
172 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
173 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
174 | CxJsonTokenType type = CX_JSON_TOKEN_INTEGER; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
175 | for (size_t i = 1; i < length; i++) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
176 | if (content[i] == '.') { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
177 | if (type == CX_JSON_TOKEN_NUMBER) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
178 | return CX_JSON_TOKEN_ERROR; // more than one decimal separator |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
179 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
180 | type = CX_JSON_TOKEN_NUMBER; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
181 | } else if (content[i] == 'e' || content[i] == 'E') { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
182 | return num_isexp(content, length, i + 1) ? CX_JSON_TOKEN_NUMBER : CX_JSON_TOKEN_ERROR; |
1132
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
183 | } else if (!json_isdigit(content[i])) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
184 | return CX_JSON_TOKEN_ERROR; // char is not a digit, decimal separator or exponent sep |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
185 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
186 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
187 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
188 | return type; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
189 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
190 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
191 | static CxJsonToken token_create(CxJson *json, bool isstring, size_t start, size_t end) { |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
192 | cxmutstr str = cx_mutstrn(json->buffer.space + start, end - start); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
193 | bool allocated = false; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
194 | if (json->uncompleted.tokentype != CX_JSON_NO_TOKEN) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
195 | allocated = true; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
196 | str = cx_strcat_m(json->uncompleted.content, 1, str); |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
197 | if (str.ptr == NULL) { // LCOV_EXCL_START |
1020
e78e65405c56
fix wrong "variant" of zero/NULL/false
Mike Becker <universe@uap-core.de>
parents:
1014
diff
changeset
|
198 | return (CxJsonToken){CX_JSON_NO_TOKEN, false, {NULL, 0}}; |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
199 | } // LCOV_EXCL_STOP |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
200 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
201 | json->uncompleted = (CxJsonToken){0}; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
202 | CxJsonTokenType ttype; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
203 | if (isstring) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
204 | ttype = CX_JSON_TOKEN_STRING; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
205 | } else { |
1009 | 206 | cxstring s = cx_strcast(str); |
207 | if (!cx_strcmp(s, CX_STR("true")) || !cx_strcmp(s, CX_STR("false")) | |
208 | || !cx_strcmp(s, CX_STR("null"))) { | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
209 | ttype = CX_JSON_TOKEN_LITERAL; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
210 | } else { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
211 | ttype = token_numbertype(str.ptr, str.length); |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
212 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
213 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
214 | if (ttype == CX_JSON_TOKEN_ERROR) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
215 | if (allocated) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
216 | cx_strfree(&str); |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
217 | } |
1020
e78e65405c56
fix wrong "variant" of zero/NULL/false
Mike Becker <universe@uap-core.de>
parents:
1014
diff
changeset
|
218 | return (CxJsonToken){CX_JSON_TOKEN_ERROR, false, {NULL, 0}}; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
219 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
220 | return (CxJsonToken){ttype, allocated, str}; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
221 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
222 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
223 | static CxJsonTokenType char2ttype(char c) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
224 | switch (c) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
225 | case '[': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
226 | return CX_JSON_TOKEN_BEGIN_ARRAY; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
227 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
228 | case '{': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
229 | return CX_JSON_TOKEN_BEGIN_OBJECT; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
230 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
231 | case ']': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
232 | return CX_JSON_TOKEN_END_ARRAY; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
233 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
234 | case '}': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
235 | return CX_JSON_TOKEN_END_OBJECT; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
236 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
237 | case ':': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
238 | return CX_JSON_TOKEN_NAME_SEPARATOR; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
239 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
240 | case ',': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
241 | return CX_JSON_TOKEN_VALUE_SEPARATOR; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
242 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
243 | case '"': { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
244 | return CX_JSON_TOKEN_STRING; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
245 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
246 | default: { |
1132
b7fea9b2874c
remove uses of ctype.h - temporarily fixes #577
Mike Becker <universe@uap-core.de>
parents:
1130
diff
changeset
|
247 | if (json_isspace(c)) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
248 | return CX_JSON_TOKEN_SPACE; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
249 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
250 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
251 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
252 | return CX_JSON_NO_TOKEN; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
253 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
254 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
255 | static enum cx_json_status token_parse_next(CxJson *json, CxJsonToken *result) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
256 | // check if there is data in the buffer |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
257 | if (cxBufferEof(&json->buffer)) { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
258 | return json->uncompleted.tokentype == CX_JSON_NO_TOKEN ? |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
259 | CX_JSON_NO_DATA : CX_JSON_INCOMPLETE_DATA; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
260 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
261 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
262 | // current token type and start index |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
263 | CxJsonTokenType ttype = json->uncompleted.tokentype; |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
264 | size_t token_part_start = json->buffer.pos; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
265 | |
1139
7dfa5bcf39ee
remove token_escape bool from CxJson struct
Mike Becker <universe@uap-core.de>
parents:
1132
diff
changeset
|
266 | bool escape_end_of_string = ttype == CX_JSON_TOKEN_STRING |
7dfa5bcf39ee
remove token_escape bool from CxJson struct
Mike Becker <universe@uap-core.de>
parents:
1132
diff
changeset
|
267 | && json->uncompleted.content.ptr[json->uncompleted.content.length-1] == '\\'; |
7dfa5bcf39ee
remove token_escape bool from CxJson struct
Mike Becker <universe@uap-core.de>
parents:
1132
diff
changeset
|
268 | |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
269 | for (size_t i = json->buffer.pos; i < json->buffer.size; i++) { |
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
270 | char c = json->buffer.space[i]; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
271 | if (ttype != CX_JSON_TOKEN_STRING) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
272 | // currently non-string token |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
273 | CxJsonTokenType ctype = char2ttype(c); // start of new token? |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
274 | if (ttype == CX_JSON_NO_TOKEN) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
275 | if (ctype == CX_JSON_TOKEN_SPACE) { |
1008
3b69f025f083
json: enable multiple subsequent fills - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1007
diff
changeset
|
276 | json->buffer.pos++; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
277 | continue; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
278 | } else if (ctype == CX_JSON_TOKEN_STRING) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
279 | // begin string |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
280 | ttype = CX_JSON_TOKEN_STRING; |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
281 | token_part_start = i; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
282 | } else if (ctype != CX_JSON_NO_TOKEN) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
283 | // single-char token |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
284 | json->buffer.pos = i + 1; |
1020
e78e65405c56
fix wrong "variant" of zero/NULL/false
Mike Becker <universe@uap-core.de>
parents:
1014
diff
changeset
|
285 | *result = (CxJsonToken){ctype, false, {NULL, 0}}; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
286 | return CX_JSON_NO_ERROR; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
287 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
288 | ttype = CX_JSON_TOKEN_LITERAL; // number or literal |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
289 | token_part_start = i; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
290 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
291 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
292 | // finish token |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
293 | if (ctype != CX_JSON_NO_TOKEN) { |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
294 | *result = token_create(json, false, token_part_start, i); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
295 | if (result->tokentype == CX_JSON_NO_TOKEN) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
296 | return CX_JSON_BUFFER_ALLOC_FAILED; // LCOV_EXCL_LINE |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
297 | } |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
298 | if (result->tokentype == CX_JSON_TOKEN_ERROR) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
299 | return CX_JSON_FORMAT_ERROR_NUMBER; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
300 | } |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
301 | json->buffer.pos = i; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
302 | return CX_JSON_NO_ERROR; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
303 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
304 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
305 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
306 | // currently inside a string |
1139
7dfa5bcf39ee
remove token_escape bool from CxJson struct
Mike Becker <universe@uap-core.de>
parents:
1132
diff
changeset
|
307 | if (escape_end_of_string) { |
7dfa5bcf39ee
remove token_escape bool from CxJson struct
Mike Becker <universe@uap-core.de>
parents:
1132
diff
changeset
|
308 | escape_end_of_string = false; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
309 | } else { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
310 | if (c == '"') { |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
311 | *result = token_create(json, true, token_part_start, i + 1); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
312 | if (result->tokentype == CX_JSON_NO_TOKEN) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
313 | return CX_JSON_BUFFER_ALLOC_FAILED; // LCOV_EXCL_LINE |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
314 | } |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
315 | json->buffer.pos = i + 1; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
316 | return CX_JSON_NO_ERROR; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
317 | } else if (c == '\\') { |
1139
7dfa5bcf39ee
remove token_escape bool from CxJson struct
Mike Becker <universe@uap-core.de>
parents:
1132
diff
changeset
|
318 | escape_end_of_string = true; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
319 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
320 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
321 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
322 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
323 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
324 | if (ttype != CX_JSON_NO_TOKEN) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
325 | // uncompleted token |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
326 | size_t uncompleted_len = json->buffer.size - token_part_start; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
327 | if (json->uncompleted.tokentype == CX_JSON_NO_TOKEN) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
328 | // current token is uncompleted |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
329 | // save current token content |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
330 | CxJsonToken uncompleted = { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
331 | ttype, true, |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
332 | cx_strdup(cx_strn(json->buffer.space + token_part_start, uncompleted_len)) |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
333 | }; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
334 | if (uncompleted.content.ptr == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
335 | return CX_JSON_BUFFER_ALLOC_FAILED; // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
336 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
337 | json->uncompleted = uncompleted; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
338 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
339 | // previously we also had an uncompleted token |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
340 | // combine the uncompleted token with the current token |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
341 | assert(json->uncompleted.allocated); |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
342 | cxmutstr str = cx_strcat_m(json->uncompleted.content, 1, |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
343 | cx_strn(json->buffer.space + token_part_start, uncompleted_len)); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
344 | if (str.ptr == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
345 | return CX_JSON_BUFFER_ALLOC_FAILED; // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
346 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
347 | json->uncompleted.content = str; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
348 | } |
1008
3b69f025f083
json: enable multiple subsequent fills - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1007
diff
changeset
|
349 | // advance the buffer position - we saved the stuff in the uncompleted token |
3b69f025f083
json: enable multiple subsequent fills - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1007
diff
changeset
|
350 | json->buffer.pos += uncompleted_len; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
351 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
352 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
353 | return CX_JSON_INCOMPLETE_DATA; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
354 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
355 | |
1156
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
356 | // converts a Unicode codepoint to utf8 |
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
357 | static unsigned codepoint_to_utf8(uint32_t codepoint, char *output_buf) { |
1149
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
358 | if (codepoint <= 0x7F) { |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
359 | *output_buf = (char)codepoint; |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
360 | return 1; |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
361 | } else if (codepoint <= 0x7FF) { |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
362 | output_buf[0] = (char)(0xC0 | ((codepoint >> 6) & 0x1F)); |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
363 | output_buf[1] = (char)(0x80 | (codepoint & 0x3F)); |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
364 | return 2; |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
365 | } else if (codepoint <= 0xFFFF) { |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
366 | output_buf[0] = (char)(0xE0 | ((codepoint >> 12) & 0x0F)); |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
367 | output_buf[1] = (char)(0x80 | ((codepoint >> 6) & 0x3F)); |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
368 | output_buf[2] = (char)(0x80 | (codepoint & 0x3F)); |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
369 | return 3; |
1152
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
370 | } else if (codepoint <= 0x10FFFF) { |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
371 | output_buf[0] = (char)(0xF0 | ((codepoint >> 18) & 0x07)); |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
372 | output_buf[1] = (char)(0x80 | ((codepoint >> 12) & 0x3F)); |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
373 | output_buf[2] = (char)(0x80 | ((codepoint >> 6) & 0x3F)); |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
374 | output_buf[3] = (char)(0x80 | (codepoint & 0x3F)); |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
375 | return 4; |
1149
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
376 | } |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
377 | |
1156
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
378 | return 0; // LCOV_EXCL_LINE |
1149
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
379 | } |
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
380 | |
1152
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
381 | // converts a utf16 surrogate pair to utf8 |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
382 | static inline uint32_t utf16pair_to_codepoint(uint16_t c0, uint16_t c1) { |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
383 | return ((c0 - 0xD800) << 10) + (c1 - 0xDC00) + 0x10000; |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
384 | } |
e4af44b488bc
implement decoder for utf16 surrogate pairs in unescape_string
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1151
diff
changeset
|
385 | |
1158
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
386 | static unsigned unescape_unicode_string(cxstring str, char *utf8buf) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
387 | // str is supposed to start with "\uXXXX" or "\uXXXX\uXXXX" |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
388 | // remaining bytes in the string are ignored (str may be larger!) |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
389 | |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
390 | if (str.length < 6 || str.ptr[0] != '\\' || str.ptr[1] != 'u') { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
391 | return 0; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
392 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
393 | |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
394 | unsigned utf8len = 0; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
395 | cxstring ustr1 = { str.ptr + 2, 4}; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
396 | uint16_t utf16a, utf16b; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
397 | if (!cx_strtou16_lc(ustr1, &utf16a, 16, "")) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
398 | uint32_t codepoint; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
399 | if (utf16a < 0xD800 || utf16a > 0xE000) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
400 | // character is in the Basic Multilingual Plane |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
401 | // and encoded as a single utf16 char |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
402 | codepoint = utf16a; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
403 | utf8len = codepoint_to_utf8(codepoint, utf8buf); |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
404 | } else if (utf16a >= 0xD800 && utf16a <= 0xDBFF) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
405 | // character is encoded as a surrogate pair |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
406 | // get next 6 bytes |
1159 | 407 | if (str.length >= 12) { |
1160 | 408 | if (str.ptr[6] == '\\' && str.ptr[7] == 'u') { |
1158
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
409 | cxstring ustr2 = { str.ptr+8, 4 }; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
410 | if (!cx_strtou16_lc(ustr2, &utf16b, 16, "") |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
411 | && utf16b >= 0xDC00 && utf16b <= 0xDFFF) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
412 | codepoint = utf16pair_to_codepoint(utf16a, utf16b); |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
413 | utf8len = codepoint_to_utf8(codepoint, utf8buf); |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
414 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
415 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
416 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
417 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
418 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
419 | return utf8len; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
420 | } |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
421 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
422 | static cxmutstr unescape_string(const CxAllocator *a, cxmutstr str) { |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
423 | // note: this function expects that str contains the enclosing quotes! |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
424 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
425 | cxmutstr result; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
426 | result.length = 0; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
427 | result.ptr = cxMalloc(a, str.length - 1); |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
428 | if (result.ptr == NULL) return result; // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
429 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
430 | bool u = false; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
431 | for (size_t i = 1; i < str.length - 1; i++) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
432 | char c = str.ptr[i]; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
433 | if (u) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
434 | u = false; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
435 | if (c == 'n') { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
436 | c = '\n'; |
1156
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
437 | } else if (c == '"') { |
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
438 | c = '"'; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
439 | } else if (c == 't') { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
440 | c = '\t'; |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
441 | } else if (c == 'r') { |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
442 | c = '\r'; |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
443 | } else if (c == '\\') { |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
444 | c = '\\'; |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
445 | } else if (c == '/') { |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
446 | c = '/'; // always unescape, we don't need settings here |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
447 | } else if (c == 'f') { |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
448 | c = '\f'; |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
449 | } else if (c == 'b') { |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
450 | c = '\b'; |
1149
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
451 | } else if (c == 'u') { |
1158
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
452 | char utf8buf[4]; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
453 | unsigned utf8len = unescape_unicode_string( |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
454 | cx_strn(str.ptr + i - 1, str.length + 1 - i), |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
455 | utf8buf |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
456 | ); |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
457 | if(utf8len > 0) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
458 | i += utf8len < 4 ? 4 : 10; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
459 | // add all bytes from utf8buf except the last char |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
460 | // to the result (last char will be added below) |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
461 | utf8len--; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
462 | c = utf8buf[utf8len]; |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
463 | for (unsigned x = 0; x < utf8len; x++) { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
464 | result.ptr[result.length++] = utf8buf[x]; |
1156
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
465 | } |
1158
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
466 | } else { |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
467 | // decoding failed, ignore the entire sequence |
fa2811e9ab19
extract unescape_unicode_string() and fix rages
Mike Becker <universe@uap-core.de>
parents:
1156
diff
changeset
|
468 | result.ptr[result.length++] = '\\'; |
1149
df5665de7344
implement unicode escape sequences in json unescape_string function
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1139
diff
changeset
|
469 | } |
1156
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
470 | } else { |
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
471 | // TODO: discuss the behavior for unrecognized escape sequences |
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
472 | // most parsers throw an error here - we just ignore it |
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
473 | result.ptr[result.length++] = '\\'; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
474 | } |
1156
96f16b5a0029
add test and implementation for malformed escape sequences
Mike Becker <universe@uap-core.de>
parents:
1152
diff
changeset
|
475 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
476 | result.ptr[result.length++] = c; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
477 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
478 | if (c == '\\') { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
479 | u = true; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
480 | } else { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
481 | result.ptr[result.length++] = c; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
482 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
483 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
484 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
485 | result.ptr[result.length] = 0; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
486 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
487 | return result; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
488 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
489 | |
1123
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
490 | static cxmutstr escape_string(cxmutstr str, bool escape_slash) { |
1122
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
491 | // note: this function produces the string without enclosing quotes |
49ab92de9a13
add more escape sequences to unescape function
Mike Becker <universe@uap-core.de>
parents:
1121
diff
changeset
|
492 | // the reason is that we don't want to allocate memory just for that |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
493 | CxBuffer buf = {0}; |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
494 | |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
495 | bool all_printable = true; |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
496 | for (size_t i = 0; i < str.length; i++) { |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
497 | unsigned char c = str.ptr[i]; |
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
498 | bool escape = c < 0x20 || c == '\\' || c == '"' |
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
499 | || (escape_slash && c == '/'); |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
500 | |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
501 | if (all_printable && escape) { |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
502 | size_t capa = str.length + 32; |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
503 | char *space = cxMallocDefault(capa); |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
504 | if (space == NULL) return cx_mutstrn(NULL, 0); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
505 | cxBufferInit(&buf, space, capa, NULL, CX_BUFFER_AUTO_EXTEND); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
506 | cxBufferWrite(str.ptr, 1, i, &buf); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
507 | all_printable = false; |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
508 | } |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
509 | if (escape) { |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
510 | cxBufferPut(&buf, '\\'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
511 | if (c == '\"') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
512 | cxBufferPut(&buf, '\"'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
513 | } else if (c == '\n') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
514 | cxBufferPut(&buf, 'n'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
515 | } else if (c == '\t') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
516 | cxBufferPut(&buf, 't'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
517 | } else if (c == '\r') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
518 | cxBufferPut(&buf, 'r'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
519 | } else if (c == '\\') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
520 | cxBufferPut(&buf, '\\'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
521 | } else if (c == '/') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
522 | cxBufferPut(&buf, '/'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
523 | } else if (c == '\f') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
524 | cxBufferPut(&buf, 'f'); |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
525 | } else if (c == '\b') { |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
526 | cxBufferPut(&buf, 'b'); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
527 | } else { |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
528 | char code[6]; |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
529 | snprintf(code, sizeof(code), "u%04x", (unsigned int) c); |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
530 | cxBufferPutString(&buf, code); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
531 | } |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
532 | } else if (!all_printable) { |
1130
5bcb725119b6
fix wrong accidental unicode escaping
Mike Becker <universe@uap-core.de>
parents:
1123
diff
changeset
|
533 | cxBufferPut(&buf, c); |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
534 | } |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
535 | } |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
536 | if (!all_printable) { |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
537 | str = cx_mutstrn(buf.space, buf.size); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
538 | } |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
539 | cxBufferDestroy(&buf); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
540 | return str; |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
541 | } |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
542 | |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
543 | static CxJsonValue* json_create_value(CxJson *json, CxJsonValueType type) { |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
544 | CxJsonValue *v = cxCalloc(json->allocator, 1, sizeof(CxJsonValue)); |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
545 | if (v == NULL) return NULL; // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
546 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
547 | // initialize the value |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
548 | v->type = type; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
549 | v->allocator = json->allocator; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
550 | if (type == CX_JSON_ARRAY) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
551 | cx_array_initialize_a(json->allocator, v->value.array.array, 16); |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
552 | if (v->value.array.array == NULL) goto create_json_value_exit_error; // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
553 | } else if (type == CX_JSON_OBJECT) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
554 | cx_array_initialize_a(json->allocator, v->value.object.values, 16); |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
555 | v->value.object.indices = cxCalloc(json->allocator, 16, sizeof(size_t)); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
556 | if (v->value.object.values == NULL || |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
557 | v->value.object.indices == NULL) |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
558 | goto create_json_value_exit_error; // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
559 | } |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
560 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
561 | // add the new value to a possible parent |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
562 | if (json->vbuf_size > 0) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
563 | CxJsonValue *parent = json->vbuf[json->vbuf_size - 1]; |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
564 | assert(parent != NULL); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
565 | if (parent->type == CX_JSON_ARRAY) { |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
566 | CxArrayReallocator value_realloc = cx_array_reallocator(json->allocator, NULL); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
567 | if (cx_array_simple_add_a(&value_realloc, parent->value.array.array, v)) { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
568 | goto create_json_value_exit_error; // LCOV_EXCL_LINE |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
569 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
570 | } else if (parent->type == CX_JSON_OBJECT) { |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
571 | // the member was already created after parsing the name |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
572 | assert(json->uncompleted_member.name.ptr != NULL); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
573 | json->uncompleted_member.value = v; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
574 | if (json_add_objvalue(parent, json->uncompleted_member)) { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
575 | goto create_json_value_exit_error; // LCOV_EXCL_LINE |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
576 | } |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
577 | json->uncompleted_member.name = (cxmutstr) {NULL, 0}; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
578 | } else { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
579 | assert(false); // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
580 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
581 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
582 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
583 | // add the new value to the stack, if it is an array or object |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
584 | if (type == CX_JSON_ARRAY || type == CX_JSON_OBJECT) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
585 | CxArrayReallocator vbuf_realloc = cx_array_reallocator(NULL, json->vbuf_internal); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
586 | if (cx_array_simple_add_a(&vbuf_realloc, json->vbuf, v)) { |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
587 | goto create_json_value_exit_error; // LCOV_EXCL_LINE |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
588 | } |
940
bbf41b9c2658
fix memory leak in json reader when handling incomplete tokens
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
938
diff
changeset
|
589 | } |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
590 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
591 | // if currently no value is parsed, this is now the value of interest |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
592 | if (json->parsed == NULL) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
593 | json->parsed = v; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
594 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
595 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
596 | return v; |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
597 | // LCOV_EXCL_START |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
598 | create_json_value_exit_error: |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
599 | cxJsonValueFree(v); |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
600 | return NULL; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
601 | // LCOV_EXCL_STOP |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
602 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
603 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
604 | #define JP_STATE_VALUE_BEGIN 0 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
605 | #define JP_STATE_VALUE_END 10 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
606 | #define JP_STATE_VALUE_BEGIN_OBJ 1 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
607 | #define JP_STATE_OBJ_SEP_OR_CLOSE 11 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
608 | #define JP_STATE_VALUE_BEGIN_AR 2 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
609 | #define JP_STATE_ARRAY_SEP_OR_CLOSE 12 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
610 | #define JP_STATE_OBJ_NAME_OR_CLOSE 5 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
611 | #define JP_STATE_OBJ_NAME 6 |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
612 | #define JP_STATE_OBJ_COLON 7 |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
613 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
614 | void cxJsonInit(CxJson *json, const CxAllocator *allocator) { |
996
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
615 | if (allocator == NULL) { |
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
616 | allocator = cxDefaultAllocator; |
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
617 | } |
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
618 | |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
619 | memset(json, 0, sizeof(CxJson)); |
996
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
620 | json->allocator = allocator; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
621 | |
946
b428424c0214
avoid state buffer allocation for JSON with reasonable nesting depth
Mike Becker <universe@uap-core.de>
parents:
944
diff
changeset
|
622 | json->states = json->states_internal; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
623 | json->states_capacity = cx_nmemb(json->states_internal); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
624 | json->states[0] = JP_STATE_VALUE_BEGIN; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
625 | json->states_size = 1; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
626 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
627 | json->vbuf = json->vbuf_internal; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
628 | json->vbuf_capacity = cx_nmemb(json->vbuf_internal); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
629 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
630 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
631 | void cxJsonDestroy(CxJson *json) { |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
632 | cxBufferDestroy(&json->buffer); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
633 | if (json->states != json->states_internal) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
634 | cxFreeDefault(json->states); |
946
b428424c0214
avoid state buffer allocation for JSON with reasonable nesting depth
Mike Becker <universe@uap-core.de>
parents:
944
diff
changeset
|
635 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
636 | if (json->vbuf != json->vbuf_internal) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
637 | cxFreeDefault(json->vbuf); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
638 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
639 | cxJsonValueFree(json->parsed); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
640 | json->parsed = NULL; |
1075
0cc4b63a0ae0
fix cxJsonDestroy() not freeing uncompleted object member names
Mike Becker <universe@uap-core.de>
parents:
1072
diff
changeset
|
641 | if (json->uncompleted_member.name.ptr != NULL) { |
0cc4b63a0ae0
fix cxJsonDestroy() not freeing uncompleted object member names
Mike Becker <universe@uap-core.de>
parents:
1072
diff
changeset
|
642 | cx_strfree_a(json->allocator, &json->uncompleted_member.name); |
0cc4b63a0ae0
fix cxJsonDestroy() not freeing uncompleted object member names
Mike Becker <universe@uap-core.de>
parents:
1072
diff
changeset
|
643 | json->uncompleted_member = (CxJsonObjValue){{NULL, 0}, NULL}; |
0cc4b63a0ae0
fix cxJsonDestroy() not freeing uncompleted object member names
Mike Becker <universe@uap-core.de>
parents:
1072
diff
changeset
|
644 | } |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
645 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
646 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
647 | int cxJsonFilln(CxJson *json, const char *buf, size_t size) { |
1060
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
648 | if (cxBufferEof(&json->buffer)) { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
649 | // reinitialize the buffer |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
650 | cxBufferDestroy(&json->buffer); |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
651 | cxBufferInit(&json->buffer, (char*) buf, size, |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
652 | NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_COPY_ON_WRITE); |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
653 | json->buffer.size = size; |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
654 | return 0; |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
655 | } else { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
656 | return size != cxBufferAppend(buf, 1, size, &json->buffer); |
1007
81b2986d2b04
fix that cxBufferSeek() cannot move pos past the end - fixes #523
Mike Becker <universe@uap-core.de>
parents:
1002
diff
changeset
|
657 | } |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
658 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
659 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
660 | static void json_add_state(CxJson *json, int state) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
661 | // we have guaranteed the necessary space with cx_array_simple_reserve() |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
662 | // therefore, we can safely add the state in the simplest way possible |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
663 | json->states[json->states_size++] = state; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
664 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
665 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
666 | #define return_rec(code) \ |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
667 | token_destroy(&token); \ |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
668 | return code |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
669 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
670 | static enum cx_json_status json_parse(CxJson *json) { |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
671 | // Reserve a pointer for a possibly read value |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
672 | CxJsonValue *vbuf = NULL; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
673 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
674 | // grab the next token |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
675 | CxJsonToken token; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
676 | { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
677 | enum cx_json_status ret = token_parse_next(json, &token); |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
678 | if (ret != CX_JSON_NO_ERROR) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
679 | return ret; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
680 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
681 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
682 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
683 | // pop the current state |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
684 | assert(json->states_size > 0); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
685 | int state = json->states[--json->states_size]; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
686 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
687 | // guarantee that at least two more states fit on the stack |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
688 | CxArrayReallocator state_realloc = cx_array_reallocator(NULL, json->states_internal); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
689 | if (cx_array_simple_reserve_a(&state_realloc, json->states, 2)) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
690 | return CX_JSON_BUFFER_ALLOC_FAILED; // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
691 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
692 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
693 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
694 | // 0 JP_STATE_VALUE_BEGIN value begin |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
695 | // 10 JP_STATE_VALUE_END expect value end |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
696 | // 1 JP_STATE_VALUE_BEGIN_OBJ value begin (inside object) |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
697 | // 11 JP_STATE_OBJ_SEP_OR_CLOSE object, expect separator, objclose |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
698 | // 2 JP_STATE_VALUE_BEGIN_AR value begin (inside array) |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
699 | // 12 JP_STATE_ARRAY_SEP_OR_CLOSE array, expect separator or arrayclose |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
700 | // 5 JP_STATE_OBJ_NAME_OR_CLOSE object, expect name or objclose |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
701 | // 6 JP_STATE_OBJ_NAME object, expect name |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
702 | // 7 JP_STATE_OBJ_COLON object, expect ':' |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
703 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
704 | if (state < 3) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
705 | // push expected end state to the stack |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
706 | json_add_state(json, 10 + state); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
707 | switch (token.tokentype) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
708 | case CX_JSON_TOKEN_BEGIN_ARRAY: { |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
709 | if (json_create_value(json, CX_JSON_ARRAY) == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
710 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
711 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
712 | json_add_state(json, JP_STATE_VALUE_BEGIN_AR); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
713 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
714 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
715 | case CX_JSON_TOKEN_BEGIN_OBJECT: { |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
716 | if (json_create_value(json, CX_JSON_OBJECT) == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
717 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
718 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
719 | json_add_state(json, JP_STATE_OBJ_NAME_OR_CLOSE); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
720 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
721 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
722 | case CX_JSON_TOKEN_STRING: { |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
723 | if ((vbuf = json_create_value(json, CX_JSON_STRING)) == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
724 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
725 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
726 | cxmutstr str = unescape_string(json->allocator, token.content); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
727 | if (str.ptr == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
728 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
729 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
730 | vbuf->value.string = str; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
731 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
732 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
733 | case CX_JSON_TOKEN_INTEGER: |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
734 | case CX_JSON_TOKEN_NUMBER: { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
735 | int type = token.tokentype == CX_JSON_TOKEN_INTEGER ? CX_JSON_INTEGER : CX_JSON_NUMBER; |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
736 | if (NULL == (vbuf = json_create_value(json, type))) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
737 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
738 | } |
1060
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
739 | if (type == CX_JSON_INTEGER) { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
740 | if (cx_strtoi64(token.content, &vbuf->value.integer, 10)) { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
741 | return_rec(CX_JSON_FORMAT_ERROR_NUMBER); |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
742 | } |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
743 | } else { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
744 | if (cx_strtod(token.content, &vbuf->value.number)) { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
745 | return_rec(CX_JSON_FORMAT_ERROR_NUMBER); |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
746 | } |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
747 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
748 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
749 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
750 | case CX_JSON_TOKEN_LITERAL: { |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
751 | if ((vbuf = json_create_value(json, CX_JSON_LITERAL)) == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
752 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
753 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
754 | if (0 == cx_strcmp(cx_strcast(token.content), cx_str("true"))) { |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
755 | vbuf->value.literal = CX_JSON_TRUE; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
756 | } else if (0 == cx_strcmp(cx_strcast(token.content), cx_str("false"))) { |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
757 | vbuf->value.literal = CX_JSON_FALSE; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
758 | } else { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
759 | vbuf->value.literal = CX_JSON_NULL; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
760 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
761 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
762 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
763 | default: { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
764 | return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
765 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
766 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
767 | } else if (state == JP_STATE_ARRAY_SEP_OR_CLOSE) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
768 | // expect ',' or ']' |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
769 | if (token.tokentype == CX_JSON_TOKEN_VALUE_SEPARATOR) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
770 | json_add_state(json, JP_STATE_VALUE_BEGIN_AR); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
771 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
772 | } else if (token.tokentype == CX_JSON_TOKEN_END_ARRAY) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
773 | // discard the array from the value buffer |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
774 | json->vbuf_size--; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
775 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
776 | } else { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
777 | return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
778 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
779 | } else if (state == JP_STATE_OBJ_NAME_OR_CLOSE || state == JP_STATE_OBJ_NAME) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
780 | if (state == JP_STATE_OBJ_NAME_OR_CLOSE && token.tokentype == CX_JSON_TOKEN_END_OBJECT) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
781 | // discard the obj from the value buffer |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
782 | json->vbuf_size--; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
783 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
784 | } else { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
785 | // expect string |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
786 | if (token.tokentype != CX_JSON_TOKEN_STRING) { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
787 | return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
788 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
789 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
790 | // add new entry |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
791 | cxmutstr name = unescape_string(json->allocator, token.content); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
792 | if (name.ptr == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
793 | return_rec(CX_JSON_VALUE_ALLOC_FAILED); // LCOV_EXCL_LINE |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
794 | } |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
795 | assert(json->uncompleted_member.name.ptr == NULL); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
796 | json->uncompleted_member.name = name; |
1037
83620ba72cc1
generify cxJsonObjGet() - fixes #525
Mike Becker <universe@uap-core.de>
parents:
1033
diff
changeset
|
797 | assert(json->vbuf_size > 0); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
798 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
799 | // next state |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
800 | json_add_state(json, JP_STATE_OBJ_COLON); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
801 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
802 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
803 | } else if (state == JP_STATE_OBJ_COLON) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
804 | // expect ':' |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
805 | if (token.tokentype != CX_JSON_TOKEN_NAME_SEPARATOR) { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
806 | return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
807 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
808 | // next state |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
809 | json_add_state(json, JP_STATE_VALUE_BEGIN_OBJ); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
810 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
811 | } else if (state == JP_STATE_OBJ_SEP_OR_CLOSE) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
812 | // expect ',' or '}' |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
813 | if (token.tokentype == CX_JSON_TOKEN_VALUE_SEPARATOR) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
814 | json_add_state(json, JP_STATE_OBJ_NAME); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
815 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
816 | } else if (token.tokentype == CX_JSON_TOKEN_END_OBJECT) { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
817 | // discard the obj from the value buffer |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
818 | json->vbuf_size--; |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
819 | return_rec(CX_JSON_NO_ERROR); |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
820 | } else { |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
821 | return_rec(CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
822 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
823 | } else { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
824 | // should be unreachable |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
825 | assert(false); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
826 | return_rec(-1); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
827 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
828 | } |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
829 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
830 | CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value) { |
1060
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
831 | // check if buffer has been filled |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
832 | if (json->buffer.space == NULL) { |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
833 | return CX_JSON_NULL_DATA; |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
834 | } |
0a7c1bb2372d
avoid copying the filled data in the json parser when possible - fixes #530
Mike Becker <universe@uap-core.de>
parents:
1057
diff
changeset
|
835 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
836 | // initialize output value |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
837 | *value = &cx_json_value_nothing; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
838 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
839 | // parse data |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
840 | CxJsonStatus result; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
841 | do { |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
842 | result = json_parse(json); |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
843 | if (result == CX_JSON_NO_ERROR && json->states_size == 1) { |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
844 | // final state reached |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
845 | assert(json->states[0] == JP_STATE_VALUE_END); |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
846 | assert(json->vbuf_size == 0); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
847 | |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
848 | // write output value |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
849 | *value = json->parsed; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
850 | json->parsed = NULL; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
851 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
852 | // re-initialize state machine |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
853 | json->states[0] = JP_STATE_VALUE_BEGIN; |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
854 | |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
855 | return CX_JSON_NO_ERROR; |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
856 | } |
1002
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
857 | } while (result == CX_JSON_NO_ERROR); |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
858 | |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
859 | // the parser might think there is no data |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
860 | // but when we did not reach the final state, |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
861 | // we know that there must be more to come |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
862 | if (result == CX_JSON_NO_DATA && json->states_size > 1) { |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
863 | return CX_JSON_INCOMPLETE_DATA; |
1483c47063a8
add status codes to json parser - relates to #431
Mike Becker <universe@uap-core.de>
parents:
1000
diff
changeset
|
864 | } |
1000
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
865 | |
1aecddf7e209
simplify how the json parser works
Mike Becker <universe@uap-core.de>
parents:
996
diff
changeset
|
866 | return result; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
867 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
868 | |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
869 | void cxJsonValueFree(CxJsonValue *value) { |
1012
21884374edbb
add documentation - resolves #431
Mike Becker <universe@uap-core.de>
parents:
1009
diff
changeset
|
870 | if (value == NULL || value->type == CX_JSON_NOTHING) return; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
871 | switch (value->type) { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
872 | case CX_JSON_OBJECT: { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
873 | CxJsonObject obj = value->value.object; |
967
a58f602ed2fe
simplify parsing of array and object elements
Mike Becker <universe@uap-core.de>
parents:
965
diff
changeset
|
874 | for (size_t i = 0; i < obj.values_size; i++) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
875 | cxJsonValueFree(obj.values[i].value); |
1037
83620ba72cc1
generify cxJsonObjGet() - fixes #525
Mike Becker <universe@uap-core.de>
parents:
1033
diff
changeset
|
876 | cx_strfree_a(value->allocator, &obj.values[i].name); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
877 | } |
996
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
878 | cxFree(value->allocator, obj.values); |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
879 | cxFree(value->allocator, obj.indices); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
880 | break; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
881 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
882 | case CX_JSON_ARRAY: { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
883 | CxJsonArray array = value->value.array; |
967
a58f602ed2fe
simplify parsing of array and object elements
Mike Becker <universe@uap-core.de>
parents:
965
diff
changeset
|
884 | for (size_t i = 0; i < array.array_size; i++) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
885 | cxJsonValueFree(array.array[i]); |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
886 | } |
996
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
887 | cxFree(value->allocator, array.array); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
888 | break; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
889 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
890 | case CX_JSON_STRING: { |
996
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
891 | cxFree(value->allocator, value->value.string.ptr); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
892 | break; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
893 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
894 | default: { |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
895 | break; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
896 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
897 | } |
996
333155f234c4
add support for allocators to the json parser
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
976
diff
changeset
|
898 | cxFree(value->allocator, value); |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
899 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
900 | |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
901 | CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator) { |
1116
b381da3a9b19
fix JSON create value functions not actually accepting NULL as allocator arg
Mike Becker <universe@uap-core.de>
parents:
1083
diff
changeset
|
902 | if (allocator == NULL) allocator = cxDefaultAllocator; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
903 | CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
904 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
905 | v->allocator = allocator; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
906 | v->type = CX_JSON_OBJECT; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
907 | cx_array_initialize_a(allocator, v->value.object.values, 16); |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
908 | if (v->value.object.values == NULL) { // LCOV_EXCL_START |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
909 | cxFree(allocator, v); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
910 | return NULL; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
911 | // LCOV_EXCL_STOP |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
912 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
913 | v->value.object.indices = cxCalloc(allocator, 16, sizeof(size_t)); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
914 | if (v->value.object.indices == NULL) { // LCOV_EXCL_START |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
915 | cxFree(allocator, v->value.object.values); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
916 | cxFree(allocator, v); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
917 | return NULL; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
918 | // LCOV_EXCL_STOP |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
919 | } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
920 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
921 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
922 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
923 | CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator) { |
1116
b381da3a9b19
fix JSON create value functions not actually accepting NULL as allocator arg
Mike Becker <universe@uap-core.de>
parents:
1083
diff
changeset
|
924 | if (allocator == NULL) allocator = cxDefaultAllocator; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
925 | CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
926 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
927 | v->allocator = allocator; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
928 | v->type = CX_JSON_ARRAY; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
929 | cx_array_initialize_a(allocator, v->value.array.array, 16); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
930 | if (v->value.array.array == NULL) { cxFree(allocator, v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
931 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
932 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
933 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
934 | CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num) { |
1116
b381da3a9b19
fix JSON create value functions not actually accepting NULL as allocator arg
Mike Becker <universe@uap-core.de>
parents:
1083
diff
changeset
|
935 | if (allocator == NULL) allocator = cxDefaultAllocator; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
936 | CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
937 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
938 | v->allocator = allocator; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
939 | v->type = CX_JSON_NUMBER; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
940 | v->value.number = num; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
941 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
942 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
943 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
944 | CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num) { |
1116
b381da3a9b19
fix JSON create value functions not actually accepting NULL as allocator arg
Mike Becker <universe@uap-core.de>
parents:
1083
diff
changeset
|
945 | if (allocator == NULL) allocator = cxDefaultAllocator; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
946 | CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
947 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
948 | v->allocator = allocator; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
949 | v->type = CX_JSON_INTEGER; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
950 | v->value.integer = num; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
951 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
952 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
953 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
954 | CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char* str) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
955 | return cxJsonCreateCxString(allocator, cx_str(str)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
956 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
957 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
958 | CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str) { |
1116
b381da3a9b19
fix JSON create value functions not actually accepting NULL as allocator arg
Mike Becker <universe@uap-core.de>
parents:
1083
diff
changeset
|
959 | if (allocator == NULL) allocator = cxDefaultAllocator; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
960 | CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
961 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
962 | v->allocator = allocator; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
963 | v->type = CX_JSON_STRING; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
964 | cxmutstr s = cx_strdup_a(allocator, str); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
965 | if (s.ptr == NULL) { cxFree(allocator, v); return NULL; } |
1057
4e8436c3e806
add tests for JSON create functions and fix a bug in cxJsonCreateCxString()
Mike Becker <universe@uap-core.de>
parents:
1055
diff
changeset
|
966 | v->value.string = s; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
967 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
968 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
969 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
970 | CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit) { |
1116
b381da3a9b19
fix JSON create value functions not actually accepting NULL as allocator arg
Mike Becker <universe@uap-core.de>
parents:
1083
diff
changeset
|
971 | if (allocator == NULL) allocator = cxDefaultAllocator; |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
972 | CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
973 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
974 | v->allocator = allocator; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
975 | v->type = CX_JSON_LITERAL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
976 | v->value.literal = lit; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
977 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
978 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
979 | |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
980 | // LCOV_EXCL_START |
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
981 | // never called as long as malloc() does not return NULL |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
982 | static void json_arr_free_temp(CxJsonValue** values, size_t count) { |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
983 | for (size_t i = 0; i < count; i++) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
984 | if (values[i] == NULL) break; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
985 | cxJsonValueFree(values[i]); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
986 | } |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
987 | cxFreeDefault(values); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
988 | } |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1060
diff
changeset
|
989 | // LCOV_EXCL_STOP |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
990 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
991 | int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
992 | CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
993 | if (values == NULL) return -1; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
994 | for (size_t i = 0; i < count; i++) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
995 | values[i] = cxJsonCreateNumber(arr->allocator, num[i]); |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
996 | if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
997 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
998 | int ret = cxJsonArrAddValues(arr, values, count); |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
999 | cxFreeDefault(values); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1000 | return ret; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1001 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1002 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1003 | int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1004 | CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1005 | if (values == NULL) return -1; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1006 | for (size_t i = 0; i < count; i++) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1007 | values[i] = cxJsonCreateInteger(arr->allocator, num[i]); |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1008 | if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1009 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1010 | int ret = cxJsonArrAddValues(arr, values, count); |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1011 | cxFreeDefault(values); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1012 | return ret; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1013 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1014 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1015 | int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1016 | CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1017 | if (values == NULL) return -1; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1018 | for (size_t i = 0; i < count; i++) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1019 | values[i] = cxJsonCreateString(arr->allocator, str[i]); |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1020 | if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1021 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1022 | int ret = cxJsonArrAddValues(arr, values, count); |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1023 | cxFreeDefault(values); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1024 | return ret; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1025 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1026 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1027 | int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1028 | CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1029 | if (values == NULL) return -1; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1030 | for (size_t i = 0; i < count; i++) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1031 | values[i] = cxJsonCreateCxString(arr->allocator, str[i]); |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1032 | if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1033 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1034 | int ret = cxJsonArrAddValues(arr, values, count); |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1035 | cxFreeDefault(values); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1036 | return ret; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1037 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1038 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1039 | int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1040 | CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1041 | if (values == NULL) return -1; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1042 | for (size_t i = 0; i < count; i++) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1043 | values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]); |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1044 | if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1045 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1046 | int ret = cxJsonArrAddValues(arr, values, count); |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
1047 | cxFreeDefault(values); |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1048 | return ret; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1049 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1050 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1051 | int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1052 | CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1053 | assert(arr->type == CX_JSON_ARRAY); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1054 | return cx_array_simple_copy_a(&value_realloc, |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1055 | arr->value.array.array, |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1056 | arr->value.array.array_size, |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1057 | val, count |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1058 | ); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1059 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1060 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1061 | int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1062 | cxmutstr k = cx_strdup_a(obj->allocator, name); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1063 | if (k.ptr == NULL) return -1; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1064 | CxJsonObjValue kv = {k, child}; |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1065 | if (json_add_objvalue(obj, kv)) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1066 | cx_strfree_a(obj->allocator, &k); |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1067 | return 1; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1068 | } else { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1069 | return 0; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1070 | } |
1054
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1071 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1072 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1073 | CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1074 | CxJsonValue* v = cxJsonCreateObj(obj->allocator); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1075 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1076 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1077 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1078 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1079 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1080 | CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1081 | CxJsonValue* v = cxJsonCreateArr(obj->allocator); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1082 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1083 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1084 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1085 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1086 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1087 | CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1088 | CxJsonValue* v = cxJsonCreateNumber(obj->allocator, num); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1089 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1090 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1091 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1092 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1093 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1094 | CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1095 | CxJsonValue* v = cxJsonCreateInteger(obj->allocator, num); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1096 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1097 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1098 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1099 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1100 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1101 | CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1102 | CxJsonValue* v = cxJsonCreateString(obj->allocator, str); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1103 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1104 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1105 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1106 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1107 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1108 | CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1109 | CxJsonValue* v = cxJsonCreateCxString(obj->allocator, str); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1110 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1111 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1112 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1113 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1114 | |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1115 | CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit) { |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1116 | CxJsonValue* v = cxJsonCreateLiteral(obj->allocator, lit); |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1117 | if (v == NULL) return NULL; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1118 | if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;} |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1119 | return v; |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1120 | } |
fb1076ead56f
add implementation for creating new json values
Mike Becker <universe@uap-core.de>
parents:
1040
diff
changeset
|
1121 | |
1009 | 1122 | CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) { |
967
a58f602ed2fe
simplify parsing of array and object elements
Mike Becker <universe@uap-core.de>
parents:
965
diff
changeset
|
1123 | if (index >= value->value.array.array_size) { |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1124 | return &cx_json_value_nothing; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1125 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1126 | return value->value.array.array[index]; |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1127 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1128 | |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1129 | CxIterator cxJsonArrIter(const CxJsonValue *value) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1130 | return cxIteratorPtr( |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1131 | value->value.array.array, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1132 | value->value.array.array_size |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1133 | ); |
1033
e3009345984b
add cxJsonArrIter() - fixes #524
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
1134 | } |
e3009345984b
add cxJsonArrIter() - fixes #524
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
1135 | |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1136 | CxIterator cxJsonObjIter(const CxJsonValue *value) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1137 | return cxIterator( |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1138 | value->value.object.values, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1139 | sizeof(CxJsonObjValue), |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1140 | value->value.object.values_size |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1141 | ); |
1033
e3009345984b
add cxJsonArrIter() - fixes #524
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
1142 | } |
e3009345984b
add cxJsonArrIter() - fixes #524
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
1143 | |
1037
83620ba72cc1
generify cxJsonObjGet() - fixes #525
Mike Becker <universe@uap-core.de>
parents:
1033
diff
changeset
|
1144 | CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) { |
1067
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
1145 | CxJsonObjValue *member = json_find_objvalue(value, name); |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
1146 | if (member == NULL) { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
1147 | return &cx_json_value_nothing; |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
1148 | } else { |
7799addf475f
optimize cxJsonObjGet() part 1 - binary search
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
1149 | return member->value; |
937
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1150 | } |
10123f4d5618
add first draft of json implementation - relates to #431
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1151 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1152 | |
1077
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1153 | CxJsonWriter cxJsonWriterCompact(void) { |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1154 | return (CxJsonWriter) { |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1155 | false, |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1156 | true, |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1157 | 6, |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1158 | false, |
1123
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
1159 | 4, |
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
1160 | false |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1161 | }; |
1077
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1162 | } |
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1163 | |
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1164 | CxJsonWriter cxJsonWriterPretty(bool use_spaces) { |
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1165 | return (CxJsonWriter) { |
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1166 | true, |
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1167 | true, |
1117
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1168 | 6, |
1077
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1169 | use_spaces, |
1123
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
1170 | 4, |
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
1171 | false |
1077
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1172 | }; |
911a154dd469
add functions to create default JSON writers - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1075
diff
changeset
|
1173 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1174 | |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1175 | static int cx_json_writer_indent( |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1176 | void *target, |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1177 | cx_write_func wfunc, |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1178 | const CxJsonWriter *settings, |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1179 | unsigned int depth |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1180 | ) { |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1181 | if (depth == 0) return 0; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1182 | |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1183 | // determine the width and characters to use |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1184 | const char* indent; // for 32 prepared chars |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1185 | size_t width = depth; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1186 | if (settings->indent_space) { |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1187 | if (settings->indent == 0) return 0; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1188 | width *= settings->indent; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1189 | indent = " "; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1190 | } else { |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1191 | indent = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1192 | } |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1193 | |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1194 | // calculate the number of write calls and write |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1195 | size_t full = width / 32; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1196 | size_t remaining = width % 32; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1197 | for (size_t i = 0; i < full; i++) { |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1198 | if (32 != wfunc(indent, 1, 32, target)) return 1; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1199 | } |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1200 | if (remaining != wfunc(indent, 1, remaining, target)) return 1; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1201 | |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1202 | return 0; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1203 | } |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1204 | |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1205 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1206 | int cx_json_write_rec( |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1207 | void *target, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1208 | const CxJsonValue *value, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1209 | cx_write_func wfunc, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1210 | const CxJsonWriter *settings, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1211 | unsigned int depth |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1212 | ) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1213 | // keep track of written items |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1214 | // the idea is to reduce the number of jumps for error checking |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1215 | size_t actual = 0, expected = 0; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1216 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1217 | // small buffer for number to string conversions |
1117
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1218 | char numbuf[40]; |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1219 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1220 | // recursively write the values |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1221 | switch (value->type) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1222 | case CX_JSON_OBJECT: { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1223 | const char *begin_obj = "{\n"; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1224 | if (settings->pretty) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1225 | actual += wfunc(begin_obj, 1, 2, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1226 | expected += 2; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1227 | } else { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1228 | actual += wfunc(begin_obj, 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1229 | expected++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1230 | } |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1231 | depth++; |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1232 | size_t elem_count = value->value.object.values_size; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1233 | for (size_t look_idx = 0; look_idx < elem_count; look_idx++) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1234 | // get the member either via index array or directly |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1235 | size_t elem_idx = settings->sort_members |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1236 | ? look_idx |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1237 | : value->value.object.indices[look_idx]; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1238 | CxJsonObjValue *member = &value->value.object.values[elem_idx]; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1239 | if (settings->sort_members) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1240 | depth++;depth--; |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1241 | } |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1242 | |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1243 | // possible indentation |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1244 | if (settings->pretty) { |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1245 | if (cx_json_writer_indent(target, wfunc, settings, depth)) { |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1246 | return 1; // LCOV_EXCL_LINE |
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1247 | } |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1248 | } |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1249 | |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1250 | // the name |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1251 | actual += wfunc("\"", 1, 1, target); |
1123
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
1252 | cxmutstr name = escape_string(member->name, settings->escape_slash); |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1253 | actual += wfunc(name.ptr, 1, name.length, target); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1254 | if (name.ptr != member->name.ptr) { |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1255 | cx_strfree(&name); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1256 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1257 | actual += wfunc("\"", 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1258 | const char *obj_name_sep = ": "; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1259 | if (settings->pretty) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1260 | actual += wfunc(obj_name_sep, 1, 2, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1261 | expected += 4 + member->name.length; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1262 | } else { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1263 | actual += wfunc(obj_name_sep, 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1264 | expected += 3 + member->name.length; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1265 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1266 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1267 | // the value |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1268 | if (cx_json_write_rec(target, member->value, wfunc, settings, depth)) return 1; |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1269 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1270 | // end of object-value |
1082
46cdc8689fc4
implement index array to preserve order of json object members
Mike Becker <universe@uap-core.de>
parents:
1079
diff
changeset
|
1271 | if (look_idx < elem_count - 1) { |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1272 | const char *obj_value_sep = ",\n"; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1273 | if (settings->pretty) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1274 | actual += wfunc(obj_value_sep, 1, 2, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1275 | expected += 2; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1276 | } else { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1277 | actual += wfunc(obj_value_sep, 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1278 | expected++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1279 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1280 | } else { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1281 | if (settings->pretty) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1282 | actual += wfunc("\n", 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1283 | expected ++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1284 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1285 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1286 | } |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1287 | depth--; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1288 | if (settings->pretty) { |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1289 | if (cx_json_writer_indent(target, wfunc, settings, depth)) return 1; |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1290 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1291 | actual += wfunc("}", 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1292 | expected++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1293 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1294 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1295 | case CX_JSON_ARRAY: { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1296 | actual += wfunc("[", 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1297 | expected++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1298 | CxIterator iter = cxJsonArrIter(value); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1299 | cx_foreach(CxJsonValue*, element, iter) { |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1300 | if (cx_json_write_rec( |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1301 | target, element, |
1078
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1302 | wfunc, settings, depth) |
ffa8bb4e9288
implement JSON pretty printing - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1077
diff
changeset
|
1303 | ) return 1; |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1304 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1305 | if (iter.index < iter.elem_count - 1) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1306 | const char *arr_value_sep = ", "; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1307 | if (settings->pretty) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1308 | actual += wfunc(arr_value_sep, 1, 2, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1309 | expected += 2; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1310 | } else { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1311 | actual += wfunc(arr_value_sep, 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1312 | expected++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1313 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1314 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1315 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1316 | actual += wfunc("]", 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1317 | expected++; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1318 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1319 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1320 | case CX_JSON_STRING: { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1321 | actual += wfunc("\"", 1, 1, target); |
1123
2b83302d595a
make escaping slashes optional - fixes #569
Mike Becker <universe@uap-core.de>
parents:
1122
diff
changeset
|
1322 | cxmutstr str = escape_string(value->value.string, settings->escape_slash); |
1119
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1323 | actual += wfunc(str.ptr, 1, str.length, target); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1324 | if (str.ptr != value->value.string.ptr) { |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1325 | cx_strfree(&str); |
ff4d7e76f85a
implement string escape - resolves #526
Mike Becker <universe@uap-core.de>
parents:
1117
diff
changeset
|
1326 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1327 | actual += wfunc("\"", 1, 1, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1328 | expected += 2 + value->value.string.length; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1329 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1330 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1331 | case CX_JSON_NUMBER: { |
1117
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1332 | int precision = settings->frac_max_digits; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1333 | // because of the way how %g is defined, we need to |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1334 | // double the precision and truncate ourselves |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1335 | precision = 1 + (precision > 15 ? 30 : 2 * precision); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1336 | snprintf(numbuf, 40, "%.*g", precision, value->value.number); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1337 | char *dot, *exp; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1338 | unsigned char max_digits; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1339 | // find the decimal separator and hope that it's one of . or , |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1340 | dot = strchr(numbuf, '.'); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1341 | if (dot == NULL) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1342 | dot = strchr(numbuf, ','); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1343 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1344 | if (dot == NULL) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1345 | // no decimal separator found |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1346 | // output everything until a possible exponent |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1347 | max_digits = 30; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1348 | dot = numbuf; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1349 | } else { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1350 | // found a decimal separator |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1351 | // output everything until the separator |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1352 | // and set max digits to what the settings say |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1353 | size_t len = dot - numbuf; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1354 | actual += wfunc(numbuf, 1, len, target); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1355 | expected += len; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1356 | max_digits = settings->frac_max_digits; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1357 | if (max_digits > 15) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1358 | max_digits = 15; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1359 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1360 | // locale independent separator |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1361 | if (max_digits > 0) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1362 | actual += wfunc(".", 1, 1, target); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1363 | expected++; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1364 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1365 | dot++; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1366 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1367 | // find the exponent |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1368 | exp = strchr(dot, 'e'); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1369 | if (exp == NULL) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1370 | // no exponent - output the rest |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1371 | if (max_digits > 0) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1372 | size_t len = strlen(dot); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1373 | if (len > max_digits) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1374 | len = max_digits; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1375 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1376 | actual += wfunc(dot, 1, len, target); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1377 | expected += len; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1378 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1379 | } else { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1380 | // exponent found - truncate the frac digits |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1381 | // and then output the rest |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1382 | if (max_digits > 0) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1383 | size_t len = exp - dot - 1; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1384 | if (len > max_digits) { |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1385 | len = max_digits; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1386 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1387 | actual += wfunc(dot, 1, len, target); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1388 | expected += len; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1389 | } |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1390 | actual += wfunc("e", 1, 1, target); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1391 | expected++; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1392 | exp++; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1393 | size_t len = strlen(exp); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1394 | actual += wfunc(exp, 1, len, target); |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1395 | expected += len; |
54df904472b0
add fractional number formatting - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1116
diff
changeset
|
1396 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1397 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1398 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1399 | case CX_JSON_INTEGER: { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1400 | snprintf(numbuf, 32, "%" PRIi64, value->value.integer); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1401 | size_t len = strlen(numbuf); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1402 | actual += wfunc(numbuf, 1, len, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1403 | expected += len; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1404 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1405 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1406 | case CX_JSON_LITERAL: { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1407 | if (value->value.literal == CX_JSON_TRUE) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1408 | actual += wfunc("true", 1, 4, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1409 | expected += 4; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1410 | } else if (value->value.literal == CX_JSON_FALSE) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1411 | actual += wfunc("false", 1, 5, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1412 | expected += 5; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1413 | } else { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1414 | actual += wfunc("null", 1, 4, target); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1415 | expected += 4; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1416 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1417 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1418 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1419 | case CX_JSON_NOTHING: { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1420 | // deliberately supported as an empty string! |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1421 | // users might want to just write the result |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1422 | // of a get operation without testing the value |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1423 | // and therefore this should not blow up |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1424 | break; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1425 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1426 | default: assert(false); // LCOV_EXCL_LINE |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1427 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1428 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1429 | return expected != actual; |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1430 | } |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1431 | |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1432 | int cxJsonWrite( |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1433 | void *target, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1434 | const CxJsonValue *value, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1435 | cx_write_func wfunc, |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1436 | const CxJsonWriter *settings |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1437 | ) { |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1438 | assert(target != NULL); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1439 | assert(value != NULL); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1440 | assert(wfunc != NULL); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1441 | |
1121
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1442 | CxJsonWriter writer_default = cxJsonWriterCompact(); |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1443 | if (settings == NULL) { |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1444 | settings = &writer_default; |
7fd2672199d7
minor cleanup of json.c
Mike Becker <universe@uap-core.de>
parents:
1119
diff
changeset
|
1445 | } |
1072
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1446 | return cx_json_write_rec(target, value, wfunc, settings, 0); |
c89283cd559b
first mvp for the json writer - relates to #526
Mike Becker <universe@uap-core.de>
parents:
1067
diff
changeset
|
1447 | } |