summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Toso <me@victortoso.com>2015-05-01 23:36:32 +0200
committerJuan A. Suarez Romero <jasuarez@igalia.com>2015-09-06 16:03:58 +0200
commit66957722d9a440776d8eb2b6f9802e9a2c743d6d (patch)
tree60829b364d2a913ea253c720ea2a60ea792e04b5
parent7a33fde6948cafe89ce66399664735d32524b0b6 (diff)
downloadgrilo-66957722d9a440776d8eb2b6f9802e9a2c743d6d.tar.gz
grl-registry: allow register same metadata key
In case the plugin wants to reregister a metadata-key we don't throw an error. Common situation for this is when application unload() and load() again a plugin with custom metadata keys. https://bugzilla.gnome.org/show_bug.cgi?id=748550
-rw-r--r--src/grl-registry.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/grl-registry.c b/src/grl-registry.c
index cd24da4..3edd4d7 100644
--- a/src/grl-registry.c
+++ b/src/grl-registry.c
@@ -122,6 +122,8 @@ static const gchar *key_id_handler_get_name (struct KeyIDHandler *handler,
static GrlKeyID key_id_handler_add (struct KeyIDHandler *handler,
GrlKeyID key, const gchar *key_name);
+static gboolean param_spec_is_equal (GParamSpec *curr, GParamSpec *new);
+
static void shutdown_plugin (GrlPlugin *plugin);
static void configs_free (GList *configs);
@@ -728,6 +730,25 @@ grl_registry_register_metadata_key_full (GrlRegistry *registry,
GrlKeyID registered_key;
key_name = g_param_spec_get_name (param_spec);
+ registered_key = key_id_handler_get_key (&registry->priv->key_id_handler, key_name);
+ if (registered_key != GRL_METADATA_KEY_INVALID) {
+ GParamSpec *key_spec = g_hash_table_lookup (registry->priv->system_keys,
+ (gpointer) key_name);
+ if (param_spec_is_equal (key_spec, param_spec)) {
+ /* Key registered */
+ GRL_DEBUG ("metadata key '%s' already registered with same spec", key_name);
+ g_param_spec_unref (param_spec);
+ return registered_key;
+ } else {
+ GRL_WARNING ("metadata key '%s' already exists", key_name);
+ g_set_error (error,
+ GRL_CORE_ERROR,
+ GRL_CORE_ERROR_REGISTER_METADATA_KEY_FAILED,
+ _("Metadata key '%s' already registered in different format"),
+ key_name);
+ return GRL_METADATA_KEY_INVALID;
+ }
+ }
registered_key = key_id_handler_add (&registry->priv->key_id_handler, key, key_name);
@@ -853,6 +874,98 @@ key_id_handler_get_all_keys (struct KeyIDHandler *handler)
return g_hash_table_get_values (handler->string_to_id);
}
+#define CHECK_NUMERIC_PARAM_SPEC_LIMITS(is_type, cast_type, a, b) { \
+ if (is_type) { \
+ if ((cast_type(a))->maximum != (cast_type(b))->maximum || \
+ (cast_type(a))->minimum != (cast_type(b))->minimum || \
+ (cast_type(a))->default_value != (cast_type(b))->default_value) \
+ return FALSE; \
+ return TRUE; \
+ } \
+}
+
+/* @curr: The current spec we have
+ * @new: The spec to match
+ *
+ * Returns: true if specs are the same, false otherwise.
+ */
+static gboolean
+param_spec_is_equal (GParamSpec *cur,
+ GParamSpec *new)
+{
+ GType ctype = G_PARAM_SPEC_TYPE (cur);
+
+ if (ctype != G_PARAM_SPEC_TYPE (new))
+ return FALSE;
+
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_INT),
+ G_PARAM_SPEC_INT, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_LONG),
+ G_PARAM_SPEC_LONG, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_INT64),
+ G_PARAM_SPEC_INT64, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_CHAR),
+ G_PARAM_SPEC_CHAR, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_UINT),
+ G_PARAM_SPEC_UINT, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_ULONG),
+ G_PARAM_SPEC_ULONG, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_UINT64),
+ G_PARAM_SPEC_UINT64, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_UCHAR),
+ G_PARAM_SPEC_UCHAR, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_FLOAT),
+ G_PARAM_SPEC_FLOAT, cur, new);
+ CHECK_NUMERIC_PARAM_SPEC_LIMITS ((ctype == G_TYPE_PARAM_DOUBLE),
+ G_PARAM_SPEC_DOUBLE, cur, new);
+ if (ctype == G_TYPE_PARAM_STRING) {
+ GParamSpecString *c = G_PARAM_SPEC_STRING (cur);
+ GParamSpecString *n = G_PARAM_SPEC_STRING (new);
+ return (g_strcmp0 (c->default_value, n->default_value) == 0);
+ } else if (ctype == G_TYPE_PARAM_ENUM) {
+ GParamSpecEnum *c = G_PARAM_SPEC_ENUM (cur);
+ GParamSpecEnum *n = G_PARAM_SPEC_ENUM (new);
+ if (c->default_value != n->default_value ||
+ cur->value_type != new->value_type) {
+ GRL_DEBUG ("%s differ (values: %d and %d) (types: %s and %s)",
+ g_type_name (ctype), c->default_value, n->default_value,
+ g_type_name (cur->value_type), g_type_name (new->value_type));
+ return FALSE;
+ }
+ } else if (ctype == G_TYPE_PARAM_FLAGS) {
+ GParamSpecFlags *c = G_PARAM_SPEC_FLAGS (cur);
+ GParamSpecFlags *n = G_PARAM_SPEC_FLAGS (new);
+ if (c->default_value != n->default_value ||
+ cur->value_type != new->value_type) {
+ GRL_DEBUG ("%s differ (values: %d and %d) (types: %s and %s)",
+ g_type_name (ctype), c->default_value, n->default_value,
+ g_type_name (cur->value_type), g_type_name (new->value_type));
+ return FALSE;
+ }
+ } else if (ctype == G_TYPE_PARAM_BOOLEAN) {
+ GParamSpecBoolean *c = G_PARAM_SPEC_BOOLEAN (cur);
+ GParamSpecBoolean *n = G_PARAM_SPEC_BOOLEAN (new);
+ if (c->default_value != n->default_value) {
+ GRL_DEBUG ("%s type differ: %s != %s", g_type_name (ctype),
+ g_type_name (cur->value_type), g_type_name (new->value_type));
+ return FALSE;
+ }
+ } else if (ctype == G_TYPE_PARAM_BOXED || ctype == G_TYPE_PARAM_OBJECT) {
+ if (cur->value_type != new->value_type) {
+ GRL_DEBUG ("%s type differ: %s != %s", g_type_name (ctype),
+ g_type_name (cur->value_type), g_type_name (new->value_type));
+ return FALSE;
+ }
+ } else {
+ g_warn_if_reached();
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#undef CHECK_NUMERIC_PARAM_SPEC_LIMITS
+
static void
shutdown_plugin (GrlPlugin *plugin)
{