| 44 const CxJsonObjValue *left = l; |
44 const CxJsonObjValue *left = l; |
| 45 const CxJsonObjValue *right = r; |
45 const CxJsonObjValue *right = r; |
| 46 return cx_strcmp(cx_strcast(left->name), cx_strcast(right->name)); |
46 return cx_strcmp(cx_strcast(left->name), cx_strcast(right->name)); |
| 47 } |
47 } |
| 48 |
48 |
| 49 static CxJsonObjValue *json_find_objvalue(const CxJsonValue *obj, cxstring name) { |
49 static size_t json_find_objvalue(const CxJsonValue *obj, cxstring name) { |
| 50 assert(obj->type == CX_JSON_OBJECT); |
50 assert(obj->type == CX_JSON_OBJECT); |
| 51 CxJsonObjValue kv_dummy; |
51 CxJsonObjValue kv_dummy; |
| 52 kv_dummy.name = cx_mutstrn((char*) name.ptr, name.length); |
52 kv_dummy.name = cx_mutstrn((char*) name.ptr, name.length); |
| 53 size_t index = cx_array_binary_search( |
53 return cx_array_binary_search( |
| 54 obj->value.object.values, |
54 obj->value.object.values, |
| 55 obj->value.object.values_size, |
55 obj->value.object.values_size, |
| 56 sizeof(CxJsonObjValue), |
56 sizeof(CxJsonObjValue), |
| 57 &kv_dummy, |
57 &kv_dummy, |
| 58 json_cmp_objvalue |
58 json_cmp_objvalue |
| 59 ); |
59 ); |
| 60 if (index == obj->value.object.values_size) { |
|
| 61 return NULL; |
|
| 62 } else { |
|
| 63 return &obj->value.object.values[index]; |
|
| 64 } |
|
| 65 } |
60 } |
| 66 |
61 |
| 67 static int json_add_objvalue(CxJsonValue *objv, CxJsonObjValue member) { |
62 static int json_add_objvalue(CxJsonValue *objv, CxJsonObjValue member) { |
| 68 assert(objv->type == CX_JSON_OBJECT); |
63 assert(objv->type == CX_JSON_OBJECT); |
| 69 const CxAllocator * const al = objv->allocator; |
64 const CxAllocator * const al = objv->allocator; |
| 982 static void json_arr_free_temp(CxJsonValue** values, size_t count) { |
977 static void json_arr_free_temp(CxJsonValue** values, size_t count) { |
| 983 for (size_t i = 0; i < count; i++) { |
978 for (size_t i = 0; i < count; i++) { |
| 984 if (values[i] == NULL) break; |
979 if (values[i] == NULL) break; |
| 985 cxJsonValueFree(values[i]); |
980 cxJsonValueFree(values[i]); |
| 986 } |
981 } |
| 987 free(values); |
982 cxFreeDefault(values); |
| 988 } |
983 } |
| 989 // LCOV_EXCL_STOP |
984 // LCOV_EXCL_STOP |
| 990 |
985 |
| 991 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) { |
986 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count) { |
| 992 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
987 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
| 993 if (values == NULL) return -1; |
988 if (values == NULL) return -1; |
| 994 for (size_t i = 0; i < count; i++) { |
989 for (size_t i = 0; i < count; i++) { |
| 995 values[i] = cxJsonCreateNumber(arr->allocator, num[i]); |
990 values[i] = cxJsonCreateNumber(arr->allocator, num[i]); |
| 996 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
991 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
| 997 } |
992 } |
| 998 int ret = cxJsonArrAddValues(arr, values, count); |
993 int ret = cxJsonArrAddValues(arr, values, count); |
| 999 free(values); |
994 cxFreeDefault(values); |
| 1000 return ret; |
995 return ret; |
| 1001 } |
996 } |
| 1002 |
997 |
| 1003 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) { |
998 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count) { |
| 1004 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
999 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
| 1005 if (values == NULL) return -1; |
1000 if (values == NULL) return -1; |
| 1006 for (size_t i = 0; i < count; i++) { |
1001 for (size_t i = 0; i < count; i++) { |
| 1007 values[i] = cxJsonCreateInteger(arr->allocator, num[i]); |
1002 values[i] = cxJsonCreateInteger(arr->allocator, num[i]); |
| 1008 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1003 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
| 1009 } |
1004 } |
| 1010 int ret = cxJsonArrAddValues(arr, values, count); |
1005 int ret = cxJsonArrAddValues(arr, values, count); |
| 1011 free(values); |
1006 cxFreeDefault(values); |
| 1012 return ret; |
1007 return ret; |
| 1013 } |
1008 } |
| 1014 |
1009 |
| 1015 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) { |
1010 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count) { |
| 1016 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
1011 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
| 1017 if (values == NULL) return -1; |
1012 if (values == NULL) return -1; |
| 1018 for (size_t i = 0; i < count; i++) { |
1013 for (size_t i = 0; i < count; i++) { |
| 1019 values[i] = cxJsonCreateString(arr->allocator, str[i]); |
1014 values[i] = cxJsonCreateString(arr->allocator, str[i]); |
| 1020 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1015 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
| 1021 } |
1016 } |
| 1022 int ret = cxJsonArrAddValues(arr, values, count); |
1017 int ret = cxJsonArrAddValues(arr, values, count); |
| 1023 free(values); |
1018 cxFreeDefault(values); |
| 1024 return ret; |
1019 return ret; |
| 1025 } |
1020 } |
| 1026 |
1021 |
| 1027 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) { |
1022 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count) { |
| 1028 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
1023 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
| 1029 if (values == NULL) return -1; |
1024 if (values == NULL) return -1; |
| 1030 for (size_t i = 0; i < count; i++) { |
1025 for (size_t i = 0; i < count; i++) { |
| 1031 values[i] = cxJsonCreateCxString(arr->allocator, str[i]); |
1026 values[i] = cxJsonCreateCxString(arr->allocator, str[i]); |
| 1032 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1027 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
| 1033 } |
1028 } |
| 1034 int ret = cxJsonArrAddValues(arr, values, count); |
1029 int ret = cxJsonArrAddValues(arr, values, count); |
| 1035 free(values); |
1030 cxFreeDefault(values); |
| 1036 return ret; |
1031 return ret; |
| 1037 } |
1032 } |
| 1038 |
1033 |
| 1039 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) { |
1034 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count) { |
| 1040 CxJsonValue** values = calloc(count, sizeof(CxJsonValue*)); |
1035 CxJsonValue** values = cxCallocDefault(count, sizeof(CxJsonValue*)); |
| 1041 if (values == NULL) return -1; |
1036 if (values == NULL) return -1; |
| 1042 for (size_t i = 0; i < count; i++) { |
1037 for (size_t i = 0; i < count; i++) { |
| 1043 values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]); |
1038 values[i] = cxJsonCreateLiteral(arr->allocator, lit[i]); |
| 1044 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
1039 if (values[i] == NULL) { json_arr_free_temp(values, count); return -1; } |
| 1045 } |
1040 } |
| 1046 int ret = cxJsonArrAddValues(arr, values, count); |
1041 int ret = cxJsonArrAddValues(arr, values, count); |
| 1047 free(values); |
1042 cxFreeDefault(values); |
| 1048 return ret; |
1043 return ret; |
| 1049 } |
1044 } |
| 1050 |
1045 |
| 1051 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { |
1046 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count) { |
| 1052 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); |
1047 CxArrayReallocator value_realloc = cx_array_reallocator(arr->allocator, NULL); |
| 1140 value->value.object.values_size |
1149 value->value.object.values_size |
| 1141 ); |
1150 ); |
| 1142 } |
1151 } |
| 1143 |
1152 |
| 1144 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) { |
1153 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) { |
| 1145 CxJsonObjValue *member = json_find_objvalue(value, name); |
1154 size_t index = json_find_objvalue(value, name); |
| 1146 if (member == NULL) { |
1155 if (index >= value->value.object.values_size) { |
| 1147 return &cx_json_value_nothing; |
1156 return &cx_json_value_nothing; |
| 1148 } else { |
1157 } else { |
| 1149 return member->value; |
1158 return value->value.object.values[index].value; |
| |
1159 } |
| |
1160 } |
| |
1161 |
| |
1162 CxJsonValue *cx_json_obj_remove_cxstr(CxJsonValue *value, cxstring name) { |
| |
1163 size_t index = json_find_objvalue(value, name); |
| |
1164 if (index >= value->value.object.values_size) { |
| |
1165 return NULL; |
| |
1166 } else { |
| |
1167 CxJsonObjValue kv = value->value.object.values[index]; |
| |
1168 cx_strfree_a(value->allocator, &kv.name); |
| |
1169 // TODO: replace with cx_array_remove() |
| |
1170 value->value.object.values_size--; |
| |
1171 memmove(value->value.object.values + index, value->value.object.values + index + 1, (value->value.object.values_size - index) * sizeof(CxJsonObjValue)); |
| |
1172 return kv.value; |
| 1150 } |
1173 } |
| 1151 } |
1174 } |
| 1152 |
1175 |
| 1153 CxJsonWriter cxJsonWriterCompact(void) { |
1176 CxJsonWriter cxJsonWriterCompact(void) { |
| 1154 return (CxJsonWriter) { |
1177 return (CxJsonWriter) { |