[json-glib] reader: Allow using read_element() on objects
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [json-glib] reader: Allow using read_element() on objects
- Date: Sun, 6 Feb 2011 12:23:48 +0000 (UTC)
commit b2880f5a4dad07ff96a9b6578ffc5d677f75eb94
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Sun Feb 6 11:34:22 2011 +0000
reader: Allow using read_element() on objects
If we assume that a JSON object is just an array with a named mapping
then the JsonReader API should be able to descend into objects using the
same API used for arrays.
This obviously is less useful than it sounds if we take a very strict
interpretation of JSON objects as unordered string-to-value mappings; as
the ordering is not guaranteed to be stable, parsers would be fairly
weak against various JSON definitions.
If the JSON format parsed is guaranteed to be stable then an integer
offset might be an easy (albeit slightly less performant) way to access
data.
json-glib/json-reader.c | 67 +++++++++++++++++++++++++++++++----------
json-glib/tests/reader-test.c | 6 ++++
2 files changed, 57 insertions(+), 16 deletions(-)
---
diff --git a/json-glib/json-reader.c b/json-glib/json-reader.c
index 5c2c00c..8262def 100644
--- a/json-glib/json-reader.c
+++ b/json-glib/json-reader.c
@@ -410,8 +410,8 @@ json_reader_is_value (JsonReader *reader)
* @reader: a #JsonReader
* @index_: the index of the element
*
- * Advances the cursor of @reader to the element @index_ of array at the
- * current position.
+ * Advances the cursor of @reader to the element @index_ of the array
+ * or the object at the current position.
*
* You can use the json_reader_get_value* family of functions to retrieve
* the value of the element; for instance:
@@ -434,9 +434,9 @@ json_reader_is_value (JsonReader *reader)
* json_reader_end_element (reader);
* ]|
*
- * If @reader is not currently on an array, or if the @index_ is bigger than
- * the size of the array, the #JsonReader will be put in an error state until
- * json_reader_end_element() is called.
+ * If @reader is not currently on an array or an object, or if the @index_ is
+ * bigger than the size of the array or the object, the #JsonReader will be
+ * put in an error state until json_reader_end_element() is called.
*
* Return value: %TRUE on success, and %FALSE otherwise
*
@@ -447,7 +447,6 @@ json_reader_read_element (JsonReader *reader,
guint index_)
{
JsonReaderPrivate *priv;
- JsonArray *array;
g_return_val_if_fail (JSON_READER (reader), FALSE);
json_reader_return_val_if_error_set (reader, FALSE);
@@ -457,21 +456,57 @@ json_reader_read_element (JsonReader *reader,
if (priv->current_node == NULL)
priv->current_node = priv->root;
- if (!JSON_NODE_HOLDS_ARRAY (priv->current_node))
+ if (!(JSON_NODE_HOLDS_ARRAY (priv->current_node) ||
+ JSON_NODE_HOLDS_OBJECT (priv->current_node)))
return json_reader_set_error (reader, JSON_READER_ERROR_NO_ARRAY,
"The current node is of type '%s', but "
- "an array was expected.",
+ "an array or an object was expected.",
json_node_type_name (priv->current_node));
- array = json_node_get_array (priv->current_node);
- if (index_ >= json_array_get_length (array))
- return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX,
- "The index '%d' is greater than the size "
- "of the array at the current position.",
- index_);
+ switch (json_node_get_node_type (priv->current_node))
+ {
+ case JSON_NODE_ARRAY:
+ {
+ JsonArray *array = json_node_get_array (priv->current_node);
+
+ if (index_ >= json_array_get_length (array))
+ return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX,
+ "The index '%d' is greater than the size "
+ "of the array at the current position.",
+ index_);
+
+ priv->previous_node = priv->current_node;
+ priv->current_node = json_array_get_element (array, index_);
+ }
+ break;
- priv->previous_node = priv->current_node;
- priv->current_node = json_array_get_element (array, index_);
+ case JSON_NODE_OBJECT:
+ {
+ JsonObject *object = json_node_get_object (priv->current_node);
+ GList *members;
+ const gchar *name;
+
+ if (index_ >= json_object_get_size (object))
+ return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX,
+ "The index '%d' is greater than the size "
+ "of the object at the current position.",
+ index_);
+
+ priv->previous_node = priv->current_node;
+
+ members = json_object_get_members (object);
+ name = g_list_nth_data (members, index_);
+
+ priv->current_node = json_object_get_member (object, name);
+
+ g_list_free (members);
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
return TRUE;
}
diff --git a/json-glib/tests/reader-test.c b/json-glib/tests/reader-test.c
index 7eb982f..e92908e 100644
--- a/json-glib/tests/reader-test.c
+++ b/json-glib/tests/reader-test.c
@@ -58,6 +58,12 @@ test_base_object (void)
json_reader_end_member (reader);
g_assert (json_reader_get_error (reader) == NULL);
+ g_assert (json_reader_read_element (reader, 2));
+ g_assert (json_reader_is_value (reader));
+ g_assert_cmpint (json_reader_get_int_value (reader), ==, 47);
+ json_reader_end_element (reader);
+ g_assert (json_reader_get_error (reader) == NULL);
+
g_object_unref (reader);
g_object_unref (parser);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]