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