src/json.c

changeset 967
a58f602ed2fe
parent 965
dfdfedbe2c86
child 969
72e5432f6b42
equal deleted inserted replaced
966:1aa7ec3e46e7 967:a58f602ed2fe
28 28
29 #include <string.h> 29 #include <string.h>
30 #include <ctype.h> 30 #include <ctype.h>
31 31
32 #include "cx/json.h" 32 #include "cx/json.h"
33 #include "cx/array_list.h"
34 33
35 /* 34 /*
36 * RFC 8259 35 * RFC 8259
37 * https://tools.ietf.org/html/rfc8259 36 * https://tools.ietf.org/html/rfc8259
38 */ 37 */
564 p->readvalue_stack[0] = NULL; 563 p->readvalue_stack[0] = NULL;
565 564
566 return 0; 565 return 0;
567 } 566 }
568 567
569 static int obj_init_values(CxJson *p, CxJsonValue *v) {
570 v->value.object.values = calloc(p->reader_array_alloc, sizeof(CxJsonObjValue));
571 if (!v->value.object.values) {
572 return -1;
573 }
574 v->value.object.alloc = p->reader_array_alloc;
575 v->value.object.size = 0;
576
577 return 0;
578 }
579
580 static int obj_add_value(CxJson *p, CxJsonValue *parent, CxJsonObjValue v) {
581 if (!parent->value.object.values) {
582 if (obj_init_values(p, parent)) {
583 return -1;
584 }
585 }
586
587 if (parent->value.object.size == parent->value.object.alloc) {
588 parent->value.object.alloc *= 2;
589 if (cx_reallocate(&parent->value.object.values,
590 sizeof(CxJsonObjValue) * parent->value.object.alloc)) {
591 return -1;
592 }
593 }
594
595 parent->value.object.values[parent->value.object.size++] = v;
596
597 return 0;
598 }
599
600 static int array_init(CxJson *p, CxJsonValue *v) {
601 v->value.array.array = calloc(p->reader_array_alloc, sizeof(CxJsonValue *));
602 if (!v->value.array.array) {
603 return -1;
604 }
605 v->value.array.alloc = p->reader_array_alloc;
606 v->value.array.size = 0;
607
608 return 0;
609 }
610
611 static int array_add_value(CxJson *p, CxJsonValue *parent, CxJsonValue *v) {
612 if (!parent->value.array.array) {
613 if (array_init(p, parent)) {
614 return -1;
615 }
616 }
617
618 if (parent->value.array.size == parent->value.array.alloc) {
619 parent->value.array.alloc *= 2;
620 if (cx_reallocate(parent->value.array.array,
621 sizeof(CxJsonValue *) * parent->value.array.alloc)) {
622 return -1;
623 }
624 }
625
626 parent->value.array.array[parent->value.array.size++] = v;
627
628 return 0;
629 }
630
631 static int add_to_parent(CxJson *p, CxJsonValue *parent, CxJsonValue *v) { 568 static int add_to_parent(CxJson *p, CxJsonValue *parent, CxJsonValue *v) {
632 if (!parent) { 569 if (!parent) {
633 return -1; // shouldn't happen but who knows 570 return -1; // shouldn't happen but who knows
634 } 571 }
635 572
636 int ret = 0;
637 if (parent->type == CX_JSON_OBJECT) { 573 if (parent->type == CX_JSON_OBJECT) {
638 if (!p->value_name || p->value_name_len == 0) { 574 if (!p->value_name || p->value_name_len == 0) {
639 return -1; 575 return -1;
640 } 576 }
641 char *valuename = p->value_name; 577 char *valuename = p->value_name;
643 579
644 CxJsonObjValue newvalue; 580 CxJsonObjValue newvalue;
645 newvalue.name = valuename; 581 newvalue.name = valuename;
646 newvalue.value = v; 582 newvalue.value = v;
647 583
648 ret = obj_add_value(p, parent, newvalue); 584 return cx_array_simple_add(parent->value.object.values, newvalue);
649 } else if (parent->type == CX_JSON_ARRAY) { 585 } else if (parent->type == CX_JSON_ARRAY) {
650 ret = array_add_value(p, parent, v); 586 return cx_array_simple_add(parent->value.array.array, v);
651 } else { 587 } else {
652 ret = -1; // should also never happen 588 return -1; // should also never happen
653 } 589 }
654
655 return ret;
656 } 590 }
657 591
658 592
659 static int readvaluestack_add(CxJson *p, CxJsonValue *v) { 593 static int readvaluestack_add(CxJson *p, CxJsonValue *v) {
660 if (p->readvalue_nelm == p->readvalue_alloc) { 594 if (p->readvalue_nelm == p->readvalue_alloc) {
790 724
791 // TODO: discuss if we should keep freeing the stuff recursively 725 // TODO: discuss if we should keep freeing the stuff recursively
792 switch (value->type) { 726 switch (value->type) {
793 case CX_JSON_OBJECT: { 727 case CX_JSON_OBJECT: {
794 CxJsonObject obj = value->value.object; 728 CxJsonObject obj = value->value.object;
795 for (size_t i = 0; i < obj.size; i++) { 729 for (size_t i = 0; i < obj.values_size; i++) {
796 cxJsonValueFree(obj.values[i].value); 730 cxJsonValueFree(obj.values[i].value);
797 free(obj.values[i].name); 731 free(obj.values[i].name);
798 } 732 }
799 free(obj.values); 733 free(obj.values);
800 break; 734 break;
801 } 735 }
802 case CX_JSON_ARRAY: { 736 case CX_JSON_ARRAY: {
803 CxJsonArray array = value->value.array; 737 CxJsonArray array = value->value.array;
804 for (size_t i = 0; i < array.size; i++) { 738 for (size_t i = 0; i < array.array_size; i++) {
805 cxJsonValueFree(array.array[i]); 739 cxJsonValueFree(array.array[i]);
806 } 740 }
807 free(array.array); 741 free(array.array);
808 break; 742 break;
809 } 743 }
817 } 751 }
818 free(value); 752 free(value);
819 } 753 }
820 754
821 CxJsonValue *cxJsonArrGet(CxJsonValue *value, size_t index) { 755 CxJsonValue *cxJsonArrGet(CxJsonValue *value, size_t index) {
822 if (index >= value->value.array.size) { 756 if (index >= value->value.array.array_size) {
823 return &cx_json_value_nothing; 757 return &cx_json_value_nothing;
824 } 758 }
825 return value->value.array.array[index]; 759 return value->value.array.array[index];
826 } 760 }
827 761
828 CxJsonValue *cxJsonObjGet(CxJsonValue *value, const char *name) { 762 CxJsonValue *cxJsonObjGet(CxJsonValue *value, const char *name) {
829 CxJsonObject *obj = &(value->value.object); 763 CxJsonObject *obj = &(value->value.object);
830 // TODO: think about sorting the object so that we can use binary search here 764 // TODO: think about sorting the object so that we can use binary search here
831 for (size_t i = 0; i < obj->size; i++) { 765 for (size_t i = 0; i < obj->values_size; i++) {
832 // TODO: we might want to store names as cxmutstr 766 // TODO: we might want to store names as cxmutstr
833 if (0 == strcmp(name, obj->values[i].name)) { 767 if (0 == strcmp(name, obj->values[i].name)) {
834 return obj->values[i].value; 768 return obj->values[i].value;
835 } 769 }
836 } 770 }

mercurial