summaryrefslogtreecommitdiff
path: root/json-glib
diff options
context:
space:
mode:
Diffstat (limited to 'json-glib')
-rw-r--r--json-glib/Makefile.am2
-rw-r--r--json-glib/json-array.c64
-rw-r--r--json-glib/json-data.c93
-rw-r--r--json-glib/json-node.c269
-rw-r--r--json-glib/json-object.c44
-rw-r--r--json-glib/json-parser.c87
-rw-r--r--json-glib/json-parser.h2
-rw-r--r--json-glib/json-private.h38
-rw-r--r--json-glib/json-types.h59
9 files changed, 427 insertions, 231 deletions
diff --git a/json-glib/Makefile.am b/json-glib/Makefile.am
index 8ca1d4e..446520b 100644
--- a/json-glib/Makefile.am
+++ b/json-glib/Makefile.am
@@ -46,7 +46,7 @@ source_h_private = json-private.h
source_c = \
json-array.c \
- json-data.c \
+ json-node.c \
json-object.c \
json-parser.c \
$(NULL)
diff --git a/json-glib/json-array.c b/json-glib/json-array.c
index 6596c90..2f0a249 100644
--- a/json-glib/json-array.c
+++ b/json-glib/json-array.c
@@ -3,11 +3,17 @@
#include "json-types.h"
#include "json-private.h"
+/**
+ * SECTION:json-array
+ * @short_description: a JSON array representation
+ *
+ */
+
struct _JsonArray
{
- GValueArray *elements;
+ GPtrArray *elements;
- volatile guint ref_count;
+ volatile gint ref_count;
};
JsonArray *
@@ -18,7 +24,7 @@ json_array_new (void)
array = g_slice_new (JsonArray);
array->ref_count = 1;
- array->elements = g_value_array_new (0);
+ array->elements = g_ptr_array_new ();
return array;
}
@@ -31,7 +37,7 @@ json_array_sized_new (guint n_elements)
array = g_slice_new (JsonArray);
array->ref_count = 1;
- array->elements = g_value_array_new (n_elements);
+ array->elements = g_ptr_array_sized_new (n_elements);
return array;
}
@@ -77,7 +83,12 @@ json_array_unref (JsonArray *array)
g_atomic_int_compare_and_exchange (&array->ref_count, old_ref, old_ref - 1);
else
{
- g_value_array_free (array->elements);
+ gint i;
+
+ for (i = 0; i < array->elements->len; i++)
+ json_node_free (g_ptr_array_index (array->elements, i));
+
+ g_ptr_array_free (array->elements, TRUE);
array->elements = NULL;
g_slice_free (JsonArray, array);
@@ -88,7 +99,7 @@ json_array_unref (JsonArray *array)
* json_array_get_elements:
* @array: a #JsonArray
*
- * Gets the elements of a #JsonArray in list form.
+ * Gets the elements of a #JsonArray as a list of #JsonNode<!-- -->s.
*
* Return value: a #GList containing the elements of the array. The
* contents of the list are owned by the array and should never be
@@ -104,9 +115,9 @@ json_array_get_elements (JsonArray *array)
g_return_val_if_fail (array != NULL, NULL);
retval = NULL;
- for (i = 0; i < array->elements->n_values; i++)
+ for (i = 0; i < array->elements->len; i++)
retval = g_list_prepend (retval,
- g_value_array_get_nth (array->elements, i));
+ g_ptr_array_index (array->elements, i));
return g_list_reverse (retval);
}
@@ -118,16 +129,16 @@ json_array_get_elements (JsonArray *array)
*
* Retrieves the element at @index_ inside a #JsonArray.
*
- * Return value: a pointer to the value at the requested position
+ * Return value: a pointer to the #JsonNode at the requested index
*/
-GValue *
+JsonNode *
json_array_get_element (JsonArray *array,
guint index_)
{
g_return_val_if_fail (array != NULL, NULL);
- g_return_val_if_fail (index_ < array->elements->n_values, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
- return g_value_array_get_nth (array->elements, index_);
+ return g_ptr_array_index (array->elements, index_);
}
/**
@@ -143,34 +154,15 @@ json_array_get_length (JsonArray *array)
{
g_return_val_if_fail (array != NULL, 0);
- return array->elements->n_values;
-}
-
-void
-json_array_append_element (JsonArray *array,
- const GValue *value)
-{
- g_return_if_fail (array != NULL);
-
- g_value_array_append (array->elements, value);
-}
-
-void
-json_array_prepend_element (JsonArray *array,
- const GValue *value)
-{
- g_return_if_fail (array != NULL);
-
- g_value_array_prepend (array->elements, value);
+ return array->elements->len;
}
void
-json_array_insert_element (JsonArray *array,
- gint index_,
- const GValue *value)
+json_array_add_element (JsonArray *array,
+ JsonNode *node)
{
g_return_if_fail (array != NULL);
- g_return_if_fail (index_ <= array->elements->n_values);
+ g_return_if_fail (node != NULL);
- g_value_array_insert (array->elements, index_, value);
+ g_ptr_array_add (array->elements, node);
}
diff --git a/json-glib/json-data.c b/json-glib/json-data.c
deleted file mode 100644
index ce6f7ab..0000000
--- a/json-glib/json-data.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "config.h"
-
-#include <glib.h>
-
-#include "json-types.h"
-#include "json-private.h"
-
-JsonData *
-json_data_new (JsonDataType type)
-{
- JsonData *data;
-
- data = g_slice_new (JsonData);
- data->type = type;
-
- return data;
-}
-
-void
-json_data_set_object (JsonData *data,
- JsonObject *object)
-{
- g_return_if_fail (data != NULL);
- g_return_if_fail (JSON_DATA_TYPE (data) == JSON_DATA_OBJECT);
- g_return_if_fail (object != NULL);
-
- data->data.object = object;
-}
-
-/**
- * json_data_get_object:
- * @data: a #JsonData
- *
- * Retrieves the #JsonObject stored inside a #JsonData
- *
- * Return value: the #JsonObject
- */
-JsonObject *
-json_data_get_object (JsonData *data)
-{
- g_return_val_if_fail (data != NULL, NULL);
- g_return_val_if_fail (JSON_DATA_TYPE (data) == JSON_DATA_OBJECT, NULL);
-
- return data->data.object;
-}
-
-void
-json_data_set_array (JsonData *data,
- JsonArray *array)
-{
- g_return_if_fail (data != NULL);
- g_return_if_fail (JSON_DATA_TYPE (data) == JSON_DATA_ARRAY);
- g_return_if_fail (array != NULL);
-
- data->data.array = array;
-}
-
-/**
- * json_data_get_array:
- * @data: a #JsonData
- *
- * Retrieves the #JsonArray stored inside a #JsonData
- *
- * Return value: the #JsonArray
- */
-JsonArray *
-json_data_get_array (JsonData *data)
-{
- g_return_val_if_fail (data != NULL, NULL);
- g_return_val_if_fail (JSON_DATA_TYPE (data) == JSON_DATA_ARRAY, NULL);
-
- return data->data.array;
-}
-
-void
-json_data_free (JsonData *data)
-{
- if (data)
- {
- switch (data->type)
- {
- case JSON_DATA_OBJECT:
- json_object_unref (data->data.object);
- break;
-
- case JSON_DATA_ARRAY:
- json_array_unref (data->data.array);
- break;
- }
-
- g_slice_free (JsonData, data);
- }
-}
diff --git a/json-glib/json-node.c b/json-glib/json-node.c
new file mode 100644
index 0000000..50d3df0
--- /dev/null
+++ b/json-glib/json-node.c
@@ -0,0 +1,269 @@
+/**
+ * SECTION:json-node
+ * @short_description: Base element in a JSON stream
+ *
+ * A #JsonNode is a generic container of elements inside a JSON stream.
+ * It can contain fundamental types (integers, booleans, floating point
+ * numbers, strings) and complex types (arrays and objects).
+ *
+ * When parsing a JSON data stream you extract the root node and walk
+ * the node tree by retrieving the type of data contained inside the
+ * node with the %JSON_NODE_TYPE macro. If the node contains a fundamental
+ * type you can retrieve a copy of the GValue holding it with the
+ * json_node_get_value() function, and then use the GValue API to extract
+ * the data; if the node contains a complex type you can retrieve the
+ * #JsonObject or the #JsonArray using json_node_get_object() or
+ * json_node_get_array() respectively, and then retrieve the nodes
+ * they contain.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "json-types.h"
+#include "json-private.h"
+
+JsonNode *
+json_node_new (JsonNodeType type)
+{
+ JsonNode *data;
+
+ data = g_slice_new (JsonNode);
+ data->type = type;
+
+ return data;
+}
+
+JsonNode *
+json_node_copy (JsonNode *node)
+{
+ JsonNode *copy;
+
+ g_return_val_if_fail (node != NULL, NULL);
+
+ copy = g_slice_new (JsonNode);
+ *copy = *node;
+
+ switch (copy->type)
+ {
+ case JSON_NODE_OBJECT:
+ copy->data.object = json_object_ref (node->data.object);
+ break;
+ case JSON_NODE_ARRAY:
+ copy->data.array = json_array_ref (node->data.array);
+ break;
+ case JSON_NODE_VALUE:
+ g_value_init (&(copy->data.value), G_VALUE_TYPE (&(node->data.value)));
+ g_value_copy (&(node->data.value), &(copy->data.value));
+ break;
+ case JSON_NODE_NULL:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return copy;
+}
+
+void
+json_node_set_object (JsonNode *node,
+ JsonObject *object)
+{
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
+
+ if (node->data.object)
+ json_object_unref (node->data.object);
+
+ if (object)
+ node->data.object = json_object_ref (object);
+ else
+ node->data.object = NULL;
+}
+
+void
+json_node_take_object (JsonNode *node,
+ JsonObject *object)
+{
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
+
+ if (node->data.object)
+ {
+ json_object_unref (node->data.object);
+ node->data.object = NULL;
+ }
+
+ if (object)
+ node->data.object = object;
+}
+
+/**
+ * json_node_get_object:
+ * @data: a #JsonNode
+ *
+ * Retrieves the #JsonObject stored inside a #JsonNode
+ *
+ * Return value: the #JsonObject
+ */
+JsonObject *
+json_node_get_object (JsonNode *node)
+{
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
+
+ return node->data.object;
+}
+
+JsonObject *
+json_node_dup_object (JsonNode *node)
+{
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
+
+ if (node->data.object)
+ return json_object_ref (node->data.object);
+
+ return NULL;
+}
+
+void
+json_node_set_array (JsonNode *node,
+ JsonArray *array)
+{
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
+
+ if (node->data.array)
+ json_array_unref (node->data.array);
+
+ if (array)
+ node->data.array = json_array_ref (array);
+ else
+ node->data.array = NULL;
+}
+
+void
+json_node_take_array (JsonNode *node,
+ JsonArray *array)
+{
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
+
+ if (node->data.array)
+ {
+ json_array_unref (node->data.array);
+ node->data.array = NULL;
+ }
+
+ if (array)
+ node->data.array = array;
+}
+
+/**
+ * json_node_get_array:
+ * @node: a #JsonNode
+ *
+ * Retrieves the #JsonArray stored inside a #JsonNode
+ *
+ * Return value: the #JsonArray
+ */
+JsonArray *
+json_node_get_array (JsonNode *node)
+{
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
+
+ return node->data.array;
+}
+
+JsonArray *
+json_node_dup_array (JsonNode *node)
+{
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
+
+ if (node->data.array)
+ return json_array_ref (node->data.array);
+
+ return NULL;
+}
+
+void
+json_node_get_value (JsonNode *node,
+ GValue *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)) != 0)
+ {
+ g_value_init (value, G_VALUE_TYPE (&(node->data.value)));
+ g_value_copy (&(node->data.value), value);
+ }
+}
+
+void
+json_node_set_value (JsonNode *node,
+ const GValue *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)) != 0)
+ g_value_unset (&(node->data.value));
+
+ g_value_init (&(node->data.value), G_VALUE_TYPE (value));
+ g_value_copy (value, &(node->data.value));
+}
+
+void
+json_node_free (JsonNode *node)
+{
+ if (G_LIKELY (node))
+ {
+ switch (node->type)
+ {
+ case JSON_NODE_OBJECT:
+ json_object_unref (node->data.object);
+ break;
+
+ case JSON_NODE_ARRAY:
+ json_array_unref (node->data.array);
+ break;
+
+ case JSON_NODE_VALUE:
+ g_value_unset (&(node->data.value));
+ break;
+
+ case JSON_NODE_NULL:
+ break;
+ }
+
+ g_slice_free (JsonNode, node);
+ }
+}
+
+G_CONST_RETURN gchar *
+json_node_type_name (JsonNode *node)
+{
+ g_return_val_if_fail (node != NULL, "(null)");
+
+ switch (node->type)
+ {
+ case JSON_NODE_OBJECT:
+ return "JsonObject";
+
+ case JSON_NODE_ARRAY:
+ return "JsonArray";
+
+ case JSON_NODE_NULL:
+ return "NULL";
+
+ case JSON_NODE_VALUE:
+ return g_type_name (G_VALUE_TYPE (&(node->data.value)));
+ }
+
+ return "unknown";
+}
diff --git a/json-glib/json-object.c b/json-glib/json-object.c
index aa4d517..0aa7855 100644
--- a/json-glib/json-object.c
+++ b/json-glib/json-object.c
@@ -7,7 +7,7 @@
/**
* SECTION:json-object
- * @short_description: a JSON Object type
+ * @short_description: a JSON object representation
*
* #JsonObject is a boxed type representing a JSON object data type. Each
* JSON object can have zero or more members, and each member is accessed
@@ -19,7 +19,7 @@ struct _JsonObject
{
GHashTable *members;
- volatile guint ref_count;
+ volatile gint ref_count;
};
JsonObject *
@@ -32,7 +32,7 @@ json_object_new (void)
object->ref_count = 1;
object->members = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free,
- g_free);
+ (GDestroyNotify) json_node_free);
return object;
}
@@ -57,21 +57,6 @@ json_object_ref (JsonObject *object)
return object;
}
-static void
-object_unset_members (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GValue *gvalue = value;
-
- /* we copy the contents of the GValues, so we need to unset it
- * before actually freeing them along with the hash table
- */
-
- if (G_VALUE_TYPE (gvalue) != 0) /* we allow unset values */
- g_value_unset (gvalue);
-}
-
/**
* json_object_unref:
* @object: a #JsonObject
@@ -93,7 +78,6 @@ json_object_unref (JsonObject *object)
g_atomic_int_compare_and_exchange (&object->ref_count, old_ref, old_ref - 1);
else
{
- g_hash_table_foreach (object->members, object_unset_members, NULL);
g_hash_table_destroy (object->members);
object->members = NULL;
@@ -102,27 +86,23 @@ json_object_unref (JsonObject *object)
}
void
-json_object_add_member (JsonObject *object,
- const gchar *member_name,
- const GValue *value)
+json_object_add_member (JsonObject *object,
+ const gchar *member_name,
+ JsonNode *node)
{
- GValue *copy;
-
g_return_if_fail (object != NULL);
g_return_if_fail (member_name != NULL);
- g_return_if_fail (value != NULL);
+ g_return_if_fail (node != NULL);
if (json_object_has_member (object, member_name))
{
- g_warning ("JsonObject already has a `%s' member", member_name);
+ g_warning ("JsonObject already has a `%s' member of type `%s'",
+ member_name,
+ json_node_type_name (node));
return;
}
- copy = g_new (GValue, 1);
- g_value_init (copy, G_VALUE_TYPE (value));
- g_value_copy (value, copy);
-
- g_hash_table_replace (object->members, g_strdup (member_name), copy);
+ g_hash_table_replace (object->members, g_strdup (member_name), node);
}
/**
@@ -155,7 +135,7 @@ json_object_get_members (JsonObject *object)
* Return value: a pointer to the value for the requested object
* member, or %NULL
*/
-GValue *
+JsonNode *
json_object_get_member (JsonObject *object,
const gchar *member_name)
{
diff --git a/json-glib/json-parser.c b/json-glib/json-parser.c
index a97554a..4d50137 100644
--- a/json-glib/json-parser.c
+++ b/json-glib/json-parser.c
@@ -17,9 +17,8 @@ json_parser_error_quark (void)
struct _JsonParserPrivate
{
- GList *top_levels;
-
- gint depth;
+ JsonNode *root;
+ JsonNode *current_node;
};
static const GScannerConfig json_scanner_config =
@@ -98,6 +97,14 @@ static guint json_parse_object (JsonParser *parser,
static void
json_parser_dispose (GObject *gobject)
{
+ JsonParserPrivate *priv = JSON_PARSER_GET_PRIVATE (gobject);
+
+ if (priv->root)
+ {
+ json_node_free (priv->root);
+ priv->root = NULL;
+ }
+
G_OBJECT_CLASS (json_parser_parent_class)->dispose (gobject);
}
@@ -136,7 +143,8 @@ json_parser_init (JsonParser *parser)
parser->priv = priv = JSON_PARSER_GET_PRIVATE (parser);
- priv->top_levels = NULL;
+ priv->root = NULL;
+ priv->current_node = NULL;
}
static guint
@@ -161,20 +169,26 @@ json_parse_array (JsonParser *parser,
token = g_scanner_get_next_token (scanner);
while (token != G_TOKEN_RIGHT_BRACE)
{
+ JsonNode *node = NULL;
GValue value = { 0, };
/* nested array */
if (token == G_TOKEN_LEFT_BRACE)
{
- priv->depth += 1;
+ JsonNode *old_node = priv->current_node;
+
+ priv->current_node = json_node_new (JSON_NODE_ARRAY);
token = json_parse_array (parser, scanner, TRUE);
- priv->depth -= 1;
+ node = priv->current_node;
+ priv->current_node = old_node;
if (token != G_TOKEN_NONE)
return token;
+ json_array_add_element (array, node);
+
token = g_scanner_get_next_token (scanner);
if (token == G_TOKEN_RIGHT_BRACE)
break;
@@ -191,42 +205,59 @@ json_parse_array (JsonParser *parser,
case G_TOKEN_INT:
g_value_init (&value, G_TYPE_INT);
g_value_set_int (&value, scanner->value.v_int);
- json_array_append_element (array, &value);
+
+ node = json_node_new (JSON_NODE_VALUE);
+ json_node_set_value (node, &value);
+
+ g_value_unset (&value);
break;
case G_TOKEN_FLOAT:
g_value_init (&value, G_TYPE_FLOAT);
g_value_set_float (&value, scanner->value.v_float);
- json_array_append_element (array, &value);
+
+ node = json_node_new (JSON_NODE_VALUE);
+ json_node_set_value (node, &value);
+
+ g_value_unset (&value);
break;
case G_TOKEN_STRING:
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, scanner->value.v_string);
- json_array_append_element (array, &value);
+
+ node = json_node_new (JSON_NODE_VALUE);
+ json_node_set_value (node, &value);
+
+ g_value_unset (&value);
break;
case JSON_TOKEN_TRUE:
case JSON_TOKEN_FALSE:
g_value_init (&value, G_TYPE_BOOLEAN);
- g_value_set_boolean (&value, token == JSON_TOKEN_TRUE ? TRUE
- : FALSE);
- json_array_append_element (array, &value);
+ g_value_set_boolean (&value, token == JSON_TOKEN_TRUE ? TRUE : FALSE);
+
+ node = json_node_new (JSON_NODE_VALUE);
+ json_node_set_value (node, &value);
+
+ g_value_unset (&value);
break;
case JSON_TOKEN_NULL:
- /* NULL values are packed as empty GValues */
+ node = json_node_new (JSON_NODE_NULL);
break;
default:
return G_TOKEN_RIGHT_BRACE;
}
+ if (node)
+ json_array_add_element (array, node);
+
token = g_scanner_get_next_token (scanner);
}
- if (priv->depth == 0)
- priv->top_levels = g_list_prepend (priv->top_levels, array);
+ json_node_set_array (priv->current_node, array);
return G_TOKEN_NONE;
}
@@ -256,15 +287,18 @@ static guint
json_parse_statement (JsonParser *parser,
GScanner *scanner)
{
+ JsonParserPrivate *priv = parser->priv;
guint token;
token = g_scanner_peek_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_CURLY:
+ priv->root = priv->current_node = json_node_new (JSON_NODE_OBJECT);
return json_parse_object (parser, scanner);
case G_TOKEN_LEFT_BRACE:
+ priv->root = priv->current_node = json_node_new (JSON_NODE_ARRAY);
return json_parse_array (parser, scanner, FALSE);
default:
@@ -401,6 +435,12 @@ json_parser_load_from_data (JsonParser *parser,
if (length < 0)
length = strlen (data);
+ if (parser->priv->root)
+ {
+ json_node_free (parser->priv->root);
+ parser->priv->root = NULL;
+ }
+
scanner = json_scanner_new (parser);
g_scanner_input_text (scanner, data, strlen (data));
@@ -479,24 +519,25 @@ json_parser_load_from_data (JsonParser *parser,
g_scanner_destroy (scanner);
+ parser->priv->current_node = NULL;
+
return retval;
}
/**
- * json_parser_get_toplevels:
+ * json_parser_get_root:
* @parser: a #JsonParser
*
- * Retrieves the top level entities from the parsed JSON stream.
+ * Retrieves the top level node from the parsed JSON stream.
*
- * Return value: a list of pointers to the top-level entites. The
- * returned list is owned by the #JsonParser and should never be
- * modified or freed.
+ * Return value: the root #JsonNode . The returned node is owned by
+ * the #JsonParser and should never be modified or freed.
*/
-GList *
-json_parser_get_toplevels (JsonParser *parser)
+JsonNode *
+json_parser_get_root (JsonParser *parser)
{
g_return_val_if_fail (JSON_IS_PARSER (parser), NULL);
- return parser->priv->top_levels;
+ return parser->priv->root;
}
diff --git a/json-glib/json-parser.h b/json-glib/json-parser.h
index 071b881..2b2152b 100644
--- a/json-glib/json-parser.h
+++ b/json-glib/json-parser.h
@@ -72,7 +72,7 @@ gboolean json_parser_load_from_data (JsonParser *parser,
const gchar *data,
gsize length,
GError **error);
-GList * json_parser_get_toplevels (JsonParser *parser);
+JsonNode * json_parser_get_root (JsonParser *parser);
G_END_DECLS
diff --git a/json-glib/json-private.h b/json-glib/json-private.h
index 76d27d0..1cfc655 100644
--- a/json-glib/json-private.h
+++ b/json-glib/json-private.h
@@ -2,31 +2,29 @@
#define __JSON_PRIVATE_H__
#include <glib-object.h>
-#include <json-glib/json-types.h>
+#include "json-types.h"
G_BEGIN_DECLS
-JsonData *json_data_new (JsonDataType type);
-void json_data_set_object (JsonData *data,
- JsonObject *object);
-void json_data_set_array (JsonData *data,
- JsonArray *array);
-void json_data_free (JsonData *data);
+JsonNode * json_node_new (JsonNodeType type);
+JsonNode * json_node_copy (JsonNode *node);
+void json_node_set_object (JsonNode *node,
+ JsonObject *object);
+void json_node_set_array (JsonNode *node,
+ JsonArray *array);
+void json_node_set_value (JsonNode *node,
+ const GValue *value);
+void json_node_free (JsonNode *node);
-JsonObject *json_object_new (void);
-void json_object_add_member (JsonObject *object,
- const gchar *member_name,
- const GValue *value);
+JsonObject * json_object_new (void);
+void json_object_add_member (JsonObject *object,
+ const gchar *member_name,
+ JsonNode *node);
-JsonArray * json_array_new (void);
-JsonArray * json_array_sized_new (guint n_elements);
-void json_array_append_element (JsonArray *array,
- const GValue *value);
-void json_array_prepend_element (JsonArray *array,
- const GValue *value);
-void json_array_insert_element (JsonArray *array,
- gint index_,
- const GValue *value);
+JsonArray * json_array_new (void);
+JsonArray * json_array_sized_new (guint n_elements);
+void json_array_add_element (JsonArray *array,
+ JsonNode *node);
G_END_DECLS
diff --git a/json-glib/json-types.h b/json-glib/json-types.h
index f8e61a2..0cacec3 100644
--- a/json-glib/json-types.h
+++ b/json-glib/json-types.h
@@ -5,48 +5,57 @@
G_BEGIN_DECLS
-#define JSON_DATA_TYPE(data) (((JsonData *) (data))->type)
+#define JSON_NODE_TYPE(node) (((JsonNode *) (node))->type)
#define JSON_TYPE_OBJECT (json_object_get_type ())
#define JSON_TYPE_ARRAY (json_array_get_type ())
typedef struct _JsonObject JsonObject;
typedef struct _JsonArray JsonArray;
-typedef struct _JsonData JsonData;
+typedef struct _JsonNode JsonNode;
typedef enum {
- JSON_DATA_OBJECT,
- JSON_DATA_ARRAY
-} JsonDataType;
+ JSON_NODE_OBJECT,
+ JSON_NODE_ARRAY,
+ JSON_NODE_VALUE,
+ JSON_NODE_NULL
+} JsonNodeType;
-struct _JsonData
+struct _JsonNode
{
/*< private >*/
- JsonDataType type;
+ JsonNodeType type;
union {
JsonObject *object;
JsonArray *array;
+ GValue value;
} data;
+
+ JsonNode *parent;
};
-JsonObject * json_data_get_object (JsonData *data);
-JsonArray * json_data_get_array (JsonData *data);
-
-JsonObject * json_object_ref (JsonObject *object);
-void json_object_unref (JsonObject *object);
-GList * json_object_get_members (JsonObject *object);
-GValue * json_object_get_member (JsonObject *object,
- const gchar *member_name);
-gboolean json_object_has_member (JsonObject *object,
- const gchar *member_name);
-guint json_object_get_size (JsonObject *object);
-
-JsonArray * json_array_ref (JsonArray *array);
-void json_array_unref (JsonArray *array);
-GList * json_array_get_elements (JsonArray *array);
-GValue * json_array_get_element (JsonArray *array,
- guint index_);
-guint json_array_get_length (JsonArray *array);
+JsonObject * json_node_get_object (JsonNode *node);
+JsonArray * json_node_get_array (JsonNode *node);
+void json_node_get_value (JsonNode *node,
+ GValue *value);
+JsonNode * json_node_get_parent (JsonNode *node);
+G_CONST_RETURN gchar *json_node_type_name (JsonNode *node);
+
+JsonObject * json_object_ref (JsonObject *object);
+void json_object_unref (JsonObject *object);
+GList * json_object_get_members (JsonObject *object);
+JsonNode * json_object_get_member (JsonObject *object,
+ const gchar *member_name);
+gboolean json_object_has_member (JsonObject *object,
+ const gchar *member_name);
+guint json_object_get_size (JsonObject *object);
+
+JsonArray * json_array_ref (JsonArray *array);
+void json_array_unref (JsonArray *array);
+GList * json_array_get_elements (JsonArray *array);
+JsonNode * json_array_get_element (JsonArray *array,
+ guint index_);
+guint json_array_get_length (JsonArray *array);
G_END_DECLS