[Multi-valued V2 (grilo) 11/12] core: Merge GrlDataMulti into GrlData
- From: "Juan A. Suarez Romero" <jasuarez igalia com>
- To: grilo-list gnome org
- Subject: [Multi-valued V2 (grilo) 11/12] core: Merge GrlDataMulti into GrlData
- Date: Tue, 1 Mar 2011 10:50:30 +0100
Makes GrlData a truly multi-valued container, keeping the old API for those
applications that are not actually interested in the multi-valued but in the
single-valued data.
Applications using the singled-value API are actually using the first value of
multi-valued elements.
Signed-off-by: Juan A. Suarez Romero <jasuarez igalia com>
---
src/Makefile.am | 2 -
src/data/grl-data-multi.c | 521 -----------------------------------
src/data/grl-data-multi.h | 112 --------
src/data/grl-data.c | 665 +++++++++++++++++++++++++++++++++++++--------
src/data/grl-data.h | 25 ++
src/data/grl-media.c | 2 +-
src/data/grl-media.h | 6 +-
7 files changed, 587 insertions(+), 746 deletions(-)
delete mode 100644 src/data/grl-data-multi.c
delete mode 100644 src/data/grl-data-multi.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 0b37616..cff0f27 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,7 +51,6 @@ lib@GRL_NAME@_la_SOURCES = \
data_c_sources = \
data/grl-data.c \
- data/grl-data-multi.c \
data/grl-property.c \
data/grl-media.c \
data/grl-media-audio.c \
@@ -80,7 +79,6 @@ lib@GRL_NAME@inc_HEADERS = \
data_h_headers = \
data/grl-data.h \
- data/grl-data-multi.h \
data/grl-property.h \
data/grl-media.h \
data/grl-media-box.h \
diff --git a/src/data/grl-data-multi.c b/src/data/grl-data-multi.c
deleted file mode 100644
index d595bff..0000000
--- a/src/data/grl-data-multi.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * Copyright (C) 2011 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez igalia com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:grl-data-multi
- * @short_description: Low-level class to store multivalued data
- * @see_also: #GrlMedia, #GrlMediaBox, #GrlMediaVideo, #GrlMediaAudio, #GrlMediaImage
- *
- * This class acts as dictionary where keys and their values can be stored. It
- * is suggested to better high level classes, like #GrlMedia, which
- * provides functions to access known properties.
- */
-
-#include "grl-data-multi.h"
-#include "grl-log.h"
-#include "grl-plugin-registry.h"
-
-struct _GrlDataMultiPrivate {
- GHashTable *extended_data;
-};
-
-static void grl_data_multi_finalize (GObject *object);
-
-#define GRL_DATA_MULTI_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), GRL_TYPE_DATA_MULTI, GrlDataMultiPrivate))
-
-static void free_list_values (GrlKeyID key, GList *values, gpointer user_data);
-
-/* ================ GrlDataMulti GObject ================ */
-
-G_DEFINE_TYPE (GrlDataMulti, grl_data_multi, GRL_TYPE_DATA);
-
-static void
-grl_data_multi_class_init (GrlDataMultiClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *)klass;
-
- gobject_class->finalize = grl_data_multi_finalize;
-
- g_type_class_add_private (klass, sizeof (GrlDataMultiPrivate));
-}
-
-static void
-grl_data_multi_init (GrlDataMulti *self)
-{
- self->priv = GRL_DATA_MULTI_GET_PRIVATE (self);
- self->priv->extended_data = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- NULL);
-}
-
-static void
-grl_data_multi_finalize (GObject *object)
-{
- GrlDataMulti *mdata = GRL_DATA_MULTI (object);
-
- g_hash_table_foreach (mdata->priv->extended_data,
- (GHFunc) free_list_values,
- NULL);
- g_hash_table_unref (mdata->priv->extended_data);
-
- G_OBJECT_CLASS (grl_data_multi_parent_class)->finalize (object);
-}
-
-/* ================ Utitilies ================ */
-
-static void
-free_list_values (GrlKeyID key, GList *values, gpointer user_data)
-{
- g_list_foreach (values, (GFunc) g_object_unref, NULL);
- g_list_free (values);
-}
-
-/* ================ API ================ */
-
-/**
- * grl_data_multi_new:
- *
- * Creates a new multivalued data object.
- *
- * Returns: a new multivalued data object.
- **/
-GrlDataMulti *
-grl_data_multi_new (void)
-{
- return g_object_new (GRL_TYPE_DATA_MULTI,
- NULL);
-}
-
-/**
- * grl_data_multi_add:
- * @mdata: a multivalued data
- * @prop: a set of related properties with their values
- *
- * Adds a new set of values.
- *
- * All keys in prop must be related among them.
- *
- * mdata will take the ownership of prop, so do not modify it.
- **/
-void
-grl_data_multi_add (GrlDataMulti *mdata,
- GrlProperty *prop)
-{
- GList *key;
- GList *keys;
- GList *values;
- GrlPluginRegistry *registry;
- const GList *related_keys;
- guint l;
-
- g_return_if_fail (GRL_IS_DATA_MULTI (mdata));
- g_return_if_fail (GRL_IS_PROPERTY (prop));
-
- keys = grl_data_get_keys (GRL_DATA (prop));
- if (!keys) {
- /* Ignore empty properties */
- GRL_WARNING ("Empty set of values");
- g_object_unref (prop);
- return;
- }
-
- /* It is assumed that this property only contains values for related properties.
- Check if it must be inserted in data or in extended_data */
-
- l = grl_data_multi_length (mdata, keys->data);
-
- if (l > 0) {
- /* Get the representative element of key */
- registry = grl_plugin_registry_get_default ();
- related_keys =
- grl_plugin_registry_lookup_metadata_key_relation (registry,
- keys->data);
-
- if (!related_keys) {
- GRL_WARNING ("Related keys not found for key: %s",
- grl_metadata_key_get_name (related_keys->data));
- g_list_free (keys);
- return;
- }
-
- values = g_hash_table_lookup (mdata->priv->extended_data,
- related_keys->data);
- values = g_list_append (values, prop);
- g_hash_table_insert (mdata->priv->extended_data,
- related_keys->data,
- values);
- } else {
- /* Insert it as single valued data */
- for (key = keys; key; key = g_list_next (key)) {
- grl_data_set (GRL_DATA (mdata),
- key->data,
- grl_data_get (GRL_DATA (prop), key->data));
- }
- g_object_unref (prop);
- }
- g_list_free (keys);
-}
-
-/**
- * grl_data_multi_length:
- * @mdata: a multivalued data
- * @key: a metadata key
- *
- * Returns how many values key has in mdata.
- *
- * Returns: number of values
- **/
-guint
-grl_data_multi_length (GrlDataMulti *mdata,
- GrlKeyID key)
-{
- GrlPluginRegistry *registry;
- const GList *related_keys;
- gboolean found = FALSE;
- guint length;
-
- g_return_val_if_fail (GRL_IS_DATA_MULTI (mdata), 0);
-
- /* Get the representative element of key */
- registry = grl_plugin_registry_get_default ();
- related_keys = grl_plugin_registry_lookup_metadata_key_relation (registry,
- key);
-
- if (!related_keys) {
- GRL_WARNING ("Related keys not found for key: %s",
- grl_metadata_key_get_name (related_keys->data));
- return 0;
- }
-
- /* Check first extended data */
- length = g_list_length (g_hash_table_lookup (mdata->priv->extended_data,
- related_keys->data));
- if (length == 0) {
- /* Check if we can find the information in data. It is a success if there is
- at least one value for one of the related keys */
- while (related_keys && !found) {
- found = grl_data_key_is_known (GRL_DATA (mdata), related_keys->data);
- related_keys = g_list_next (related_keys);
- }
-
- if (found) {
- return 1;
- } else {
- return 0;
- }
- } else {
- return length + 1;
- }
-}
-
-/**
- * grl_data_multi_get:
- * @mdata: a multivalued data
- * @key: a metadata key
- * @pos: element to retrieve, starting at 0
- *
- * Returns a set containing the values for key and related keys at position specified.
- *
- * Returns: a new #GrlProperty. It must be freed with #g_object_unref()
- **/
-GrlProperty *
-grl_data_multi_get (GrlDataMulti *mdata,
- GrlKeyID key,
- guint pos)
-{
- GrlData *collect_from = NULL;
- GrlPluginRegistry *registry;
- GrlProperty *prop = NULL;
- const GList *related_keys;
- GList *list_el;
-
- g_return_val_if_fail (GRL_IS_DATA_MULTI (mdata), NULL);
-
- /* Get the representative element of key */
- registry = grl_plugin_registry_get_default ();
- related_keys = grl_plugin_registry_lookup_metadata_key_relation (registry,
- key);
-
- if (!related_keys) {
- GRL_WARNING ("Related keys not found for key: %s",
- grl_metadata_key_get_name (related_keys->data));
- return NULL;
- }
-
- if (pos == 0) {
- collect_from = GRL_DATA (mdata);
- } else {
- list_el = g_list_nth (g_hash_table_lookup (mdata->priv->extended_data,
- related_keys->data),
- pos - 1);
- if (list_el) {
- collect_from = GRL_DATA (list_el->data);
- } else {
- GRL_WARNING ("Wrong position %u to get data", pos);
- }
- }
-
- if (collect_from) {
- prop = grl_property_new ();
- while (related_keys) {
- grl_data_set (GRL_DATA (prop),
- related_keys->data,
- grl_data_get (collect_from, related_keys->data));
- related_keys = g_list_next (related_keys);
- }
- }
-
- return prop;
-}
-
-/**
- * grl_data_multi_get_all_single:
- * @mdata: a multivalued data
- * @key: a metadata key
- *
- * Returns all non-NULL values for specified key. This ignores completely the
- * related keys.
- *
- * Returns: (element-type GObject.Value) (transfer container): a #GList with
- * values. Free it with #g_list_free.
- **/
-GList *
-grl_data_multi_get_all_single (GrlDataMulti *mdata,
- GrlKeyID key)
-{
- GList *list_values;
- GList *result = NULL;
- GValue *value;
- GrlPluginRegistry *registry;
- const GList *related_keys;
-
- g_return_val_if_fail (GRL_IS_DATA_MULTI (mdata), NULL);
-
- /* Get the representative element of key */
- registry = grl_plugin_registry_get_default ();
- related_keys = grl_plugin_registry_lookup_metadata_key_relation (registry,
- key);
- if (!related_keys) {
- GRL_WARNING ("Not found related keys");
- return result;
- }
-
- /* Get the first value */
- value = (GValue *) grl_data_get (GRL_DATA (mdata), key);
- if (value) {
- result = g_list_prepend (result, value);
- }
-
- /* Get the remaining list of values */
- list_values = g_hash_table_lookup (mdata->priv->extended_data,
- related_keys->data);
- while (list_values) {
- value = (GValue *) grl_data_get (GRL_DATA (list_values->data), key);
- if (value) {
- result = g_list_prepend (result, value);
- }
- list_values = g_list_next (list_values);
- }
-
- return g_list_reverse (result);
-}
-
-/**
- * grl_data_multi_get_all_single_string:
- * @mdata: a multivalued data
- * @key: a metadata key
- *
- * Returns all non-NULL values for specified key of type string. This ignores
- * completely the related keys.
- *
- * Returns: (element-type utf8) (transfer container): a #GList with
- * values. Free it with #g_list_free.
- **/
-GList *
-grl_data_multi_get_all_single_string (GrlDataMulti *mdata,
- GrlKeyID key)
-{
- GList *list_strings = NULL;
- GList *list_values;
- GList *value;
- const gchar *string_value;
-
- /* Verify key is of type string */
- if (GRL_METADATA_KEY_GET_TYPE (key) != G_TYPE_STRING) {
- GRL_WARNING ("Wrong type (not string)");
- return NULL;
- }
-
- list_values = grl_data_multi_get_all_single (mdata, key);
- for (value = list_values; value; value = g_list_next (value)) {
- string_value = g_value_get_string (value->data);
- if (string_value) {
- list_strings = g_list_prepend (list_strings, (gpointer) string_value);
- }
- }
-
- g_list_free (list_values);
-
- return g_list_reverse (list_strings);
-}
-
-/**
- * grl_data_multi_remove:
- * @mdata: a multivalued data
- * @key: a metadata key
- * @pos: position of key to be removed, starting at 0
- *
- * Removes key and related keys from position in mdata.
- **/
-void
-grl_data_multi_remove (GrlDataMulti *mdata,
- GrlKeyID key,
- guint pos)
-{
- GList *list_values;
- GList *to_remove;
- GrlPluginRegistry *registry;
- GrlProperty *prop_at_1;
- const GList *rel_key;
- const GList *related_keys;
-
- g_return_if_fail (GRL_IS_DATA_MULTI (mdata));
-
- /* Get the representative element of key */
- registry = grl_plugin_registry_get_default ();
- related_keys = grl_plugin_registry_lookup_metadata_key_relation (registry,
- key);
-
- if (!related_keys) {
- GRL_WARNING ("Related keys not found for key: %s",
- grl_metadata_key_get_name (related_keys->data));
- return;
- }
-
- /* If element to remove is in position 0 (single-data), then we can replace it
- by value in pos 1 (extended-data) and then remove 1. If element to remove
- is >0 then we must remove it and shift values the empty position */
-
- if (pos == 0) {
- prop_at_1 = grl_data_multi_get (mdata, key, 1);
- if (prop_at_1) {
- /* Replace related keys in pos 0 */
- for (rel_key = related_keys; rel_key; rel_key = g_list_next (rel_key)) {
- grl_data_set (GRL_DATA (mdata),
- rel_key->data,
- grl_data_get (GRL_DATA (prop_at_1), rel_key->data));
- }
- pos = 1;
- } else {
- /* There is no multivalues; remove data */
- for (rel_key = related_keys; rel_key; rel_key = g_list_next (rel_key)) {
- grl_data_remove (GRL_DATA (mdata), rel_key->data);
- }
- }
- }
-
- if (pos > 0) {
- list_values = g_hash_table_lookup (mdata->priv->extended_data,
- related_keys->data);
- to_remove = g_list_nth (list_values, pos - 1);
- if (!to_remove) {
- /* Wrong index; ignore */
- return;
- }
-
- g_object_unref (to_remove->data);
- list_values = g_list_delete_link (list_values, to_remove);
- g_hash_table_insert (mdata->priv->extended_data,
- related_keys->data,
- list_values);
- }
-}
-
-/**
- * grl_data_multi_update:
- * @mdata: a multivalued data
- * @prop: a set of related keys
- * @pos: position to be updated
- *
- * Updates the values at position in mdata with values in prop.
- *
- * GrlDataMulti will take ownership of prop, so do not free it after invoking
- * this function.
- **/
-void
-grl_data_multi_update (GrlDataMulti *mdata,
- GrlProperty *prop,
- guint pos)
-{
- GList *keys;
- GList *list_val;
- GrlPluginRegistry *registry;
- const GList *related_keys;
-
- g_return_if_fail (GRL_IS_DATA_MULTI (mdata));
- g_return_if_fail (GRL_IS_PROPERTY (prop));
-
- keys = grl_data_get_keys (GRL_DATA (prop));
- if (!keys) {
- GRL_WARNING ("Empty properties");
- g_object_unref (prop);
- return;
- }
-
- /* Get the representative element of key */
- registry = grl_plugin_registry_get_default ();
- related_keys = grl_plugin_registry_lookup_metadata_key_relation (registry,
- keys->data);
-
- if (!related_keys) {
- GRL_WARNING ("Related keys not found for key: %s",
- grl_metadata_key_get_name (related_keys->data));
- return;
- }
-
- if (pos == 0) {
- while (related_keys) {
- grl_data_set (GRL_DATA (mdata),
- related_keys->data,
- grl_data_get (GRL_DATA (prop), related_keys->data));
- related_keys = g_list_next (related_keys);
- }
- g_object_unref (prop);
- } else {
- /* Replace the entire element */
- list_val = g_list_nth (g_hash_table_lookup (mdata->priv->extended_data,
- related_keys->data),
- pos - 1);
- if (!list_val) {
- GRL_WARNING ("%s: index %u out of range", __FUNCTION__, pos);
- g_object_unref (prop);
- return;
- }
-
- g_object_unref (list_val->data);
- list_val->data = prop;
- }
-}
diff --git a/src/data/grl-data-multi.h b/src/data/grl-data-multi.h
deleted file mode 100644
index 88aed98..0000000
--- a/src/data/grl-data-multi.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2011 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez igalia com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#if !defined (_GRILO_H_INSIDE_) && !defined (GRILO_COMPILATION)
-#error "Only <grilo.h> can be included directly."
-#endif
-
-#ifndef _GRL_DATA_MULTI_H_
-#define _GRL_DATA_MULTI_H_
-
-#include <grl-data.h>
-#include <grl-property.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_DATA_MULTI \
- (grl_data_multi_get_type())
-
-#define GRL_DATA_MULTI(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_DATA_MULTI, \
- GrlDataMulti))
-
-#define GRL_DATA_MULTI_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_DATA_MULTI, \
- GrlDataMultiClass))
-
-#define GRL_IS_DATA_MULTI(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_DATA_MULTI))
-
-#define GRL_IS_DATA_MULTI_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_DATA_MULTI))
-
-#define GRL_DATA_MULTI_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_DATA_MULTI, \
- GrlDataMultiClass))
-
-typedef struct _GrlDataMulti GrlDataMulti;
-typedef struct _GrlDataMultiPrivate GrlDataMultiPrivate;
-typedef struct _GrlDataMultiClass GrlDataMultiClass;
-
-/**
- * GrlDataMultiClass:
- * @parent_class: the parent class structure
- *
- * Grilo Data Multivalued class
- */
-struct _GrlDataMultiClass
-{
- GrlDataClass parent_class;
-
- /*< private >*/
- gpointer _grl_reserved[GRL_PADDING];
-};
-
-struct _GrlDataMulti
-{
- GrlData parent;
-
- /*< private >*/
- GrlDataMultiPrivate *priv;
-
- gpointer _grl_reserved[GRL_PADDING_SMALL];
-};
-
-GType grl_data_multi_get_type (void) G_GNUC_CONST;
-
-GrlDataMulti *grl_data_multi_new (void);
-
-void grl_data_multi_add (GrlDataMulti *mdata, GrlProperty *prop);
-
-guint grl_data_multi_length (GrlDataMulti *mdata, GrlKeyID key);
-
-GrlProperty *grl_data_multi_get (GrlDataMulti *mdata, GrlKeyID key, guint pos);
-
-GList *grl_data_multi_get_all_single (GrlDataMulti *mdata, GrlKeyID key);
-
-GList *grl_data_multi_get_all_single_string (GrlDataMulti *mdata, GrlKeyID key);
-
-void grl_data_multi_remove (GrlDataMulti *mdata, GrlKeyID key, guint pos);
-
-void grl_data_multi_update (GrlDataMulti *mdata, GrlProperty *prop, guint pos);
-
-G_END_DECLS
-
-#endif /* _GRL_DATA_MULTI_H_ */
diff --git a/src/data/grl-data.c b/src/data/grl-data.c
index 116319c..6dcee80 100644
--- a/src/data/grl-data.c
+++ b/src/data/grl-data.c
@@ -34,6 +34,10 @@
#include "grl-data.h"
#include "grl-log.h"
+#include <grl-plugin-registry.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT data_log_domain
+GRL_LOG_DOMAIN(data_log_domain);
enum {
PROP_0,
@@ -45,39 +49,35 @@ struct _GrlDataPrivate {
gboolean overwrite;
};
-static void grl_data_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
+static void grl_data_set_gobject_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
-static void grl_data_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
+static void grl_data_get_gobject_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
static void grl_data_finalize (GObject *object);
+static void free_list_values (GrlKeyID key, GList *values, gpointer user_data);
#define GRL_DATA_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GRL_TYPE_DATA, GrlDataPrivate))
-G_DEFINE_TYPE (GrlData, grl_data, G_TYPE_OBJECT);
+static void free_list_values (GrlKeyID key, GList *values, gpointer user_data);
-static void
-free_val (GValue *val)
-{
- if (val) {
- g_value_unset (val);
- g_free (val);
- }
-}
+/* ================ GrlData GObject ================ */
+
+G_DEFINE_TYPE (GrlData, grl_data, G_TYPE_OBJECT);
static void
grl_data_class_init (GrlDataClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
- gobject_class->set_property = grl_data_set_property;
- gobject_class->get_property = grl_data_get_property;
+ gobject_class->set_property = grl_data_set_gobject_property;
+ gobject_class->get_property = grl_data_get_gobject_property;
gobject_class->finalize = grl_data_finalize;
g_type_class_add_private (klass, sizeof (GrlDataPrivate));
@@ -98,21 +98,28 @@ grl_data_init (GrlData *self)
self->priv->data = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
- (GDestroyNotify) free_val);
+ NULL);
}
static void
grl_data_finalize (GObject *object)
{
+ GrlData *data = GRL_DATA (object);
+
g_signal_handlers_destroy (object);
+ g_hash_table_foreach (data->priv->data,
+ (GHFunc) free_list_values,
+ NULL);
+ g_hash_table_unref (data->priv->data);
+
G_OBJECT_CLASS (grl_data_parent_class)->finalize (object);
}
static void
-grl_data_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+grl_data_set_gobject_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GrlData *self = GRL_DATA (object);
@@ -128,10 +135,10 @@ grl_data_set_property (GObject *object,
}
static void
-grl_data_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+grl_data_get_gobject_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GrlData *self = GRL_DATA (object);
@@ -146,6 +153,66 @@ grl_data_get_property (GObject *object,
}
}
+/* ================ Utitilies ================ */
+
+/* Free the list of values, which are of type #GrlProperty */
+static void
+free_list_values (GrlKeyID key, GList *values, gpointer user_data)
+{
+ g_list_foreach (values, (GFunc) g_object_unref, NULL);
+ g_list_free (values);
+}
+
+/* Returns the sample key that represents the set of keys related with @key */
+static GrlKeyID
+get_sample_key (GrlKeyID key)
+{
+ GrlPluginRegistry *registry;
+ const GList *related_keys;
+
+ registry = grl_plugin_registry_get_default ();
+ related_keys =
+ grl_plugin_registry_lookup_metadata_key_relation (registry, key);
+
+ if (!related_keys) {
+ GRL_WARNING ("Related keys not found for key \"%s\"",
+ grl_metadata_key_get_name (related_keys->data));
+ return NULL;
+ } else {
+ return related_keys->data;
+ }
+}
+
+/* Sets the first value of data. If it already has a value and overwrite is
+ %TRUE it is replaced */
+static void
+data_set (GrlData *data, GrlKeyID key, const GValue *value, gboolean overwrite)
+{
+ GrlProperty *prop = NULL;
+
+ /* Get the right property */
+ if (grl_data_length (data, key) > 0) {
+ prop = grl_data_get_property (data, key, 0);
+ }
+
+ if (!prop) {
+ /* No property; add it */
+ prop = grl_property_new_for_key (key);
+ grl_property_set (prop, key, value);
+ grl_data_add_property (data, prop);
+ } else {
+ if (grl_property_key_is_known (prop, key) && !overwrite) {
+ /* Property already has a value, and we can not overwrite it */
+ return;
+ } else {
+ /* Set the new value */
+ grl_property_set (prop, key, value);
+ }
+ }
+}
+
+/* ================ API ================ */
+
/**
* grl_data_new:
*
@@ -165,10 +232,9 @@ grl_data_new (void)
/**
* grl_data_get:
* @data: data to retrieve value
- * @key: (type GObject.ParamSpec): key to look up.
+ * @key: (type Grl.KeyID): key to look up.
*
- * Get the value associated with the key. If it does not contain any value, NULL
- * will be returned.
+ * Get the first value associated with the key.
*
* Returns: (transfer none): a #GValue. This value should not be modified nor freed by user.
*
@@ -177,20 +243,31 @@ grl_data_new (void)
const GValue *
grl_data_get (GrlData *data, GrlKeyID key)
{
+ GrlProperty *prop = NULL;
+
g_return_val_if_fail (GRL_IS_DATA (data), NULL);
g_return_val_if_fail (key, NULL);
- return g_hash_table_lookup (data->priv->data, key);
+ if (grl_data_length (data, key) > 0) {
+ prop = grl_data_get_property (data, key, 0);
+ }
+
+ if (!prop) {
+ return NULL;
+ }
+
+ return grl_property_get (prop, key);
}
/**
* grl_data_set:
* @data: data to modify
- * @key: (type GObject.ParamSpec): key to change or add
+ * @key: (type Grl.KeyID): key to change or add
* @value: the new value
*
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is freed and the new one is set.
+ * Sets the first value associated with the key. If key already has a value and
+ * #overwrite is %TRUE, old value is freed and the new one is set. Else the new
+ * one is assigned.
*
* Also, checks that value is compliant with the key specification, modifying it
* accordingly. For instance, if the key requires a number between 0 and 10, but
@@ -201,42 +278,20 @@ grl_data_get (GrlData *data, GrlKeyID key)
void
grl_data_set (GrlData *data, GrlKeyID key, const GValue *value)
{
- GValue *copy = NULL;
-
g_return_if_fail (GRL_IS_DATA (data));
g_return_if_fail (key);
- if (data->priv->overwrite ||
- g_hash_table_lookup (data->priv->data, key) == NULL) {
- /* Dup value */
- if (value) {
- if (G_VALUE_TYPE (value) == GRL_METADATA_KEY_GET_TYPE (key)) {
- copy = g_new0 (GValue, 1);
- g_value_init (copy, G_VALUE_TYPE (value));
- g_value_copy (value, copy);
- } else {
- GRL_WARNING ("value has type %s, but expected %s",
- g_type_name (G_VALUE_TYPE (value)),
- g_type_name (GRL_METADATA_KEY_GET_TYPE (key)));
- }
- }
-
- if (copy && g_param_value_validate (key, copy)) {
- GRL_WARNING ("'%s' value invalid, adjusting",
- GRL_METADATA_KEY_GET_NAME (key));
- }
- g_hash_table_insert (data->priv->data, key, copy);
- }
+ data_set (data, key, value, data->priv->overwrite);
}
/**
* grl_data_set_string:
* @data: data to modify
- * @key: (type GObject.ParamSpec): key to change or add
+ * @key: (type Grl.KeyID): key to change or add
* @strvalue: the new value
*
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is freed and the new one is set.
+ * Sets the first value associated with the key. If key already has a value and
+ * #overwrite is %TRUE, old value is freed and the new one is set.
*
* Since: 0.1.4
**/
@@ -259,12 +314,13 @@ grl_data_set_string (GrlData *data,
/**
* grl_data_get_string:
* @data: data to inspect
- * @key: (type GObject.ParamSpec): key to use
+ * @key: (type Grl.KeyID): key to use
*
- * Returns the value associated with the key. If key has no value, or value is
- * not string, or key is not in data, then NULL is returned.
+ * Returns the first value associated with the key. If key has no first value,
+ * or value is not string, or key is not in data, then %NULL is returned.
*
- * Returns: string associated with key, or NULL in other case. Caller should not change nor free the value.
+ * Returns: string associated with key, or %NULL in other case. Caller should
+ * not change nor free the value.
*
* Since: 0.1.4
**/
@@ -273,7 +329,7 @@ grl_data_get_string (GrlData *data, GrlKeyID key)
{
const GValue *value = grl_data_get (data, key);
- if (!value || !G_VALUE_HOLDS_STRING(value)) {
+ if (!value || !G_VALUE_HOLDS_STRING (value)) {
return NULL;
} else {
return g_value_get_string (value);
@@ -283,11 +339,11 @@ grl_data_get_string (GrlData *data, GrlKeyID key)
/**
* grl_data_set_int:
* @data: data to change
- * @key: (type GObject.ParamSpec): key to change or add
+ * @key: (type Grl.KeyID): key to change or add
* @intvalue: the new value
*
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is replaced by the new one.
+ * Sets the first value associated with the key. If key already has a first
+ * value and #overwrite is %TRUE, old value is replaced by the new one.
*
* Since: 0.1.4
**/
@@ -303,10 +359,10 @@ grl_data_set_int (GrlData *data, GrlKeyID key, gint intvalue)
/**
* grl_data_get_int:
* @data: data to inspect
- * @key: (type GObject.ParamSpec): key to use
+ * @key: (type Grl.KeyID): key to use
*
- * Returns the value associated with the key. If key has no value, or value is
- * not a gint, or key is not in data, then 0 is returned.
+ * Returns the first value associated with the key. If key has no first value,
+ * or value is not a gint, or key is not in data, then 0 is returned.
*
* Returns: int value associated with key, or 0 in other case.
*
@@ -317,7 +373,7 @@ grl_data_get_int (GrlData *data, GrlKeyID key)
{
const GValue *value = grl_data_get (data, key);
- if (!value || !G_VALUE_HOLDS_INT(value)) {
+ if (!value || !G_VALUE_HOLDS_INT (value)) {
return 0;
} else {
return g_value_get_int (value);
@@ -327,11 +383,11 @@ grl_data_get_int (GrlData *data, GrlKeyID key)
/**
* grl_data_set_float:
* @data: data to change
- * @key: (type GObject.ParamSpec): key to change or add
+ * @key: (type Grl.KeyID): key to change or add
* @floatvalue: the new value
*
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is replaced by the new one.
+ * Sets the first value associated with the key. If key already has a first
+ * value and #overwrite is %TRUE, old value is replaced by the new one.
*
* Since: 0.1.5
**/
@@ -343,13 +399,14 @@ grl_data_set_float (GrlData *data, GrlKeyID key, float floatvalue)
g_value_set_float (&value, floatvalue);
grl_data_set (data, key, &value);
}
+
/**
* grl_data_get_float:
* @data: data to inspect
- * @key: (type GObject.ParamSpec): key to use
+ * @key: (type Grl.KeyID): key to use
*
- * Returns the value associated with the key. If key has no value, or value is
- * not a gfloat, or key is not in data, then 0 is returned.
+ * Returns the first value associated with the key. If key has no first value,
+ * or value is not a gfloat, or key is not in data, then 0 is returned.
*
* Returns: float value associated with key, or 0 in other case.
*
@@ -360,7 +417,7 @@ grl_data_get_float (GrlData *data, GrlKeyID key)
{
const GValue *value = grl_data_get (data, key);
- if (!value || !G_VALUE_HOLDS_FLOAT(value)) {
+ if (!value || !G_VALUE_HOLDS_FLOAT (value)) {
return 0;
} else {
return g_value_get_float (value);
@@ -370,12 +427,12 @@ grl_data_get_float (GrlData *data, GrlKeyID key)
/**
* grl_data_set_binary:
* @data: data to change
- * @key: (type GObject.ParamSpec): key to change or add
+ * @key: (type Grl.KeyID): key to change or add
* @buf: buffer holding the data
* @size: size of the buffer
*
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is replaced by the new one.
+ * Sets the first value associated with the key. If key already has a first
+ * value and #overwrite is %TRUE, old value is replaced by the new one.
**/
void
grl_data_set_binary (GrlData *data, GrlKeyID key, const guint8 *buf, gsize size)
@@ -396,13 +453,13 @@ grl_data_set_binary (GrlData *data, GrlKeyID key, const guint8 *buf, gsize size)
/**
* grl_data_get_binary:
* @data: data to inspect
- * @key: (type GObject.ParamSpec): key to use
+ * @key: (type Grl.KeyID): key to use
* @size: location to store the buffer size
*
- * Returns the value associated with the key. If key has no value, or value is
- * not a gfloat, or key is not in data, then 0 is returned.
+ * Returns the first value associated with the key. If key has no first value,
+ * or value is not a gfloat, or key is not in data, then 0 is returned.
*
- * Returns: buffer location associated with the key, or NULL in other case. If
+ * Returns: buffer location associated with the key, or %NULL in other case. If
* successful size will be set the to the buffer size.
**/
const guint8 *
@@ -412,7 +469,7 @@ grl_data_get_binary(GrlData *data, GrlKeyID key, gsize *size)
const GValue *value = grl_data_get (data, key);
- if (!value || !G_VALUE_HOLDS_BOXED(value)) {
+ if (!value || !G_VALUE_HOLDS_BOXED (value)) {
return NULL;
} else {
GByteArray * array;
@@ -426,7 +483,7 @@ grl_data_get_binary(GrlData *data, GrlKeyID key, gsize *size)
/**
* grl_data_add:
* @data: data to change
- * @key: (type GObject.ParamSpec): key to add
+ * @key: (type Grl.KeyID): key to add
*
* Adds a new key to data, with no value. If key already exists, it does
* nothing.
@@ -444,10 +501,12 @@ grl_data_add (GrlData *data, GrlKeyID key)
/**
* grl_data_remove:
* @data: data to change
- * @key: (type GObject.ParamSpec): key to remove
+ * @key: (type Grl.KeyID): key to remove
+ *
+ * Removes the first value for key from data. If key is not in data, or value is
+ * %NULL, hen it does nothing.
*
- * Removes key from data, freeing its value. If key is not in data, then
- * it does nothing.
+ * Notice this function ignores the value of #overwrite property.
*
* Since: 0.1.4
**/
@@ -455,18 +514,19 @@ void
grl_data_remove (GrlData *data, GrlKeyID key)
{
g_return_if_fail (GRL_IS_DATA (data));
+ g_return_if_fail (key);
- g_hash_table_remove (data->priv->data, key);
+ data_set (data, key, NULL, TRUE);
}
/**
* grl_data_has_key:
* @data: data to inspect
- * @key: (type GObject.ParamSpec): key to search
+ * @key: (type Grl.KeyID): key to search
*
* Checks if key is in data.
*
- * Returns: TRUE if key is in data, FALSE in other case.
+ * Returns: %TRUE if key is in data, %FALSE in other case.
*
* Since: 0.1.4
**/
@@ -484,9 +544,9 @@ grl_data_has_key (GrlData *data, GrlKeyID key)
*
* Returns a list with keys contained in data.
*
- * Returns: (transfer container) (element-type GObject.ParamSpec): an array with
- * the keys. The content of the list should not be modified or freed. Use g_list_free()
- * when done using the list.
+ * Returns: (transfer container) (element-type Grl.KeyID): an array with the
+ * keys. The content of the list should not be modified or freed. Use
+ * g_list_free() when done using the list.
*
* Since: 0.1.4
**/
@@ -505,35 +565,426 @@ grl_data_get_keys (GrlData *data)
/**
* grl_data_key_is_known:
* @data: data to inspect
- * @key: (type GObject.ParamSpec): key to search
+ * @key: (type Grl.KeyID): key to search
*
- * Checks if the key has a value.
+ * Checks if the key has a first value.
*
- * Returns: TRUE if key has a value.
+ * Returns: %TRUE if key has a value.
*
* Since: 0.1.4
**/
gboolean
grl_data_key_is_known (GrlData *data, GrlKeyID key)
{
- GValue *v;
+ const GValue *v;
g_return_val_if_fail (GRL_IS_DATA (data), FALSE);
+ g_return_val_if_fail (key, FALSE);
- v = g_hash_table_lookup (data->priv->data, key);
+ v = grl_data_get (data, key);
if (!v) {
return FALSE;
}
if (G_VALUE_HOLDS_STRING (v)) {
- return g_value_get_string(v) != NULL;
+ return g_value_get_string (v) != NULL;
}
return TRUE;
}
/**
+ * grl_data_add_property:
+ * @data: data to change
+ * @prop: a set of related properties with their values
+ *
+ * Adds a new set of values.
+ *
+ * All keys in prop must be related among them.
+ *
+ * @data will take the ownership of prop, so do not modify it.
+ **/
+void
+grl_data_add_property (GrlData *data,
+ GrlProperty *prop)
+{
+ GList *keys;
+ GList *list_prop;
+ GrlKeyID sample_key;
+
+ g_return_if_fail (GRL_IS_DATA (data));
+ g_return_if_fail (GRL_IS_PROPERTY (prop));
+
+ keys = grl_property_get_keys (prop, TRUE);
+ if (!keys) {
+ /* Ignore empty properties */
+ GRL_WARNING ("Empty set of values");
+ g_object_unref (prop);
+ return;
+ }
+
+ sample_key = get_sample_key (keys->data);
+ g_list_free (keys);
+
+ if (!sample_key) {
+ g_object_unref (prop);
+ return;
+ }
+
+ list_prop = g_hash_table_lookup (data->priv->data, sample_key);
+ list_prop = g_list_append (list_prop, prop);
+ g_hash_table_insert (data->priv->data, sample_key, list_prop);
+}
+
+/**
+ * grl_data_add_string:
+ * @data: data to append
+ * @key: (type Grl.KeyID): key to append
+ * @strvalue: the new value
+ *
+ * Appends a new string value for @key in @data. All related keys are set to
+ * %NULL.
+ **/
+void
+grl_data_add_string (GrlData *data,
+ GrlKeyID key,
+ const gchar *strvalue)
+{
+ GrlProperty *prop;
+
+ prop = grl_property_new_for_key (key);
+ grl_property_set_string (prop, key, strvalue);
+ grl_data_add_property (data, prop);
+}
+
+/**
+ * grl_data_add_int:
+ * @data: data to append
+ * @key: (type Grl.KeyID): key to append
+ * @intvalue: the new value
+ *
+ * Appends a new int value for @key in @data. All related keys are set to
+ * %NULL.
+ **/
+void
+grl_data_add_int (GrlData *data,
+ GrlKeyID key,
+ gint intvalue)
+{
+ GrlProperty *prop;
+
+ prop = grl_property_new_for_key (key);
+ grl_property_set_int (prop, key, intvalue);
+ grl_data_add_property (data, prop);
+}
+
+/**
+ * grl_data_add_float:
+ * @data: data to append
+ * @key: (type Grl.KeyID): key to append
+ * @floatvalue: the new value
+ *
+ * Appends a new float value for @key in @data. All related keys are set to
+ * %NULL.
+ **/
+void
+grl_data_add_float (GrlData *data,
+ GrlKeyID key,
+ gfloat floatvalue)
+{
+ GrlProperty *prop;
+
+ prop = grl_property_new_for_key (key);
+ grl_property_set_float (prop, key, floatvalue);
+ grl_data_add_property (data, prop);
+}
+
+/**
+ * grl_data_add_binary:
+ * @data: data to append
+ * @key: (type Grl.KeyID): key to append
+ * @buf: the buffer containing the new value
+ * @size: size of buffer
+ *
+ * Appends a new binary value for @key in @data. All related keys are set to
+ * %NULL.
+ **/
+void
+grl_data_add_binary (GrlData *data,
+ GrlKeyID key,
+ const guint8 *buf,
+ gsize size)
+{
+ GrlProperty *prop;
+
+ prop = grl_property_new_for_key (key);
+ grl_property_set_binary (prop, key, buf, size);
+ grl_data_add_property (data, prop);
+}
+
+/**
+ * grl_data_length:
+ * @data: a data
+ * @key: a metadata key
+ *
+ * Returns how many values key has in mdata.
+ *
+ * Returns: number of values
+ **/
+guint
+grl_data_length (GrlData *data,
+ GrlKeyID key)
+{
+ GrlKeyID sample_key;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), 0);
+ g_return_val_if_fail (key, 0);
+
+ sample_key = get_sample_key (key);
+ if (!sample_key) {
+ return 0;
+ }
+
+ return g_list_length (g_hash_table_lookup (data->priv->data, sample_key));
+}
+
+/**
+ * grl_data_get_property:
+ * @mdata: a data
+ * @key: a metadata key
+ * @index: element to retrieve, starting at 0
+ *
+ * Returns a set containing the values for key and related keys at position specified.
+ *
+ * If user changes any of the values in the property, the changes will become permanent.
+ *
+ * Returns: a #GrlProperty. Do not free it.
+ **/
+GrlProperty *
+grl_data_get_property (GrlData *data,
+ GrlKeyID key,
+ guint index)
+{
+ GList *prop_list;
+ GrlKeyID sample_key;
+ GrlProperty *prop;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), NULL);
+ g_return_val_if_fail (key, NULL);
+
+ sample_key = get_sample_key (key);
+ if (!sample_key) {
+ return NULL;
+ }
+
+ prop_list = g_hash_table_lookup (data->priv->data, sample_key);
+ prop = g_list_nth_data (prop_list, index);
+
+ if (!prop) {
+ /* GRL_WARNING ("%s: index %u out of range", __FUNCTION__, index); */
+ GRL_WARNING("oUT OF RANGE");
+ return NULL;
+ }
+
+ return prop;
+}
+
+/**
+ * grl_data_get_all_single_property:
+ * @mdata: a data
+ * @key: a metadata key
+ *
+ * Returns all non-%NULL values for specified key. This ignores completely the
+ * related keys.
+ *
+ * Returns: (element-type GObject.Value) (transfer container): a #GList with
+ * values. Do not change or free the values. Free the list with #g_list_free.
+ **/
+GList *
+grl_data_get_all_single_property (GrlData *data,
+ GrlKeyID key)
+{
+ GrlKeyID sample_key;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), NULL);
+ g_return_val_if_fail (key, NULL);
+
+ sample_key = get_sample_key (key);
+ if (!sample_key) {
+ return NULL;
+ }
+
+ return g_list_copy (g_hash_table_lookup (data->priv->data, sample_key));
+}
+
+/**
+ * grl_data_get_all_single_property_string:
+ * @mdata: a data
+ * @key: a metadata key
+ *
+ * Returns all non-%NULL values for specified key of type string. This ignores
+ * completely the related keys.
+ *
+ * Returns: (element-type utf8) (transfer container): a #GList with values. Do
+ * not change or free the strings. Free the list with #g_list_free.
+ **/
+GList *
+grl_data_get_all_single_property_string (GrlData *data,
+ GrlKeyID key)
+{
+ GList *list_strings = NULL;
+ GList *list_values;
+ GList *value;
+ const gchar *string_value;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), NULL);
+ g_return_val_if_fail (key, NULL);
+
+ /* Verify key is of type string */
+ if (GRL_METADATA_KEY_GET_TYPE (key) != G_TYPE_STRING) {
+ GRL_WARNING ("Wrong type (not string)");
+ return NULL;
+ }
+
+ list_values = grl_data_get_all_single_property (data, key);
+ for (value = list_values; value; value = g_list_next (value)) {
+ string_value = g_value_get_string (value->data);
+ if (string_value) {
+ list_strings = g_list_prepend (list_strings, (gpointer) string_value);
+ }
+ }
+
+ g_list_free (list_values);
+
+ return g_list_reverse (list_strings);
+}
+
+/**
+ * grl_data_remove_property:
+ * @data: a data
+ * @key: a metadata key
+ * @index: index of key to be removed, starting at 0
+ *
+ * Removes key and related keys from position in mdata.
+ **/
+void
+grl_data_remove_property (GrlData *data,
+ GrlKeyID key,
+ guint index)
+{
+ GList *prop_element;
+ GList *prop_list;
+ GrlKeyID sample_key;
+
+ g_return_if_fail (GRL_IS_DATA (data));
+ g_return_if_fail (key);
+
+ sample_key = get_sample_key (key);
+ if (!sample_key) {
+ return;
+ }
+
+ prop_list = g_hash_table_lookup (data->priv->data, sample_key);
+ prop_element = g_list_nth (prop_list, index);
+ if (!prop_element) {
+ GRL_WARNING ("%s: index %u out of range", __FUNCTION__, index);
+ return;
+ }
+
+ g_object_unref (prop_element->data);
+ prop_list = g_list_delete_link (prop_list, prop_element);
+ g_hash_table_insert (data->priv->data, sample_key, prop_list);
+}
+
+/**
+ * grl_data_set_property:
+ * @data: a data
+ * @prop: a set of related keys
+ * @index: position to be updated, starting at 0
+ *
+ * Updates the values at position in @data with values in @prop.
+ *
+ * @data will take ownership of @prop, so do not free it after invoking this
+ * function.
+ **/
+void
+grl_data_set_property (GrlData *data,
+ GrlProperty *prop,
+ guint index)
+{
+ GList *keys;
+ GList *prop_element;
+ GList *prop_list;
+ GrlKeyID sample_key;
+
+ g_return_if_fail (GRL_IS_DATA (data));
+ g_return_if_fail (GRL_IS_PROPERTY (prop));
+
+ keys = grl_property_get_keys (prop, TRUE);
+ if (!keys) {
+ GRL_WARNING ("Empty properties");
+ g_object_unref (prop);
+ return;
+ }
+
+ sample_key = get_sample_key (keys->data);
+ g_list_free (keys);
+ if (!sample_key) {
+ return;
+ }
+
+ prop_list = g_hash_table_lookup (data->priv->data, sample_key);
+ prop_element = g_list_nth (prop_list, index);
+ if (!prop_element) {
+ GRL_WARNING ("%s: index %u out of range", __FUNCTION__, index);
+ return;
+ }
+
+ g_object_unref (prop_element->data);
+ prop_element->data = prop;
+}
+
+/**
+ * grl_data_dup:
+ * @data: data to duplicate
+ *
+ * Makes a deep copy of @data and all its contents.
+ *
+ * Returns: a new #GrlData. Free it with #g_object_unref.
+ **/
+GrlData *
+grl_data_dup (GrlData *data)
+{
+ GList *dup_prop_list;
+ GList *key;
+ GList *keys;
+ GList *prop_list;
+ GrlData *dup_data;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), NULL);
+
+ dup_data = grl_data_new ();
+ keys = g_hash_table_get_keys (data->priv->data);
+ for (key = keys; key; key = g_list_next (key)) {
+ dup_prop_list = NULL;
+ prop_list = g_hash_table_lookup (data->priv->data, key->data);
+ while (prop_list) {
+ dup_prop_list = g_list_prepend (dup_prop_list,
+ grl_property_dup (prop_list->data));
+ prop_list = g_list_next (prop_list);
+ }
+ g_hash_table_insert (dup_data->priv->data,
+ key->data,
+ g_list_reverse (prop_list));
+ }
+
+ g_list_free (keys);
+
+ return dup_data;
+}
+
+/**
* grl_data_set_overwrite:
* @data: data to change
* @overwrite: if data can be overwritten
@@ -541,8 +992,8 @@ grl_data_key_is_known (GrlData *data, GrlKeyID key)
* This controls if #grl_data_set will overwrite current value of a property
* with the new one.
*
- * Set it to TRUE so old values are overwritten, or FALSE in other case (default
- * is FALSE).
+ * Set it to %TRUE so old values are overwritten, or %FALSE in other case (default
+ * is %FALSE).
*
* Since: 0.1.4
**/
@@ -563,7 +1014,7 @@ grl_data_set_overwrite (GrlData *data, gboolean overwrite)
*
* Checks if old values are replaced when calling #grl_data_set.
*
- * Returns: TRUE if values will be overwritten.
+ * Returns: %TRUE if values will be overwritten.
*
* Since: 0.1.4
**/
diff --git a/src/data/grl-data.h b/src/data/grl-data.h
index 6af3ad4..d358502 100644
--- a/src/data/grl-data.h
+++ b/src/data/grl-data.h
@@ -32,6 +32,7 @@
#include <glib-object.h>
#include <grl-metadata-key.h>
#include <grl-definitions.h>
+#include <grl-property.h>
G_BEGIN_DECLS
@@ -127,6 +128,30 @@ GList *grl_data_get_keys (GrlData *data);
gboolean grl_data_key_is_known (GrlData *data, GrlKeyID key);
+void grl_data_add_property (GrlData *data, GrlProperty *prop);
+
+void grl_data_add_string (GrlData *data, GrlKeyID key, const gchar *strvalue);
+
+void grl_data_add_int (GrlData *data, GrlKeyID key, gint intvalue);
+
+void grl_data_add_float (GrlData *data, GrlKeyID key, gfloat floatvalue);
+
+void grl_data_add_binary (GrlData *data, GrlKeyID key, const guint8 *buf, gsize size);
+
+guint grl_data_length (GrlData *data, GrlKeyID key);
+
+GrlProperty *grl_data_get_property (GrlData *data, GrlKeyID key, guint index);
+
+GList *grl_data_get_all_single_property (GrlData *data, GrlKeyID key);
+
+GList *grl_data_get_all_single_property_string (GrlData *data, GrlKeyID key);
+
+void grl_data_remove_property (GrlData *data, GrlKeyID key, guint index);
+
+void grl_data_set_property (GrlData *data, GrlProperty *prop, guint index);
+
+GrlData *grl_data_dup (GrlData *data);
+
void grl_data_set_overwrite (GrlData *data, gboolean overwrite);
gboolean grl_data_get_overwrite (GrlData *data);
diff --git a/src/data/grl-media.c b/src/data/grl-media.c
index ad3cf63..d37bed3 100644
--- a/src/data/grl-media.c
+++ b/src/data/grl-media.c
@@ -44,7 +44,7 @@ GRL_LOG_DOMAIN(media_log_domain);
static void grl_media_dispose (GObject *object);
static void grl_media_finalize (GObject *object);
-G_DEFINE_TYPE (GrlMedia, grl_media, GRL_TYPE_DATA_MULTI);
+G_DEFINE_TYPE (GrlMedia, grl_media, GRL_TYPE_DATA);
static void
grl_media_class_init (GrlMediaClass *klass)
diff --git a/src/data/grl-media.h b/src/data/grl-media.h
index 347b48f..31c2928 100644
--- a/src/data/grl-media.h
+++ b/src/data/grl-media.h
@@ -29,7 +29,7 @@
#ifndef _GRL_MEDIA_H_
#define _GRL_MEDIA_H_
-#include <grl-data-multi.h>
+#include <grl-data.h>
#include <grl-definitions.h>
G_BEGIN_DECLS
@@ -85,7 +85,7 @@ typedef struct _GrlMediaClass GrlMediaClass;
*/
struct _GrlMediaClass
{
- GrlDataMultiClass parent_class;
+ GrlDataClass parent_class;
/*< private >*/
gpointer _grl_reserved[GRL_PADDING];
@@ -93,7 +93,7 @@ struct _GrlMediaClass
struct _GrlMedia
{
- GrlDataMulti parent;
+ GrlData parent;
/*< private >*/
gpointer _grl_reserved[GRL_PADDING_SMALL];
--
1.7.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]