[json-glib] Auto-promote integer types to G_TYPE_INT64



commit d87b18675ac02f42be23bf4070134690b8b9934b
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Aug 12 12:13:11 2009 +0100

    Auto-promote integer types to G_TYPE_INT64
    
    The JSON RFC does not specify the size of the integer type, thus
    implicitly falling back to machine-size.
    
    This would all be fine and dandy if some demented Web Developer (and
    I use the term "developer" *very much* loosely) did not decide to
    use integers to store unique identifiers for objects; obviously, you
    can't have more than 2^32-1 status messages in a database with
    millions of users who update their status multiple times per day.
    Right, Twitter?
    
    Anyway, some languages do a type auto-promotion from Integer to
    Long, thus pushing the limit of allowed positive values -- until the
    next integer overflow, that is. C, and GLib, do not do that
    transparently for us so we need to:
    
      - always use gint64 when parsing a JSON data stream using
        JsonScanner
      - move all the Node, Object and Array APIs to gint64
      - auto-promote G_TYPE_INT to G_TYPE_INT64 when setting
        a GValue manually
      - auto-promote and auto-demote G_TYPE_INT properties when
        (de)serializing GObjects.
    
    The GLib types used internally by JSON-GLib are, thus:
    
      integer       -> G_TYPE_INT64
      boolean       -> G_TYPE_BOOLEAN
      float         -> G_TYPE_DOUBLE
      string        -> G_TYPE_STRING

 json-glib/json-array.c        |    4 +-
 json-glib/json-generator.c    |    4 +-
 json-glib/json-gobject.c      |   58 ++++++++++++++++++++++++++++++---------
 json-glib/json-node.c         |   61 +++++++++++++++++++++++++++++++++--------
 json-glib/json-object.c       |    4 +-
 json-glib/json-types.h        |   12 ++++----
 json-glib/tests/array-test.c  |    2 +-
 json-glib/tests/node-test.c   |   14 +++++-----
 json-glib/tests/object-test.c |    2 +-
 tests/test-generator.c        |    4 +-
 tests/test-parser.c           |    4 +-
 tests/test-serialize-full.c   |    9 +-----
 12 files changed, 121 insertions(+), 57 deletions(-)
---
diff --git a/json-glib/json-array.c b/json-glib/json-array.c
index 08e0449..16f36a4 100644
--- a/json-glib/json-array.c
+++ b/json-glib/json-array.c
@@ -241,7 +241,7 @@ json_array_get_element (JsonArray *array,
  *
  * Since: 0.8
  */
-gint
+gint64
 json_array_get_int_element (JsonArray *array,
                             guint      index_)
 {
@@ -483,7 +483,7 @@ json_array_add_element (JsonArray *array,
  */
 void
 json_array_add_int_element (JsonArray *array,
-                            gint       value)
+                            gint64     value)
 {
   JsonNode *node;
 
diff --git a/json-glib/json-generator.c b/json-glib/json-generator.c
index f662fbf..01e5832 100644
--- a/json-glib/json-generator.c
+++ b/json-glib/json-generator.c
@@ -290,8 +290,8 @@ dump_value (JsonGenerator *generator,
 
   switch (G_VALUE_TYPE (&value))
     {
-    case G_TYPE_INT:
-      g_string_append_printf (buffer, "%d", g_value_get_int (&value));
+    case G_TYPE_INT64:
+      g_string_append_printf (buffer, "%" G_GINT64_FORMAT, g_value_get_int64 (&value));
       break;
 
     case G_TYPE_STRING:
diff --git a/json-glib/json-gobject.c b/json-glib/json-gobject.c
index 35b191b..6913537 100644
--- a/json-glib/json-gobject.c
+++ b/json-glib/json-gobject.c
@@ -216,29 +216,50 @@ json_deserialize_pspec (GValue     *value,
 
     case JSON_NODE_VALUE:
       json_node_get_value (node, &node_value);
+#if 0
+      {
+        gchar *node_str = g_strdup_value_contents (&node_value);
+        g_debug ("%s: value type '%s' := node value type '%s' -> '%s'",
+                 G_STRLOC,
+                 g_type_name (G_VALUE_TYPE (value)),
+                 g_type_name (G_VALUE_TYPE (&node_value)),
+                 node_str);
+        g_free (node_str);
+      }
+#endif
 
       switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
         {
         case G_TYPE_BOOLEAN:
-        case G_TYPE_INT:
+        case G_TYPE_INT64:
         case G_TYPE_DOUBLE:
         case G_TYPE_STRING:
           g_value_copy (&node_value, value);
           retval = TRUE;
           break;
 
+        case G_TYPE_INT:
+          g_value_set_int (value, (gint) g_value_get_int64 (&node_value));
+          retval = TRUE;
+          break;
+
         case G_TYPE_CHAR:
-          g_value_set_char (value, (gchar) g_value_get_int (&node_value));
+          g_value_set_char (value, (gchar) g_value_get_int64 (&node_value));
           retval = TRUE;
           break;
 
         case G_TYPE_UINT:
-          g_value_set_uint (value, (gint) g_value_get_int (&node_value));
+          g_value_set_uint (value, (guint) g_value_get_int64 (&node_value));
           retval = TRUE;
           break;
 
         case G_TYPE_UCHAR:
-          g_value_set_uchar (value, (guchar) g_value_get_int (&node_value));
+          g_value_set_uchar (value, (guchar) g_value_get_int64 (&node_value));
+          retval = TRUE;
+          break;
+
+        case G_TYPE_FLOAT:
+          g_value_set_float (value, (gfloat) g_value_get_double (&node_value));
           retval = TRUE;
           break;
 
@@ -246,9 +267,9 @@ json_deserialize_pspec (GValue     *value,
           {
             gint enum_value;
 
-            if (G_VALUE_HOLDS (&node_value, G_TYPE_INT))
+            if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
               {
-                enum_value = g_value_get_int (&node_value);
+                enum_value = g_value_get_int64 (&node_value);
                 retval = TRUE;
               }
             else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
@@ -267,9 +288,9 @@ json_deserialize_pspec (GValue     *value,
           {
             gint flags_value;
 
-            if (G_VALUE_HOLDS (&node_value, G_TYPE_INT))
+            if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
               {
-                flags_value = g_value_get_int (&node_value);
+                flags_value = g_value_get_int64 (&node_value);
                 retval = TRUE;
               }
             else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
@@ -309,7 +330,7 @@ json_serialize_pspec (const GValue *real_value,
 
   switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value)))
     {
-    case G_TYPE_INT:
+    case G_TYPE_INT64:
     case G_TYPE_BOOLEAN:
     case G_TYPE_DOUBLE:
       /* JSON native types */
@@ -320,9 +341,14 @@ json_serialize_pspec (const GValue *real_value,
       g_value_unset (&value);
       break;
 
+    case G_TYPE_INT:
+      retval = json_node_new (JSON_NODE_VALUE);
+      json_node_set_int (retval, g_value_get_int (real_value));
+      break;
+
     case G_TYPE_FLOAT:
       retval = json_node_new (JSON_NODE_VALUE);
-      json_node_set_double (retval, (gdouble) g_value_get_float (real_value));
+      json_node_set_double (retval, g_value_get_float (real_value));
       break;
 
     case G_TYPE_STRING:
@@ -367,21 +393,27 @@ json_serialize_pspec (const GValue *real_value,
 
     case G_TYPE_UINT:
       retval = json_node_new (JSON_NODE_VALUE);
-      json_node_set_int (retval, (gint) g_value_get_uint (real_value));
+      json_node_set_int (retval, g_value_get_uint (real_value));
       break;
 
     case G_TYPE_LONG:
+      retval = json_node_new (JSON_NODE_VALUE);
+      json_node_set_int (retval, g_value_get_long (real_value));
+      break;
+
     case G_TYPE_ULONG:
+      retval = json_node_new (JSON_NODE_VALUE);
+      json_node_set_int (retval, g_value_get_long (real_value));
       break;
 
     case G_TYPE_CHAR:
       retval = json_node_new (JSON_NODE_VALUE);
-      json_node_set_int (retval, (gint) g_value_get_char (real_value));
+      json_node_set_int (retval, g_value_get_char (real_value));
       break;
 
     case G_TYPE_UCHAR:
       retval = json_node_new (JSON_NODE_VALUE);
-      json_node_set_int (retval, (gint) g_value_get_uchar (real_value));
+      json_node_set_int (retval, g_value_get_uchar (real_value));
       break;
 
     case G_TYPE_ENUM:
diff --git a/json-glib/json-node.c b/json-glib/json-node.c
index 1a0aeee..e1e457a 100644
--- a/json-glib/json-node.c
+++ b/json-glib/json-node.c
@@ -359,6 +359,13 @@ json_node_get_value (JsonNode *node,
     }
 }
 
+static void inline
+node_value_unset (JsonNode *node)
+{
+  if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
+    g_value_unset (&(node->data.value));
+}
+
 /**
  * json_node_set_value:
  * @node: a #JsonNode
@@ -372,12 +379,42 @@ json_node_set_value (JsonNode     *node,
 {
   g_return_if_fail (node != NULL);
   g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
+  g_return_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID);
 
-  if (G_VALUE_TYPE (&(node->data.value)) != 0)
-    g_value_unset (&(node->data.value));
+  switch (G_VALUE_TYPE (value))
+    {
+    /* direct copy for the types we use */
+    case G_TYPE_INT64:
+    case G_TYPE_BOOLEAN:
+    case G_TYPE_DOUBLE:
+    case G_TYPE_STRING:
+      node_value_unset (node);
+      g_value_init (&(node->data.value), G_VALUE_TYPE (value));
+      g_value_copy (value, &(node->data.value));
+      break;
+
+    /* auto-promote ints to long longs */
+    case G_TYPE_INT:
+      node_value_unset (node);
+      g_value_init (&(node->data.value), G_TYPE_INT64);
+      g_value_set_int64 (&(node->data.value),
+                         g_value_get_int (value));
+      break;
+
+    /* auto-promote single precision to double precision */
+    case G_TYPE_FLOAT:
+      node_value_unset (node);
+      g_value_init (&(node->data.value), G_TYPE_DOUBLE);
+      g_value_set_double (&(node->data.value),
+                          g_value_get_float (value));
+      break;
+
+    default:
+      g_warning ("Invalid value of type '%s'",
+                 g_type_name (G_VALUE_TYPE (value)));
+      return;
+    }
 
-  g_value_init (&(node->data.value), G_VALUE_TYPE (value));
-  g_value_copy (value, &(node->data.value));
 }
 
 /**
@@ -548,19 +585,19 @@ json_node_dup_string (JsonNode *node)
  */
 void
 json_node_set_int (JsonNode *node,
-                   gint      value)
+                   gint64    value)
 {
   g_return_if_fail (node != NULL);
   g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
 
-  if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT)
-    g_value_set_int (&(node->data.value), value);
+  if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT64)
+    g_value_set_int64 (&(node->data.value), value);
   else
     {
       GValue copy = { 0, };
 
-      g_value_init (&copy, G_TYPE_INT);
-      g_value_set_int (&copy, value);
+      g_value_init (&copy, G_TYPE_INT64);
+      g_value_set_int64 (&copy, value);
 
       json_node_set_value (node, &copy);
 
@@ -576,7 +613,7 @@ json_node_set_int (JsonNode *node,
  *
  * Return value: an integer value.
  */
-gint
+gint64
 json_node_get_int (JsonNode *node)
 {
   g_return_val_if_fail (node != NULL, 0);
@@ -584,8 +621,8 @@ json_node_get_int (JsonNode *node)
   if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
     return 0;
 
-  if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT)
-    return g_value_get_int (&(node->data.value));
+  if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT64)
+    return g_value_get_int64 (&(node->data.value));
 
   return 0;
 }
diff --git a/json-glib/json-object.c b/json-glib/json-object.c
index 7f329cf..0cc6d55 100644
--- a/json-glib/json-object.c
+++ b/json-glib/json-object.c
@@ -223,7 +223,7 @@ json_object_set_member (JsonObject  *object,
 void
 json_object_set_int_member (JsonObject  *object,
                             const gchar *member_name,
-                            gint         value)
+                            gint64       value)
 {
   JsonNode *node;
 
@@ -570,7 +570,7 @@ json_object_get_member (JsonObject  *object,
  *
  * Since: 0.8
  */
-gint
+gint64
 json_object_get_int_member (JsonObject  *object,
                             const gchar *member_name)
 {
diff --git a/json-glib/json-types.h b/json-glib/json-types.h
index 1538488..a3bae4b 100644
--- a/json-glib/json-types.h
+++ b/json-glib/json-types.h
@@ -151,8 +151,8 @@ void                  json_node_set_string      (JsonNode     *node,
 G_CONST_RETURN gchar *json_node_get_string      (JsonNode     *node);
 gchar *               json_node_dup_string      (JsonNode     *node);
 void                  json_node_set_int         (JsonNode     *node,
-                                                 gint          value);
-gint                  json_node_get_int         (JsonNode     *node);
+                                                 gint64        value);
+gint64                json_node_get_int         (JsonNode     *node);
 void                  json_node_set_double      (JsonNode     *node,
                                                  gdouble       value);
 gdouble               json_node_get_double      (JsonNode     *node);
@@ -180,7 +180,7 @@ void                  json_object_set_member         (JsonObject  *object,
                                                       JsonNode    *node);
 void                  json_object_set_int_member     (JsonObject  *object,
                                                       const gchar *member_name,
-                                                      gint         value);
+                                                      gint64       value);
 void                  json_object_set_double_member  (JsonObject  *object,
                                                       const gchar *member_name,
                                                       gdouble      value);
@@ -203,7 +203,7 @@ JsonNode *            json_object_get_member         (JsonObject  *object,
                                                       const gchar *member_name);
 JsonNode *            json_object_dup_member         (JsonObject  *object,
                                                       const gchar *member_name);
-gint                  json_object_get_int_member     (JsonObject  *object,
+gint64                json_object_get_int_member     (JsonObject  *object,
                                                       const gchar *member_name);
 gdouble               json_object_get_double_member  (JsonObject  *object,
                                                       const gchar *member_name);
@@ -235,7 +235,7 @@ void                  json_array_unref               (JsonArray   *array);
 void                  json_array_add_element         (JsonArray   *array,
                                                       JsonNode    *node);
 void                  json_array_add_int_element     (JsonArray   *array,
-                                                      gint         value);
+                                                      gint64       value);
 void                  json_array_add_double_element  (JsonArray   *array,
                                                       gdouble      value);
 void                  json_array_add_boolean_element (JsonArray   *array,
@@ -250,7 +250,7 @@ void                  json_array_add_object_element  (JsonArray   *array,
 GList *               json_array_get_elements        (JsonArray   *array);
 JsonNode *            json_array_get_element         (JsonArray   *array,
                                                       guint        index_);
-gint                  json_array_get_int_element     (JsonArray   *array,
+gint64                json_array_get_int_element     (JsonArray   *array,
                                                       guint        index_);
 gdouble               json_array_get_double_element  (JsonArray   *array,
                                                       guint        index_);
diff --git a/json-glib/tests/array-test.c b/json-glib/tests/array-test.c
index 3d3bf20..89f0175 100644
--- a/json-glib/tests/array-test.c
+++ b/json-glib/tests/array-test.c
@@ -56,7 +56,7 @@ static const struct {
   JsonNodeType element_type;
   GType element_gtype;
 } type_verify[] = {
-  { JSON_NODE_VALUE, G_TYPE_INT },
+  { JSON_NODE_VALUE, G_TYPE_INT64 },
   { JSON_NODE_VALUE, G_TYPE_BOOLEAN },
   { JSON_NODE_VALUE, G_TYPE_STRING },
   { JSON_NODE_NULL, G_TYPE_INVALID }
diff --git a/json-glib/tests/node-test.c b/json-glib/tests/node-test.c
index 8ccc402..3e3d0ff 100644
--- a/json-glib/tests/node-test.c
+++ b/json-glib/tests/node-test.c
@@ -76,19 +76,19 @@ test_value (void)
 
   g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE);
 
-  g_value_init (&value, G_TYPE_INT);
-  g_value_set_int (&value, 42);
+  g_value_init (&value, G_TYPE_INT64);
+  g_value_set_int64 (&value, 42);
 
-  g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_TYPE_INT);
-  g_assert_cmpint (g_value_get_int (&value), ==, 42);
+  g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_TYPE_INT64);
+  g_assert_cmpint (g_value_get_int64 (&value), ==, 42);
 
   json_node_set_value (node, &value);
   json_node_get_value (node, &check);
 
   g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_VALUE_TYPE (&check));
-  g_assert_cmpint (g_value_get_int (&value), ==, g_value_get_int (&check));
-  g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_INT);
-  g_assert_cmpint (g_value_get_int (&check), ==, 42);
+  g_assert_cmpint (g_value_get_int64 (&value), ==, g_value_get_int64 (&check));
+  g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_INT64);
+  g_assert_cmpint (g_value_get_int64 (&check), ==, 42);
 
   g_value_unset (&value);
   g_value_unset (&check);
diff --git a/json-glib/tests/object-test.c b/json-glib/tests/object-test.c
index 5528342..d9b9edd 100644
--- a/json-glib/tests/object-test.c
+++ b/json-glib/tests/object-test.c
@@ -57,7 +57,7 @@ static const struct {
   JsonNodeType member_type;
   GType member_gtype;
 } type_verify[] = {
-  { "integer", JSON_NODE_VALUE, G_TYPE_INT },
+  { "integer", JSON_NODE_VALUE, G_TYPE_INT64 },
   { "boolean", JSON_NODE_VALUE, G_TYPE_BOOLEAN },
   { "string", JSON_NODE_VALUE, G_TYPE_STRING },
   { "null", JSON_NODE_NULL, G_TYPE_INVALID }
diff --git a/tests/test-generator.c b/tests/test-generator.c
index 4d456c7..e5671c2 100644
--- a/tests/test-generator.c
+++ b/tests/test-generator.c
@@ -151,8 +151,8 @@ test_nested_array (void)
   }
 
   val = json_node_new (JSON_NODE_VALUE);
-  g_value_init (&value, G_TYPE_INT);
-  g_value_set_int (&value, 42);
+  g_value_init (&value, G_TYPE_INT64);
+  g_value_set_int64 (&value, 42);
   json_node_set_value (val, &value);
   json_array_add_element (array, val);
   g_value_unset (&value);
diff --git a/tests/test-parser.c b/tests/test-parser.c
index 9331b85..d0f98c4 100644
--- a/tests/test-parser.c
+++ b/tests/test-parser.c
@@ -19,7 +19,7 @@ static const struct {
   GType gtype;
 } test_base_values[] = {
   { "null", JSON_NODE_NULL, G_TYPE_INVALID },
-  { "42", JSON_NODE_VALUE, G_TYPE_INT },
+  { "42", JSON_NODE_VALUE, G_TYPE_INT64 },
   { "true", JSON_NODE_VALUE, G_TYPE_BOOLEAN },
   { "\"string\"", JSON_NODE_VALUE, G_TYPE_STRING }
 };
@@ -54,7 +54,7 @@ static const struct {
   JsonNodeType type;
   GType gtype;
 } test_simple_objects[] = {
-  { "{ \"test\" : 42 }", 1, "test", JSON_NODE_VALUE, G_TYPE_INT },
+  { "{ \"test\" : 42 }", 1, "test", JSON_NODE_VALUE, G_TYPE_INT64 },
   { "{ \"foo\" : \"bar\", \"baz\" : null }", 2, "baz", JSON_NODE_NULL, G_TYPE_INVALID },
   { "{ \"channel\" : \"/meta/connect\" }", 1, "channel", JSON_NODE_VALUE, G_TYPE_STRING }
 };
diff --git a/tests/test-serialize-full.c b/tests/test-serialize-full.c
index f38bc5c..6144954 100644
--- a/tests/test-serialize-full.c
+++ b/tests/test-serialize-full.c
@@ -154,13 +154,8 @@ test_object_serialize_property (JsonSerializable *serializable,
       
       boxed = g_value_get_boxed (value);
 
-      val = json_node_new (JSON_NODE_VALUE);
-      json_node_set_int (val, boxed->foo);
-      json_object_set_member (obj, "foo", val);
-
-      val = json_node_new (JSON_NODE_VALUE);
-      json_node_set_boolean (val, boxed->bar);
-      json_object_set_member (obj, "bar", val);
+      json_object_set_int_member (obj, "foo", boxed->foo);
+      json_object_set_boolean_member (obj, "bar", boxed->bar);
 
       json_node_take_object (retval, obj);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]