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 | |
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')
-rw-r--r-- | json-glib/json-array.c | 4 | ||||
-rw-r--r-- | json-glib/json-generator.c | 4 | ||||
-rw-r--r-- | json-glib/json-gobject.c | 58 | ||||
-rw-r--r-- | json-glib/json-node.c | 61 | ||||
-rw-r--r-- | json-glib/json-object.c | 4 | ||||
-rw-r--r-- | json-glib/json-types.h | 12 | ||||
-rw-r--r-- | json-glib/tests/array-test.c | 2 | ||||
-rw-r--r-- | json-glib/tests/node-test.c | 14 | ||||
-rw-r--r-- | json-glib/tests/object-test.c | 2 |
9 files changed, 115 insertions, 46 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 } |