summaryrefslogtreecommitdiff
path: root/json-glib/json-gobject.c
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2009-08-12 12:13:11 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2009-08-12 12:13:11 +0100
commitd87b18675ac02f42be23bf4070134690b8b9934b (patch)
tree5697a9c79056a7af04fe3996c9dcd26e8ca5241f /json-glib/json-gobject.c
parent7411cadc0fdd9ffc2bd7004c9980913ac857a495 (diff)
downloadjson-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.c58
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: