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; |
1154 value->value.object.values_size |
1149 value->value.object.values_size |
1155 ); |
1150 ); |
1156 } |
1151 } |
1157 |
1152 |
1158 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) { |
1153 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name) { |
1159 CxJsonObjValue *member = json_find_objvalue(value, name); |
1154 size_t index = json_find_objvalue(value, name); |
1160 if (member == NULL) { |
1155 if (index == value->value.object.values_size) { |
1161 return &cx_json_value_nothing; |
1156 return &cx_json_value_nothing; |
1162 } else { |
1157 } else { |
1163 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; |
1164 } |
1173 } |
1165 } |
1174 } |
1166 |
1175 |
1167 CxJsonWriter cxJsonWriterCompact(void) { |
1176 CxJsonWriter cxJsonWriterCompact(void) { |
1168 return (CxJsonWriter) { |
1177 return (CxJsonWriter) { |