summaryrefslogtreecommitdiff
path: root/json-glib/json-node.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-node.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-node.c')
-rw-r--r--json-glib/json-node.c61
1 files changed, 49 insertions, 12 deletions
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;
}