diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2009-08-12 12:13:11 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2009-08-12 12:13:11 +0100 |
commit | d87b18675ac02f42be23bf4070134690b8b9934b (patch) | |
tree | 5697a9c79056a7af04fe3996c9dcd26e8ca5241f /json-glib/json-gobject.c | |
parent | 7411cadc0fdd9ffc2bd7004c9980913ac857a495 (diff) | |
download | json-glib-d87b18675ac02f42be23bf4070134690b8b9934b.tar.gz |
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
Diffstat (limited to 'json-glib/json-gobject.c')
-rw-r--r-- | json-glib/json-gobject.c | 58 |
1 files changed, 45 insertions, 13 deletions
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: |