diff --git a/json_object.c b/json_object.c index c2463c1..a272277 100644 --- a/json_object.c +++ b/json_object.c @@ -1138,60 +1138,63 @@ static void json_object_string_delete(struct json_object *jso) json_object_generic_delete(jso); } -struct json_object *json_object_new_string(const char *s) +struct json_object *json_object_new_string_ext(const char *s, const int len, + int flags) { - struct json_object *jso = json_object_new(json_type_string); - if (!jso) + if (len <= 0 || flags == 0) return NULL; - jso->_delete = &json_object_string_delete; - jso->_to_json_string = &json_object_string_to_json_string; - jso->o.c_string.len = strlen(s); - if (jso->o.c_string.len < LEN_DIRECT_STRING_DATA) - { - memcpy(jso->o.c_string.str.data, s, jso->o.c_string.len); - } - else - { - jso->o.c_string.str.ptr = strdup(s); - if (!jso->o.c_string.str.ptr) - { - json_object_generic_delete(jso); - errno = ENOMEM; - return NULL; - } - } - return jso; -} -struct json_object *json_object_new_string_len(const char *s, const int len) -{ - char *dstbuf; struct json_object *jso = json_object_new(json_type_string); if (!jso) return NULL; + char *dstbuf = NULL; jso->_delete = &json_object_string_delete; jso->_to_json_string = &json_object_string_to_json_string; + jso->o.c_string.len = len; + + /* short cut if the internal string buffer of jso is big enough */ if (len < LEN_DIRECT_STRING_DATA) { dstbuf = jso->o.c_string.str.data; + memcpy(dstbuf, s, jso->o.c_string.len); + dstbuf[len] = '\0'; + return jso; } - else + + if (flags & JSON_C_NEW_STRING_STRDUP) + dstbuf = strdup(s); + else if (flags & JSON_C_NEW_STRING_LENGTH) { - jso->o.c_string.str.ptr = (char *)malloc(len + 1); - if (!jso->o.c_string.str.ptr) + dstbuf = malloc(len + 1); + if (dstbuf) { - json_object_generic_delete(jso); - errno = ENOMEM; - return NULL; + memcpy(dstbuf, s, len); + dstbuf[len] = '\0'; } - dstbuf = jso->o.c_string.str.ptr; } - memcpy(dstbuf, (const void *)s, len); - dstbuf[len] = '\0'; - jso->o.c_string.len = len; + + /* cannot be reached if o.c_string.str.data is used */ + if (!dstbuf) + { + /* errno has already been set by malloc or strdup */ + json_object_generic_delete(jso); + return NULL; + } + + jso->o.c_string.str.ptr = dstbuf; return jso; } +struct json_object *json_object_new_string(const char *s) +{ + return json_object_new_string_ext(s, strlen(s), JSON_C_NEW_STRING_STRDUP); +} + +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); +} + const char *json_object_get_string(struct json_object *jso) { if (!jso) diff --git a/json_object.h b/json_object.h index 7c0d1f2..0bb732f 100644 --- a/json_object.h +++ b/json_object.h @@ -45,6 +45,16 @@ extern "C" { #define JSON_OBJECT_DEF_HASH_ENTRIES 16 +/** + * A copy of the string is made and the memory is managed by the json_object. + */ +#define JSON_C_NEW_STRING_STRDUP (1 << 0) +/** + * A copy of the string with a maximum of len characters is made and the + * memory is managed by the json_object. + */ +#define JSON_C_NEW_STRING_LENGTH (1 << 1) + /** * A flag for the json_object_to_json_string_ext() and * json_object_to_file_ext() functions which causes the output @@ -867,13 +877,27 @@ JSON_EXPORT int json_object_set_double(struct json_object *obj, double new_value /* string type methods */ +/** Create a new json_object of type json_type_string in a configurable way + * + * The string will be embedded into the new object as specified by the given + * flags parameter. + * + * @param s the string + * @param len the size of the string buffer in bytes + * @param flags process-modifying options, MUST NOT equal zero, and only one + * option can be specified. + * @returns a json_object of type json_type_string + */ +JSON_EXPORT struct json_object *json_object_new_string_ext(const char *s, const int len, + int flags); + /** Create a new empty json_object of type json_type_string * * A copy of the string is made and the memory is managed by the json_object * * @param s the string * @returns a json_object of type json_type_string - * @see json_object_new_string_len() + * @see json_object_new_string_ext() */ JSON_EXPORT struct json_object *json_object_new_string(const char *s); @@ -883,9 +907,9 @@ JSON_EXPORT struct json_object *json_object_new_string(const char *s); * A copy of the string is made and the memory is managed by the json_object * * @param s the string - * @param len max length of the new string + * @param len max length of the new string, must be >= 1 * @returns a json_object of type json_type_string - * @see json_object_new_string() + * @see json_object_new_string_ext() */ JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len);