diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2014-12-20 23:22:09 +0000 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2015-01-25 17:02:31 +0000 |
commit | 1f6668a9534c01523361075dad290c0dc49d7623 (patch) | |
tree | e8c14076f3145ef40694ea5e9f6a558b9cf88abd /json-glib/json-reader.c | |
parent | 23e69e79484d41c722ab8bcab78fe850b960316e (diff) | |
download | json-glib-1f6668a9534c01523361075dad290c0dc49d7623.tar.gz |
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
Diffstat (limited to 'json-glib/json-reader.c')
-rw-r--r-- | json-glib/json-reader.c | 29 |
1 files changed, 16 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); } |