[json-glib] reader: Maintain a stack of member names
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [json-glib] reader: Maintain a stack of member names
- Date: Sun, 25 Jan 2015 17:02:38 +0000 (UTC)
commit 1f6668a9534c01523361075dad290c0dc49d7623
Author: Philip Withnall <philip tecnocode co uk>
Date: Sat Dec 20 23:22:09 2014 +0000
reader: Maintain a stack of member names
This fixes the case where, with nested objects, we call:
json_reader_read_member (reader, "outer");
// json_reader_get_member_name (reader) == "outer"
json_reader_read_member (reader, "inner");
// json_reader_get_member_name (reader) == "inner"
// do something useful
json_reader_end_member (reader);
but at the end, the following assertion no longer holds:
// json_reader_get_member_name (reader) == "outer"
even though the JsonReader state should have been reset after ending the
inner node.
Fix it by maintaining a stack of member names. This works with both
json_reader_read_member() and json_reader_read_element(). Updates to the
unit tests are included.
https://bugzilla.gnome.org/show_bug.cgi?id=741824
json-glib/json-reader.c | 29 ++++++++++++++++-------------
json-glib/tests/reader.c | 13 +++++++++++++
2 files changed, 29 insertions(+), 13 deletions(-)
---
diff --git a/json-glib/json-reader.c b/json-glib/json-reader.c
index 67b67a5..85455a3 100644
--- a/json-glib/json-reader.c
+++ b/json-glib/json-reader.c
@@ -86,7 +86,8 @@ struct _JsonReaderPrivate
JsonNode *current_node;
JsonNode *previous_node;
- gchar *current_member;
+ /* Stack of member names. */
+ GPtrArray *members;
GError *error;
};
@@ -117,7 +118,8 @@ json_reader_finalize (GObject *gobject)
if (priv->error != NULL)
g_clear_error (&priv->error);
- g_free (priv->current_member);
+ if (priv->members != NULL)
+ g_ptr_array_unref (priv->members);
G_OBJECT_CLASS (json_reader_parent_class)->finalize (gobject);
}
@@ -189,6 +191,7 @@ static void
json_reader_init (JsonReader *self)
{
self->priv = json_reader_get_instance_private (self);
+ self->priv->members = g_ptr_array_new_with_free_func (g_free);
}
/**
@@ -487,13 +490,12 @@ json_reader_read_element (JsonReader *reader,
index_);
priv->previous_node = priv->current_node;
- g_free (priv->current_member);
members = json_object_get_members (object);
name = g_list_nth_data (members, index_);
priv->current_node = json_object_get_member (object, name);
- priv->current_member = g_strdup (name);
+ g_ptr_array_add (priv->members, g_strdup (name));
g_list_free (members);
}
@@ -536,8 +538,8 @@ json_reader_end_element (JsonReader *reader)
else
tmp = NULL;
- g_free (priv->current_member);
- priv->current_member = NULL;
+ if (json_node_get_node_type (priv->previous_node) == JSON_NODE_OBJECT)
+ g_ptr_array_remove_index (priv->members, priv->members->len - 1);
priv->current_node = priv->previous_node;
priv->previous_node = tmp;
@@ -648,11 +650,9 @@ json_reader_read_member (JsonReader *reader,
"object at the current position."),
member_name);
- g_free (priv->current_member);
-
priv->previous_node = priv->current_node;
priv->current_node = json_object_get_member (object, member_name);
- priv->current_member = g_strdup (member_name);
+ g_ptr_array_add (priv->members, g_strdup (member_name));
return TRUE;
}
@@ -686,8 +686,7 @@ json_reader_end_member (JsonReader *reader)
else
tmp = NULL;
- g_free (priv->current_member);
- priv->current_member = NULL;
+ g_ptr_array_remove_index (priv->members, priv->members->len - 1);
priv->current_node = priv->previous_node;
priv->previous_node = tmp;
@@ -1032,8 +1031,12 @@ json_reader_get_member_name (JsonReader *reader)
{
json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
_("No node available at the current position"));
- return FALSE;
+ return NULL;
}
- return reader->priv->current_member;
+ if (reader->priv->members->len == 0)
+ return NULL;
+
+ return g_ptr_array_index (reader->priv->members,
+ reader->priv->members->len - 1);
}
diff --git a/json-glib/tests/reader.c b/json-glib/tests/reader.c
index 19f58c9..79f50e2 100644
--- a/json-glib/tests/reader.c
+++ b/json-glib/tests/reader.c
@@ -153,24 +153,37 @@ test_reader_level (void)
/* Grab the list */
g_assert (json_reader_read_member (reader, "list"));
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, "list");
members = json_reader_list_members (reader);
g_assert (members != NULL);
g_strfreev (members);
g_assert (json_reader_read_member (reader, "181195771"));
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, "181195771");
g_assert (!json_reader_read_member (reader, "resolved_url"));
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, NULL);
g_assert (json_reader_get_error (reader) != NULL);
json_reader_end_member (reader);
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, "181195771");
+
g_assert (json_reader_read_member (reader, "given_url"));
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, "given_url");
g_assert_cmpstr (json_reader_get_string_value (reader), ==, "http://www.gnome.org/json-glib-test");
json_reader_end_member (reader);
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, "181195771");
+
json_reader_end_member (reader);
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, "list");
+
json_reader_end_member (reader);
+
+ g_assert_cmpstr (json_reader_get_member_name (reader), ==, NULL);
+
g_clear_object (&reader);
g_clear_object (&parser);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]