@@ -166,12 +166,14 @@ JSONC_0.15 { | |||||
JSONC_0.16 { | JSONC_0.16 { | ||||
global: | global: | ||||
lh_string_data; | |||||
lh_string_size; | |||||
lh_string_print; | |||||
json_key_data; | |||||
json_key_size; | |||||
json_object_object_add_len; | json_object_object_add_len; | ||||
json_object_object_add_ex_len; | json_object_object_add_ex_len; | ||||
json_object_object_add_key; | |||||
json_object_object_del_len; | json_object_object_del_len; | ||||
json_object_object_del_key; | |||||
json_object_object_get_len; | json_object_object_get_len; | ||||
json_object_object_get_ex_len; | json_object_object_get_ex_len; | ||||
json_object_object_get_key; | |||||
} JSONC_0.15; | } JSONC_0.15; |
@@ -116,12 +116,6 @@ static inline const struct json_object_string *JC_STRING_C(const struct json_obj | |||||
static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size, | static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size, | ||||
json_object_to_json_string_fn *to_json_string); | json_object_to_json_string_fn *to_json_string); | ||||
static int json_object_object_del_internal(struct json_object *jso_base, | |||||
const struct lh_string *key); | |||||
static json_bool json_object_object_get_internal(const struct json_object *jso, | |||||
const struct lh_string *key, | |||||
struct json_object **value); | |||||
static void json_object_object_delete(struct json_object *jso_base); | static void json_object_object_delete(struct json_object *jso_base); | ||||
static void json_object_string_delete(struct json_object *jso); | static void json_object_string_delete(struct json_object *jso); | ||||
static void json_object_array_delete(struct json_object *jso); | static void json_object_array_delete(struct json_object *jso); | ||||
@@ -512,7 +506,7 @@ static int json_object_object_to_json_string(struct json_object *jso, struct pri | |||||
printbuf_strappend(pb, " "); | printbuf_strappend(pb, " "); | ||||
indent(pb, level + 1, flags); | indent(pb, level + 1, flags); | ||||
printbuf_strappend(pb, "\""); | printbuf_strappend(pb, "\""); | ||||
json_escape_str(pb, lh_string_data(iter.key), lh_string_size(iter.key), flags); | |||||
json_escape_str(pb, json_key_data(iter.key), json_key_size(iter.key), flags); | |||||
if (flags & JSON_C_TO_STRING_SPACED) | if (flags & JSON_C_TO_STRING_SPACED) | ||||
printbuf_strappend(pb, "\": "); | printbuf_strappend(pb, "\": "); | ||||
else | else | ||||
@@ -583,20 +577,20 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key, | |||||
int json_object_object_add_ex_len(struct json_object *jso, const char *const key, const int len, | int json_object_object_add_ex_len(struct json_object *jso, const char *const key, const int len, | ||||
struct json_object *const val, const unsigned opts) | struct json_object *const val, const unsigned opts) | ||||
{ | { | ||||
// Created on the stack rather than calling `lh_string_new_ptr` | |||||
// or `lh_string_new_imm` since this saves copying `key` if it turns | |||||
// Created on the stack rather than calling `json_key_new_ptr` | |||||
// or `json_key_new_imm` since this saves copying `key` if it turns | |||||
// out the value already exists in the hash table | // out the value already exists in the hash table | ||||
const struct lh_string hashable = {.length = len, .str = {.pdata = key}}; | |||||
return json_object_object_add_internal(jso, &hashable, val, opts); | |||||
const struct json_key hashable = {.length = len, .str = {.pdata = key}}; | |||||
return json_object_object_add_key(jso, &hashable, val, opts); | |||||
} | } | ||||
int json_object_object_add_internal(struct json_object *jso, const struct lh_string *key, | |||||
struct json_object *const val, const unsigned opts) | |||||
int json_object_object_add_key(struct json_object *jso, const struct json_key *key, | |||||
struct json_object *const val, const unsigned opts) | |||||
{ | { | ||||
struct json_object *existing_value; | struct json_object *existing_value; | ||||
struct lh_entry *existing_entry; | struct lh_entry *existing_entry; | ||||
unsigned long hash; | unsigned long hash; | ||||
/** Required due to the `lh_get_hash` function wanting a `const struct lh_string *` */ | |||||
/** Required due to the `lh_get_hash` function wanting a `const struct json_key *` */ | |||||
assert(json_object_get_type(jso) == json_type_object); | assert(json_object_get_type(jso) == json_type_object); | ||||
@@ -619,12 +613,12 @@ int json_object_object_add_internal(struct json_object *jso, const struct lh_str | |||||
{ | { | ||||
// need to copy `key` because the caller might have created it | // need to copy `key` because the caller might have created it | ||||
// on the stack, which would be more efficient than copying | // on the stack, which would be more efficient than copying | ||||
// `lh_string_data` into `key->string.idata` if it had happened | |||||
// `json_key_data` into `key->string.idata` if it had happened | |||||
// that `existing_entry` wasn't NULL. | // that `existing_entry` wasn't NULL. | ||||
const struct lh_string *k = | |||||
const struct json_key *k = | |||||
(opts & JSON_C_OBJECT_KEY_IS_CONSTANT) | (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) | ||||
? lh_string_new_ptr(lh_string_size(key), lh_string_data(key)) | |||||
: lh_string_new_imm(lh_string_size(key), lh_string_data(key)); | |||||
? json_key_new_ptr(json_key_size(key), json_key_data(key)) | |||||
: json_key_new_imm(json_key_size(key), json_key_data(key)); | |||||
// TODO some optimization where (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) | // TODO some optimization where (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) | ||||
if (k == NULL) | if (k == NULL) | ||||
{ | { | ||||
@@ -632,7 +626,7 @@ int json_object_object_add_internal(struct json_object *jso, const struct lh_str | |||||
} | } | ||||
return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, | return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, | ||||
opts & ~JSON_C_OBJECT_KEY_IS_CONSTANT); | opts & ~JSON_C_OBJECT_KEY_IS_CONSTANT); | ||||
// `struct lh_string` always needs to be freed, | |||||
// `struct json_key` always needs to be freed, | |||||
// so JSON_C_OBJECT_KEY_IS_CONSTANT cannot be set | // so JSON_C_OBJECT_KEY_IS_CONSTANT cannot be set | ||||
} | } | ||||
else | else | ||||
@@ -703,8 +697,8 @@ json_bool json_object_object_get_ex_len(const struct json_object *jso, const cha | |||||
{ | { | ||||
case json_type_object: | case json_type_object: | ||||
{ | { | ||||
const struct lh_string hashable = {.length = len, .str = {.pdata = key}}; | |||||
return json_object_object_get_internal(jso, &hashable, value); | |||||
const struct json_key hashable = {.length = len, .str = {.pdata = key}}; | |||||
return json_object_object_get_key(jso, &hashable, value); | |||||
} | } | ||||
default: | default: | ||||
if (value != NULL) | if (value != NULL) | ||||
@@ -713,8 +707,8 @@ json_bool json_object_object_get_ex_len(const struct json_object *jso, const cha | |||||
} | } | ||||
} | } | ||||
json_bool json_object_object_get_internal(const struct json_object *jso, | |||||
const struct lh_string *key, struct json_object **value) | |||||
json_bool json_object_object_get_key(const struct json_object *jso, const struct json_key *key, | |||||
struct json_object **value) | |||||
{ | { | ||||
assert(json_object_get_type(jso) == json_type_object); | assert(json_object_get_type(jso) == json_type_object); | ||||
return lh_table_lookup_ex(JC_OBJECT_C(jso)->c_object, key, (void **)value); | return lh_table_lookup_ex(JC_OBJECT_C(jso)->c_object, key, (void **)value); | ||||
@@ -727,11 +721,11 @@ void json_object_object_del(struct json_object *jso, const char *key) | |||||
void json_object_object_del_len(struct json_object *jso, const char *key, const int len) | void json_object_object_del_len(struct json_object *jso, const char *key, const int len) | ||||
{ | { | ||||
const struct lh_string hashable = {.length = len, .str = {.pdata = key}}; | |||||
json_object_object_del_internal(jso, &hashable); | |||||
const struct json_key hashable = {.length = len, .str = {.pdata = key}}; | |||||
json_object_object_del_key(jso, &hashable); | |||||
} | } | ||||
int json_object_object_del_internal(struct json_object *jso, const struct lh_string *key) | |||||
int json_object_object_del_key(struct json_object *jso, const struct json_key *key) | |||||
{ | { | ||||
assert(json_object_get_type(jso) == json_type_object); | assert(json_object_get_type(jso) == json_type_object); | ||||
return lh_table_delete(JC_OBJECT(jso)->c_object, key); | return lh_table_delete(JC_OBJECT(jso)->c_object, key); | ||||
@@ -1721,7 +1715,7 @@ static int json_object_copy_serializer_data(struct json_object *src, struct json | |||||
* | * | ||||
* This always returns -1 or 1. It will never return 2 since it does not copy the serializer. | * This always returns -1 or 1. It will never return 2 since it does not copy the serializer. | ||||
*/ | */ | ||||
int json_c_shallow_copy_default(json_object *src, json_object *parent, const struct lh_string *key, | |||||
int json_c_shallow_copy_default(json_object *src, json_object *parent, const struct json_key *key, | |||||
size_t index, json_object **dst) | size_t index, json_object **dst) | ||||
{ | { | ||||
switch (src->o_type) | switch (src->o_type) | ||||
@@ -1769,7 +1763,7 @@ int json_c_shallow_copy_default(json_object *src, json_object *parent, const str | |||||
* Note: caller is responsible for freeing *dst if this fails and returns -1. | * Note: caller is responsible for freeing *dst if this fails and returns -1. | ||||
*/ | */ | ||||
static int json_object_deep_copy_recursive(struct json_object *src, struct json_object *parent, | static int json_object_deep_copy_recursive(struct json_object *src, struct json_object *parent, | ||||
const struct lh_string *key_in_parent, | |||||
const struct json_key *key_in_parent, | |||||
size_t index_in_parent, struct json_object **dst, | size_t index_in_parent, struct json_object **dst, | ||||
json_c_shallow_copy_fn *shallow_copy) | json_c_shallow_copy_fn *shallow_copy) | ||||
{ | { | ||||
@@ -1802,7 +1796,7 @@ static int json_object_deep_copy_recursive(struct json_object *src, struct json_ | |||||
return -1; | return -1; | ||||
} | } | ||||
if (json_object_object_add_internal(*dst, iter.key, jso, 0) < 0) | |||||
if (json_object_object_add_key(*dst, iter.key, jso, 0) < 0) | |||||
{ | { | ||||
json_object_put(jso); | json_object_put(jso); | ||||
return -1; | return -1; | ||||
@@ -1876,3 +1870,46 @@ static void json_abort(const char *message) | |||||
fprintf(stderr, "json-c aborts with error: %s\n", message); | fprintf(stderr, "json-c aborts with error: %s\n", message); | ||||
abort(); | abort(); | ||||
} | } | ||||
size_t json_key_size(const struct json_key *str) | |||||
{ | |||||
return (str->length > 0) ? (size_t)str->length : (size_t)(-(str->length)); | |||||
} | |||||
const char *json_key_data(const struct json_key *str) | |||||
{ | |||||
return (str->length > 0) ? str->str.pdata : str->str.idata; | |||||
} | |||||
struct json_key *json_key_new_ptr(const size_t length, const char *data) | |||||
{ | |||||
struct json_key *result = malloc(sizeof(struct json_key)); | |||||
if (result == NULL) | |||||
{ | |||||
return NULL; | |||||
} | |||||
result->length = length; | |||||
result->str.pdata = data; | |||||
return result; | |||||
} | |||||
struct json_key *json_key_new_imm(const size_t length, const char *data) | |||||
{ | |||||
struct json_key *result; | |||||
if (length > | |||||
SSIZE_T_MAX - (sizeof(struct json_key) - sizeof(((struct json_key *)NULL)->str)) - 1) | |||||
{ | |||||
return NULL; | |||||
} | |||||
result = | |||||
malloc(sizeof(struct json_key) - sizeof(((struct json_key *)NULL)->str) + length + 1); | |||||
if (result == NULL) | |||||
{ | |||||
return NULL; | |||||
} | |||||
result->length = -length; | |||||
char *unconst = _LH_UNCONST(result->str.idata); | |||||
memcpy(unconst, data, length); | |||||
unconst[length] = '\0'; | |||||
return result; | |||||
} |
@@ -456,8 +456,27 @@ JSON_EXPORT int json_object_object_add_ex_len(struct json_object *obj, const cha | |||||
const int len, struct json_object *const val, | const int len, struct json_object *const val, | ||||
const unsigned opts); | const unsigned opts); | ||||
/** Get the json_object associate with a given object field. | |||||
* Deprecated/discouraged: used json_object_object_get_ex instead. | |||||
/** | |||||
* @brief Add an object field to a json_object of type json_type_object | |||||
* | |||||
* The semantics are identical to `json_object_object_add_ex`, except that @p key | |||||
* contains both the data and the length. | |||||
* | |||||
* @param obj the json_object instance | |||||
* @param key the object field name (a private copy will be duplicated) | |||||
* @param val a json_object or NULL member to associate with the given field | |||||
* @param opts process-modifying options. To specify multiple options, use | |||||
* (OPT1|OPT2) | |||||
* @return On success, @c 0 is returned. | |||||
* On error, a negative value is returned. | |||||
*/ | |||||
JSON_EXPORT int json_object_object_add_key(struct json_object *obj, const struct json_key *key, | |||||
struct json_object *const val, const unsigned opts); | |||||
/** | |||||
* @brief Get the json_object associate with a given object field. | |||||
* | |||||
* @deprecated Deprecated/discouraged: used json_object_object_get_ex instead. | |||||
* | * | ||||
* This functions exactly like calling | * This functions exactly like calling | ||||
* @code json_object_object_get_len(obj, key, strlen(key)) @endcode | * @code json_object_object_get_len(obj, key, strlen(key)) @endcode | ||||
@@ -469,8 +488,10 @@ JSON_EXPORT int json_object_object_add_ex_len(struct json_object *obj, const cha | |||||
*/ | */ | ||||
JSON_EXPORT struct json_object *json_object_object_get(const struct json_object *obj, | JSON_EXPORT struct json_object *json_object_object_get(const struct json_object *obj, | ||||
const char *key); | const char *key); | ||||
/** Get the json_object associate with a given object field. | |||||
* Deprecated/discouraged: used json_object_object_get_ex_len instead. | |||||
/** | |||||
* @brief Get the json_object associate with a given object field. | |||||
* | |||||
* @deprecated Deprecated/discouraged: used json_object_object_get_ex_len instead. | |||||
* | * | ||||
* This returns NULL if the field is found but its value is null, or if | * This returns NULL if the field is found but its value is null, or if | ||||
* the field is not found, or if obj is not a json_type_object. If you | * the field is not found, or if obj is not a json_type_object. If you | ||||
@@ -496,7 +517,8 @@ JSON_EXPORT struct json_object *json_object_object_get(const struct json_object | |||||
JSON_EXPORT struct json_object *json_object_object_get_len(const struct json_object *obj, | JSON_EXPORT struct json_object *json_object_object_get_len(const struct json_object *obj, | ||||
const char *key, const int len); | const char *key, const int len); | ||||
/** Get the json_object associated with a given object field. | |||||
/** | |||||
* @brief Get the json_object associated with a given object field. | |||||
* | * | ||||
* This functions exactly like calling | * This functions exactly like calling | ||||
* @code json_object_object_get_ex_len(obj, key, strlen(key), value) @endcode | * @code json_object_object_get_ex_len(obj, key, strlen(key), value) @endcode | ||||
@@ -513,7 +535,8 @@ JSON_EXPORT struct json_object *json_object_object_get_len(const struct json_obj | |||||
JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, const char *key, | JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, const char *key, | ||||
struct json_object **value); | struct json_object **value); | ||||
/** Get the json_object associated with a given object field. | |||||
/** | |||||
* @brief Get the json_object associated with a given object field. | |||||
* | * | ||||
* This returns true if the key is found, false in all other cases (including | * This returns true if the key is found, false in all other cases (including | ||||
* if obj isn't a json_type_object). | * if obj isn't a json_type_object). | ||||
@@ -536,7 +559,29 @@ JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, c | |||||
JSON_EXPORT json_bool json_object_object_get_ex_len(const struct json_object *obj, const char *key, | JSON_EXPORT json_bool json_object_object_get_ex_len(const struct json_object *obj, const char *key, | ||||
const int len, struct json_object **value); | const int len, struct json_object **value); | ||||
/** Delete the given json_object field | |||||
/** | |||||
* @brief Get the json_object associated with a given object field. | |||||
* | |||||
* *No* reference counts will be changed. There is no need to manually adjust | |||||
* reference counts through the json_object_put/json_object_get methods unless | |||||
* you need to have the child (value) reference maintain a different lifetime | |||||
* than the owning parent (obj). Ownership of value is retained by obj. | |||||
* | |||||
* @param obj the json_object instance | |||||
* @param key the object field name | |||||
* @param value a pointer where to store a reference to the json_object | |||||
* associated with the given field name. | |||||
* \n | |||||
* It is safe to pass a NULL value. | |||||
* @returns true if the key is found, false in all other cases (including | |||||
* if obj isn't a json_type_object) | |||||
*/ | |||||
JSON_EXPORT json_bool json_object_object_get_key(const struct json_object *jso, | |||||
const struct json_key *key, | |||||
struct json_object **value); | |||||
/** | |||||
* @brief Delete the given json_object field | |||||
* | * | ||||
* The reference count will be decremented for the deleted object. If there | * The reference count will be decremented for the deleted object. If there | ||||
* are no more owners of the value represented by this key, then the value is | * are no more owners of the value represented by this key, then the value is | ||||
@@ -547,7 +592,8 @@ JSON_EXPORT json_bool json_object_object_get_ex_len(const struct json_object *ob | |||||
*/ | */ | ||||
JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key); | JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key); | ||||
/** Delete the given json_object field | |||||
/** | |||||
* @brief Delete the given json_object field | |||||
* | * | ||||
* The reference count will be decremented for the deleted object. If there | * The reference count will be decremented for the deleted object. If there | ||||
* are no more owners of the value represented by this key, then the value is | * are no more owners of the value represented by this key, then the value is | ||||
@@ -558,10 +604,24 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key | |||||
* which is not terminated by a NULL ( @c '\0' ) character | * which is not terminated by a NULL ( @c '\0' ) character | ||||
* @param len the length of @p key | * @param len the length of @p key | ||||
*/ | */ | ||||
void json_object_object_del_len(struct json_object *jso, const char *key, const int len); | |||||
JSON_EXPORT void json_object_object_del_len(struct json_object *jso, const char *key, | |||||
const int len); | |||||
/** | /** | ||||
* Iterate through all keys and values of an object. | |||||
* @brief Delete the given json_object field | |||||
* | |||||
* The reference count will be decremented for the deleted object. If there | |||||
* are no more owners of the value represented by this key, then the value is | |||||
* freed. Otherwise, the reference to the value will remain in memory. | |||||
* | |||||
* @param obj the json_object instance | |||||
* @param key the object field name | |||||
*/ | |||||
JSON_EXPORT int json_object_object_del_key(struct json_object *jso_base, | |||||
const struct json_key *key); | |||||
/** | |||||
* @brief Iterate through all keys and values of an object. | |||||
* | * | ||||
* Adding keys to the object while iterating is NOT allowed. | * Adding keys to the object while iterating is NOT allowed. | ||||
* | * | ||||
@@ -577,14 +637,14 @@ void json_object_object_del_len(struct json_object *jso, const char *key, const | |||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) | (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) | ||||
#define json_object_object_foreach(obj, key, val) \ | #define json_object_object_foreach(obj, key, val) \ | ||||
struct lh_string *key = NULL; \ | |||||
struct json_key *key = NULL; \ | |||||
struct json_object *val __attribute__((__unused__)) = NULL; \ | struct json_object *val __attribute__((__unused__)) = NULL; \ | ||||
for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ | for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ | ||||
*entry_next##key = NULL; \ | *entry_next##key = NULL; \ | ||||
({ \ | ({ \ | ||||
if (entry##key) \ | if (entry##key) \ | ||||
{ \ | { \ | ||||
key = (struct lh_string *)lh_entry_k(entry##key); \ | |||||
key = (struct json_key *)lh_entry_k(entry##key); \ | |||||
val = (struct json_object *)lh_entry_v(entry##key); \ | val = (struct json_object *)lh_entry_v(entry##key); \ | ||||
entry_next##key = entry##key->next; \ | entry_next##key = entry##key->next; \ | ||||
}; \ | }; \ | ||||
@@ -608,13 +668,14 @@ void json_object_object_del_len(struct json_object *jso, const char *key, const | |||||
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) */ | #endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) */ | ||||
/** Iterate through all keys and values of an object (ANSI C Safe) | |||||
/** | |||||
* @brief Iterate through all keys and values of an object (ANSI C Safe) | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param iter the object iterator, use type json_object_iter | * @param iter the object iterator, use type json_object_iter | ||||
*/ | */ | ||||
#define json_object_object_foreachC(obj, iter) \ | #define json_object_object_foreachC(obj, iter) \ | ||||
for (iter.entry = json_object_get_object(obj)->head; \ | for (iter.entry = json_object_get_object(obj)->head; \ | ||||
(iter.entry ? (iter.key = (struct lh_string *)lh_entry_k(iter.entry), \ | |||||
(iter.entry ? (iter.key = (struct json_key *)lh_entry_k(iter.entry), \ | |||||
iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \ | iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \ | ||||
: 0); \ | : 0); \ | ||||
iter.entry = iter.entry->next) | iter.entry = iter.entry->next) | ||||
@@ -1129,7 +1190,7 @@ JSON_EXPORT int json_object_equal(struct json_object *obj1, struct json_object * | |||||
* @return On success 1 or 2, -1 on errors | * @return On success 1 or 2, -1 on errors | ||||
*/ | */ | ||||
typedef int(json_c_shallow_copy_fn)(json_object *src, json_object *parent, | typedef int(json_c_shallow_copy_fn)(json_object *src, json_object *parent, | ||||
const struct lh_string *key, size_t index, json_object **dst); | |||||
const struct json_key *key, size_t index, json_object **dst); | |||||
/** | /** | ||||
* The default shallow copy implementation for use with json_object_deep_copy(). | * The default shallow copy implementation for use with json_object_deep_copy(). | ||||
@@ -1166,6 +1227,53 @@ JSON_EXPORT json_c_shallow_copy_fn json_c_shallow_copy_default; | |||||
JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst, | JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst, | ||||
json_c_shallow_copy_fn *shallow_copy); | json_c_shallow_copy_fn *shallow_copy); | ||||
/* Json Object Keys */ | |||||
/** | |||||
* @brief Get the length of the data stored in a `struct json_key *` | |||||
* | |||||
* @param str value to retrieve the length of | |||||
*/ | |||||
JSON_EXPORT size_t json_key_size(const struct json_key *str); | |||||
/** | |||||
* @brief Get the data from a `struct json_key *` | |||||
* | |||||
* @param str value to retrieve the data from | |||||
*/ | |||||
JSON_EXPORT const char *json_key_data(const struct json_key *str); | |||||
/** | |||||
* @brief Creates a new `struct json_key` that uses the `pdata` field. | |||||
* | |||||
* This avoids unneeded copying, for cases wher ethe key is in an area of | |||||
* memory that will not be modified or freed until after this object is freed. | |||||
* | |||||
* @param length The length of the data located at @p data | |||||
* @param data The data to include | |||||
* @return On success, a pointer to the new key is returned. | |||||
* On error, a null pointer is returned. | |||||
*/ | |||||
JSON_EXPORT struct json_key *json_key_new_ptr(const size_t length, const char *data); | |||||
/** | |||||
* @brief Creates a new `struct json_key` that uses the `idata` field. | |||||
* | |||||
* @param length The length of the data to copy into the returned value | |||||
* @param data The data to include and copy into the returned value | |||||
* @return On success, a pointer to the new key is returned. | |||||
* On error, a null pointer is returned. | |||||
*/ | |||||
JSON_EXPORT struct json_key *json_key_new_imm(const size_t length, const char *data); | |||||
/** | |||||
* @brief Frees the memory associated with a `struct json_key` | |||||
* | |||||
* @param key The data to free | |||||
*/ | |||||
JSON_EXPORT void json_key_del(const struct json_key *key); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
@@ -104,12 +104,12 @@ void json_object_iter_next(struct json_object_iterator *iter) | |||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
const struct lh_string *json_object_iter_peek_name(const struct json_object_iterator *iter) | |||||
const struct json_key *json_object_iter_peek_name(const struct json_object_iterator *iter) | |||||
{ | { | ||||
JASSERT(NULL != iter); | JASSERT(NULL != iter); | ||||
JASSERT(kObjectEndIterValue != iter->opaque_); | JASSERT(kObjectEndIterValue != iter->opaque_); | ||||
return (const struct lh_string *)(((const struct lh_entry *)iter->opaque_)->k); | |||||
return (const struct json_key *)(((const struct lh_entry *)iter->opaque_)->k); | |||||
} | } | ||||
/** | /** | ||||
@@ -168,7 +168,7 @@ JSON_EXPORT void json_object_iter_next(struct json_object_iterator *iter); | |||||
* deleted or modified, and MUST NOT be modified or | * deleted or modified, and MUST NOT be modified or | ||||
* freed by the user. | * freed by the user. | ||||
*/ | */ | ||||
JSON_EXPORT const struct lh_string * | |||||
JSON_EXPORT const struct json_key * | |||||
json_object_iter_peek_name(const struct json_object_iterator *iter); | json_object_iter_peek_name(const struct json_object_iterator *iter); | ||||
/** Returns a pointer to the json-c instance representing the | /** Returns a pointer to the json-c instance representing the | ||||
@@ -98,27 +98,53 @@ struct json_object_string | |||||
void _json_c_set_last_err(const char *err_fmt, ...); | void _json_c_set_last_err(const char *err_fmt, ...); | ||||
/** | |||||
* @brief Add an object field to a json_object of type json_type_object | |||||
* | |||||
* The semantics are identical to json_object_object_add_ex, except that @p key | |||||
* contains both the data and the length. | |||||
* | |||||
* @param obj the json_object instance | |||||
* @param key the object field name (a private copy will be duplicated) | |||||
* @param val a json_object or NULL member to associate with the given field | |||||
* @param opts process-modifying options. To specify multiple options, use | |||||
* (OPT1|OPT2) | |||||
* @return On success, @c 0 is returned. | |||||
* On error, a negative value is returned. | |||||
*/ | |||||
int json_object_object_add_internal(struct json_object *obj, const struct lh_string *key, | |||||
struct json_object *const val, const unsigned opts); | |||||
/** | /** | ||||
* The characters that can make up hexadecimal numbers | * The characters that can make up hexadecimal numbers | ||||
*/ | */ | ||||
extern const char *json_hex_chars; | extern const char *json_hex_chars; | ||||
/** | |||||
* @brief A buffer of characters that may contain null charaters in the middle | |||||
* | |||||
* A buffer of data that can hold a normal null-terminated string | |||||
* (in which case `length` should just be equal to `strlen`) | |||||
* or a string with embedded null characters (in which case `length` reflects | |||||
* all the characters that make up the "string"). | |||||
* Either way, this struct can be treated as if it contains null characters, | |||||
* since the `length` member should always be equal to the proper size of the | |||||
* buffer and the terminating null character wouldn't be included | |||||
* (it wouldn't be counted by strlen). | |||||
*/ | |||||
struct json_key | |||||
{ | |||||
/** | |||||
* @brief Stores the length of the buffer | |||||
* | |||||
* If the length is positive, then `pdata` should be used. | |||||
* Otherwise, idata should be used. | |||||
*/ | |||||
ssize_t length; | |||||
union | |||||
{ | |||||
/** | |||||
* @brief A pointer to data that is stored elsewhere | |||||
* | |||||
* If the data stored there will not change for the lifetime of | |||||
* the key, use `pdata` rather than `idata`. | |||||
*/ | |||||
const char *pdata; | |||||
/** | |||||
* @brief Data stored inline | |||||
* | |||||
* If the data stored may be overwritten, such as if it is | |||||
* copied from the stack, this struct should be allocated with | |||||
* enough space to store the whole string (of length `len`) | |||||
* and one additional null character. | |||||
*/ | |||||
const char idata[0]; | |||||
} str; | |||||
}; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
@@ -1106,8 +1106,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * | |||||
printbuf_memappend_fast(tok->pb, case_start, | printbuf_memappend_fast(tok->pb, case_start, | ||||
str - case_start); | str - case_start); | ||||
obj_field_name = | obj_field_name = | ||||
lh_string_new_imm(tok->pb->bpos, tok->pb->buf); | |||||
// lh_string_print(obj_field_name, stdout); | |||||
json_key_new_imm(tok->pb->bpos, tok->pb->buf); | |||||
saved_state = json_tokener_state_object_field_end; | saved_state = json_tokener_state_object_field_end; | ||||
state = json_tokener_state_eatws; | state = json_tokener_state_eatws; | ||||
break; | break; | ||||
@@ -1155,7 +1154,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * | |||||
goto redo_char; | goto redo_char; | ||||
case json_tokener_state_object_value_add: | case json_tokener_state_object_value_add: | ||||
json_object_object_add_internal(current, obj_field_name, obj, 0); | |||||
json_object_object_add_key(current, obj_field_name, obj, 0); | |||||
free(obj_field_name); | free(obj_field_name); | ||||
obj_field_name = NULL; | obj_field_name = NULL; | ||||
saved_state = json_tokener_state_object_sep; | saved_state = json_tokener_state_object_sep; | ||||
@@ -17,7 +17,6 @@ | |||||
#define _json_tokener_h_ | #define _json_tokener_h_ | ||||
#include "json_object.h" | #include "json_object.h" | ||||
#include "linkhash.h" | |||||
#include <stddef.h> | #include <stddef.h> | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -86,7 +85,7 @@ struct json_tokener_srec | |||||
enum json_tokener_state state, saved_state; | enum json_tokener_state state, saved_state; | ||||
struct json_object *obj; | struct json_object *obj; | ||||
struct json_object *current; | struct json_object *current; | ||||
struct lh_string *obj_field_name; | |||||
struct json_key *obj_field_name; | |||||
}; | }; | ||||
#define JSON_TOKENER_DEFAULT_DEPTH 32 | #define JSON_TOKENER_DEFAULT_DEPTH 32 | ||||
@@ -33,7 +33,7 @@ struct printbuf; | |||||
*/ | */ | ||||
struct json_object_iter | struct json_object_iter | ||||
{ | { | ||||
struct lh_string *key; | |||||
struct json_key *key; | |||||
struct json_object *val; | struct json_object *val; | ||||
struct lh_entry *entry; | struct lh_entry *entry; | ||||
}; | }; | ||||
@@ -71,6 +71,8 @@ typedef enum json_type | |||||
json_type_string | json_type_string | ||||
} json_type; | } json_type; | ||||
typedef struct json_key json_key; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
@@ -13,7 +13,7 @@ | |||||
#include "json_visit.h" | #include "json_visit.h" | ||||
#include "linkhash.h" | #include "linkhash.h" | ||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, const struct lh_string *jso_key, | |||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, const struct json_key *jso_key, | |||||
size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg); | size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg); | ||||
int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, void *userarg) | int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, void *userarg) | ||||
@@ -28,7 +28,7 @@ int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *user | |||||
default: return JSON_C_VISIT_RETURN_ERROR; | default: return JSON_C_VISIT_RETURN_ERROR; | ||||
} | } | ||||
} | } | ||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, const struct lh_string *jso_key, | |||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, const struct json_key *jso_key, | |||||
size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg) | size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg) | ||||
{ | { | ||||
int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg); | int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg); | ||||
@@ -13,7 +13,7 @@ extern "C" { | |||||
#endif | #endif | ||||
typedef int(json_c_visit_userfunc)(json_object *jso, int flags, json_object *parent_jso, | typedef int(json_c_visit_userfunc)(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, | |||||
const struct json_key *jso_key, size_t *jso_index, | |||||
void *userarg); | void *userarg); | ||||
/** | /** | ||||
@@ -486,62 +486,14 @@ static unsigned long lh_char_hash(const void *k) | |||||
random_seed = seed; /* potentially racy */ | random_seed = seed; /* potentially racy */ | ||||
#endif | #endif | ||||
} | } | ||||
return hashlittle(lh_string_data((const struct lh_string *)k), | |||||
lh_string_size((const struct lh_string *)k), random_seed); | |||||
return hashlittle(json_key_data((const struct json_key *)k), | |||||
json_key_size((const struct json_key *)k), random_seed); | |||||
} | } | ||||
int lh_char_equal(const void *k1, const void *k2) | int lh_char_equal(const void *k1, const void *k2) | ||||
{ | { | ||||
return lh_string_size(k1) == lh_string_size(k2) && | |||||
memcmp(lh_string_data(k1), lh_string_data(k2), lh_string_size(k1)) == 0; | |||||
} | |||||
const char *lh_string_data(const struct lh_string *str) | |||||
{ | |||||
return (str->length > 0) ? str->str.pdata : str->str.idata; | |||||
} | |||||
size_t lh_string_size(const struct lh_string *str) | |||||
{ | |||||
return (str->length > 0) ? (size_t)str->length : (size_t)(-(str->length)); | |||||
} | |||||
size_t lh_string_print(const struct lh_string *key, FILE *stream) | |||||
{ | |||||
return fwrite(lh_string_data(key), lh_string_size(key), 1, stream); | |||||
} | |||||
struct lh_string *lh_string_new_ptr(const size_t length, const char *data) | |||||
{ | |||||
struct lh_string *result = malloc(sizeof(struct lh_string)); | |||||
if (result == NULL) | |||||
{ | |||||
return NULL; | |||||
} | |||||
result->length = length; | |||||
result->str.pdata = data; | |||||
return result; | |||||
} | |||||
struct lh_string *lh_string_new_imm(const size_t length, const char *data) | |||||
{ | |||||
struct lh_string *result; | |||||
if (length > | |||||
SSIZE_T_MAX - (sizeof(struct lh_string) - sizeof(((struct lh_string *)NULL)->str)) - 1) | |||||
{ | |||||
return NULL; | |||||
} | |||||
result = | |||||
malloc(sizeof(struct lh_string) - sizeof(((struct lh_string *)NULL)->str) + length + 1); | |||||
if (result == NULL) | |||||
{ | |||||
return NULL; | |||||
} | |||||
result->length = -length; | |||||
char *unconst = _LH_UNCONST(result->str.idata); | |||||
memcpy(unconst, data, length); | |||||
unconst[length] = '\0'; | |||||
return result; | |||||
return json_key_size(k1) == json_key_size(k2) && | |||||
memcmp(json_key_data(k1), json_key_data(k2), json_key_size(k1)) == 0; | |||||
} | } | ||||
struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn, | struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn, | ||||
@@ -20,7 +20,6 @@ | |||||
#define _json_c_linkhash_h_ | #define _json_c_linkhash_h_ | ||||
#include "json_object.h" | #include "json_object.h" | ||||
#include <stdio.h> | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
@@ -80,34 +79,6 @@ typedef unsigned long(lh_hash_fn)(const void *k); | |||||
*/ | */ | ||||
typedef int(lh_equal_fn)(const void *k1, const void *k2); | typedef int(lh_equal_fn)(const void *k1, const void *k2); | ||||
/** | |||||
* @brief A buffer of characters that may contain null charaters in the middle | |||||
* | |||||
* A buffer of data that can hold a normal null-terminated string | |||||
* (in which case `length` should just be equal to `strlen`) | |||||
* or a string with embedded null characters (in which case `length` reflects | |||||
* all the characters that make up the "string"). | |||||
* Either way, this struct can be treated as if it contains null characters, | |||||
* since the `length` member should always be equal to the proper size of the | |||||
* buffer and the terminating null character wouldn't be included | |||||
* (it wouldn't be counted by strlen). | |||||
*/ | |||||
struct lh_string | |||||
{ | |||||
/** | |||||
* @brief Stores the length of the buffer | |||||
* | |||||
* If the length is positive, then `pdata` should be used. | |||||
* Otherwise, idata should be used. | |||||
*/ | |||||
ssize_t length; | |||||
union | |||||
{ | |||||
const char *pdata; | |||||
const char idata[0]; | |||||
} str; | |||||
}; | |||||
/** | /** | ||||
* An entry in the hash table | * An entry in the hash table | ||||
*/ | */ | ||||
@@ -193,49 +164,6 @@ typedef struct lh_table lh_table; | |||||
#define lh_foreach_safe(table, entry, tmp) \ | #define lh_foreach_safe(table, entry, tmp) \ | ||||
for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) | for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) | ||||
/** | |||||
* @brief Get the data from a `struct lh_string *` | |||||
* | |||||
* @param str value to retrieve the data from | |||||
*/ | |||||
extern const char *lh_string_data(const struct lh_string *str); | |||||
/** | |||||
* @brief Get the length of the data stored in a `struct lh_string *` | |||||
* | |||||
* @param str value to retrieve the length of | |||||
*/ | |||||
extern size_t lh_string_size(const struct lh_string *str); | |||||
/** | |||||
* @brief Print a `struct lh_string` to a given stream | |||||
* | |||||
* @param str value to print | |||||
* @param stream Stream to write data to | |||||
*/ | |||||
extern size_t lh_string_print(const struct lh_string *str, FILE *stream); | |||||
/** | |||||
* @brief Creates a new `struct lh_string` using the `pdata` field. | |||||
* | |||||
* This avoids unneeded copying, for cases wher ethe key is in an area of | |||||
* memory that will not be modified or freed until after this object is freed. | |||||
* | |||||
* @param length The length of the data located at @p data | |||||
* @param data The data to include | |||||
* @return `NULL` on error | |||||
*/ | |||||
extern struct lh_string *lh_string_new_ptr(const size_t length, const char *data); | |||||
/** | |||||
* @brief Creates a new `struct lh_string` using the `idata` field. | |||||
* | |||||
* @param length The length of the data to copy into the returned value | |||||
* @param data The data to include and copy into the returned value | |||||
* @return `NULL` on error | |||||
*/ | |||||
extern struct lh_string *lh_string_new_imm(const size_t length, const char *data); | |||||
/** | /** | ||||
* Create a new linkhash table. | * Create a new linkhash table. | ||||
* | * | ||||
@@ -307,7 +307,7 @@ int main(int argc, char **argv) | |||||
json_object_object_foreach(my_object, key, val) | json_object_object_foreach(my_object, key, val) | ||||
{ | { | ||||
putchar('\t'); | putchar('\t'); | ||||
lh_string_print(key, stdout); | |||||
fwrite(json_key_data(key), json_key_size(key), 1, stdout); | |||||
printf(": %s\n", json_object_to_json_string(val)); | printf(": %s\n", json_object_to_json_string(val)); | ||||
} | } | ||||
printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object)); | printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object)); | ||||
@@ -24,11 +24,11 @@ int main(int argc, char **argv) | |||||
int orig_count = 0; | int orig_count = 0; | ||||
json_object_object_foreach(my_object, key0, val0) | json_object_object_foreach(my_object, key0, val0) | ||||
{ | { | ||||
printf("Key at index %d is [%s] %d", orig_count, lh_string_data(key0), | |||||
printf("Key at index %d is [%s] %d", orig_count, json_key_data(key0), | |||||
(val0 == NULL)); | (val0 == NULL)); | ||||
if (strcmp(lh_string_data(key0), "deleteme") == 0) | |||||
if (strcmp(json_key_data(key0), "deleteme") == 0) | |||||
{ | { | ||||
json_object_object_del(my_object, lh_string_data(key0)); | |||||
json_object_object_del(my_object, json_key_data(key0)); | |||||
printf(" (deleted)\n"); | printf(" (deleted)\n"); | ||||
} | } | ||||
else | else | ||||
@@ -38,18 +38,18 @@ int main(int argc, char **argv) | |||||
printf("==== replace-value first loop starting ====\n"); | printf("==== replace-value first loop starting ====\n"); | ||||
const struct lh_string *original_key = NULL; | |||||
const struct json_key *original_key = NULL; | |||||
orig_count = 0; | orig_count = 0; | ||||
json_object_object_foreach(my_object, key, val) | json_object_object_foreach(my_object, key, val) | ||||
{ | { | ||||
printf("Key at index %d is [%s] %d\n", orig_count, lh_string_data(key), | |||||
printf("Key at index %d is [%s] %d\n", orig_count, json_key_data(key), | |||||
(val == NULL)); | (val == NULL)); | ||||
orig_count++; | orig_count++; | ||||
if (strcmp(lh_string_data(key), "foo2") != 0) | |||||
if (strcmp(json_key_data(key), "foo2") != 0) | |||||
continue; | continue; | ||||
printf("replacing value for key [%s]\n", lh_string_data(key)); | |||||
printf("replacing value for key [%s]\n", json_key_data(key)); | |||||
original_key = key; | original_key = key; | ||||
json_object_object_add(my_object, lh_string_data(key0), | |||||
json_object_object_add(my_object, json_key_data(key0), | |||||
json_object_new_string("zzz")); | json_object_new_string("zzz")); | ||||
} | } | ||||
@@ -59,12 +59,12 @@ int main(int argc, char **argv) | |||||
int retval = 0; | int retval = 0; | ||||
json_object_object_foreach(my_object, key2, val2) | json_object_object_foreach(my_object, key2, val2) | ||||
{ | { | ||||
printf("Key at index %d is [%s] %d\n", new_count, lh_string_data(key2), | |||||
printf("Key at index %d is [%s] %d\n", new_count, json_key_data(key2), | |||||
(val2 == NULL)); | (val2 == NULL)); | ||||
new_count++; | new_count++; | ||||
if (strcmp(lh_string_data(key2), "foo2") != 0) | |||||
if (strcmp(json_key_data(key2), "foo2") != 0) | |||||
continue; | continue; | ||||
printf("pointer for key [%s] does %smatch\n", lh_string_data(key2), | |||||
printf("pointer for key [%s] does %smatch\n", json_key_data(key2), | |||||
(key2 == original_key) ? "" : "NOT "); | (key2 == original_key) ? "" : "NOT "); | ||||
if (key2 != original_key) | if (key2 != original_key) | ||||
retval = 1; | retval = 1; | ||||
@@ -93,14 +93,14 @@ int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level | |||||
} | } | ||||
json_c_shallow_copy_fn my_shallow_copy; | json_c_shallow_copy_fn my_shallow_copy; | ||||
int my_shallow_copy(json_object *src, json_object *parent, const struct lh_string *key, | |||||
size_t index, json_object **dst) | |||||
int my_shallow_copy(json_object *src, json_object *parent, const struct json_key *key, size_t index, | |||||
json_object **dst) | |||||
{ | { | ||||
int rc; | int rc; | ||||
rc = json_c_shallow_copy_default(src, parent, key, index, dst); | rc = json_c_shallow_copy_default(src, parent, key, index, dst); | ||||
if (rc < 0) | if (rc < 0) | ||||
return rc; | return rc; | ||||
if (key != NULL && strcmp(lh_string_data(key), "with_serializer") == 0) | |||||
if (key != NULL && strcmp(json_key_data(key), "with_serializer") == 0) | |||||
{ | { | ||||
printf("CALLED: my_shallow_copy on with_serializer object\n"); | printf("CALLED: my_shallow_copy on with_serializer object\n"); | ||||
void *userdata = json_object_get_userdata(src); | void *userdata = json_object_get_userdata(src); | ||||
@@ -114,8 +114,8 @@ int main(void) | |||||
json_object_object_foreach(parsed, key, val) | json_object_object_foreach(parsed, key, val) | ||||
{ | { | ||||
putchar('\"'); | putchar('\"'); | ||||
fwrite(lh_string_data(key), lh_string_size(key), 1, stdout); | |||||
printf("\" (%zd)\n", lh_string_size(key)); | |||||
fwrite(json_key_data(key), json_key_size(key), 1, stdout); | |||||
printf("\" (%zd)\n", json_key_size(key)); | |||||
} | } | ||||
return 1; | return 1; | ||||
} | } | ||||
@@ -1,5 +1,5 @@ | |||||
Parsed input: { "biff\u0000": null, "\u0000zxcvbnm": 178 } | Parsed input: { "biff\u0000": null, "\u0000zxcvbnm": 178 } | ||||
Result is `json_type_object` | Result is `json_type_object` | ||||
Expected keys ("biff\0" and "\0zxcvbnm") present with expected values | |||||
Expected keys ("biff\u0000" and "\u0000zxcvbnm") present with expected values | |||||
Key deleted properly | Key deleted properly | ||||
PASS | PASS |
@@ -31,7 +31,7 @@ int main(int atgc, char **argv) | |||||
while (!json_object_iter_equal(&it, &itEnd)) | while (!json_object_iter_equal(&it, &itEnd)) | ||||
{ | { | ||||
printf("%s\n", lh_string_data(json_object_iter_peek_name(&it))); | |||||
printf("%s\n", json_key_data(json_object_iter_peek_name(&it))); | |||||
printf("%s\n", json_object_to_json_string(json_object_iter_peek_value(&it))); | printf("%s\n", json_object_to_json_string(json_object_iter_peek_value(&it))); | ||||
json_object_iter_next(&it); | json_object_iter_next(&it); | ||||
} | } | ||||
@@ -215,7 +215,7 @@ static void do_clear_serializer(json_object *jso) | |||||
} | } | ||||
static int clear_serializer(json_object *jso, int flags, json_object *parent_jso, | static int clear_serializer(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
if (jso) | if (jso) | ||||
json_object_set_serializer(jso, NULL, NULL, NULL); | json_object_set_serializer(jso, NULL, NULL, NULL); | ||||
@@ -69,16 +69,16 @@ int main(void) | |||||
} | } | ||||
static int emit_object(json_object *jso, int flags, json_object *parent_jso, | static int emit_object(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | ||||
(jso_key ? lh_string_data(jso_key) : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||||
(jso_key ? json_key_data(jso_key) : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||||
json_object_to_json_string(jso)); | json_object_to_json_string(jso)); | ||||
return JSON_C_VISIT_RETURN_CONTINUE; | return JSON_C_VISIT_RETURN_CONTINUE; | ||||
} | } | ||||
static int skip_arrays(json_object *jso, int flags, json_object *parent_jso, | static int skip_arrays(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | ||||
if (json_object_get_type(jso) == json_type_array) | if (json_object_get_type(jso) == json_type_array) | ||||
@@ -87,15 +87,15 @@ static int skip_arrays(json_object *jso, int flags, json_object *parent_jso, | |||||
} | } | ||||
static int pop_and_stop(json_object *jso, int flags, json_object *parent_jso, | static int pop_and_stop(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | ||||
if (jso_key != NULL && strcmp(lh_string_data(jso_key), "subobj1") == 0) | |||||
if (jso_key != NULL && strcmp(json_key_data(jso_key), "subobj1") == 0) | |||||
{ | { | ||||
printf("POP after handling subobj1\n"); | printf("POP after handling subobj1\n"); | ||||
return JSON_C_VISIT_RETURN_POP; | return JSON_C_VISIT_RETURN_POP; | ||||
} | } | ||||
if (jso_key != NULL && strcmp(lh_string_data(jso_key), "obj3") == 0) | |||||
if (jso_key != NULL && strcmp(json_key_data(jso_key), "obj3") == 0) | |||||
{ | { | ||||
printf("STOP after handling obj3\n"); | printf("STOP after handling obj3\n"); | ||||
return JSON_C_VISIT_RETURN_STOP; | return JSON_C_VISIT_RETURN_STOP; | ||||
@@ -104,10 +104,10 @@ static int pop_and_stop(json_object *jso, int flags, json_object *parent_jso, | |||||
} | } | ||||
static int err_on_subobj2(json_object *jso, int flags, json_object *parent_jso, | static int err_on_subobj2(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | ||||
if (jso_key != NULL && strcmp(lh_string_data(jso_key), "subobj2") == 0) | |||||
if (jso_key != NULL && strcmp(json_key_data(jso_key), "subobj2") == 0) | |||||
{ | { | ||||
printf("ERROR after handling subobj1\n"); | printf("ERROR after handling subobj1\n"); | ||||
return JSON_C_VISIT_RETURN_ERROR; | return JSON_C_VISIT_RETURN_ERROR; | ||||
@@ -116,7 +116,7 @@ static int err_on_subobj2(json_object *jso, int flags, json_object *parent_jso, | |||||
} | } | ||||
static int pop_array(json_object *jso, int flags, json_object *parent_jso, | static int pop_array(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | ||||
if (jso_index != NULL && (*jso_index == 0)) | if (jso_index != NULL && (*jso_index == 0)) | ||||
@@ -128,7 +128,7 @@ static int pop_array(json_object *jso, int flags, json_object *parent_jso, | |||||
} | } | ||||
static int stop_array(json_object *jso, int flags, json_object *parent_jso, | static int stop_array(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | ||||
if (jso_index != NULL && (*jso_index == 0)) | if (jso_index != NULL && (*jso_index == 0)) | ||||
@@ -140,10 +140,10 @@ static int stop_array(json_object *jso, int flags, json_object *parent_jso, | |||||
} | } | ||||
static int err_return(json_object *jso, int flags, json_object *parent_jso, | static int err_return(json_object *jso, int flags, json_object *parent_jso, | ||||
const struct lh_string *jso_key, size_t *jso_index, void *userarg) | |||||
const struct json_key *jso_key, size_t *jso_index, void *userarg) | |||||
{ | { | ||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | ||||
(jso_key ? lh_string_data(jso_key) : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||||
(jso_key ? json_key_data(jso_key) : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||||
json_object_to_json_string(jso)); | json_object_to_json_string(jso)); | ||||
return 100; | return 100; | ||||
} | } |