[PATCH 4/8] core: Add filtering by equal key
- From: Guillaume Emont <gemont igalia com>
- To: grilo-list <grilo-list gnome org>
- Subject: [PATCH 4/8] core: Add filtering by equal key
- Date: Wed, 14 Dec 2011 18:16:20 +0100
From: "Juan A. Suarez Romero" <jasuarez igalia com>
It supports filtering by equal operator, as "artist = Madonna".
Contains modifications by Guillaume Emont <gemont igalia com>
---
src/grl-caps.c | 50 ++++++++++++
src/grl-caps.h | 7 ++
src/grl-operation-options-priv.h | 1 +
src/grl-operation-options.c | 164 ++++++++++++++++++++++++++++++++++++++
src/grl-operation-options.h | 16 ++++
src/grl-value-helper.c | 6 ++
src/grl-value-helper.h | 2 +
7 files changed, 246 insertions(+), 0 deletions(-)
diff --git a/src/grl-caps.c b/src/grl-caps.c
index afbc9e3..4669499 100644
--- a/src/grl-caps.c
+++ b/src/grl-caps.c
@@ -61,6 +61,7 @@ G_DEFINE_TYPE (GrlCaps, grl_caps, G_TYPE_OBJECT);
struct _GrlCapsPrivate {
GHashTable *data;
GrlTypeFilter type_filter;
+ GList *key_filter;
};
@@ -75,6 +76,7 @@ static void
grl_caps_finalize (GrlCaps *self)
{
g_hash_table_unref (self->priv->data);
+ g_list_free (self->priv->key_filter);
G_OBJECT_CLASS (grl_caps_parent_class)->finalize ((GObject *) self);
}
@@ -88,6 +90,7 @@ grl_caps_init (GrlCaps *self)
/* by default, type filtering is not considered to be supported. The source
* has to explicitly modify its caps. */
self->priv->type_filter = GRL_TYPE_FILTER_NONE;
+ self->priv->key_filter = NULL;
}
static void
@@ -144,6 +147,11 @@ grl_caps_test_option (GrlCaps *caps, const gchar *key, const GValue *value)
return filter == (filter & supported_filter);
}
+ if (0 == g_strcmp0 (key, GRL_OPERATION_OPTION_KEY_EQUAL_FILTER)) {
+ GrlKeyID metadata_key = g_value_get_grl_key_id (value);
+ return grl_caps_is_key_filter (caps, metadata_key);
+ }
+
return FALSE;
}
@@ -163,3 +171,45 @@ grl_caps_set_type_filter (GrlCaps *caps, GrlTypeFilter filter)
caps->priv->type_filter = filter;
}
+/**
+ * grl_caps_get_key_filter:
+ *
+ * Returns: (transfer none) (element-type GrlKeyID):
+ */
+GList *
+grl_caps_get_key_filter (GrlCaps *caps)
+{
+ g_return_val_if_fail (caps, NULL);
+
+ return caps->priv->key_filter;
+}
+
+/**
+ * grl_caps_set_key_filter:
+ * @caps:
+ * @keys: (transfer none) (element-type GrlKeyID):
+ */
+void
+grl_caps_set_key_filter (GrlCaps *caps, GList *keys)
+{
+ g_return_if_fail (caps);
+
+ if (caps->priv->key_filter) {
+ g_list_free (caps->priv->key_filter);
+ }
+
+ caps->priv->key_filter = g_list_copy (keys);
+}
+
+gboolean
+grl_caps_is_key_filter (GrlCaps *caps, GrlKeyID key)
+{
+ g_return_val_if_fail (caps, FALSE);
+
+ if(caps->priv->key_filter) {
+ return g_list_find (caps->priv->key_filter,
+ GRLKEYID_TO_POINTER(key)) != NULL;
+ }
+
+ return FALSE;
+}
diff --git a/src/grl-caps.h b/src/grl-caps.h
index de1ecef..e3abdfa 100644
--- a/src/grl-caps.h
+++ b/src/grl-caps.h
@@ -29,6 +29,7 @@
#include <glib-object.h>
#include <grl-definitions.h>
+#include <grl-metadata-key.h>
G_BEGIN_DECLS
@@ -87,6 +88,12 @@ GrlTypeFilter grl_caps_get_type_filter (GrlCaps *caps);
void grl_caps_set_type_filter (GrlCaps *caps, GrlTypeFilter filter);
+GList *grl_caps_get_key_filter (GrlCaps *caps);
+
+void grl_caps_set_key_filter (GrlCaps *caps, GList *keys);
+
+gboolean grl_caps_is_key_filter (GrlCaps *caps, GrlKeyID key);
+
G_END_DECLS
#endif /* _GRL_CAPS_H_ */
diff --git a/src/grl-operation-options-priv.h b/src/grl-operation-options-priv.h
index b420bc5..2f5d9c3 100644
--- a/src/grl-operation-options-priv.h
+++ b/src/grl-operation-options-priv.h
@@ -35,6 +35,7 @@
#define GRL_OPERATION_OPTION_COUNT "count"
#define GRL_OPERATION_OPTION_FLAGS "flags"
#define GRL_OPERATION_OPTION_TYPE_FILTER "type-filter"
+#define GRL_OPERATION_OPTION_KEY_EQUAL_FILTER "key-equal-filter"
gboolean grl_operation_options_key_is_set (GrlOperationOptions *options,
const gchar *key);
diff --git a/src/grl-operation-options.c b/src/grl-operation-options.c
index f5632ff..265f20f 100644
--- a/src/grl-operation-options.c
+++ b/src/grl-operation-options.c
@@ -30,6 +30,8 @@
*/
#include <grl-operation-options.h>
#include <grl-value-helper.h>
+#include <grl-log.h>
+#include <grl-plugin-registry.h>
#include "grl-operation-options-priv.h"
#include "grl-type-builtins.h"
@@ -41,6 +43,7 @@ G_DEFINE_TYPE (GrlOperationOptions, grl_operation_options, G_TYPE_OBJECT);
struct _GrlOperationOptionsPrivate {
GHashTable *data;
+ GHashTable *key_filter;
GrlCaps *caps;
};
@@ -59,6 +62,7 @@ static void
grl_operation_options_finalize (GrlOperationOptions *self)
{
g_hash_table_unref (self->priv->data);
+ g_hash_table_unref (self->priv->key_filter);
if (self->priv->caps)
g_object_unref (self->priv->caps);
G_OBJECT_CLASS (grl_operation_options_parent_class)->finalize ((GObject *) self);
@@ -70,6 +74,7 @@ grl_operation_options_init (GrlOperationOptions *self)
self->priv = GRL_OPERATION_OPTIONS_GET_PRIVATE (self);
self->priv->data = grl_g_value_hashtable_new ();
+ self->priv->key_filter = grl_g_value_hashtable_new_direct ();
self->priv->caps = NULL;
}
@@ -130,6 +135,11 @@ check_and_copy_option (GrlOperationOptions *options,
return TRUE;
}
+static void
+key_filter_dup (gpointer key_p, GValue *value, GHashTable *destination)
+{
+ g_hash_table_insert (destination, key_p, grl_g_value_dup (value));
+}
/* ========== API ========== */
@@ -178,6 +188,9 @@ grl_operation_options_obey_caps (GrlOperationOptions *options,
GrlOperationOptions **unsupported_options)
{
gboolean ret = TRUE;
+ GHashTableIter table_iter;
+ gpointer key_ptr;
+ GValue *value;
if (supported_options) {
*supported_options = grl_operation_options_new (caps);
@@ -197,6 +210,26 @@ grl_operation_options_obey_caps (GrlOperationOptions *options,
supported_options,
unsupported_options);
+ /* Check filter-by-equal-key */
+ g_hash_table_iter_init (&table_iter, options->priv->key_filter);
+ while (g_hash_table_iter_next (&table_iter, &key_ptr, (gpointer *)&value)) {
+ GrlKeyID key_id = GRLPOINTER_TO_KEYID (key_ptr);
+ if (grl_caps_is_key_filter (caps, key_id)) {
+ if (supported_options) {
+ g_hash_table_insert ((*supported_options)->priv->key_filter,
+ key_ptr,
+ grl_g_value_dup (value));
+ }
+ } else {
+ ret = FALSE;
+ if (unsupported_options) {
+ g_hash_table_insert ((*unsupported_options)->priv->key_filter,
+ key_ptr,
+ grl_g_value_dup (value));
+ }
+ }
+ }
+
return ret;
}
@@ -217,6 +250,10 @@ grl_operation_options_copy (GrlOperationOptions *options)
copy_option (options, copy, GRL_OPERATION_OPTION_FLAGS);
copy_option (options, copy, GRL_OPERATION_OPTION_TYPE_FILTER);
+ g_hash_table_foreach (options->priv->key_filter,
+ (GHFunc) key_filter_dup,
+ copy->priv->key_filter);
+
return copy;
}
@@ -431,3 +468,130 @@ grl_operation_options_get_type_filter (GrlOperationOptions *options)
return TYPE_FILTER_DEFAULT;
}
+
+gboolean
+grl_operation_options_set_key_filter_value (GrlOperationOptions *options,
+ GrlKeyID key,
+ GValue *value)
+{
+ gboolean ret;
+ GrlPluginRegistry *registry;
+ GType key_type;
+
+ registry = grl_plugin_registry_get_default ();
+ key_type = grl_plugin_registry_lookup_metadata_key_type (registry, key);
+
+ if (G_VALUE_TYPE (value) != key_type)
+ return FALSE;
+
+ ret = (options->priv->caps == NULL) ||
+ grl_caps_is_key_filter (options->priv->caps, key);
+
+ if (ret) {
+ if (value) {
+ g_hash_table_insert (options->priv->key_filter,
+ GRLKEYID_TO_POINTER (key),
+ grl_g_value_dup (value));
+ } else {
+ g_hash_table_remove (options->priv->key_filter,
+ GRLKEYID_TO_POINTER (key));
+ }
+ }
+
+ return ret;
+}
+
+gboolean
+grl_operation_options_set_key_filters (GrlOperationOptions *options,
+ ...)
+{
+ GType key_type;
+ GValue value = { 0 };
+ GrlKeyID next_key;
+ gboolean skip;
+ gboolean success = TRUE;
+ va_list args;
+
+ va_start (args, options);
+ next_key = va_arg (args, GrlKeyID);
+ while (next_key) {
+ key_type = GRL_METADATA_KEY_GET_TYPE (next_key);
+ g_value_init (&value, key_type);
+ skip = FALSE;
+ if (key_type == G_TYPE_STRING) {
+ g_value_set_string (&value, va_arg (args, gchar *));
+ } else if (key_type == G_TYPE_INT) {
+ g_value_set_int (&value, va_arg (args, gint));
+ } else {
+ GRL_WARNING ("Unexpected key type when setting up the filter");
+ success = FALSE;
+ skip = TRUE;
+ }
+
+ if (!skip) {
+ success &= grl_operation_options_set_key_filter_value (options,
+ next_key,
+ &value);
+ }
+
+ g_value_unset (&value);
+ next_key = va_arg (args, GrlKeyID);
+ }
+
+ va_end (args);
+
+ return success;
+}
+
+/**
+ * grl_operation_options_set_key_filter_dictionary:
+ * @options:
+ * @filters: (transfer none) (element-type GrlKeyID GValue):
+ *
+ *
+ * Rename to: grl_operation_options_set_key_filters
+ */
+gboolean
+grl_operation_options_set_key_filter_dictionary (GrlOperationOptions *options,
+ GHashTable *filters)
+{
+ GHashTableIter iter;
+ gpointer _key, _value;
+ gboolean ret = TRUE;
+
+ g_hash_table_iter_init (&iter, filters);
+ while (g_hash_table_iter_next (&iter, &_key, &_value)) {
+ GrlKeyID key = GRLPOINTER_TO_KEYID (_key);
+ GValue *value = (GValue *)_value;
+ ret &=
+ grl_operation_options_set_key_filter_value (options, key, value);
+ }
+
+ return ret;
+}
+
+/**
+ * grl_operation_options_get_key_filter:
+ * @options:
+ * @key:
+ *
+ * Returns: (transfer none): the filter
+ */
+GValue *
+grl_operation_options_get_key_filter (GrlOperationOptions *options,
+ GrlKeyID key)
+{
+ return g_hash_table_lookup (options->priv->key_filter,
+ GRLKEYID_TO_POINTER (key));
+}
+
+/**
+ * grl_operation_options_get_key_filter_list:
+ *
+ * Returns: (transfer container) (element-type GrlKeyID):
+ */
+GList *
+grl_operation_options_get_key_filter_list (GrlOperationOptions *options)
+{
+ return g_hash_table_get_keys (options->priv->key_filter);
+}
diff --git a/src/grl-operation-options.h b/src/grl-operation-options.h
index 0cf992f..5682ca1 100644
--- a/src/grl-operation-options.h
+++ b/src/grl-operation-options.h
@@ -25,6 +25,7 @@
#endif
#include <grl-caps.h>
+#include <grl-metadata-key.h>
#if !defined (_GRL_OPERATION_OPTIONS_H_)
#define _GRL_OPERATION_OPTIONS_H_
@@ -101,6 +102,21 @@ gboolean grl_operation_options_set_type_filter (GrlOperationOptions *options,
GrlTypeFilter grl_operation_options_get_type_filter (GrlOperationOptions *options);
+gboolean grl_operation_options_set_key_filter_value (GrlOperationOptions *options,
+ GrlKeyID key,
+ GValue *value);
+
+gboolean grl_operation_options_set_key_filters (GrlOperationOptions *options,
+ ...) G_GNUC_NULL_TERMINATED;
+
+gboolean grl_operation_options_set_key_filter_dictionary (GrlOperationOptions *options,
+ GHashTable *filters);
+
+GValue *grl_operation_options_get_key_filter (GrlOperationOptions *options,
+ GrlKeyID key);
+
+GList *grl_operation_options_get_key_filter_list (GrlOperationOptions *options);
+
G_END_DECLS
#endif /* _GRL_OPERATION_OPTIONS_H_ */
diff --git a/src/grl-value-helper.c b/src/grl-value-helper.c
index 572d6c8..74fe7cb 100644
--- a/src/grl-value-helper.c
+++ b/src/grl-value-helper.c
@@ -67,6 +67,12 @@ grl_g_value_hashtable_new (void)
return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)grl_g_value_free);
}
+GHashTable *
+grl_g_value_hashtable_new_direct (void)
+{
+ return g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)grl_g_value_free);
+}
+
/**
* grl_g_value_dup: (skip):
*/
diff --git a/src/grl-value-helper.h b/src/grl-value-helper.h
index 6079822..bda9069 100644
--- a/src/grl-value-helper.h
+++ b/src/grl-value-helper.h
@@ -37,6 +37,8 @@ void grl_g_value_free (GValue *value);
GHashTable *grl_g_value_hashtable_new (void);
+GHashTable *grl_g_value_hashtable_new_direct (void);
+
GValue *grl_g_value_dup (const GValue *value);
G_END_DECLS
--
1.7.5.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]