[json-glib] Auto-promote integer types to G_TYPE_INT64
- From: Emmanuele Bassi <ebassi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [json-glib] Auto-promote integer types to G_TYPE_INT64
- Date: Wed, 12 Aug 2009 11:35:22 +0000 (UTC)
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 (©, G_TYPE_INT);
- g_value_set_int (©, value);
+ g_value_init (©, G_TYPE_INT64);
+ g_value_set_int64 (©, value);
json_node_set_value (node, ©);
@@ -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]