[PATCH 7/8] core: Add range-filtering
- From: Guillaume Emont <gemont igalia com>
- To: grilo-list <grilo-list gnome org>
- Subject: [PATCH 7/8] core: Add range-filtering
- Date: Wed, 14 Dec 2011 18:16:23 +0100
From: "Juan A. Suarez Romero" <jasuarez igalia com>
Contains modifications by Guillaume Emont <guijemont igalia com>
---
src/Makefile.am | 4 +-
src/grl-caps.c | 52 ++++++++++++
src/grl-caps.h | 6 ++
src/grl-operation-options-priv.h | 1 +
src/grl-operation-options.c | 171 ++++++++++++++++++++++++++++++++++++++
src/grl-operation-options.h | 16 ++++
src/grl-range-value.c | 92 ++++++++++++++++++++
src/grl-range-value.h | 57 +++++++++++++
8 files changed, 398 insertions(+), 1 deletions(-)
create mode 100644 src/grl-range-value.c
create mode 100644 src/grl-range-value.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 085fc32..b1d64eb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,6 +55,7 @@ lib@GRL_NAME@_la_SOURCES = \
grl-value-helper.c \
grl-caps.c \
grl-operation-options.c grl-operation-options-priv.h \
+ grl-range-value.c \
grilo.c
data_c_sources = \
@@ -87,7 +88,8 @@ lib@GRL_NAME@inc_HEADERS = \
grl-operation.h \
grl-value-helper.h \
grl-caps.h \
- grl-operation-options.h
+ grl-operation-options.h \
+ grl-range-value.h
data_h_headers = \
data/grl-data.h \
diff --git a/src/grl-caps.c b/src/grl-caps.c
index 4669499..0654240 100644
--- a/src/grl-caps.c
+++ b/src/grl-caps.c
@@ -62,6 +62,7 @@ struct _GrlCapsPrivate {
GHashTable *data;
GrlTypeFilter type_filter;
GList *key_filter;
+ GList *key_range_filter;
};
@@ -77,6 +78,8 @@ grl_caps_finalize (GrlCaps *self)
{
g_hash_table_unref (self->priv->data);
g_list_free (self->priv->key_filter);
+ g_list_free (self->priv->key_range_filter);
+
G_OBJECT_CLASS (grl_caps_parent_class)->finalize ((GObject *) self);
}
@@ -91,6 +94,7 @@ grl_caps_init (GrlCaps *self)
* has to explicitly modify its caps. */
self->priv->type_filter = GRL_TYPE_FILTER_NONE;
self->priv->key_filter = NULL;
+ self->priv->key_range_filter = NULL;
}
static void
@@ -152,6 +156,11 @@ grl_caps_test_option (GrlCaps *caps, const gchar *key, const GValue *value)
return grl_caps_is_key_filter (caps, metadata_key);
}
+ if (0 == g_strcmp0 (key, GRL_OPERATION_OPTION_KEY_RANGE_FILTER)) {
+ GrlKeyID grl_key = g_value_get_grl_key_id (value);
+ return grl_caps_is_key_range_filter (caps, grl_key);
+ }
+
return FALSE;
}
@@ -213,3 +222,46 @@ grl_caps_is_key_filter (GrlCaps *caps, GrlKeyID key)
return FALSE;
}
+
+/**
+ * grl_caps_get_key_range_filter:
+ * @caps:
+ *
+ * Returns: (transfer none) (element-type GrlKeyID):
+ */
+GList *
+grl_caps_get_key_range_filter (GrlCaps *caps)
+{
+ g_return_val_if_fail (caps, NULL);
+
+ return caps->priv->key_range_filter;
+}
+
+/**
+ * grl_caps_set_key_range_filter:
+ * @caps:
+ * @keys: (transfer none) (element-type GrlKeyID):
+ */
+void
+grl_caps_set_key_range_filter (GrlCaps *caps, GList *keys)
+{
+ g_return_if_fail (caps);
+
+ if (caps->priv->key_range_filter) {
+ g_list_free (caps->priv->key_range_filter);
+ }
+
+ caps->priv->key_range_filter = g_list_copy (keys);
+}
+
+gboolean
+grl_caps_is_key_range_filter (GrlCaps *caps, GrlKeyID key)
+{
+ g_return_val_if_fail (caps, FALSE);
+
+ if(caps->priv->key_range_filter) {
+ return g_list_find (caps->priv->key_range_filter, GRLKEYID_TO_POINTER (key)) != NULL;
+ }
+
+ return FALSE;
+}
diff --git a/src/grl-caps.h b/src/grl-caps.h
index e3abdfa..b53de9f 100644
--- a/src/grl-caps.h
+++ b/src/grl-caps.h
@@ -94,6 +94,12 @@ void grl_caps_set_key_filter (GrlCaps *caps, GList *keys);
gboolean grl_caps_is_key_filter (GrlCaps *caps, GrlKeyID key);
+GList *grl_caps_get_key_range_filter (GrlCaps *caps);
+
+void grl_caps_set_key_range_filter (GrlCaps *caps, GList *keys);
+
+gboolean grl_caps_is_key_range_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 2f5d9c3..172edb2 100644
--- a/src/grl-operation-options-priv.h
+++ b/src/grl-operation-options-priv.h
@@ -36,6 +36,7 @@
#define GRL_OPERATION_OPTION_FLAGS "flags"
#define GRL_OPERATION_OPTION_TYPE_FILTER "type-filter"
#define GRL_OPERATION_OPTION_KEY_EQUAL_FILTER "key-equal-filter"
+#define GRL_OPERATION_OPTION_KEY_RANGE_FILTER "key-range-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 265f20f..9f681d8 100644
--- a/src/grl-operation-options.c
+++ b/src/grl-operation-options.c
@@ -30,6 +30,7 @@
*/
#include <grl-operation-options.h>
#include <grl-value-helper.h>
+#include <grl-range-value.h>
#include <grl-log.h>
#include <grl-plugin-registry.h>
@@ -44,6 +45,7 @@ G_DEFINE_TYPE (GrlOperationOptions, grl_operation_options, G_TYPE_OBJECT);
struct _GrlOperationOptionsPrivate {
GHashTable *data;
GHashTable *key_filter;
+ GHashTable *key_range_filter;
GrlCaps *caps;
};
@@ -63,6 +65,7 @@ grl_operation_options_finalize (GrlOperationOptions *self)
{
g_hash_table_unref (self->priv->data);
g_hash_table_unref (self->priv->key_filter);
+ g_hash_table_unref (self->priv->key_range_filter);
if (self->priv->caps)
g_object_unref (self->priv->caps);
G_OBJECT_CLASS (grl_operation_options_parent_class)->finalize ((GObject *) self);
@@ -75,6 +78,7 @@ grl_operation_options_init (GrlOperationOptions *self)
self->priv->data = grl_g_value_hashtable_new ();
self->priv->key_filter = grl_g_value_hashtable_new_direct ();
+ self->priv->key_range_filter = grl_range_value_hashtable_new ();
self->priv->caps = NULL;
}
@@ -141,6 +145,12 @@ key_filter_dup (gpointer key_p, GValue *value, GHashTable *destination)
g_hash_table_insert (destination, key_p, grl_g_value_dup (value));
}
+static void
+key_range_filter_dup (GrlKeyID key, GrlRangeValue *value, GHashTable *destination)
+{
+ grl_range_value_hashtable_insert (destination, GRLKEYID_TO_POINTER (key), value->min, value->max);
+}
+
/* ========== API ========== */
/**
@@ -191,6 +201,7 @@ grl_operation_options_obey_caps (GrlOperationOptions *options,
GHashTableIter table_iter;
gpointer key_ptr;
GValue *value;
+ GrlRangeValue *range_value;
if (supported_options) {
*supported_options = grl_operation_options_new (caps);
@@ -230,6 +241,26 @@ grl_operation_options_obey_caps (GrlOperationOptions *options,
}
}
+ /* Check filter-by-range-key */
+ g_hash_table_iter_init (&table_iter, options->priv->key_range_filter);
+ while (g_hash_table_iter_next (&table_iter, &key_ptr, (gpointer *)&range_value)) {
+ GrlKeyID key_id = GRLPOINTER_TO_KEYID (key_ptr);
+ if (grl_caps_is_key_range_filter (caps, key_id)) {
+ if (supported_options) {
+ g_hash_table_insert ((*supported_options)->priv->key_range_filter,
+ key_ptr,
+ grl_range_value_dup (range_value));
+ }
+ } else {
+ ret = FALSE;
+ if (unsupported_options) {
+ g_hash_table_insert ((*unsupported_options)->priv->key_range_filter,
+ key_ptr,
+ grl_range_value_dup (range_value));
+ }
+ }
+ }
+
return ret;
}
@@ -254,6 +285,10 @@ grl_operation_options_copy (GrlOperationOptions *options)
(GHFunc) key_filter_dup,
copy->priv->key_filter);
+ g_hash_table_foreach (options->priv->key_range_filter,
+ (GHFunc) key_range_filter_dup,
+ copy->priv->key_range_filter);
+
return copy;
}
@@ -595,3 +630,139 @@ grl_operation_options_get_key_filter_list (GrlOperationOptions *options)
{
return g_hash_table_get_keys (options->priv->key_filter);
}
+
+gboolean
+grl_operation_options_set_key_range_filter_value (GrlOperationOptions *options,
+ GrlKeyID key,
+ GValue *min_value,
+ GValue *max_value)
+{
+ gboolean ret;
+
+ ret = (options->priv->caps == NULL) ||
+ grl_caps_is_key_range_filter (options->priv->caps, key);
+
+ if (ret) {
+ if (min_value || max_value) {
+ grl_range_value_hashtable_insert (options->priv->key_range_filter,
+ GRLKEYID_TO_POINTER (key),
+ min_value, max_value);
+ } else {
+ g_hash_table_remove (options->priv->key_range_filter,
+ GRLKEYID_TO_POINTER (key));
+ }
+ }
+
+ return ret;
+}
+
+gboolean
+grl_operation_options_set_key_range_filter (GrlOperationOptions *options,
+ ...)
+{
+ GType key_type;
+ GValue min_value = { 0 };
+ GValue *min_p_value;
+ gint min_int_value;
+ gchar *min_str_value;
+ GValue max_value = { 0 };
+ GValue *max_p_value;
+ gint max_int_value;
+ gchar *max_str_value;
+ 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 (&min_value, key_type);
+ g_value_init (&max_value, key_type);
+ min_p_value = NULL;
+ max_p_value = NULL;
+ skip = FALSE;
+ if (key_type == G_TYPE_STRING) {
+ min_str_value = va_arg (args, gchar *);
+ max_str_value = va_arg (args, gchar *);
+ if (min_str_value) {
+ g_value_set_string (&min_value, min_str_value);
+ min_p_value = &min_value;
+ }
+ if (max_str_value) {
+ g_value_set_string (&max_value, max_str_value);
+ max_p_value = &max_value;
+ }
+ } else if (key_type == G_TYPE_INT) {
+ min_int_value = va_arg (args, gint);
+ max_int_value = va_arg (args, gint);
+ if (min_int_value > G_MININT) {
+ g_value_set_int (&min_value, min_int_value);
+ min_p_value = &min_value;
+ }
+ if (max_int_value < G_MAXINT) {
+ g_value_set_int (&max_value, max_int_value);
+ max_p_value = &max_value;
+ }
+ } else {
+ GRL_WARNING ("Unexpected key type when setting up the filter");
+ success = FALSE;
+ skip = TRUE;
+ }
+
+ if (!skip) {
+ success &= grl_operation_options_set_key_range_filter_value (options,
+ next_key,
+ min_p_value,
+ max_p_value);
+ }
+
+ g_value_unset (&min_value);
+ g_value_unset (&max_value);
+ next_key = va_arg (args, GrlKeyID);
+ }
+
+ va_end (args);
+
+ return success;
+}
+
+void
+grl_operation_options_get_key_range_filter (GrlOperationOptions *options,
+ GrlKeyID key,
+ GValue **min_value,
+ GValue **max_value)
+{
+ GrlRangeValue *range =
+ (GrlRangeValue *) g_hash_table_lookup (options->priv->key_range_filter,
+ GRLKEYID_TO_POINTER (key));
+
+ if (min_value) {
+ if (range && range->min) {
+ *min_value = range->min;
+ } else {
+ *min_value = NULL;
+ }
+ }
+
+ if (max_value) {
+ if (range && range->max) {
+ *max_value = range->max;
+ } else {
+ *max_value = NULL;
+ }
+ }
+}
+
+/**
+ * grl_operation_options_get_key_range_filter_list:
+ * @options:
+ *
+ * Returns: (transfer container) (element-type GrlKeyID):
+ */
+GList *
+grl_operation_options_get_key_range_filter_list (GrlOperationOptions *options)
+{
+ return g_hash_table_get_keys (options->priv->key_range_filter);
+}
diff --git a/src/grl-operation-options.h b/src/grl-operation-options.h
index 5682ca1..ef4bf85 100644
--- a/src/grl-operation-options.h
+++ b/src/grl-operation-options.h
@@ -117,6 +117,22 @@ GValue *grl_operation_options_get_key_filter (GrlOperationOptions *options,
GList *grl_operation_options_get_key_filter_list (GrlOperationOptions *options);
+gboolean grl_operation_options_set_key_range_filter_value (GrlOperationOptions *options,
+ GrlKeyID key,
+ GValue *min_value,
+ GValue *max_value);
+
+gboolean grl_operation_options_set_key_range_filter (GrlOperationOptions *options,
+ ...);
+
+void grl_operation_options_get_key_range_filter (GrlOperationOptions *options,
+ GrlKeyID key,
+ GValue **min_value,
+ GValue **max_value);
+
+
+GList *grl_operation_options_get_key_range_filter_list (GrlOperationOptions *options);
+
G_END_DECLS
#endif /* _GRL_OPERATION_OPTIONS_H_ */
diff --git a/src/grl-range-value.c b/src/grl-range-value.c
new file mode 100644
index 0000000..6dfb4ab
--- /dev/null
+++ b/src/grl-range-value.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral 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-range-value
+ * @short_description: helpers to use Range Values
+ *
+ * This module provides helper functions to use Range Values easily. Inspired by
+ * libsoup's soup-value-utils:
+ * http://git.gnome.org/browse/libsoup/tree/libsoup/soup-value-utils.c
+ *
+ */
+
+#include <grl-range-value.h>
+#include <grl-value-helper.h>
+
+G_DEFINE_BOXED_TYPE (GrlRangeValue, grl_range_value,
+ (GBoxedCopyFunc) grl_range_value_dup,
+ (GBoxedFreeFunc) grl_range_value_free)
+
+
+GrlRangeValue *
+grl_range_value_new (GValue *min, GValue *max)
+{
+ GrlRangeValue *range;
+
+ range = g_slice_new0 (GrlRangeValue);
+ if (min) {
+ range->min = grl_g_value_dup (min);
+ }
+
+ if (max) {
+ range->max = grl_g_value_dup (max);
+ }
+
+ return range;
+}
+
+void
+grl_range_value_free (GrlRangeValue *range)
+{
+ if (range->min) {
+ grl_g_value_free (range->min);
+ }
+
+ if (range->max) {
+ grl_g_value_free (range->max);
+ }
+
+ g_slice_free (GrlRangeValue, range);
+}
+
+GHashTable *
+grl_range_value_hashtable_new (void)
+{
+ return g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)grl_range_value_free);
+}
+
+GrlRangeValue *
+grl_range_value_dup (const GrlRangeValue *range)
+{
+ return grl_range_value_new (range->min, range->max);
+}
+
+void
+grl_range_value_hashtable_insert (GHashTable *hash_table,
+ gpointer key,
+ GValue *min,
+ GValue *max)
+{
+ GrlRangeValue *range = grl_range_value_new (min, max);
+ g_hash_table_insert (hash_table, key, range);
+}
diff --git a/src/grl-range-value.h b/src/grl-range-value.h
new file mode 100644
index 0000000..5bce911
--- /dev/null
+++ b/src/grl-range-value.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral 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
+
+#if !defined (_GRL_RANGE_VALUE_HELPER_H_)
+#define _GRL_RANGE_VALUE_HELPER_H_
+
+#include <glib-object.h>
+
+typedef struct {
+ GValue *min;
+ GValue *max;
+} GrlRangeValue;
+
+G_BEGIN_DECLS
+
+GrlRangeValue *grl_range_value_new (GValue *min,
+ GValue *max);
+
+void grl_range_value_free (GrlRangeValue *range);
+
+GHashTable *grl_range_value_hashtable_new (void);
+
+GrlRangeValue *grl_range_value_dup (const GrlRangeValue *range);
+
+void grl_range_value_hashtable_insert (GHashTable *hash_table,
+ gpointer key,
+ GValue *min,
+ GValue *max);
+
+GType grl_range_value_get_type (void);
+
+G_END_DECLS
+
+#endif /* _GRL_RANGE_VALUE_HELPER_H_ */
--
1.7.5.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]