Add json_object_free_userdata() and json_object_userdata_to_json_string() too.tags/json-c-0.12-20140410
| @@ -1,7 +1,10 @@ | |||||
| NEXT.VERSION | NEXT.VERSION | ||||
| * Nothing yet... | |||||
| * Added a json_object_new_double_s() convenience function to allow | |||||
| an exact string representation of a double to be specified when | |||||
| creating the object and use it in json_tokener_parse_ex() so | |||||
| a re-serialized object more exactly matches the input. | |||||
| 0.11 | 0.11 | ||||
| @@ -601,11 +601,36 @@ static int json_object_double_to_json_string(struct json_object* jso, | |||||
| struct json_object* json_object_new_double(double d) | struct json_object* json_object_new_double(double d) | ||||
| { | { | ||||
| struct json_object *jso = json_object_new(json_type_double); | |||||
| if(!jso) return NULL; | |||||
| jso->_to_json_string = &json_object_double_to_json_string; | |||||
| jso->o.c_double = d; | |||||
| return jso; | |||||
| struct json_object *jso = json_object_new(json_type_double); | |||||
| if (!jso) | |||||
| return NULL; | |||||
| jso->_to_json_string = &json_object_double_to_json_string; | |||||
| jso->o.c_double = d; | |||||
| return jso; | |||||
| } | |||||
| struct json_object* json_object_new_double_s(double d, const char *ds) | |||||
| { | |||||
| struct json_object *jso = json_object_new_double(d); | |||||
| if (!jso) | |||||
| return NULL; | |||||
| json_object_set_serializer(jso, json_object_userdata_to_json_string, | |||||
| strdup(ds), json_object_free_userdata); | |||||
| return jso; | |||||
| } | |||||
| int json_object_userdata_to_json_string(struct json_object *jso, | |||||
| struct printbuf *pb, int level, int flags) | |||||
| { | |||||
| int userdata_len = strlen(jso->_userdata); | |||||
| printbuf_memappend(pb, jso->_userdata, userdata_len); | |||||
| return userdata_len; | |||||
| } | |||||
| void json_object_free_userdata(struct json_object *jso, void *userdata) | |||||
| { | |||||
| free(userdata); | |||||
| } | } | ||||
| double json_object_get_double(struct json_object *jso) | double json_object_get_double(struct json_object *jso) | ||||
| @@ -197,6 +197,25 @@ extern void json_object_set_serializer(json_object *jso, | |||||
| void *userdata, | void *userdata, | ||||
| json_object_delete_fn *user_delete); | json_object_delete_fn *user_delete); | ||||
| /** | |||||
| * Simply call free on the userdata pointer. | |||||
| * Can be used with json_object_set_serializer(). | |||||
| * | |||||
| * @param jso unused | |||||
| * @param userdata the pointer that is passed to free(). | |||||
| */ | |||||
| json_object_delete_fn json_object_free_userdata; | |||||
| /** | |||||
| * Copy the jso->_userdata string over to pb as-is. | |||||
| * Can be used with json_object_set_serializer(). | |||||
| * | |||||
| * @param jso The object whose _userdata is used. | |||||
| * @param pb The destination buffer. | |||||
| * @param level Ignored. | |||||
| * @param flags Ignored. | |||||
| */ | |||||
| json_object_to_json_string_fn json_object_userdata_to_json_string; | |||||
| /* object type methods */ | /* object type methods */ | ||||
| @@ -493,6 +512,29 @@ extern int64_t json_object_get_int64(struct json_object *obj); | |||||
| */ | */ | ||||
| extern struct json_object* json_object_new_double(double d); | extern struct json_object* json_object_new_double(double d); | ||||
| /** | |||||
| * Create a new json_object of type json_type_double, using | |||||
| * the exact serialized representation of the value. | |||||
| * | |||||
| * This allows for numbers that would otherwise get displayed | |||||
| * inefficiently (e.g. 12.3 => "12.300000000000001") to be | |||||
| * serialized with the more convenient form. | |||||
| * | |||||
| * Note: this is used by json_tokener_parse_ex() to allow for | |||||
| * an exact re-serialization of a parsed object. | |||||
| * | |||||
| * An equivalent sequence of calls is: | |||||
| * @code | |||||
| * jso = json_object_new_double(d); | |||||
| * json_object_set_serializer(d, json_object_userdata_to_json_string, | |||||
| * strdup(ds), json_object_free_userdata) | |||||
| * @endcode | |||||
| * | |||||
| * @param d the numeric value of the double. | |||||
| * @param ds the string representation of the double. This will be copied. | |||||
| */ | |||||
| extern struct json_object* json_object_new_double_s(double d, const char *ds); | |||||
| /** Get the double floating point value of a json_object | /** Get the double floating point value of a json_object | ||||
| * | * | ||||
| * The type is coerced to a double if the passed object is not a double. | * The type is coerced to a double if the passed object is not a double. | ||||
| @@ -599,8 +599,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
| goto out; | goto out; | ||||
| } | } | ||||
| current = json_object_new_int64(num64); | current = json_object_new_int64(num64); | ||||
| } else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0) { | |||||
| current = json_object_new_double(numd); | |||||
| } | |||||
| else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0) | |||||
| { | |||||
| current = json_object_new_double_s(numd, tok->pb->buf); | |||||
| } else { | } else { | ||||
| tok->err = json_tokener_error_parse_number; | tok->err = json_tokener_error_parse_number; | ||||
| goto out; | goto out; | ||||
| @@ -1,2 +1,2 @@ | |||||
| new_obj.to_string()=[ 1.200000, 3.400000, 123456.780000, 5.000000, 23000000000.000000 ] | |||||
| new_obj.to_string()=[1.2,3.4,123456.78,5.0,23000000000.0] | |||||
| new_obj.to_string()=[ 1.2, 3.4, 123456.78, 5.0, 2.3e10 ] | |||||
| new_obj.to_string()=[1.2,3.4,123456.78,5.0,2.3e10] | |||||
| @@ -5,7 +5,7 @@ new_obj.to_string()="ABC" | |||||
| new_obj.to_string()=null | new_obj.to_string()=null | ||||
| new_obj.to_string()=true | new_obj.to_string()=true | ||||
| new_obj.to_string()=12 | new_obj.to_string()=12 | ||||
| new_obj.to_string()=12.300000 | |||||
| new_obj.to_string()=12.3 | |||||
| new_obj.to_string()=[ "\n" ] | new_obj.to_string()=[ "\n" ] | ||||
| new_obj.to_string()=[ "\nabc\n" ] | new_obj.to_string()=[ "\nabc\n" ] | ||||
| new_obj.to_string()=[ null ] | new_obj.to_string()=[ null ] | ||||