]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Added a json_object_new_double_s() convenience function to allow an exact string...
authorEric Haszlakiewicz <erh+git@nimenees.com>
Thu, 12 Sep 2013 01:27:39 +0000 (20:27 -0500)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Thu, 12 Sep 2013 01:27:39 +0000 (20:27 -0500)
Add json_object_free_userdata() and json_object_userdata_to_json_string() too.

ChangeLog
json_object.c
json_object.h
json_tokener.c
tests/test_locale.expected
tests/test_parse.expected

index 578ebc7f2d462424b6ff7d3d3e2ba30392565da6..1f16787bc49207ffd27235d2390d0b66e8a1c528 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,10 @@
 
 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
 
index 1b3fc76debca8b5fafbfdbb1c4cf384451b8484e..f65ae5249cee7e7cc66969757b6383397cc3956e 100644 (file)
@@ -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 *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)
index df958bf2ccf162edfe9f2770159cfb1a4cefd6ef..100573471d007327a78d264c638f7c31c4ec6728 100644 (file)
@@ -197,6 +197,25 @@ extern void json_object_set_serializer(json_object *jso,
        void *userdata,
        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 */
@@ -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);
 
+/**
+ * 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
  *
  * The type is coerced to a double if the passed object is not a double.
index 7e1fb686e986ea6902a5a25310adf54cce1a5e04..a2a598b1a1e01c9885886c284dd7fa31f758916c 100644 (file)
@@ -599,8 +599,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
                        goto out;
                }
                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 {
           tok->err = json_tokener_error_parse_number;
           goto out;
index 80317851ccef1e1a5b2d2776f52bdf470ea65447..0068be4aae143648702de95c3515eb267e355ffe 100644 (file)
@@ -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]
index f0af0fa1b7523e24d3400458f3ae73118d5f8ee1..5ea99d84bde2968f0381d15a5f698c3ee3f7115d 100644 (file)
@@ -5,7 +5,7 @@ new_obj.to_string()="ABC"
 new_obj.to_string()=null
 new_obj.to_string()=true
 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()=[ "\nabc\n" ]
 new_obj.to_string()=[ null ]