src/json.c

changeset 946
b428424c0214
parent 944
c26299cc9897
equal deleted inserted replaced
945:84a5fab8a47c 946:b428424c0214
36 * RFC 8259 36 * RFC 8259
37 * https://tools.ietf.org/html/rfc8259 37 * https://tools.ietf.org/html/rfc8259
38 */ 38 */
39 39
40 #define PARSER_STATES_ALLOC 32 40 #define PARSER_STATES_ALLOC 32
41 #define PARSER_READVALUE_ALLOC 32
41 42
42 static CxJsonValue cx_json_value_nothing = {.type = CX_JSON_NOTHING}; 43 static CxJsonValue cx_json_value_nothing = {.type = CX_JSON_NOTHING};
43 44
44 45
45 static int token_append(CxJsonToken *token, const char *buf, size_t len) { 46 static int token_append(CxJsonToken *token, const char *buf, size_t len) {
337 338
338 return 0; 339 return 0;
339 } 340 }
340 341
341 static int add_state(CxJson *p, int state) { 342 static int add_state(CxJson *p, int state) {
343 // TODO: this is such a common pattern, try to reuse code here
342 if (p->nstates >= p->states_alloc) { 344 if (p->nstates >= p->states_alloc) {
343 p->states_alloc += PARSER_STATES_ALLOC; 345 unsigned newcap = PARSER_STATES_ALLOC;
344 if (cx_reallocate(&p->states, p->states_alloc * sizeof(int))) { 346 if (p->states == p->states_internal) {
345 return 1; 347 void *mem = malloc(newcap * sizeof(int));
346 } 348 if (mem == NULL) return 1;
349 memcpy(mem, p->states, p->nstates * sizeof(int));
350 p->states = mem;
351 } else {
352 newcap += p->states_alloc;
353 if (cx_reallocate(&p->states, newcap * sizeof(int))) {
354 return 1;
355 }
356 }
357 p->states_alloc = newcap;
347 } 358 }
348 p->states[++p->nstates] = state; 359 p->states[++p->nstates] = state;
349 return 0; 360 return 0;
350 } 361 }
351 362
543 } 554 }
544 555
545 /* -------------------- read value functions -------------------- */ 556 /* -------------------- read value functions -------------------- */
546 557
547 static int setup_read_value(CxJson *p) { 558 static int setup_read_value(CxJson *p) {
548 p->readvalue_alloc = PARSER_STATES_ALLOC; 559 p->readvalue_alloc = PARSER_READVALUE_ALLOC;
549 p->readvalue_nelm = 0; 560 p->readvalue_nelm = 0;
550 p->readvalue_stack = calloc(PARSER_STATES_ALLOC, sizeof(CxJsonValue *)); 561 p->readvalue_stack = calloc(p->readvalue_alloc, sizeof(CxJsonValue *));
551 if (!p->readvalue_stack) return -1; 562 if (!p->readvalue_stack) return -1;
552 563
553 p->read_value = NULL; 564 p->read_value = NULL;
554 p->readvalue_stack[0] = NULL; 565 p->readvalue_stack[0] = NULL;
555 566
657 return 0; 668 return 0;
658 } 669 }
659 670
660 void cxJsonInit(CxJson *json) { 671 void cxJsonInit(CxJson *json) {
661 memset(json, 0, sizeof(CxJson)); 672 memset(json, 0, sizeof(CxJson));
662 // TODO: do not allocate states right away 673 json->states = json->states_internal;
663 json->states_alloc = PARSER_STATES_ALLOC; 674 json->states_alloc = cx_nmemb(json->states_internal);
664 json->states = calloc(PARSER_STATES_ALLOC, sizeof(int));
665 // TODO: find better way to configure the initial allocation size for arrays and objects 675 // TODO: find better way to configure the initial allocation size for arrays and objects
666 json->reader_array_alloc = 8; 676 json->reader_array_alloc = 8;
667 } 677 }
668 678
669 void cxJsonDestroy(CxJson *p) { 679 void cxJsonDestroy(CxJson *p) {
670 free(p->states); 680 if (p->states != p->states_internal) {
681 free(p->states);
682 }
671 free(p->readvalue_stack); 683 free(p->readvalue_stack);
672 cxJsonValueFree(p->read_value); 684 cxJsonValueFree(p->read_value);
673 free(p->value_name); 685 free(p->value_name);
674 free(p->value_str); 686 free(p->value_str);
675 } 687 }
682 } 694 }
683 695
684 int cxJsonNext(CxJson *p, CxJsonValue **value) { 696 int cxJsonNext(CxJson *p, CxJsonValue **value) {
685 // TODO: replace int with a status enum like in CxProperties 697 // TODO: replace int with a status enum like in CxProperties
686 698
687 *value = NULL; 699 *value = NULL; // TODO: maybe better initialize with NOTHING?
688 if (!p->readvalue_stack) { 700 if (!p->readvalue_stack) {
689 if (setup_read_value(p)) return -1; 701 if (setup_read_value(p)) return -1;
690 } 702 }
691 703
692 while (p->readvalue_nelm > 0 || !p->read_value) { 704 while (p->readvalue_nelm > 0 || !p->read_value) {

mercurial