663 } |
663 } |
664 } |
664 } |
665 cxFree(value->allocator, value); |
665 cxFree(value->allocator, value); |
666 } |
666 } |
667 |
667 |
|
668 CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator) { |
|
669 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
|
670 if (v == NULL) return NULL; |
|
671 v->allocator = allocator; |
|
672 v->type = CX_JSON_OBJECT; |
|
673 cx_array_initialize_a(allocator, v->value.object.values, 16); |
|
674 if (v->value.object.values == NULL) { cxFree(allocator, v); return NULL; } |
|
675 return v; |
|
676 } |
|
677 |
|
678 CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator) { |
|
679 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
|
680 if (v == NULL) return NULL; |
|
681 v->allocator = allocator; |
|
682 v->type = CX_JSON_ARRAY; |
|
683 cx_array_initialize_a(allocator, v->value.array.array, 16); |
|
684 if (v->value.array.array == NULL) { cxFree(allocator, v); return NULL; } |
|
685 return v; |
|
686 } |
|
687 |
|
688 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num) { |
|
689 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
|
690 if (v == NULL) return NULL; |
|
691 v->allocator = allocator; |
|
692 v->type = CX_JSON_NUMBER; |
|
693 v->value.number = num; |
|
694 return v; |
|
695 } |
|
696 |
|
697 CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num) { |
|
698 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
|
699 if (v == NULL) return NULL; |
|
700 v->allocator = allocator; |
|
701 v->type = CX_JSON_INTEGER; |
|
702 v->value.integer = num; |
|
703 return v; |
|
704 } |
|
705 |
|
706 CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char* str) { |
|
707 return cxJsonCreateCxString(allocator, cx_str(str)); |
|
708 } |
|
709 |
|
710 CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str) { |
|
711 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
|
712 if (v == NULL) return NULL; |
|
713 v->allocator = allocator; |
|
714 v->type = CX_JSON_STRING; |
|
715 cxmutstr s = cx_strdup_a(allocator, str); |
|
716 if (s.ptr == NULL) { cxFree(allocator, v); return NULL; } |
|
717 return v; |
|
718 } |
|
719 |
|
720 CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit) { |
|
721 CxJsonValue* v = cxMalloc(allocator, sizeof(CxJsonValue)); |
|
722 if (v == NULL) return NULL; |
|
723 v->allocator = allocator; |
|
724 v->type = CX_JSON_LITERAL; |
|
725 v->value.literal = lit; |
|
726 return v; |
|
727 } |
|
728 |
|
729 static void cx_json_arr_free_temp(CxJsonValue** values, size_t count) { |
|
730 for (size_t i = 0; i < count; i++) { |
|
731 if (values[i] == NULL) break; |
|
732 cxJsonValueFree(values[i]); |
|
733 } |
|
734 free(values); |
|
735 } |
|
736 |
|
737 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) { |
|
738 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
|
739 if (values == NULL) return -1; |
|
740 for (size_t i = 0; i < count; i++) { |
|
741 values[i] = cxJsonCreateNumber(arr->allocator, num[i]); |
|
742 if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; } |
|
743 } |
|
744 int ret = cxJsonArrAddValues(arr, values, count); |
|
745 free(values); |
|
746 return ret; |
|
747 } |
|
748 |
|
749 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) { |
|
750 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
|
751 if (values == NULL) return -1; |
|
752 for (size_t i = 0; i < count; i++) { |
|
753 values[i] = cxJsonCreateInteger(arr->allocator, num[i]); |
|
754 if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; } |
|
755 } |
|
756 int ret = cxJsonArrAddValues(arr, values, count); |
|
757 free(values); |
|
758 return ret; |
|
759 } |
|
760 |
|
761 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) { |
|
762 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
|
763 if (values == NULL) return -1; |
|
764 for (size_t i = 0; i < count; i++) { |
|
765 values[i] = cxJsonCreateString(arr->allocator, str[i]); |
|
766 if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; } |
|
767 } |
|
768 int ret = cxJsonArrAddValues(arr, values, count); |
|
769 free(values); |
|
770 return ret; |
|
771 } |
|
772 |
|
773 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) { |
|
774 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
|
775 if (values == NULL) return -1; |
|
776 for (size_t i = 0; i < count; i++) { |
|
777 values[i] = cxJsonCreateCxString(arr->allocator, str[i]); |
|
778 if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; } |
|
779 } |
|
780 int ret = cxJsonArrAddValues(arr, values, count); |
|
781 free(values); |
|
782 return ret; |
|
783 } |
|
784 |
|
785 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) { |
|
786 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
|
787 if (values == NULL) return -1; |
|
788 for (size_t i = 0; i < count; i++) { |
|
789 values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]); |
|
790 if (values[i] == NULL) { cx_json_arr_free_temp(values, count); return -1; } |
|
791 } |
|
792 int ret = cxJsonArrAddValues(arr, values, count); |
|
793 free(values); |
|
794 return ret; |
|
795 } |
|
796 |
|
797 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { |
|
798 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); |
|
799 assert(arr->type == CX_JSON_ARRAY); |
|
800 return cx_array_simple_copy_a(&value_realloc, |
|
801 arr->value.array.array, |
|
802 arr->value.array.array_size, |
|
803 val, count |
|
804 ); |
|
805 } |
|
806 |
|
807 int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child) { |
|
808 CxArrayReallocator value_realloc = cx_array_reallocator(obj->allocator, NULL); |
|
809 assert(obj->type == CX_JSON_OBJECT); |
|
810 cxmutstr k = cx_strdup_a(obj->allocator, name); |
|
811 if (k.ptr == NULL) return -1; |
|
812 CxJsonObjValue kv = {k, child}; |
|
813 return cx_array_simple_add_a(&value_realloc, obj->value.object.values, kv); |
|
814 } |
|
815 |
|
816 CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name) { |
|
817 CxJsonValue* v = cxJsonCreateObj(obj->allocator); |
|
818 if (v == NULL) return NULL; |
|
819 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
|
820 return v; |
|
821 } |
|
822 |
|
823 CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name) { |
|
824 CxJsonValue* v = cxJsonCreateArr(obj->allocator); |
|
825 if (v == NULL) return NULL; |
|
826 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
|
827 return v; |
|
828 } |
|
829 |
|
830 CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num) { |
|
831 CxJsonValue* v = cxJsonCreateNumber(obj->allocator, num); |
|
832 if (v == NULL) return NULL; |
|
833 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
|
834 return v; |
|
835 } |
|
836 |
|
837 CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num) { |
|
838 CxJsonValue* v = cxJsonCreateInteger(obj->allocator, num); |
|
839 if (v == NULL) return NULL; |
|
840 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
|
841 return v; |
|
842 } |
|
843 |
|
844 CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str) { |
|
845 CxJsonValue* v = cxJsonCreateString(obj->allocator, str); |
|
846 if (v == NULL) return NULL; |
|
847 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
|
848 return v; |
|
849 } |
|
850 |
|
851 CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str) { |
|
852 CxJsonValue* v = cxJsonCreateCxString(obj->allocator, str); |
|
853 if (v == NULL) return NULL; |
|
854 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL; } |
|
855 return v; |
|
856 } |
|
857 |
|
858 CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit) { |
|
859 CxJsonValue* v = cxJsonCreateLiteral(obj->allocator, lit); |
|
860 if (v == NULL) return NULL; |
|
861 if (cxJsonObjPut(obj, name, v)) { cxJsonValueFree(v); return NULL;} |
|
862 return v; |
|
863 } |
|
864 |
668 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) { |
865 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) { |
669 if (index >= value->value.array.array_size) { |
866 if (index >= value->value.array.array_size) { |
670 return &cx_json_value_nothing; |
867 return &cx_json_value_nothing; |
671 } |
868 } |
672 return value->value.array.array[index]; |
869 return value->value.array.array[index]; |