#endif /* REFCOUNT_DEBUG */
+/* helper for accessing the optimized string data component in json_object
+ */
+static const char *
+get_string_component(struct json_object *jso)
+{
+ return (jso->o.c_string.len < LEN_DIRECT_STRING_DATA) ?
+ jso->o.c_string.str.data : jso->o.c_string.str.ptr;
+}
+
/* string escaping */
-static int json_escape_str(struct printbuf *pb, char *str, int len)
+static int json_escape_str(struct printbuf *pb, const char *str, int len)
{
int pos = 0, start_offset = 0;
unsigned char c;
* Parse strings into 64-bit numbers, then use the
* 64-to-32-bit number handling below.
*/
- if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
+ if (json_parse_int64(get_string_component(jso), &cint64) != 0)
return 0; /* whoops, it didn't work. */
o_type = json_type_int;
}
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:
- if (json_parse_int64(jso->o.c_string.str, &cint) == 0)
+ if (json_parse_int64(get_string_component(jso), &cint) == 0)
return cint;
default:
return 0;
return jso->o.c_boolean;
case json_type_string:
errno = 0;
- cdouble = strtod(jso->o.c_string.str,&errPtr);
+ cdouble = strtod(get_string_component(jso), &errPtr);
/* if conversion stopped at the first character, return 0.0 */
- if (errPtr == jso->o.c_string.str)
+ if (errPtr == get_string_component(jso))
return 0.0;
/*
int flags)
{
sprintbuf(pb, "\"");
- json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
+ json_escape_str(pb, get_string_component(jso), jso->o.c_string.len);
sprintbuf(pb, "\"");
return 0;
}
static void json_object_string_delete(struct json_object* jso)
{
- free(jso->o.c_string.str);
+ if(jso->o.c_string.len >= LEN_DIRECT_STRING_DATA)
+ free(jso->o.c_string.str.ptr);
json_object_generic_delete(jso);
}
return NULL;
jso->_delete = &json_object_string_delete;
jso->_to_json_string = &json_object_string_to_json_string;
- jso->o.c_string.str = strdup(s);
- if (!jso->o.c_string.str)
- {
- json_object_generic_delete(jso);
- errno = ENOMEM;
- return NULL;
- }
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, int len)
{
+ char *dstbuf;
struct json_object *jso = json_object_new(json_type_string);
if (!jso)
return NULL;
jso->_delete = &json_object_string_delete;
jso->_to_json_string = &json_object_string_to_json_string;
- jso->o.c_string.str = (char*)malloc(len + 1);
- if (!jso->o.c_string.str)
- {
- json_object_generic_delete(jso);
- errno = ENOMEM;
- return NULL;
+ if(len < LEN_DIRECT_STRING_DATA) {
+ dstbuf = jso->o.c_string.str.data;
+ } else {
+ jso->o.c_string.str.ptr = (char*)malloc(len + 1);
+ if (!jso->o.c_string.str.ptr)
+ {
+ json_object_generic_delete(jso);
+ errno = ENOMEM;
+ return NULL;
+ }
+ dstbuf = jso->o.c_string.str.ptr;
}
- memcpy(jso->o.c_string.str, (void *)s, len);
- jso->o.c_string.str[len] = '\0';
+ memcpy(dstbuf, (void *)s, len);
+ dstbuf[len] = '\0';
jso->o.c_string.len = len;
return jso;
}
switch(jso->o_type)
{
case json_type_string:
- return jso->o.c_string.str;
+ return get_string_component(jso);
default:
return json_object_to_json_string(jso);
}