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 } |