| 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]; |