⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gparam.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 2 页
字号:
      else if (!g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_VALUE_TYPE (value)))	return g_strconcat ("invalid param spec type `",			    G_PARAM_SPEC_TYPE_NAME (param),			    "' for value type `",			    G_VALUE_TYPE_NAME (value),			    "'",			    NULL);      value->data[0].v_pointer = g_param_spec_ref (param);    }  else    value->data[0].v_pointer = NULL;  return NULL;}static gchar*value_param_lcopy_value (const GValue *value,			 guint         n_collect_values,			 GTypeCValue  *collect_values,			 guint         collect_flags){  GParamSpec **param_p = collect_values[0].v_pointer;  if (!param_p)    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));  if (!value->data[0].v_pointer)    *param_p = NULL;  else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)    *param_p = value->data[0].v_pointer;  else    *param_p = g_param_spec_ref (value->data[0].v_pointer);  return NULL;}/* --- param spec pool --- */struct _GParamSpecPool{  GStaticMutex smutex;  gboolean     type_prefixing;  GHashTable  *hash_table;};static guintparam_spec_pool_hash (gconstpointer key_spec){  const GParamSpec *key = key_spec;  const gchar *p;  guint h = key->owner_type;  for (p = key->name; *p; p++)    h = (h << 5) - h + *p;  return h;}static gbooleanparam_spec_pool_equals (gconstpointer key_spec_1,			gconstpointer key_spec_2){  const GParamSpec *key1 = key_spec_1;  const GParamSpec *key2 = key_spec_2;  return (key1->owner_type == key2->owner_type &&	  strcmp (key1->name, key2->name) == 0);}GParamSpecPool*g_param_spec_pool_new (gboolean type_prefixing){  static GStaticMutex init_smutex = G_STATIC_MUTEX_INIT;  GParamSpecPool *pool = g_new (GParamSpecPool, 1);  memcpy (&pool->smutex, &init_smutex, sizeof (init_smutex));  pool->type_prefixing = type_prefixing != FALSE;  pool->hash_table = g_hash_table_new (param_spec_pool_hash, param_spec_pool_equals);  return pool;}voidg_param_spec_pool_insert (GParamSpecPool *pool,			  GParamSpec     *pspec,			  GType           owner_type){  gchar *p;    if (pool && pspec && owner_type > 0 && pspec->owner_type == 0)    {      G_SLOCK (&pool->smutex);      for (p = pspec->name; *p; p++)	{	  if (!strchr (G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_", *p))	    {	      g_warning (G_STRLOC ": pspec name \"%s\" contains invalid characters", pspec->name);	      G_SUNLOCK (&pool->smutex);	      return;	    }	}            pspec->owner_type = owner_type;      g_param_spec_ref (pspec);      g_hash_table_insert (pool->hash_table, pspec, pspec);      G_SUNLOCK (&pool->smutex);    }  else    {      g_return_if_fail (pool != NULL);      g_return_if_fail (pspec);      g_return_if_fail (owner_type > 0);      g_return_if_fail (pspec->owner_type == 0);    }}voidg_param_spec_pool_remove (GParamSpecPool *pool,			  GParamSpec     *pspec){  if (pool && pspec)    {      G_SLOCK (&pool->smutex);      if (g_hash_table_remove (pool->hash_table, pspec))	g_param_spec_unref (pspec);      else	g_warning (G_STRLOC ": attempt to remove unknown pspec `%s' from pool", pspec->name);      G_SUNLOCK (&pool->smutex);    }  else    {      g_return_if_fail (pool != NULL);      g_return_if_fail (pspec);    }}static inline GParamSpec*param_spec_ht_lookup (GHashTable  *hash_table,		      const gchar *param_name,		      GType        owner_type,		      gboolean     walk_ancestors){  GParamSpec key, *pspec;  key.owner_type = owner_type;  key.name = (gchar*) param_name;  if (walk_ancestors)    do      {	pspec = g_hash_table_lookup (hash_table, &key);	if (pspec)	  return pspec;	key.owner_type = g_type_parent (key.owner_type);      }    while (key.owner_type);  else    pspec = g_hash_table_lookup (hash_table, &key);  if (!pspec)    {      /* try canonicalized form */      key.name = g_strdup (param_name);      key.owner_type = owner_type;            canonalize_key (key.name);      if (walk_ancestors)	do	  {	    pspec = g_hash_table_lookup (hash_table, &key);	    if (pspec)	      {		g_free (key.name);		return pspec;	      }	    key.owner_type = g_type_parent (key.owner_type);	  }	while (key.owner_type);      else	pspec = g_hash_table_lookup (hash_table, &key);      g_free (key.name);    }  return pspec;}GParamSpec*g_param_spec_pool_lookup (GParamSpecPool *pool,			  const gchar    *param_name,			  GType           owner_type,			  gboolean        walk_ancestors){  GParamSpec *pspec;  gchar *delim;  if (!pool || !param_name)    {      g_return_val_if_fail (pool != NULL, NULL);      g_return_val_if_fail (param_name != NULL, NULL);    }  G_SLOCK (&pool->smutex);  delim = pool->type_prefixing ? strchr (param_name, ':') : NULL;  /* try quick and away, i.e. without prefix */  if (!delim)    {      pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors);      G_SUNLOCK (&pool->smutex);      return pspec;    }  /* strip type prefix */  if (pool->type_prefixing && delim[1] == ':')    {      guint l = delim - param_name;      gchar stack_buffer[32], *buffer = l < 32 ? stack_buffer : g_new (gchar, l + 1);      GType type;            strncpy (buffer, param_name, delim - param_name);      buffer[l] = 0;      type = g_type_from_name (buffer);      if (l >= 32)	g_free (buffer);      if (type)		/* type==0 isn't a valid type pefix */	{	  /* sanity check, these cases don't make a whole lot of sense */	  if ((!walk_ancestors && type != owner_type) || !g_type_is_a (owner_type, type))	    {	      G_SUNLOCK (&pool->smutex);	      return NULL;	    }	  owner_type = type;	  param_name += l + 2;	  pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors);	  G_SUNLOCK (&pool->smutex);	  return pspec;	}    }  /* malformed param_name */  G_SUNLOCK (&pool->smutex);  return NULL;}static voidpool_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 gintpspec_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 voidpool_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{  /* class portion */  GType           value_type;  void          (*finalize)             (GParamSpec   *pspec);  void          (*value_set_default)    (GParamSpec   *pspec,					 GValue       *value);  gboolean      (*value_validate)       (GParamSpec   *pspec,					 GValue       *value);  gint          (*values_cmp)           (GParamSpec   *pspec,					 const GValue *value1,					 const GValue *value2);} ParamSpecClassInfo;static voidparam_spec_generic_class_init (gpointer g_class,			       gpointer class_data){  GParamSpecClass *class = g_class;  ParamSpecClassInfo *info = class_data;  class->value_type = info->value_type;  if (info->finalize)    class->finalize = info->finalize;			/* optional */  class->value_set_default = info->value_set_default;  if (info->value_validate)    class->value_validate = info->value_validate;	/* optional */  class->values_cmp = info->values_cmp;  g_free (class_data);}static voiddefault_value_set_default (GParamSpec *pspec,			   GValue     *value){  /* value is already zero initialized */}static gintdefault_values_cmp (GParamSpec   *pspec,		    const GValue *value1,		    const GValue *value2){  return memcmp (&value1->data, &value2->data, sizeof (value1->data));}GTypeg_param_type_register_static (const gchar              *name,			      const GParamSpecTypeInfo *pspec_info){  GTypeInfo info = {    sizeof (GParamSpecClass),      /* class_size */    NULL,                          /* base_init */    NULL,                          /* base_destroy */    param_spec_generic_class_init, /* class_init */    NULL,                          /* class_destroy */    NULL,                          /* class_data */    0,                             /* instance_size */    16,                            /* n_preallocs */    NULL,                          /* instance_init */  };  ParamSpecClassInfo *cinfo;  g_return_val_if_fail (name != NULL, 0);  g_return_val_if_fail (pspec_info != NULL, 0);  g_return_val_if_fail (g_type_from_name (name) == 0, 0);  g_return_val_if_fail (pspec_info->instance_size >= sizeof (GParamSpec), 0);  g_return_val_if_fail (g_type_name (pspec_info->value_type) != NULL, 0);  /* default: g_return_val_if_fail (pspec_info->value_set_default != NULL, 0); */  /* optional: g_return_val_if_fail (pspec_info->value_validate != NULL, 0); */  /* default: g_return_val_if_fail (pspec_info->values_cmp != NULL, 0); */  info.instance_size = pspec_info->instance_size;  info.n_preallocs = pspec_info->n_preallocs;  info.instance_init = (GInstanceInitFunc) pspec_info->instance_init;  cinfo = g_new (ParamSpecClassInfo, 1);  cinfo->value_type = pspec_info->value_type;  cinfo->finalize = pspec_info->finalize;  cinfo->value_set_default = pspec_info->value_set_default ? pspec_info->value_set_default : default_value_set_default;  cinfo->value_validate = pspec_info->value_validate;  cinfo->values_cmp = pspec_info->values_cmp ? pspec_info->values_cmp : default_values_cmp;  info.class_data = cinfo;  return g_type_register_static (G_TYPE_PARAM, name, &info, 0);}voidg_value_set_param (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;  if (value->data[0].v_pointer)    g_param_spec_ref (value->data[0].v_pointer);}voidg_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){  g_return_val_if_fail (G_VALUE_HOLDS_PARAM (value), NULL);  return value->data[0].v_pointer;}GParamSpec*g_value_dup_param (const GValue *value){  g_return_val_if_fail (G_VALUE_HOLDS_PARAM (value), NULL);  return value->data[0].v_pointer ? g_param_spec_ref (value->data[0].v_pointer) : NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -