diff --git a/json_object.c b/json_object.c index cae67dd..e9fffab 100644 --- a/json_object.c +++ b/json_object.c @@ -116,8 +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, json_object_to_json_string_fn *to_json_string); -static int json_object_object_add_internal(struct json_object *jso, const struct lh_string *key, - struct json_object *const val, const unsigned opts); 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, diff --git a/json_object_private.h b/json_object_private.h index 4f5e7c4..5b08dd1 100644 --- a/json_object_private.h +++ b/json_object_private.h @@ -98,6 +98,22 @@ struct json_object_string 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 */ diff --git a/json_tokener.c b/json_tokener.c index aad463a..8fea883 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -1105,7 +1105,9 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * { printbuf_memappend_fast(tok->pb, case_start, str - case_start); - obj_field_name = strdup(tok->pb->buf); + obj_field_name = + lh_string_new_imm(tok->pb->bpos, tok->pb->buf); + // lh_string_print(obj_field_name, stdout); saved_state = json_tokener_state_object_field_end; state = json_tokener_state_eatws; break; @@ -1153,7 +1155,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * goto redo_char; case json_tokener_state_object_value_add: - json_object_object_add(current, obj_field_name, obj); + json_object_object_add_internal(current, obj_field_name, obj, 0); free(obj_field_name); obj_field_name = NULL; saved_state = json_tokener_state_object_sep; diff --git a/json_tokener.h b/json_tokener.h index a07e12c..9a0d411 100644 --- a/json_tokener.h +++ b/json_tokener.h @@ -17,6 +17,7 @@ #define _json_tokener_h_ #include "json_object.h" +#include "linkhash.h" #include #ifdef __cplusplus @@ -85,7 +86,7 @@ struct json_tokener_srec enum json_tokener_state state, saved_state; struct json_object *obj; struct json_object *current; - char *obj_field_name; + struct lh_string *obj_field_name; }; #define JSON_TOKENER_DEFAULT_DEPTH 32 @@ -215,7 +216,7 @@ JSON_EXPORT struct json_tokener *json_tokener_new_ex(int depth); JSON_EXPORT void json_tokener_free(struct json_tokener *tok); /** - * Reset the state of a json_tokener, to prepare to parse a + * Reset the state of a json_tokener, to prepare to parse a * brand new JSON object. */ JSON_EXPORT void json_tokener_reset(struct json_tokener *tok); @@ -279,7 +280,7 @@ JSON_EXPORT void json_tokener_set_flags(struct json_tokener *tok, int flags); * the length of the last len parameter passed in. * * The tokener does \b not maintain an internal buffer so the caller is - * responsible for a subsequent call to json_tokener_parse_ex with an + * responsible for a subsequent call to json_tokener_parse_ex with an * appropriate str parameter starting with the extra characters. * * This interface is presently not 64-bit clean due to the int len argument diff --git a/linkhash.c b/linkhash.c index bc4c155..4bb9844 100644 --- a/linkhash.c +++ b/linkhash.c @@ -511,7 +511,7 @@ size_t lh_string_print(const struct lh_string *key, FILE *stream) return fwrite(lh_string_data(key), lh_string_size(key), 1, stream); } -const struct lh_string *lh_string_new_ptr(const size_t length, const char *data) +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) @@ -523,7 +523,7 @@ const struct lh_string *lh_string_new_ptr(const size_t length, const char *data) return result; } -const struct lh_string *lh_string_new_imm(const size_t length, const char *data) +struct lh_string *lh_string_new_imm(const size_t length, const char *data) { struct lh_string *result; if (length > diff --git a/linkhash.h b/linkhash.h index 045474c..a8b82f2 100644 --- a/linkhash.h +++ b/linkhash.h @@ -225,7 +225,7 @@ extern size_t lh_string_print(const struct lh_string *str, FILE *stream); * @param data The data to include * @return `NULL` on error */ -extern const struct lh_string *lh_string_new_ptr(const size_t length, const char *data); +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. @@ -234,7 +234,7 @@ extern const struct lh_string *lh_string_new_ptr(const size_t length, const char * @param data The data to include and copy into the returned value * @return `NULL` on error */ -extern const struct lh_string *lh_string_new_imm(const size_t length, const char *data); +extern struct lh_string *lh_string_new_imm(const size_t length, const char *data); /** * Create a new linkhash table.