diff options
Diffstat (limited to 'json-glib')
| -rw-r--r-- | json-glib/Makefile.am | 2 | ||||
| -rw-r--r-- | json-glib/json-array.c | 64 | ||||
| -rw-r--r-- | json-glib/json-data.c | 93 | ||||
| -rw-r--r-- | json-glib/json-node.c | 269 | ||||
| -rw-r--r-- | json-glib/json-object.c | 44 | ||||
| -rw-r--r-- | json-glib/json-parser.c | 87 | ||||
| -rw-r--r-- | json-glib/json-parser.h | 2 | ||||
| -rw-r--r-- | json-glib/json-private.h | 38 | ||||
| -rw-r--r-- | json-glib/json-types.h | 59 |
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 |
