X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gobject%2Fgparam.c;h=db0568d7c168dd137682132dbdd9ee196aa554f1;hb=3f4617caabf1568d26b09dbd47a2aaaf05c4f44e;hp=72af807e21c2c4ff77d243fdeb5f926bf04b9dd5;hpb=45fb71949a0c0e27fe8d0948b345334f61a5c924;p=platform%2Fupstream%2Fglib.git diff --git a/gobject/gparam.c b/gobject/gparam.c index 72af807..db0568d 100644 --- a/gobject/gparam.c +++ b/gobject/gparam.c @@ -30,7 +30,6 @@ /* --- defines --- */ -#define G_PARAM_SPEC_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass)) #define G_PARAM_USER_MASK (~0 << G_PARAM_USER_SHIFT) #define PSPEC_APPLIES_TO_VALUE(pspec, value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_PARAM_SPEC_VALUE_TYPE (pspec))) #define G_SLOCK(mutex) g_static_mutex_lock (mutex) @@ -137,13 +136,14 @@ g_param_spec_init (GParamSpec *pspec, GParamSpecClass *class) { pspec->name = NULL; - pspec->nick = NULL; - pspec->blurb = NULL; + pspec->_nick = NULL; + pspec->_blurb = NULL; pspec->flags = 0; pspec->value_type = class->value_type; pspec->owner_type = 0; pspec->qdata = NULL; pspec->ref_count = 1; + pspec->param_id = 0; g_datalist_id_set_data (&pspec->qdata, quark_floating, GUINT_TO_POINTER (TRUE)); } @@ -153,8 +153,8 @@ g_param_spec_finalize (GParamSpec *pspec) g_datalist_clear (&pspec->qdata); g_free (pspec->name); - g_free (pspec->nick); - g_free (pspec->blurb); + g_free (pspec->_nick); + g_free (pspec->_blurb); g_type_free_instance ((GTypeInstance*) pspec); } @@ -233,6 +233,47 @@ g_param_spec_sink (GParamSpec *pspec) } } +G_CONST_RETURN gchar* +g_param_spec_get_name (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + return pspec->name; +} + +G_CONST_RETURN gchar* +g_param_spec_get_nick (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + return pspec->_nick ? pspec->_nick : pspec->name; +} + +G_CONST_RETURN gchar* +g_param_spec_get_blurb (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + return pspec->_blurb; +} + +static void +canonalize_key (gchar *key) +{ + gchar *p; + + for (p = key; *p != 0; p++) + { + gchar c = *p; + + if (c != '-' && + (c < '0' || c > '9') && + (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) + *p = '-'; + } +} + gpointer g_param_spec_internal (GType param_type, const gchar *name, @@ -241,18 +282,18 @@ g_param_spec_internal (GType param_type, GParamFlags flags) { GParamSpec *pspec; - + g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL); g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z'), NULL); - + pspec = (gpointer) g_type_create_instance (param_type); pspec->name = g_strdup (name); - g_strcanon (pspec->name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-'); - pspec->nick = g_strdup (nick ? nick : pspec->name); - pspec->blurb = g_strdup (blurb); + canonalize_key (pspec->name); + pspec->_nick = g_strdup (nick); + pspec->_blurb = g_strdup (blurb); pspec->flags = (flags & G_PARAM_USER_MASK) | (flags & G_PARAM_MASK); - + return pspec; } @@ -626,7 +667,7 @@ param_spec_ht_lookup (GHashTable *hash_table, key.name = g_strdup (param_name); key.owner_type = owner_type; - g_strcanon (key.name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-'); + canonalize_key (key.name); if (walk_ancestors) do { @@ -711,6 +752,130 @@ g_param_spec_pool_lookup (GParamSpecPool *pool, return NULL; } +static void +pool_list (gpointer key, + gpointer value, + gpointer user_data) +{ + GParamSpec *pspec = value; + gpointer *data = user_data; + GType owner_type = (GType) data[1]; + + if (owner_type == pspec->owner_type) + data[0] = g_list_prepend (data[0], pspec); +} + +GList* +g_param_spec_pool_list_owned (GParamSpecPool *pool, + GType owner_type) +{ + gpointer data[2]; + + g_return_val_if_fail (pool != NULL, NULL); + g_return_val_if_fail (owner_type > 0, NULL); + + G_SLOCK (&pool->smutex); + data[0] = NULL; + data[1] = (gpointer) owner_type; + g_hash_table_foreach (pool->hash_table, pool_list, &data); + G_SUNLOCK (&pool->smutex); + + return data[0]; +} + +static gint +pspec_compare_id (gconstpointer a, + gconstpointer b) +{ + const GParamSpec *pspec1 = a, *pspec2 = b; + + return pspec1->param_id < pspec2->param_id ? -1 : pspec1->param_id > pspec2->param_id; +} + +static inline GSList* +pspec_list_remove_overridden (GSList *plist, + GHashTable *ht, + GType owner_type, + guint *n_p) +{ + GSList *rlist = NULL; + + while (plist) + { + GSList *tmp = plist->next; + GParamSpec *pspec = plist->data; + + if (param_spec_ht_lookup (ht, pspec->name, owner_type, TRUE) != pspec) + g_slist_free_1 (plist); + else + { + plist->next = rlist; + rlist = plist; + *n_p += 1; + } + plist = tmp; + } + return rlist; +} + +static void +pool_depth_list (gpointer key, + gpointer value, + gpointer user_data) +{ + GParamSpec *pspec = value; + gpointer *data = user_data; + GSList **slists = data[0]; + GType owner_type = (GType) data[1]; + + if (g_type_is_a (owner_type, pspec->owner_type)) + { + guint d = g_type_depth (pspec->owner_type); + + slists[d - 1] = g_slist_prepend (slists[d - 1], pspec); + } +} + +GParamSpec** /* free result */ +g_param_spec_pool_list (GParamSpecPool *pool, + GType owner_type, + guint *n_pspecs_p) +{ + GParamSpec **pspecs, **p; + GSList **slists, *node; + gpointer data[2]; + guint d, i; + + g_return_val_if_fail (pool != NULL, NULL); + g_return_val_if_fail (owner_type > 0, NULL); + g_return_val_if_fail (n_pspecs_p != NULL, NULL); + + G_SLOCK (&pool->smutex); + *n_pspecs_p = 0; + d = g_type_depth (owner_type); + slists = g_new0 (GSList*, d); + data[0] = slists; + data[1] = (gpointer) owner_type; + g_hash_table_foreach (pool->hash_table, pool_depth_list, &data); + for (i = 0; i < d - 1; i++) + slists[i] = pspec_list_remove_overridden (slists[i], pool->hash_table, owner_type, n_pspecs_p); + *n_pspecs_p += g_slist_length (slists[i]); + pspecs = g_new (GParamSpec*, *n_pspecs_p + 1); + p = pspecs; + for (i = 0; i < d; i++) + { + slists[i] = g_slist_sort (slists[i], pspec_compare_id); + for (node = slists[i]; node; node = node->next) + *p++ = node->data; + g_slist_free (slists[i]); + } + *p++ = NULL; + g_free (slists); + G_SUNLOCK (&pool->smutex); + + return pspecs; +} + /* --- auxillary functions --- */ typedef struct @@ -814,6 +979,19 @@ g_value_set_param (GValue *value, g_param_spec_ref (value->data[0].v_pointer); } +void +g_value_set_param_take_ownership (GValue *value, + GParamSpec *param) +{ + g_return_if_fail (G_VALUE_HOLDS_PARAM (value)); + if (param) + g_return_if_fail (G_IS_PARAM_SPEC (param)); + + if (value->data[0].v_pointer) + g_param_spec_unref (value->data[0].v_pointer); + value->data[0].v_pointer = param; /* we take over the reference count */ +} + GParamSpec* g_value_get_param (const GValue *value) {