Beispiel #1
0
/**
 * g_value_register_transform_func: (skip)
 * @src_type: Source type.
 * @dest_type: Target type.
 * @transform_func: a function which transforms values of type @src_type
 *  into value of type @dest_type
 *
 * Registers a value transformation function for use in g_value_transform().
 * A previously registered transformation function for @src_type and @dest_type
 * will be replaced.
 */
void
g_value_register_transform_func (GType           src_type,
                                 GType           dest_type,
                                 GValueTransform transform_func)
{
    TransformEntry entry;

    /* these checks won't pass for dynamic types.
     * g_return_if_fail (G_TYPE_HAS_VALUE_TABLE (src_type));
     * g_return_if_fail (G_TYPE_HAS_VALUE_TABLE (dest_type));
     */
    g_return_if_fail (transform_func != NULL);

    entry.src_type = src_type;
    entry.dest_type = dest_type;

#if 0 /* let transform function replacement be a valid operation */
    if (g_bsearch_array_lookup (transform_array, &transform_bconfig, &entry))
        g_warning ("reregistering value transformation function (%p) for '%s' to '%s'",
                   transform_func,
                   g_type_name (src_type),
                   g_type_name (dest_type));
#endif

    entry.func = transform_func;
    transform_array = g_bsearch_array_replace (transform_array, &transform_bconfig, &entry);
}
Beispiel #2
0
static gchar*
boxed_proxy_lcopy_value (const GValue *value,
			 guint         n_collect_values,
			 GTypeCValue  *collect_values,
			 guint         collect_flags)
{
  gpointer *boxed_p = collect_values[0].v_pointer;

  if (!boxed_p)
    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));

  if (!value->data[0].v_pointer)
    *boxed_p = NULL;
  else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
    *boxed_p = value->data[0].v_pointer;
  else
    {
      BoxedNode key, *node;

      key.type = G_VALUE_TYPE (value);
      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
      *boxed_p = node->copy (value->data[0].v_pointer);
    }

  return NULL;
}
Beispiel #3
0
static GValueTransform
transform_func_lookup (GType src_type,
                       GType dest_type)
{
    TransformEntry entry;

    entry.src_type = src_type;
    do
    {
        entry.dest_type = dest_type;
        do
        {
            TransformEntry *e;

            e = g_bsearch_array_lookup (transform_array, &transform_bconfig, &entry);
            if (e)
            {
                /* need to check that there hasn't been a change in value handling */
                if (g_type_value_table_peek (entry.dest_type) == g_type_value_table_peek (dest_type) &&
                        g_type_value_table_peek (entry.src_type) == g_type_value_table_peek (src_type))
                    return e->func;
            }
            entry.dest_type = g_type_parent (entry.dest_type);
        }
        while (entry.dest_type);

        entry.src_type = g_type_parent (entry.src_type);
    }
    while (entry.src_type);

    return NULL;
}
Beispiel #4
0
/**
 * g_boxed_free:
 * @boxed_type: The type of @boxed.
 * @boxed: The boxed structure to be freed.
 *
 * Free the boxed structure @boxed which is of type @boxed_type.
 */
void
g_boxed_free (GType    boxed_type,
	      gpointer boxed)
{
  GTypeValueTable *value_table;

  g_return_if_fail (G_TYPE_IS_BOXED (boxed_type));
  g_return_if_fail (G_TYPE_IS_ABSTRACT (boxed_type) == FALSE);
  g_return_if_fail (boxed != NULL);

  value_table = g_type_value_table_peek (boxed_type);
  if (!value_table)
    g_return_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type));

  /* check if our proxying implementation is used, we can short-cut here */
  if (value_table->value_free == boxed_proxy_value_free)
    {
      BoxedNode key, *node;

      key.type = boxed_type;
      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
      node->free (boxed);
    }
  else
    {
      GValue value;

      /* see g_boxed_copy() on why we think we can do this */
      value_meminit (&value, boxed_type);
      value.data[0].v_pointer = boxed;
      value_table->value_free (&value);
    }
}
Beispiel #5
0
static gchar*
boxed_proxy_collect_value (GValue      *value,
			   guint        n_collect_values,
			   GTypeCValue *collect_values,
			   guint        collect_flags)
{
  BoxedNode key, *node;

  key.type = G_VALUE_TYPE (value);
  node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);

  if (!collect_values[0].v_pointer)
    value->data[0].v_pointer = NULL;
  else
    {
      if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
	{
	  value->data[0].v_pointer = collect_values[0].v_pointer;
	  value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
	}
      else
	value->data[0].v_pointer = node->copy (collect_values[0].v_pointer);
    }

  return NULL;
}
gpointer
g_boxed_copy (GType         boxed_type,
	      gconstpointer src_boxed)
{
  GTypeValueTable *value_table;
  gpointer dest_boxed;

  g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
  g_return_val_if_fail (G_TYPE_IS_ABSTRACT (boxed_type) == FALSE, NULL);
  g_return_val_if_fail (src_boxed != NULL, NULL);

  value_table = g_type_value_table_peek (boxed_type);
  if (!value_table)
    g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);

  /* check if our proxying implementation is used, we can short-cut here */
  if (value_table->value_copy == boxed_proxy_value_copy)
    {
      BoxedNode key, *node;

      key.type = boxed_type;
      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
      dest_boxed = node->copy ((gpointer) src_boxed);
    }
  else
    {
      GValue src_value, dest_value;
      
      /* we heavil rely on third-party boxed type value vtable
       * implementations to follow normal boxed value storage
       * (data[0].v_pointer is the boxed struct, and
       * data[1].v_uint holds the G_VALUE_NOCOPY_CONTENTS flag,
       * rest zero).
       * but then, we can expect that since we layed out the
       * g_boxed_*() API.
       * data[1].v_uint&G_VALUE_NOCOPY_CONTENTS shouldn't be set
       * after a copy.
       */
      /* equiv. to g_value_set_static_boxed() */
      value_meminit (&src_value, boxed_type);
      src_value.data[0].v_pointer = (gpointer) src_boxed;
      src_value.data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;

      /* call third-party code copy fucntion, fingers-crossed */
      value_meminit (&dest_value, boxed_type);
      value_table->value_copy (&src_value, &dest_value);

      /* double check and grouse if things went wrong */
      if (dest_value.data[1].v_ulong ||
	  dest_value.data[2].v_ulong)
	g_warning ("the copy_value() implementation of type `%s' seems to make use of reserved GValue fields",
		   g_type_name (boxed_type));

      dest_boxed = dest_value.data[0].v_pointer;
    }

  return dest_boxed;
}
static void
boxed_proxy_value_init (GValue *value)
{
  BoxedNode key, *node;

  key.type = G_VALUE_TYPE (value);
  node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
  value->data[0].v_pointer = NULL;
}
Beispiel #8
0
static void
boxed_proxy_value_free (GValue *value)
{
  if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
    {
      BoxedNode key, *node;

      key.type = G_VALUE_TYPE (value);
      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
      node->free (value->data[0].v_pointer);
    }
}
Beispiel #9
0
static void
boxed_proxy_value_copy (const GValue *src_value,
			GValue       *dest_value)
{
  if (src_value->data[0].v_pointer)
    {
      BoxedNode key, *node;

      key.type = G_VALUE_TYPE (src_value);
      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
      dest_value->data[0].v_pointer = node->copy (src_value->data[0].v_pointer);
    }
  else
    dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
}
Beispiel #10
0
static inline void
value_set_boxed_internal (GValue       *value,
			  gconstpointer const_boxed,
			  gboolean      need_copy,
			  gboolean      need_free)
{
  BoxedNode key, *node;
  gpointer boxed = (gpointer) const_boxed;

  if (!boxed)
    {
      /* just resetting to NULL might not be desired, need to
       * have value reinitialized also (for values defaulting
       * to other default value states than a NULL data pointer),
       * g_value_reset() will handle this
       */
      g_value_reset (value);
      return;
    }

  key.type = G_VALUE_TYPE (value);
  node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);

  if (node)
    {
      /* we proxy this type, free contents and copy right away */
      if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
	node->free (value->data[0].v_pointer);
      value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS;
      value->data[0].v_pointer = need_copy ? node->copy (boxed) : boxed;
    }
  else
    {
      /* we don't handle this type, free contents and let g_boxed_copy()
       * figure what's required
       */
      if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
	g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
      value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS;
      value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : boxed;
    }
}