/* GObject - GLib Type, Object, Parameter and Signal Library
 * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
 *
 * 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; either
 * 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, see <http://www.gnu.org/licenses/>.
 */

/*
 * FIXME: MT-safety
 */

#include "config.h"

#include <string.h>

#include "gvalue.h"
#include "gvaluecollector.h"
#include "gbsearcharray.h"
#include "gtype-private.h"


/**
 * SECTION:generic_values
 * @short_description: A polymorphic type that can hold values of any
 *     other type
 * @see_also: The fundamental types which all support #GValue
 *     operations and thus can be used as a type initializer for
 *     g_value_init() are defined by a separate interface.  See the
 *     [standard values API][gobject-Standard-Parameter-and-Value-Types]
 *     for details
 * @title: Generic values
 *
 * The #GValue structure is basically a variable container that consists
 * of a type identifier and a specific value of that type.
 * The type identifier within a #GValue structure always determines the
 * type of the associated value.
 * To create an undefined #GValue structure, simply create a zero-filled
 * #GValue structure. To initialize the #GValue, use the g_value_init()
 * function. A #GValue cannot be used until it is initialized.
 * The basic type operations (such as freeing and copying) are determined
 * by the #GTypeValueTable associated with the type ID stored in the #GValue.
 * Other #GValue operations (such as converting values between types) are
 * provided by this interface.
 *
 * The code in the example program below demonstrates #GValue's
 * features.
 *
 * |[<!-- language="C" --> 
 * #include <glib-object.h>
 *
 * static void
 * int2string (const GValue *src_value,
 *             GValue       *dest_value)
 * {
 *   if (g_value_get_int (src_value) == 42)
 *     g_value_set_static_string (dest_value, "An important number");
 *   else
 *     g_value_set_static_string (dest_value, "What's that?");
 * }
 *
 * int
 * main (int   argc,
 *       char *argv[])
 * {
 *   // GValues must be initialized
 *   GValue a = G_VALUE_INIT;
 *   GValue b = G_VALUE_INIT;
 *   const gchar *message;
 *
 *   // The GValue starts empty
 *   g_assert (!G_VALUE_HOLDS_STRING (&a));
 *
 *   // Put a string in it
 *   g_value_init (&a, G_TYPE_STRING);
 *   g_assert (G_VALUE_HOLDS_STRING (&a));
 *   g_value_set_static_string (&a, "Hello, world!");
 *   g_printf ("%s\n", g_value_get_string (&a));
 *
 *   // Reset it to its pristine state
 *   g_value_unset (&a);
 *
 *   // It can then be reused for another type
 *   g_value_init (&a, G_TYPE_INT);
 *   g_value_set_int (&a, 42);
 *
 *   // Attempt to transform it into a GValue of type STRING
 *   g_value_init (&b, G_TYPE_STRING);
 *
 *   // An INT is transformable to a STRING
 *   g_assert (g_value_type_transformable (G_TYPE_INT, G_TYPE_STRING));
 *
 *   g_value_transform (&a, &b);
 *   g_printf ("%s\n", g_value_get_string (&b));
 *
 *   // Attempt to transform it again using a custom transform function
 *   g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, int2string);
 *   g_value_transform (&a, &b);
 *   g_printf ("%s\n", g_value_get_string (&b));
 *   return 0;
 * }
 * ]|
 */


/* --- typedefs & structures --- */
typedef struct {
  GType src_type;
  GType dest_type;
  GValueTransform func;
} TransformEntry;


/* --- prototypes --- */
static gint	transform_entries_cmp	(gconstpointer bsearch_node1,
					 gconstpointer bsearch_node2);


/* --- variables --- */
static GBSearchArray *transform_array = NULL;
static GBSearchConfig transform_bconfig = {
  sizeof (TransformEntry),
  transform_entries_cmp,
  G_BSEARCH_ARRAY_ALIGN_POWER2,
};


/* --- functions --- */
void
_g_value_c_init (void)
{
  transform_array = g_bsearch_array_create (&transform_bconfig);
}

static inline void		/* keep this function in sync with gvaluecollector.h and gboxed.c */
value_meminit (GValue *value,
	       GType   value_type)
{
  value->g_type = value_type;
  memset (value->data, 0, sizeof (value->data));
}

/**
 * g_value_init:
 * @value: A zero-filled (uninitialized) #GValue structure.
 * @g_type: Type the #GValue should hold values of.
 *
 * Initializes @value with the default value of @type.
 *
 * Returns: (transfer none): the #GValue structure that has been passed in
 */
GValue*
g_value_init (GValue *value,
	      GType   g_type)
{
  GTypeValueTable *value_table;
  /* g_return_val_if_fail (G_TYPE_IS_VALUE (g_type), NULL);	be more elaborate below */
  g_return_val_if_fail (value != NULL, NULL);
  /* g_return_val_if_fail (G_VALUE_TYPE (value) == 0, NULL);	be more elaborate below */

  value_table = g_type_value_table_peek (g_type);

  if (value_table && G_VALUE_TYPE (value) == 0)
    {
      /* setup and init */
      value_meminit (value, g_type);
      value_table->value_init (value);
    }
  else if (G_VALUE_TYPE (value))
    g_warning ("%s: cannot initialize GValue with type '%s', the value has already been initialized as '%s'",
	       G_STRLOC,
	       g_type_name (g_type),
	       g_type_name (G_VALUE_TYPE (value)));
  else /* !G_TYPE_IS_VALUE (g_type) */
    g_warning ("%s: cannot initialize GValue with type '%s', %s",
               G_STRLOC,
               g_type_name (g_type),
               value_table ? "this type is abstract with regards to GValue use, use a more specific (derived) type" : "this type has no GTypeValueTable implementation");
  return value;
}

/**
 * g_value_copy:
 * @src_value: An initialized #GValue structure.
 * @dest_value: An initialized #GValue structure of the same type as @src_value.
 *
 * Copies the value of @src_value into @dest_value.
 */
void
g_value_copy (const GValue *src_value,
	      GValue       *dest_value)
{
  g_return_if_fail (src_value);
  g_return_if_fail (dest_value);
  g_return_if_fail (g_value_type_compatible (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)));
  
  if (src_value != dest_value)
    {
      GType dest_type = G_VALUE_TYPE (dest_value);
      GTypeValueTable *value_table = g_type_value_table_peek (dest_type);

      g_return_if_fail (value_table);

      /* make sure dest_value's value is free()d */
      if (value_table->value_free)
	value_table->value_free (dest_value);

      /* setup and copy */
      value_meminit (dest_value, dest_type);
      value_table->value_copy (src_value, dest_value);
    }
}

/**
 * g_value_reset:
 * @value: An initialized #GValue structure.
 *
 * Clears the current value in @value and resets it to the default value
 * (as if the value had just been initialized).
 *
 * Returns: the #GValue structure that has been passed in
 */
GValue*
g_value_reset (GValue *value)
{
  GTypeValueTable *value_table;
  GType g_type;

  g_return_val_if_fail (value, NULL);
  g_type = G_VALUE_TYPE (value);

  value_table = g_type_value_table_peek (g_type);
  g_return_val_if_fail (value_table, NULL);

  /* make sure value's value is free()d */
  if (value_table->value_free)
    value_table->value_free (value);

  /* setup and init */
  value_meminit (value, g_type);
  value_table->value_init (value);

  return value;
}

/**
 * g_value_unset:
 * @value: An initialized #GValue structure.
 *
 * Clears the current value in @value (if any) and "unsets" the type,
 * this releases all resources associated with this GValue. An unset
 * value is the same as an uninitialized (zero-filled) #GValue
 * structure.
 */
void
g_value_unset (GValue *value)
{
  GTypeValueTable *value_table;
  
  if (value->g_type == 0)
    return;

  g_return_if_fail (value);

  value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
  g_return_if_fail (value_table);

  if (value_table->value_free)
    value_table->value_free (value);
  memset (value, 0, sizeof (*value));
}

/**
 * g_value_fits_pointer:
 * @value: An initialized #GValue structure.
 *
 * Determines if @value will fit inside the size of a pointer value.
 * This is an internal function introduced mainly for C marshallers.
 *
 * Returns: %TRUE if @value will fit inside a pointer value.
 */
gboolean
g_value_fits_pointer (const GValue *value)
{
  GTypeValueTable *value_table;

  g_return_val_if_fail (value, FALSE);

  value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
  g_return_val_if_fail (value_table, FALSE);

  return value_table->value_peek_pointer != NULL;
}

/**
 * g_value_peek_pointer:
 * @value: An initialized #GValue structure
 *
 * Returns the value contents as pointer. This function asserts that
 * g_value_fits_pointer() returned %TRUE for the passed in value.
 * This is an internal function introduced mainly for C marshallers.
 *
 * Returns: (transfer none): the value contents as pointer
 */
gpointer
g_value_peek_pointer (const GValue *value)
{
  GTypeValueTable *value_table;

  g_return_val_if_fail (value, NULL);

  value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
  g_return_val_if_fail (value_table, NULL);

  if (!value_table->value_peek_pointer)
    {
      g_return_val_if_fail (g_value_fits_pointer (value) == TRUE, NULL);
      return NULL;
    }

  return value_table->value_peek_pointer (value);
}

/**
 * g_value_set_instance:
 * @value: An initialized #GValue structure.
 * @instance: (nullable): the instance
 *
 * Sets @value from an instantiatable type via the
 * value_table's collect_value() function.
 */
void
g_value_set_instance (GValue  *value,
		      gpointer instance)
{
  GType g_type;
  GTypeValueTable *value_table;
  GTypeCValue cvalue;
  gchar *error_msg;

  g_return_if_fail (value);
  g_type = G_VALUE_TYPE (value);
  value_table = g_type_value_table_peek (g_type);
  g_return_if_fail (value_table);

  if (instance)
    {
      g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
      g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value)));
    }
  
  g_return_if_fail (strcmp (value_table->collect_format, "p") == 0);
  
  memset (&cvalue, 0, sizeof (cvalue));
  cvalue.v_pointer = instance;
  
  /* make sure value's value is free()d */
  if (value_table->value_free)
    value_table->value_free (value);

  /* setup and collect */
  value_meminit (value, g_type);
  error_msg = value_table->collect_value (value, 1, &cvalue, 0);
  if (error_msg)
    {
      g_warning ("%s: %s", G_STRLOC, error_msg);
      g_free (error_msg);
      
      /* we purposely leak the value here, it might not be
       * in a correct state if an error condition occurred
       */
      value_meminit (value, g_type);
      value_table->value_init (value);
    }
}

/**
 * g_value_init_from_instance:
 * @value: An uninitialized #GValue structure.
 * @instance: (type GObject.TypeInstance): the instance
 *
 * Initializes and sets @value from an instantiatable type via the
 * value_table's collect_value() function.
 *
 * Note: The @value will be initialised with the exact type of
 * @instance.  If you wish to set the @value's type to a different GType
 * (such as a parent class GType), you need to manually call
 * g_value_init() and g_value_set_instance().
 *
 * Since: 2.42
 */
void
g_value_init_from_instance (GValue  *value,
                            gpointer instance)
{
  g_return_if_fail (value != NULL && G_VALUE_TYPE(value) == 0);

  if (G_IS_OBJECT (instance))
    {
      /* Fast-path.
       * If G_IS_OBJECT() succeeds we know:
       * * that instance is present and valid
       * * that it is a GObject, and therefore we can directly
       *   use the collect implementation (g_object_ref) */
      value_meminit (value, G_TYPE_FROM_INSTANCE (instance));
      value->data[0].v_pointer = g_object_ref (instance);
    }
  else
    {  
      GType g_type;
      GTypeValueTable *value_table;
      GTypeCValue cvalue;
      gchar *error_msg;

      g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));

      g_type = G_TYPE_FROM_INSTANCE (instance);
      value_table = g_type_value_table_peek (g_type);
      g_return_if_fail (strcmp (value_table->collect_format, "p") == 0);

      memset (&cvalue, 0, sizeof (cvalue));
      cvalue.v_pointer = instance;

      /* setup and collect */
      value_meminit (value, g_type);
      value_table->value_init (value);
      error_msg = value_table->collect_value (value, 1, &cvalue, 0);
      if (error_msg)
        {
          g_warning ("%s: %s", G_STRLOC, error_msg);
          g_free (error_msg);

          /* we purposely leak the value here, it might not be
           * in a correct state if an error condition occurred
           */
          value_meminit (value, g_type);
          value_table->value_init (value);
        }
    }
}

static GType
transform_lookup_get_parent_type (GType type)
{
  if (g_type_fundamental (type) == G_TYPE_INTERFACE)
    return g_type_interface_instantiatable_prerequisite (type);

  return g_type_parent (type);
}

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 = transform_lookup_get_parent_type (entry.dest_type);
	}
      while (entry.dest_type);
      
      entry.src_type = transform_lookup_get_parent_type (entry.src_type);
    }
  while (entry.src_type);

  return NULL;
}

static gint
transform_entries_cmp (gconstpointer bsearch_node1,
		       gconstpointer bsearch_node2)
{
  const TransformEntry *e1 = bsearch_node1;
  const TransformEntry *e2 = bsearch_node2;
  gint cmp = G_BSEARCH_ARRAY_CMP (e1->src_type, e2->src_type);

  if (cmp)
    return cmp;
  else
    return G_BSEARCH_ARRAY_CMP (e1->dest_type, e2->dest_type);
}

/**
 * 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);
}

/**
 * g_value_type_transformable:
 * @src_type: Source type.
 * @dest_type: Target type.
 *
 * Check whether g_value_transform() is able to transform values
 * of type @src_type into values of type @dest_type. Note that for
 * the types to be transformable, they must be compatible or a
 * transformation function must be registered.
 *
 * Returns: %TRUE if the transformation is possible, %FALSE otherwise.
 */
gboolean
g_value_type_transformable (GType src_type,
			    GType dest_type)
{
  g_return_val_if_fail (src_type, FALSE);
  g_return_val_if_fail (dest_type, FALSE);

  return (g_value_type_compatible (src_type, dest_type) ||
	  transform_func_lookup (src_type, dest_type) != NULL);
}

/**
 * g_value_type_compatible:
 * @src_type: source type to be copied.
 * @dest_type: destination type for copying.
 *
 * Returns whether a #GValue of type @src_type can be copied into
 * a #GValue of type @dest_type.
 *
 * Returns: %TRUE if g_value_copy() is possible with @src_type and @dest_type.
 */
gboolean
g_value_type_compatible (GType src_type,
			 GType dest_type)
{
  g_return_val_if_fail (src_type, FALSE);
  g_return_val_if_fail (dest_type, FALSE);

  /* Fast path */
  if (src_type == dest_type)
    return TRUE;

  return (g_type_is_a (src_type, dest_type) &&
	  g_type_value_table_peek (dest_type) == g_type_value_table_peek (src_type));
}

/**
 * g_value_transform:
 * @src_value: Source value.
 * @dest_value: Target value.
 *
 * Tries to cast the contents of @src_value into a type appropriate
 * to store in @dest_value, e.g. to transform a %G_TYPE_INT value
 * into a %G_TYPE_FLOAT value. Performing transformations between
 * value types might incur precision lossage. Especially
 * transformations into strings might reveal seemingly arbitrary
 * results and shouldn't be relied upon for production code (such
 * as rcfile value or object property serialization).
 *
 * Returns: Whether a transformation rule was found and could be applied.
 *  Upon failing transformations, @dest_value is left untouched.
 */
gboolean
g_value_transform (const GValue *src_value,
		   GValue       *dest_value)
{
  GType dest_type;

  g_return_val_if_fail (src_value, FALSE);
  g_return_val_if_fail (dest_value, FALSE);

  dest_type = G_VALUE_TYPE (dest_value);
  if (g_value_type_compatible (G_VALUE_TYPE (src_value), dest_type))
    {
      g_value_copy (src_value, dest_value);
      
      return TRUE;
    }
  else
    {
      GValueTransform transform = transform_func_lookup (G_VALUE_TYPE (src_value), dest_type);

      if (transform)
	{
	  g_value_unset (dest_value);
	  
	  /* setup and transform */
	  value_meminit (dest_value, dest_type);
	  transform (src_value, dest_value);
	  
	  return TRUE;
	}
    }
  return FALSE;
}
