summaryrefslogtreecommitdiff
path: root/json-glib/json-object.c
diff options
context:
space:
mode:
Diffstat (limited to 'json-glib/json-object.c')
-rw-r--r--json-glib/json-object.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/json-glib/json-object.c b/json-glib/json-object.c
new file mode 100644
index 0000000..aa4d517
--- /dev/null
+++ b/json-glib/json-object.c
@@ -0,0 +1,201 @@
+#include "config.h"
+
+#include <glib.h>
+
+#include "json-types.h"
+#include "json-private.h"
+
+/**
+ * SECTION:json-object
+ * @short_description: a JSON Object type
+ *
+ * #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
+ * by name. Each member can contain different values: numbers, strings,
+ * arrays (see
+ */
+
+struct _JsonObject
+{
+ GHashTable *members;
+
+ volatile guint ref_count;
+};
+
+JsonObject *
+json_object_new (void)
+{
+ JsonObject *object;
+
+ object = g_slice_new (JsonObject);
+
+ object->ref_count = 1;
+ object->members = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free,
+ g_free);
+
+ return object;
+}
+
+/**
+ * json_object_ref:
+ * @object: a #JsonObject
+ *
+ * Increase by one the reference count of a #JsonObject.
+ *
+ * Return value: the passed #JsonObject, with the reference count
+ * increased by one.
+ */
+JsonObject *
+json_object_ref (JsonObject *object)
+{
+ g_return_val_if_fail (object != NULL, NULL);
+ g_return_val_if_fail (object->ref_count > 0, NULL);
+
+ g_atomic_int_exchange_and_add (&object->ref_count, 1);
+
+ 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
+ *
+ * Decreases by one the reference count of a #JsonObject. If the
+ * reference count reaches zero, the object is destroyed and all
+ * its allocated resources are freed.
+ */
+void
+json_object_unref (JsonObject *object)
+{
+ gint old_ref;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (object->ref_count > 0);
+
+ old_ref = g_atomic_int_get (&object->ref_count);
+ if (old_ref > 1)
+ 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;
+
+ g_slice_free (JsonObject, object);
+ }
+}
+
+void
+json_object_add_member (JsonObject *object,
+ const gchar *member_name,
+ const GValue *value)
+{
+ GValue *copy;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (member_name != NULL);
+ g_return_if_fail (value != NULL);
+
+ if (json_object_has_member (object, member_name))
+ {
+ g_warning ("JsonObject already has a `%s' member", member_name);
+ 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);
+}
+
+/**
+ * json_object_get_members:
+ * @object: a #JsonObject
+ *
+ * Retrieves all the names of the members of a #JsonObject. You can
+ * obtain the value for each member using json_object_get_member().
+ *
+ * Return value: a #GList of member names. The content of the list
+ * is owned by the #JsonObject and should never be modified or
+ * freed. When you have finished using the returned list, use
+ * g_slist_free() to free the resources it has allocated.
+ */
+GList *
+json_object_get_members (JsonObject *object)
+{
+ g_return_val_if_fail (object != NULL, NULL);
+
+ return g_hash_table_get_keys (object->members);
+}
+
+/**
+ * json_object_get_member:
+ * @object: a #JsonObject
+ * @member_name: the name of the JSON object member to access
+ *
+ * Retrieves the value of @member_name inside a #JsonObject.
+ *
+ * Return value: a pointer to the value for the requested object
+ * member, or %NULL
+ */
+GValue *
+json_object_get_member (JsonObject *object,
+ const gchar *member_name)
+{
+ g_return_val_if_fail (object != NULL, NULL);
+ g_return_val_if_fail (member_name != NULL, NULL);
+
+ return g_hash_table_lookup (object->members, member_name);
+}
+
+/**
+ * json_object_has_member:
+ * @object: a #JsonObject
+ * @member_name: the name of a JSON object member
+ *
+ * Checks whether @object has a member named @member_name.
+ *
+ * Return value: %TRUE if the JSON object has the requested member
+ */
+gboolean
+json_object_has_member (JsonObject *object,
+ const gchar *member_name)
+{
+ g_return_val_if_fail (object != NULL, FALSE);
+ g_return_val_if_fail (member_name != NULL, FALSE);
+
+ return (g_hash_table_lookup (object->members, member_name) != NULL);
+}
+
+/**
+ * json_object_get_size:
+ * @object: a #JsonObject
+ *
+ * Retrieves the size of a #JsonObject.
+ *
+ * Return value: the number of members the JSON object has
+ */
+guint
+json_object_get_size (JsonObject *object)
+{
+ g_return_val_if_fail (object != NULL, 0);
+
+ return g_hash_table_size (object->members);
+}