src/json.c

changeset 969
72e5432f6b42
parent 967
a58f602ed2fe
equal deleted inserted replaced
968:b5814aac3a76 969:72e5432f6b42
299 result.ptr[result.length] = 0; 299 result.ptr[result.length] = 0;
300 300
301 return result; 301 return result;
302 } 302 }
303 303
304 static int parse_integer(const char *str, size_t len, int64_t *value) { 304 static int parse_number(const char *str, size_t len, void *value, bool asint) {
305 char *endptr = NULL; 305 char *endptr = NULL;
306 char buf[32]; 306 char buf[32];
307 if (len > 30) { 307 if (len > 30) {
308 return 1; 308 return 1;
309 } 309 }
310 // TODO: if we can guarantee that we are working on a copied string already, we can avoid this memcpy
310 memcpy(buf, str, len); 311 memcpy(buf, str, len);
311 buf[len] = 0; 312 buf[len] = 0;
312 313
313 long long v = strtoll(buf, &endptr, 10); 314 if (asint) {
314 if (endptr != &buf[len]) { 315 long long v = strtoll(buf, &endptr, 10);
315 return 1; 316 *((int64_t*)value) = (int64_t) v;
316 } 317 } else {
317 *value = (int64_t) v; 318 // TODO: proper JSON spec number parser
318 319 double v = strtod(buf, &endptr);
319 return 0; 320 *((double*)value) = v;
320 } 321 }
321 322
322 static int parse_number(const char *str, size_t len, double *value) { 323 return (endptr != &buf[len]);
323 char *endptr = NULL;
324 char buf[32];
325 if (len > 30) {
326 return 1;
327 }
328 memcpy(buf, str, len);
329 buf[len] = 0;
330
331 double v = strtod(buf, &endptr);
332 if (endptr != &buf[len]) {
333 return 1;
334 }
335 *value = v;
336
337 return 0;
338 } 324 }
339 325
340 static int add_state(CxJson *p, int state) { 326 static int add_state(CxJson *p, int state) {
341 CxArrayReallocator alloc = cx_array_reallocator(NULL, p->states_internal); 327 CxArrayReallocator alloc = cx_array_reallocator(NULL, p->states_internal);
342 size_t size = p->nstates + 1; 328 size_t size = p->nstates + 1;
460 } 446 }
461 break; 447 break;
462 } 448 }
463 case CX_JSON_TOKEN_INTEGER: { 449 case CX_JSON_TOKEN_INTEGER: {
464 p->reader_type = CX_JSON_READER_INTEGER; 450 p->reader_type = CX_JSON_READER_INTEGER;
465 int64_t value; 451 if (parse_number(token.content, token.length,
466 if (parse_integer(token.content, token.length, &value)) { 452 &p->value_int, true)) {
467 ret = -1; 453 ret = -1;
468 } else {
469 p->value_int = value;
470 p->value_double = (double) value;
471 } 454 }
472 break; 455 break;
473 } 456 }
474 case CX_JSON_TOKEN_NUMBER: { 457 case CX_JSON_TOKEN_NUMBER: {
475 p->reader_type = CX_JSON_READER_NUMBER; 458 p->reader_type = CX_JSON_READER_NUMBER;
476 double value; 459 if (parse_number(token.content, token.length,
477 if (parse_number(token.content, token.length, &value)) { 460 &p->value_double, false)) {
478 ret = -1; 461 ret = -1;
479 } else {
480 p->value_double = value;
481 p->value_int = (int64_t) value;
482 } 462 }
483 break; 463 break;
484 } 464 }
485 case CX_JSON_TOKEN_LITERAL: { 465 case CX_JSON_TOKEN_LITERAL: {
486 p->reader_type = CX_JSON_READER_LITERAL; 466 p->reader_type = CX_JSON_READER_LITERAL;

mercurial