diff options
Diffstat (limited to 'json-glib/json-object.c')
-rw-r--r-- | json-glib/json-object.c | 201 |
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); +} |