src/json.c

changeset 1415
40074e643663
parent 1340
31c61b6dcaa5
equal deleted inserted replaced
1414:597cf869e8bc 1415:40074e643663
30 30
31 #include <string.h> 31 #include <string.h>
32 #include <assert.h> 32 #include <assert.h>
33 #include <stdio.h> 33 #include <stdio.h>
34 #include <inttypes.h> 34 #include <inttypes.h>
35 #include <ctype.h>
35 36
36 /* 37 /*
37 * RFC 8259 38 * RFC 8259
38 * https://tools.ietf.org/html/rfc8259 39 * https://tools.ietf.org/html/rfc8259
39 */ 40 */
125 if (token->allocated) { 126 if (token->allocated) {
126 cx_strfree(&token->content); 127 cx_strfree(&token->content);
127 } 128 }
128 } 129 }
129 130
130 static bool json_isdigit(char c) {
131 // TODO: remove once UCX has public API for this
132 return c >= '0' && c <= '9';
133 }
134
135 static bool json_isspace(char c) {
136 // TODO: remove once UCX has public API for this
137 return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f';
138 }
139
140 static int num_isexp(const char *content, size_t length, size_t pos) { 131 static int num_isexp(const char *content, size_t length, size_t pos) {
141 if (pos >= length) { 132 if (pos >= length) {
142 return 0; 133 return 0;
143 } 134 }
144 135
145 int ok = 0; 136 int ok = 0;
146 for (size_t i = pos; i < length; i++) { 137 for (size_t i = pos; i < length; i++) {
147 char c = content[i]; 138 char c = content[i];
148 if (json_isdigit(c)) { 139 if (isdigit((unsigned char)c)) {
149 ok = 1; 140 ok = 1;
150 } else if (i == pos) { 141 } else if (i == pos) {
151 if (!(c == '+' || c == '-')) { 142 if (!(c == '+' || c == '-')) {
152 return 0; 143 return 0;
153 } 144 }
160 } 151 }
161 152
162 static CxJsonTokenType token_numbertype(const char *content, size_t length) { 153 static CxJsonTokenType token_numbertype(const char *content, size_t length) {
163 if (length == 0) return CX_JSON_TOKEN_ERROR; 154 if (length == 0) return CX_JSON_TOKEN_ERROR;
164 155
165 if (content[0] != '-' && !json_isdigit(content[0])) { 156 if (content[0] != '-' && !isdigit((unsigned char)content[0])) {
166 return CX_JSON_TOKEN_ERROR; 157 return CX_JSON_TOKEN_ERROR;
167 } 158 }
168 159
169 CxJsonTokenType type = CX_JSON_TOKEN_INTEGER; 160 CxJsonTokenType type = CX_JSON_TOKEN_INTEGER;
170 for (size_t i = 1; i < length; i++) { 161 for (size_t i = 1; i < length; i++) {
173 return CX_JSON_TOKEN_ERROR; // more than one decimal separator 164 return CX_JSON_TOKEN_ERROR; // more than one decimal separator
174 } 165 }
175 type = CX_JSON_TOKEN_NUMBER; 166 type = CX_JSON_TOKEN_NUMBER;
176 } else if (content[i] == 'e' || content[i] == 'E') { 167 } else if (content[i] == 'e' || content[i] == 'E') {
177 return num_isexp(content, length, i + 1) ? CX_JSON_TOKEN_NUMBER : CX_JSON_TOKEN_ERROR; 168 return num_isexp(content, length, i + 1) ? CX_JSON_TOKEN_NUMBER : CX_JSON_TOKEN_ERROR;
178 } else if (!json_isdigit(content[i])) { 169 } else if (!isdigit((unsigned char)content[i])) {
179 return CX_JSON_TOKEN_ERROR; // char is not a digit, decimal separator or exponent sep 170 return CX_JSON_TOKEN_ERROR; // char is not a digit, decimal separator or exponent sep
180 } 171 }
181 } 172 }
182 173
183 return type; 174 return type;
237 } 228 }
238 case '"': { 229 case '"': {
239 return CX_JSON_TOKEN_STRING; 230 return CX_JSON_TOKEN_STRING;
240 } 231 }
241 default: { 232 default: {
242 if (json_isspace(c)) { 233 if (isspace((unsigned char)c)) {
243 return CX_JSON_TOKEN_SPACE; 234 return CX_JSON_TOKEN_SPACE;
244 } 235 }
245 } 236 }
246 } 237 }
247 return CX_JSON_NO_TOKEN; 238 return CX_JSON_NO_TOKEN;

mercurial