diff --git a/json_object.c b/json_object.c index a272277..355cac5 100644 --- a/json_object.c +++ b/json_object.c @@ -1158,6 +1158,14 @@ struct json_object *json_object_new_string_ext(const char *s, const int len, dstbuf = jso->o.c_string.str.data; memcpy(dstbuf, s, jso->o.c_string.len); dstbuf[len] = '\0'; + if (flags & JSON_C_NEW_STRING_NO_STRDUP) + { + /* a little hack to get rid of constness */ + memcpy(&dstbuf, &s, sizeof(char *)); + /* string buffer must be free'd here + to avoid memory leaks */ + free(dstbuf); + } return jso; } @@ -1172,6 +1180,9 @@ struct json_object *json_object_new_string_ext(const char *s, const int len, dstbuf[len] = '\0'; } } + else if (flags & JSON_C_NEW_STRING_NO_STRDUP) + /* a little hack to get rid of constness */ + memcpy(&dstbuf, &s, sizeof(char *)); /* cannot be reached if o.c_string.str.data is used */ if (!dstbuf) @@ -1195,6 +1206,11 @@ struct json_object *json_object_new_string_len(const char *s, const int len) return json_object_new_string_ext(s, len, JSON_C_NEW_STRING_LENGTH); } +struct json_object *json_object_new_string_noalloc(const char *s) +{ + return json_object_new_string_ext(s, strlen(s), JSON_C_NEW_STRING_NO_STRDUP); +} + const char *json_object_get_string(struct json_object *jso) { if (!jso) diff --git a/json_object.h b/json_object.h index 0bb732f..da71030 100644 --- a/json_object.h +++ b/json_object.h @@ -54,6 +54,11 @@ extern "C" { * memory is managed by the json_object. */ #define JSON_C_NEW_STRING_LENGTH (1 << 1) +/** + * No copy of the string is made, the given string buffer must be heap-allocated, + * and not be free'd, as its memory will be managed by the json_object then. + */ +#define JSON_C_NEW_STRING_NO_STRDUP (1 << 2) /** * A flag for the json_object_to_json_string_ext() and @@ -913,6 +918,21 @@ JSON_EXPORT struct json_object *json_object_new_string(const char *s); */ JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len); +/** Create a new empty json_object of type json_type_string without allocating + * new memory. + * + * Create a new json_object of type json_type_string and use the given string + * buffer as is, without allocating new memory nor duplication. The ownership + * of the string buffer will be transferred to the newly created json_object. + * The buffer will be freed when the last instance of this object will be + * destroyed by calling json_object_put(). + * + * @param s the string buffer, must be heap alloacted and must not be freed. + * @returns a json_object of type json_type_string + * @see json_object_new_string_ext() + */ +JSON_EXPORT struct json_object *json_object_new_string_noalloc(const char *s); + /** Get the string value of a json_object * * If the passed object is of type json_type_null (i.e. obj == NULL),