/* GStreamer
 * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstvalue
 * @title: GstValue
 * @short_description: GValue implementations specific
 * to GStreamer
 *
 * GValue implementations specific to GStreamer.
 *
 * Note that operations on the same #GValue from multiple threads may lead to
 * undefined behaviour.
 */

/* Suppress warnings for GValueAraray */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "gst_private.h"
#include "glib-compat-private.h"
#include <gst/gst.h>
#include <gobject/gvaluecollector.h>
#include "gstutils.h"

/* GstValueUnionFunc:
 * @dest: a #GValue for the result
 * @value1: a #GValue operand
 * @value2: a #GValue operand
 *
 * Used by gst_value_union() to perform unification for a specific #GValue
 * type. Register a new implementation with gst_value_register_union_func().
 *
 * Returns: %TRUE if a union was successful
 */
typedef gboolean (*GstValueUnionFunc) (GValue * dest,
    const GValue * value1, const GValue * value2);

/* GstValueIntersectFunc:
 * @dest: (out caller-allocates): a #GValue for the result
 * @value1: a #GValue operand
 * @value2: a #GValue operand
 *
 * Used by gst_value_intersect() to perform intersection for a specific #GValue
 * type. If the intersection is non-empty, the result is
 * placed in @dest and %TRUE is returned.  If the intersection is
 * empty, @dest is unmodified and %FALSE is returned.
 * Register a new implementation with gst_value_register_intersect_func().
 *
 * Returns: %TRUE if the values can intersect
 */
typedef gboolean (*GstValueIntersectFunc) (GValue * dest,
    const GValue * value1, const GValue * value2);

/* GstValueSubtractFunc:
 * @dest: (out caller-allocates): a #GValue for the result
 * @minuend: a #GValue operand
 * @subtrahend: a #GValue operand
 *
 * Used by gst_value_subtract() to perform subtraction for a specific #GValue
 * type. Register a new implementation with gst_value_register_subtract_func().
 *
 * Returns: %TRUE if the subtraction is not empty
 */
typedef gboolean (*GstValueSubtractFunc) (GValue * dest,
    const GValue * minuend, const GValue * subtrahend);

static void gst_value_register_union_func (GType type1,
    GType type2, GstValueUnionFunc func);
static void gst_value_register_intersect_func (GType type1,
    GType type2, GstValueIntersectFunc func);
static void gst_value_register_subtract_func (GType minuend_type,
    GType subtrahend_type, GstValueSubtractFunc func);

static gboolean _priv_gst_value_parse_list (gchar * s, gchar ** after,
    GValue * value, GType type);
static gboolean _priv_gst_value_parse_array (gchar * s, gchar ** after,
    GValue * value, GType type);

typedef struct _GstValueUnionInfo GstValueUnionInfo;
struct _GstValueUnionInfo
{
  GType type1;
  GType type2;
  GstValueUnionFunc func;
};

typedef struct _GstValueIntersectInfo GstValueIntersectInfo;
struct _GstValueIntersectInfo
{
  GType type1;
  GType type2;
  GstValueIntersectFunc func;
};

typedef struct _GstValueSubtractInfo GstValueSubtractInfo;
struct _GstValueSubtractInfo
{
  GType minuend;
  GType subtrahend;
  GstValueSubtractFunc func;
};

struct _GstFlagSetClass
{
  GTypeClass parent;
  GType flags_type;             /* Type of the GFlags this flagset carries (can be 0) */
};

typedef struct _GstFlagSetClass GstFlagSetClass;

typedef struct _GstValueAbbreviation GstValueAbbreviation;

struct _GstValueAbbreviation
{
  const gchar *type_name;
  GType type;
};

#define FUNDAMENTAL_TYPE_ID_MAX \
    (G_TYPE_FUNDAMENTAL_MAX >> G_TYPE_FUNDAMENTAL_SHIFT)
#define FUNDAMENTAL_TYPE_ID(type) \
    ((type) >> G_TYPE_FUNDAMENTAL_SHIFT)

#define VALUE_LIST_ARRAY(v) ((GArray *) (v)->data[0].v_pointer)
#define VALUE_LIST_SIZE(v) (VALUE_LIST_ARRAY(v)->len)
#define VALUE_LIST_GET_VALUE(v, index) ((const GValue *) &g_array_index (VALUE_LIST_ARRAY(v), GValue, (index)))

static GArray *gst_value_table;
static GHashTable *gst_value_hash;
static GstValueTable *gst_value_tables_fundamental[FUNDAMENTAL_TYPE_ID_MAX + 1];
static GArray *gst_value_union_funcs;
static GArray *gst_value_intersect_funcs;
static GArray *gst_value_subtract_funcs;

/* Forward declarations */
static gchar *gst_value_serialize_fraction (const GValue * value);

static GstValueCompareFunc gst_value_get_compare_func (const GValue * value1);
static gint gst_value_compare_with_func (const GValue * value1,
    const GValue * value2, GstValueCompareFunc compare);

static gchar *gst_string_wrap (const gchar * s);
static gchar *gst_string_unwrap (const gchar * s);

static void gst_value_move (GValue * dest, GValue * src);
static void _gst_value_list_append_and_take_value (GValue * value,
    GValue * append_value);
static void _gst_value_array_append_and_take_value (GValue * value,
    GValue * append_value);

static inline GstValueTable *
gst_value_hash_lookup_type (GType type)
{
  if (G_LIKELY (G_TYPE_IS_FUNDAMENTAL (type)))
    return gst_value_tables_fundamental[FUNDAMENTAL_TYPE_ID (type)];
  else
    return g_hash_table_lookup (gst_value_hash, (gpointer) type);
}

static void
gst_value_hash_add_type (GType type, const GstValueTable * table)
{
  if (G_TYPE_IS_FUNDAMENTAL (type))
    gst_value_tables_fundamental[FUNDAMENTAL_TYPE_ID (type)] = (gpointer) table;

  g_hash_table_insert (gst_value_hash, (gpointer) type, (gpointer) table);
}

/********
 * list *
 ********/

/* two helper functions to serialize/stringify any type of list
 * regular lists are done with { }, arrays with < >
 */
gchar *
_priv_gst_value_serialize_any_list (const GValue * value, const gchar * begin,
    const gchar * end, gboolean print_type)
{
  guint i;
  GArray *array = value->data[0].v_pointer;
  GString *s;
  GValue *v;
  gchar *s_val;
  guint alen = array->len;

  /* estimate minimum string length to minimise re-allocs in GString */
  s = g_string_sized_new (2 + (6 * alen) + 2);
  g_string_append (s, begin);
  for (i = 0; i < alen; i++) {
    v = &g_array_index (array, GValue, i);
    s_val = gst_value_serialize (v);
    if (s_val != NULL) {
      if (print_type) {
        g_string_append_c (s, '(');
        g_string_append (s, _priv_gst_value_gtype_to_abbr (G_VALUE_TYPE (v)));
        g_string_append_c (s, ')');
      }
      g_string_append (s, s_val);
      g_free (s_val);
      if (i < alen - 1) {
        g_string_append_len (s, ", ", 2);
      }
    } else {
      GST_WARNING ("Could not serialize list/array value of type '%s'",
          G_VALUE_TYPE_NAME (v));
    }
  }
  g_string_append (s, end);
  return g_string_free (s, FALSE);
}

static void
gst_value_transform_any_list_string (const GValue * src_value,
    GValue * dest_value, const gchar * begin, const gchar * end)
{
  GValue *list_value;
  GArray *array;
  GString *s;
  guint i;
  gchar *list_s;
  guint alen;

  array = src_value->data[0].v_pointer;
  alen = array->len;

  /* estimate minimum string length to minimise re-allocs in GString */
  s = g_string_sized_new (2 + (10 * alen) + 2);
  g_string_append (s, begin);
  for (i = 0; i < alen; i++) {
    list_value = &g_array_index (array, GValue, i);

    if (i != 0) {
      g_string_append_len (s, ", ", 2);
    }
    list_s = g_strdup_value_contents (list_value);
    g_string_append (s, list_s);
    g_free (list_s);
  }
  g_string_append (s, end);

  dest_value->data[0].v_pointer = g_string_free (s, FALSE);
}

static gchar *
_gst_value_serialize_g_value_array (const GValue * value, const gchar * begin,
    const gchar * end)
{
  guint i;
  GValueArray *array = value->data[0].v_pointer;
  GString *s;
  GValue *v;
  gchar *s_val;
  guint alen = 0;

  if (array)
    alen = array->n_values;

  /* estimate minimum string length to minimise re-allocs in GString */
  s = g_string_sized_new (2 + (6 * alen) + 2);
  g_string_append (s, begin);
  for (i = 0; i < alen; i++) {
    v = g_value_array_get_nth (array, i);
    s_val = gst_value_serialize (v);
    if (s_val != NULL) {
      g_string_append (s, s_val);
      g_free (s_val);
      if (i < alen - 1) {
        g_string_append_len (s, ", ", 2);
      }
    } else {
      GST_WARNING ("Could not serialize list/array value of type '%s'",
          G_VALUE_TYPE_NAME (v));
    }
  }
  g_string_append (s, end);
  return g_string_free (s, FALSE);
}

static void
_gst_value_transform_g_value_array_string (const GValue * src_value,
    GValue * dest_value, const gchar * begin, const gchar * end)
{
  GValue *list_value;
  GValueArray *array;
  GString *s;
  guint i;
  gchar *list_s;
  guint alen;

  array = src_value->data[0].v_pointer;
  alen = array->n_values;

  /* estimate minimum string length to minimise re-allocs in GString */
  s = g_string_sized_new (2 + (10 * alen) + 2);
  g_string_append (s, begin);
  for (i = 0; i < alen; i++) {
    list_value = g_value_array_get_nth (array, i);

    if (i != 0) {
      g_string_append_len (s, ", ", 2);
    }
    list_s = g_strdup_value_contents (list_value);
    g_string_append (s, list_s);
    g_free (list_s);
  }
  g_string_append (s, end);

  dest_value->data[0].v_pointer = g_string_free (s, FALSE);
}

/*
 * helper function to see if a type is fixed. Is used internally here and
 * there. Do not export, since it doesn't work for types where the content
 * decides the fixedness (e.g. GST_TYPE_ARRAY).
 */
static gboolean
gst_type_is_fixed (GType type)
{
  /* the basic int, string, double types */
  if (type <= G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_GLIB_LAST)) {
    return TRUE;
  }
  /* our fundamental types that are certainly not fixed */
  if (type == GST_TYPE_INT_RANGE || type == GST_TYPE_DOUBLE_RANGE ||
      type == GST_TYPE_INT64_RANGE ||
      type == GST_TYPE_LIST || type == GST_TYPE_FRACTION_RANGE ||
      type == GST_TYPE_STRUCTURE) {
    return FALSE;
  }
  /* other (boxed) types that are fixed */
  if (type == GST_TYPE_BUFFER) {
    return TRUE;
  }
  /* heavy checks */
  if (G_TYPE_IS_FUNDAMENTAL (type) || G_TYPE_FUNDAMENTAL (type) <=
      G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_GLIB_LAST)) {
    return TRUE;
  }

  return FALSE;
}

/* GValue functions usable for both regular lists and arrays */
static void
gst_value_init_list_or_array (GValue * value)
{
  value->data[0].v_pointer = g_array_new (FALSE, TRUE, sizeof (GValue));
}

static GArray *
copy_garray_of_gstvalue (const GArray * src)
{
  GArray *dest;
  guint i, len;

  len = src->len;
  dest = g_array_sized_new (FALSE, TRUE, sizeof (GValue), len);
  g_array_set_size (dest, len);
  for (i = 0; i < len; i++) {
    gst_value_init_and_copy (&g_array_index (dest, GValue, i),
        &g_array_index (src, GValue, i));
  }

  return dest;
}

static void
gst_value_copy_list_or_array (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_pointer =
      copy_garray_of_gstvalue ((GArray *) src_value->data[0].v_pointer);
}

static void
gst_value_free_list_or_array (GValue * value)
{
  guint i, len;
  GArray *src = (GArray *) value->data[0].v_pointer;
  len = src->len;

  if ((value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) == 0) {
    for (i = 0; i < len; i++) {
      g_value_unset (&g_array_index (src, GValue, i));
    }
    g_array_free (src, TRUE);
  }
}

static gpointer
gst_value_list_or_array_peek_pointer (const GValue * value)
{
  return value->data[0].v_pointer;
}

static gchar *
gst_value_collect_list_or_array (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  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 =
        copy_garray_of_gstvalue ((GArray *) collect_values[0].v_pointer);
  }
  return NULL;
}

static gchar *
gst_value_lcopy_list_or_array (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  GArray **dest = collect_values[0].v_pointer;

  if (!dest)
    return g_strdup_printf ("value location for `%s' passed as NULL",
        G_VALUE_TYPE_NAME (value));
  if (!value->data[0].v_pointer)
    return g_strdup_printf ("invalid value given for `%s'",
        G_VALUE_TYPE_NAME (value));
  if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
    *dest = (GArray *) value->data[0].v_pointer;
  } else {
    *dest = copy_garray_of_gstvalue ((GArray *) value->data[0].v_pointer);
  }
  return NULL;
}

static gboolean
gst_value_list_or_array_get_basic_type (const GValue * value, GType * type)
{
  if (G_UNLIKELY (value == NULL))
    return FALSE;

  if (GST_VALUE_HOLDS_LIST (value)) {
    if (VALUE_LIST_SIZE (value) == 0)
      return FALSE;
    return gst_value_list_or_array_get_basic_type (VALUE_LIST_GET_VALUE (value,
            0), type);
  }
  if (GST_VALUE_HOLDS_ARRAY (value)) {
    const GArray *array = (const GArray *) value->data[0].v_pointer;
    if (array->len == 0)
      return FALSE;
    return gst_value_list_or_array_get_basic_type (&g_array_index (array,
            GValue, 0), type);
  }

  *type = G_VALUE_TYPE (value);

  return TRUE;
}

#define IS_RANGE_COMPAT(type1,type2,t1,t2) \
  (((t1) == (type1) && (t2) == (type2)) || ((t2) == (type1) && (t1) == (type2)))

static gboolean
gst_value_list_or_array_are_compatible (const GValue * value1,
    const GValue * value2)
{
  GType basic_type1, basic_type2;

  /* empty or same type is OK */
  if (!gst_value_list_or_array_get_basic_type (value1, &basic_type1) ||
      !gst_value_list_or_array_get_basic_type (value2, &basic_type2) ||
      basic_type1 == basic_type2)
    return TRUE;

  /* ranges are distinct types for each bound type... */
  if (IS_RANGE_COMPAT (G_TYPE_INT, GST_TYPE_INT_RANGE, basic_type1,
          basic_type2))
    return TRUE;
  if (IS_RANGE_COMPAT (G_TYPE_INT64, GST_TYPE_INT64_RANGE, basic_type1,
          basic_type2))
    return TRUE;
  if (IS_RANGE_COMPAT (G_TYPE_DOUBLE, GST_TYPE_DOUBLE_RANGE, basic_type1,
          basic_type2))
    return TRUE;
  if (IS_RANGE_COMPAT (GST_TYPE_FRACTION, GST_TYPE_FRACTION_RANGE, basic_type1,
          basic_type2))
    return TRUE;

  return FALSE;
}

static inline void
_gst_value_list_append_and_take_value (GValue * value, GValue * append_value)
{
  g_array_append_vals ((GArray *) value->data[0].v_pointer, append_value, 1);
  memset (append_value, 0, sizeof (GValue));
}

/**
 * gst_value_list_append_and_take_value:
 * @value: a #GValue of type #GST_TYPE_LIST
 * @append_value: (transfer full): the value to append
 *
 * Appends @append_value to the GstValueList in @value.
 *
 * Since: 1.2
 */
void
gst_value_list_append_and_take_value (GValue * value, GValue * append_value)
{
  g_return_if_fail (GST_VALUE_HOLDS_LIST (value));
  g_return_if_fail (G_IS_VALUE (append_value));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value,
          append_value));

  _gst_value_list_append_and_take_value (value, append_value);
}

/**
 * gst_value_list_append_value:
 * @value: a #GValue of type #GST_TYPE_LIST
 * @append_value: (transfer none): the value to append
 *
 * Appends @append_value to the GstValueList in @value.
 */
void
gst_value_list_append_value (GValue * value, const GValue * append_value)
{
  GValue val = { 0, };

  g_return_if_fail (GST_VALUE_HOLDS_LIST (value));
  g_return_if_fail (G_IS_VALUE (append_value));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value,
          append_value));

  gst_value_init_and_copy (&val, append_value);
  g_array_append_vals ((GArray *) value->data[0].v_pointer, &val, 1);
}

/**
 * gst_value_list_prepend_value:
 * @value: a #GValue of type #GST_TYPE_LIST
 * @prepend_value: the value to prepend
 *
 * Prepends @prepend_value to the GstValueList in @value.
 */
void
gst_value_list_prepend_value (GValue * value, const GValue * prepend_value)
{
  GValue val = { 0, };

  g_return_if_fail (GST_VALUE_HOLDS_LIST (value));
  g_return_if_fail (G_IS_VALUE (prepend_value));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value,
          prepend_value));

  gst_value_init_and_copy (&val, prepend_value);
  g_array_prepend_vals ((GArray *) value->data[0].v_pointer, &val, 1);
}

/**
 * gst_value_list_concat:
 * @dest: (out caller-allocates): an uninitialized #GValue to take the result
 * @value1: a #GValue
 * @value2: a #GValue
 *
 * Concatenates copies of @value1 and @value2 into a list.  Values that are not
 * of type #GST_TYPE_LIST are treated as if they were lists of length 1.
 * @dest will be initialized to the type #GST_TYPE_LIST.
 */
void
gst_value_list_concat (GValue * dest, const GValue * value1,
    const GValue * value2)
{
  guint i, value1_length, value2_length;
  GArray *array;

  g_return_if_fail (dest != NULL);
  g_return_if_fail (G_VALUE_TYPE (dest) == 0);
  g_return_if_fail (G_IS_VALUE (value1));
  g_return_if_fail (G_IS_VALUE (value2));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value1, value2));

  value1_length =
      (GST_VALUE_HOLDS_LIST (value1) ? VALUE_LIST_SIZE (value1) : 1);
  value2_length =
      (GST_VALUE_HOLDS_LIST (value2) ? VALUE_LIST_SIZE (value2) : 1);
  g_value_init (dest, GST_TYPE_LIST);
  array = (GArray *) dest->data[0].v_pointer;
  g_array_set_size (array, value1_length + value2_length);

  if (GST_VALUE_HOLDS_LIST (value1)) {
    for (i = 0; i < value1_length; i++) {
      gst_value_init_and_copy (&g_array_index (array, GValue, i),
          VALUE_LIST_GET_VALUE (value1, i));
    }
  } else {
    gst_value_init_and_copy (&g_array_index (array, GValue, 0), value1);
  }

  if (GST_VALUE_HOLDS_LIST (value2)) {
    for (i = 0; i < value2_length; i++) {
      gst_value_init_and_copy (&g_array_index (array, GValue,
              i + value1_length), VALUE_LIST_GET_VALUE (value2, i));
    }
  } else {
    gst_value_init_and_copy (&g_array_index (array, GValue, value1_length),
        value2);
  }
}

/* same as gst_value_list_concat() but takes ownership of GValues */
static void
gst_value_list_concat_and_take_values (GValue * dest, GValue * val1,
    GValue * val2)
{
  guint i, val1_length, val2_length;
  gboolean val1_is_list;
  gboolean val2_is_list;
  GArray *array;

  g_assert (dest != NULL);
  g_assert (G_VALUE_TYPE (dest) == 0);
  g_assert (G_IS_VALUE (val1));
  g_assert (G_IS_VALUE (val2));
  g_assert (gst_value_list_or_array_are_compatible (val1, val2));

  val1_is_list = GST_VALUE_HOLDS_LIST (val1);
  val1_length = (val1_is_list ? VALUE_LIST_SIZE (val1) : 1);

  val2_is_list = GST_VALUE_HOLDS_LIST (val2);
  val2_length = (val2_is_list ? VALUE_LIST_SIZE (val2) : 1);

  g_value_init (dest, GST_TYPE_LIST);
  array = (GArray *) dest->data[0].v_pointer;
  g_array_set_size (array, val1_length + val2_length);

  if (val1_is_list) {
    for (i = 0; i < val1_length; i++) {
      g_array_index (array, GValue, i) = *VALUE_LIST_GET_VALUE (val1, i);
    }
    g_array_set_size (VALUE_LIST_ARRAY (val1), 0);
    g_value_unset (val1);
  } else {
    g_array_index (array, GValue, 0) = *val1;
    G_VALUE_TYPE (val1) = G_TYPE_INVALID;
  }

  if (val2_is_list) {
    for (i = 0; i < val2_length; i++) {
      const GValue *v2 = VALUE_LIST_GET_VALUE (val2, i);
      g_array_index (array, GValue, i + val1_length) = *v2;
    }
    g_array_set_size (VALUE_LIST_ARRAY (val2), 0);
    g_value_unset (val2);
  } else {
    g_array_index (array, GValue, val1_length) = *val2;
    G_VALUE_TYPE (val2) = G_TYPE_INVALID;
  }
}

/**
 * gst_value_list_merge:
 * @dest: (out caller-allocates): an uninitialized #GValue to take the result
 * @value1: a #GValue
 * @value2: a #GValue
 *
 * Merges copies of @value1 and @value2.  Values that are not
 * of type #GST_TYPE_LIST are treated as if they were lists of length 1.
 *
 * The result will be put into @dest and will either be a list that will not
 * contain any duplicates, or a non-list type (if @value1 and @value2
 * were equal).
 */
void
gst_value_list_merge (GValue * dest, const GValue * value1,
    const GValue * value2)
{
  guint i, j, k, value1_length, value2_length, skipped;
  const GValue *src;
  gboolean skip;
  GArray *array;

  g_return_if_fail (dest != NULL);
  g_return_if_fail (G_VALUE_TYPE (dest) == 0);
  g_return_if_fail (G_IS_VALUE (value1));
  g_return_if_fail (G_IS_VALUE (value2));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value1, value2));

  value1_length =
      (GST_VALUE_HOLDS_LIST (value1) ? VALUE_LIST_SIZE (value1) : 1);
  value2_length =
      (GST_VALUE_HOLDS_LIST (value2) ? VALUE_LIST_SIZE (value2) : 1);
  g_value_init (dest, GST_TYPE_LIST);
  array = (GArray *) dest->data[0].v_pointer;
  g_array_set_size (array, value1_length + value2_length);

  if (GST_VALUE_HOLDS_LIST (value1)) {
    for (i = 0; i < value1_length; i++) {
      gst_value_init_and_copy (&g_array_index (array, GValue, i),
          VALUE_LIST_GET_VALUE (value1, i));
    }
  } else {
    gst_value_init_and_copy (&g_array_index (array, GValue, 0), value1);
  }

  j = value1_length;
  skipped = 0;
  if (GST_VALUE_HOLDS_LIST (value2)) {
    for (i = 0; i < value2_length; i++) {
      skip = FALSE;
      src = VALUE_LIST_GET_VALUE (value2, i);
      for (k = 0; k < value1_length; k++) {
        if (gst_value_compare (&g_array_index (array, GValue, k),
                src) == GST_VALUE_EQUAL) {
          skip = TRUE;
          skipped++;
          break;
        }
      }
      if (!skip) {
        gst_value_init_and_copy (&g_array_index (array, GValue, j), src);
        j++;
      }
    }
  } else {
    skip = FALSE;
    for (k = 0; k < value1_length; k++) {
      if (gst_value_compare (&g_array_index (array, GValue, k),
              value2) == GST_VALUE_EQUAL) {
        skip = TRUE;
        skipped++;
        break;
      }
    }
    if (!skip) {
      gst_value_init_and_copy (&g_array_index (array, GValue, j), value2);
    }
  }
  if (skipped) {
    guint new_size = value1_length + (value2_length - skipped);

    if (new_size > 1) {
      /* shrink list */
      g_array_set_size (array, new_size);
    } else {
      GValue single_dest;

      /* size is 1, take single value in list and make it new dest */
      single_dest = g_array_index (array, GValue, 0);

      /* clean up old value allocations: must set array size to 0, because
       * allocated values are not inited meaning g_value_unset() will not
       * work on them */
      g_array_set_size (array, 0);
      g_value_unset (dest);

      /* the single value is our new result */
      *dest = single_dest;
    }
  }
}

/**
 * gst_value_list_get_size:
 * @value: a #GValue of type #GST_TYPE_LIST
 *
 * Gets the number of values contained in @value.
 *
 * Returns: the number of values
 */
guint
gst_value_list_get_size (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_LIST (value), 0);

  return ((GArray *) value->data[0].v_pointer)->len;
}

/**
 * gst_value_list_get_value:
 * @value: a #GValue of type #GST_TYPE_LIST
 * @index: index of value to get from the list
 *
 * Gets the value that is a member of the list contained in @value and
 * has the index @index.
 *
 * Returns: (transfer none): the value at the given index
 */
const GValue *
gst_value_list_get_value (const GValue * value, guint index)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_LIST (value), NULL);
  g_return_val_if_fail (index < VALUE_LIST_SIZE (value), NULL);

  return (const GValue *) &g_array_index ((GArray *) value->data[0].v_pointer,
      GValue, index);
}

/**
 * gst_value_array_append_value:
 * @value: a #GValue of type #GST_TYPE_ARRAY
 * @append_value: the value to append
 *
 * Appends @append_value to the GstValueArray in @value.
 */
void
gst_value_array_append_value (GValue * value, const GValue * append_value)
{
  GValue val = { 0, };

  g_return_if_fail (GST_VALUE_HOLDS_ARRAY (value));
  g_return_if_fail (G_IS_VALUE (append_value));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value,
          append_value));

  gst_value_init_and_copy (&val, append_value);
  g_array_append_vals ((GArray *) value->data[0].v_pointer, &val, 1);
}

static inline void
_gst_value_array_append_and_take_value (GValue * value, GValue * append_value)
{
  g_array_append_vals ((GArray *) value->data[0].v_pointer, append_value, 1);
  memset (append_value, 0, sizeof (GValue));
}

/**
 * gst_value_array_append_and_take_value:
 * @value: a #GValue of type #GST_TYPE_ARRAY
 * @append_value: (transfer full): the value to append
 *
 * Appends @append_value to the GstValueArray in @value.
 *
 * Since: 1.2
 */
void
gst_value_array_append_and_take_value (GValue * value, GValue * append_value)
{
  g_return_if_fail (GST_VALUE_HOLDS_ARRAY (value));
  g_return_if_fail (G_IS_VALUE (append_value));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value,
          append_value));

  _gst_value_array_append_and_take_value (value, append_value);
}

/**
 * gst_value_array_prepend_value:
 * @value: a #GValue of type #GST_TYPE_ARRAY
 * @prepend_value: the value to prepend
 *
 * Prepends @prepend_value to the GstValueArray in @value.
 */
void
gst_value_array_prepend_value (GValue * value, const GValue * prepend_value)
{
  GValue val = { 0, };

  g_return_if_fail (GST_VALUE_HOLDS_ARRAY (value));
  g_return_if_fail (G_IS_VALUE (prepend_value));
  g_return_if_fail (gst_value_list_or_array_are_compatible (value,
          prepend_value));

  gst_value_init_and_copy (&val, prepend_value);
  g_array_prepend_vals ((GArray *) value->data[0].v_pointer, &val, 1);
}

/**
 * gst_value_array_get_size:
 * @value: a #GValue of type #GST_TYPE_ARRAY
 *
 * Gets the number of values contained in @value.
 *
 * Returns: the number of values
 */
guint
gst_value_array_get_size (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_ARRAY (value), 0);

  return ((GArray *) value->data[0].v_pointer)->len;
}

/**
 * gst_value_array_get_value:
 * @value: a #GValue of type #GST_TYPE_ARRAY
 * @index: index of value to get from the array
 *
 * Gets the value that is a member of the array contained in @value and
 * has the index @index.
 *
 * Returns: (transfer none): the value at the given index
 */
const GValue *
gst_value_array_get_value (const GValue * value, guint index)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_ARRAY (value), NULL);
  g_return_val_if_fail (index < gst_value_array_get_size (value), NULL);

  return (const GValue *) &g_array_index ((GArray *) value->data[0].v_pointer,
      GValue, index);
}

static void
gst_value_transform_list_string (const GValue * src_value, GValue * dest_value)
{
  gst_value_transform_any_list_string (src_value, dest_value, "{ ", " }");
}

static void
gst_value_transform_array_string (const GValue * src_value, GValue * dest_value)
{
  gst_value_transform_any_list_string (src_value, dest_value, "< ", " >");
}

static void
gst_value_transform_g_value_array_string (const GValue * src_value,
    GValue * dest_value)
{
  _gst_value_transform_g_value_array_string (src_value, dest_value, "< ", " >");
}

static void
gst_value_transform_g_value_array_any_list (const GValue * src_value,
    GValue * dest_value)
{
  const GValueArray *varray;
  GArray *array;
  gint i;

  /* GLib will unset the value, memset to 0 the data instead of doing a proper
   * reset. That's why we need to allocate the array here */
  gst_value_init_list_or_array (dest_value);

  varray = g_value_get_boxed (src_value);
  array = dest_value->data[0].v_pointer;

  for (i = 0; i < varray->n_values; i++) {
    GValue val = G_VALUE_INIT;
    gst_value_init_and_copy (&val, &varray->values[i]);
    g_array_append_vals (array, &val, 1);
  }
}

static void
gst_value_transform_any_list_g_value_array (const GValue * src_value,
    GValue * dest_value)
{
  GValueArray *varray;
  const GArray *array;
  gint i;

  array = src_value->data[0].v_pointer;
  varray = g_value_array_new (array->len);

  for (i = 0; i < array->len; i++)
    g_value_array_append (varray, &g_array_index (array, GValue, i));

  g_value_take_boxed (dest_value, varray);
}

/* Do an unordered compare of the contents of a list */
static gint
gst_value_compare_value_list (const GValue * value1, const GValue * value2)
{
  guint i, j;
  GArray *array1 = value1->data[0].v_pointer;
  GArray *array2 = value2->data[0].v_pointer;
  GValue *v1;
  GValue *v2;
  gint len, to_remove;
  guint8 *removed;
  GstValueCompareFunc compare;

  /* get length and do initial length check. */
  len = array1->len;
  if (len != array2->len)
    return GST_VALUE_UNORDERED;

  /* place to mark removed value indices of array2 */
  removed = g_newa (guint8, len);
  memset (removed, 0, len);
  to_remove = len;

  /* loop over array1, all items should be in array2. When we find an
   * item in array2, remove it from array2 by marking it as removed */
  for (i = 0; i < len; i++) {
    v1 = &g_array_index (array1, GValue, i);
    if ((compare = gst_value_get_compare_func (v1))) {
      for (j = 0; j < len; j++) {
        /* item is removed, we can skip it */
        if (removed[j])
          continue;
        v2 = &g_array_index (array2, GValue, j);
        if (gst_value_compare_with_func (v1, v2, compare) == GST_VALUE_EQUAL) {
          /* mark item as removed now that we found it in array2 and
           * decrement the number of remaining items in array2. */
          removed[j] = 1;
          to_remove--;
          break;
        }
      }
      /* item in array1 and not in array2, UNORDERED */
      if (j == len)
        return GST_VALUE_UNORDERED;
    } else
      return GST_VALUE_UNORDERED;
  }
  /* if not all items were removed, array2 contained something not in array1 */
  if (to_remove != 0)
    return GST_VALUE_UNORDERED;

  /* arrays are equal */
  return GST_VALUE_EQUAL;
}

/* Perform an ordered comparison of the contents of an array */
static gint
gst_value_compare_value_array (const GValue * value1, const GValue * value2)
{
  guint i;
  GArray *array1 = value1->data[0].v_pointer;
  GArray *array2 = value2->data[0].v_pointer;
  guint len = array1->len;
  GValue *v1;
  GValue *v2;

  if (len != array2->len)
    return GST_VALUE_UNORDERED;

  for (i = 0; i < len; i++) {
    v1 = &g_array_index (array1, GValue, i);
    v2 = &g_array_index (array2, GValue, i);
    if (gst_value_compare (v1, v2) != GST_VALUE_EQUAL)
      return GST_VALUE_UNORDERED;
  }

  return GST_VALUE_EQUAL;
}

static gint
gst_value_compare_g_value_array (const GValue * value1, const GValue * value2)
{
  guint i;
  GValueArray *array1 = value1->data[0].v_pointer;
  GValueArray *array2 = value2->data[0].v_pointer;
  guint len = array1->n_values;
  GValue *v1;
  GValue *v2;

  if (len != array2->n_values)
    return GST_VALUE_UNORDERED;

  for (i = 0; i < len; i++) {
    v1 = g_value_array_get_nth (array1, i);
    v2 = g_value_array_get_nth (array2, i);
    if (gst_value_compare (v1, v2) != GST_VALUE_EQUAL)
      return GST_VALUE_UNORDERED;
  }

  return GST_VALUE_EQUAL;
}

static gchar *
gst_value_serialize_value_list (const GValue * value)
{
  return _priv_gst_value_serialize_any_list (value, "{ ", " }", TRUE);
}

static gboolean
gst_value_deserialize_value_list (GValue * dest, const gchar * s)
{
  gchar *s2 = (gchar *) s;
  return _priv_gst_value_parse_list (s2, &s2, dest, G_TYPE_INVALID);
}

static gchar *
gst_value_serialize_value_array (const GValue * value)
{
  return _priv_gst_value_serialize_any_list (value, "< ", " >", TRUE);
}

static gboolean
gst_value_deserialize_value_array (GValue * dest, const gchar * s)
{
  gchar *s2 = (gchar *) s;
  return _priv_gst_value_parse_array (s2, &s2, dest, G_TYPE_INVALID);
}

static gchar *
gst_value_serialize_g_value_array (const GValue * value)
{
  return _gst_value_serialize_g_value_array (value, "< ", " >");
}

static gboolean
gst_value_deserialize_g_value_array (GValue * dest, const gchar * s)
{
  g_warning ("gst_value_deserialize_g_value_array: unimplemented");
  return FALSE;
}

/*************
 * int range *
 *
 * Values in the range are defined as any value greater or equal
 * to min*step, AND lesser or equal to max*step.
 * For step == 1, this falls back to the traditional range semantics.
 *
 * data[0] = (min << 32) | (max)
 * data[1] = step
 *
 *************/

#define INT_RANGE_MIN(v) ((gint) (((v)->data[0].v_uint64) >> 32))
#define INT_RANGE_MAX(v) ((gint) (((v)->data[0].v_uint64) & 0xffffffff))
#define INT_RANGE_STEP(v) ((v)->data[1].v_int)

static void
gst_value_init_int_range (GValue * value)
{
  G_STATIC_ASSERT (sizeof (gint) <= 2 * sizeof (guint64));

  value->data[0].v_uint64 = 0;
  value->data[1].v_int = 1;
}

static void
gst_value_copy_int_range (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_uint64 = src_value->data[0].v_uint64;
  dest_value->data[1].v_int = src_value->data[1].v_int;
}

static gchar *
gst_value_collect_int_range (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  if (n_collect_values != 2)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[0].v_int >= collect_values[1].v_int)
    return g_strdup_printf ("range start is not smaller than end for `%s'",
        G_VALUE_TYPE_NAME (value));

  gst_value_set_int_range_step (value, collect_values[0].v_int,
      collect_values[1].v_int, 1);

  return NULL;
}

static gchar *
gst_value_lcopy_int_range (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  guint32 *int_range_start = collect_values[0].v_pointer;
  guint32 *int_range_end = collect_values[1].v_pointer;

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

  *int_range_start = INT_RANGE_MIN (value);
  *int_range_end = INT_RANGE_MAX (value);

  return NULL;
}

/**
 * gst_value_set_int_range_step:
 * @value: a GValue initialized to GST_TYPE_INT_RANGE
 * @start: the start of the range
 * @end: the end of the range
 * @step: the step of the range
 *
 * Sets @value to the range specified by @start, @end and @step.
 */
void
gst_value_set_int_range_step (GValue * value, gint start, gint end, gint step)
{
  guint64 sstart, sstop;

  g_return_if_fail (GST_VALUE_HOLDS_INT_RANGE (value));
  g_return_if_fail (start < end);
  g_return_if_fail (step > 0);
  g_return_if_fail (start % step == 0);
  g_return_if_fail (end % step == 0);

  sstart = (guint) (start / step);
  sstop = (guint) (end / step);
  value->data[0].v_uint64 = (sstart << 32) | sstop;
  value->data[1].v_int = step;
}

/**
 * gst_value_set_int_range:
 * @value: a GValue initialized to GST_TYPE_INT_RANGE
 * @start: the start of the range
 * @end: the end of the range
 *
 * Sets @value to the range specified by @start and @end.
 */
void
gst_value_set_int_range (GValue * value, gint start, gint end)
{
  gst_value_set_int_range_step (value, start, end, 1);
}

/**
 * gst_value_get_int_range_min:
 * @value: a GValue initialized to GST_TYPE_INT_RANGE
 *
 * Gets the minimum of the range specified by @value.
 *
 * Returns: the minimum of the range
 */
gint
gst_value_get_int_range_min (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value), 0);

  return INT_RANGE_MIN (value) * INT_RANGE_STEP (value);
}

/**
 * gst_value_get_int_range_max:
 * @value: a GValue initialized to GST_TYPE_INT_RANGE
 *
 * Gets the maximum of the range specified by @value.
 *
 * Returns: the maximum of the range
 */
gint
gst_value_get_int_range_max (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value), 0);

  return INT_RANGE_MAX (value) * INT_RANGE_STEP (value);
}

/**
 * gst_value_get_int_range_step:
 * @value: a GValue initialized to GST_TYPE_INT_RANGE
 *
 * Gets the step of the range specified by @value.
 *
 * Returns: the step of the range
 */
gint
gst_value_get_int_range_step (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value), 0);

  return INT_RANGE_STEP (value);
}

static void
gst_value_transform_int_range_string (const GValue * src_value,
    GValue * dest_value)
{
  if (INT_RANGE_STEP (src_value) == 1)
    dest_value->data[0].v_pointer = g_strdup_printf ("[%d,%d]",
        INT_RANGE_MIN (src_value), INT_RANGE_MAX (src_value));
  else
    dest_value->data[0].v_pointer = g_strdup_printf ("[%d,%d,%d]",
        INT_RANGE_MIN (src_value) * INT_RANGE_STEP (src_value),
        INT_RANGE_MAX (src_value) * INT_RANGE_STEP (src_value),
        INT_RANGE_STEP (src_value));
}

static gint
gst_value_compare_int_range (const GValue * value1, const GValue * value2)
{
  /* calculate the number of values in each range */
  gint n1 = INT_RANGE_MAX (value1) - INT_RANGE_MIN (value1) + 1;
  gint n2 = INT_RANGE_MAX (value2) - INT_RANGE_MIN (value2) + 1;

  /* they must be equal */
  if (n1 != n2)
    return GST_VALUE_UNORDERED;

  /* if empty, equal */
  if (n1 == 0)
    return GST_VALUE_EQUAL;

  /* if more than one value, then it is only equal if the step is equal
     and bounds lie on the same value */
  if (n1 > 1) {
    if (INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2) &&
        INT_RANGE_MIN (value1) == INT_RANGE_MIN (value2) &&
        INT_RANGE_MAX (value1) == INT_RANGE_MAX (value2)) {
      return GST_VALUE_EQUAL;
    }
    return GST_VALUE_UNORDERED;
  } else {
    /* if just one, only if the value is equal */
    if (INT_RANGE_MIN (value1) == INT_RANGE_MIN (value2))
      return GST_VALUE_EQUAL;
    return GST_VALUE_UNORDERED;
  }
}

static gchar *
gst_value_serialize_int_range (const GValue * value)
{
  if (INT_RANGE_STEP (value) == 1)
    return g_strdup_printf ("[ %d, %d ]", INT_RANGE_MIN (value),
        INT_RANGE_MAX (value));
  else
    return g_strdup_printf ("[ %d, %d, %d ]",
        INT_RANGE_MIN (value) * INT_RANGE_STEP (value),
        INT_RANGE_MAX (value) * INT_RANGE_STEP (value), INT_RANGE_STEP (value));
}

static gboolean
gst_value_deserialize_int_range (GValue * dest, const gchar * s)
{
  g_warning ("unimplemented");
  return FALSE;
}

/***************
 * int64 range *
 *
 * Values in the range are defined as any value greater or equal
 * to min*step, AND lesser or equal to max*step.
 * For step == 1, this falls back to the traditional range semantics.
 ***************/

#define INT64_RANGE_MIN(v) (((gint64 *)((v)->data[0].v_pointer))[0])
#define INT64_RANGE_MAX(v) (((gint64 *)((v)->data[0].v_pointer))[1])
#define INT64_RANGE_STEP(v) (((gint64 *)((v)->data[0].v_pointer))[2])

static void
gst_value_init_int64_range (GValue * value)
{
  gint64 *vals = g_slice_alloc0 (3 * sizeof (gint64));
  value->data[0].v_pointer = vals;
  INT64_RANGE_MIN (value) = 0;
  INT64_RANGE_MAX (value) = 0;
  INT64_RANGE_STEP (value) = 1;
}

static void
gst_value_free_int64_range (GValue * value)
{
  g_return_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value));
  g_slice_free1 (3 * sizeof (gint64), value->data[0].v_pointer);
  value->data[0].v_pointer = NULL;
}

static void
gst_value_copy_int64_range (const GValue * src_value, GValue * dest_value)
{
  gint64 *vals = (gint64 *) dest_value->data[0].v_pointer;
  gint64 *src_vals = (gint64 *) src_value->data[0].v_pointer;

  if (vals == NULL) {
    gst_value_init_int64_range (dest_value);
  }

  if (src_vals != NULL) {
    INT64_RANGE_MIN (dest_value) = INT64_RANGE_MIN (src_value);
    INT64_RANGE_MAX (dest_value) = INT64_RANGE_MAX (src_value);
    INT64_RANGE_STEP (dest_value) = INT64_RANGE_STEP (src_value);
  }
}

static gchar *
gst_value_collect_int64_range (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  gint64 *vals = value->data[0].v_pointer;

  if (n_collect_values != 2)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[0].v_int64 >= collect_values[1].v_int64)
    return g_strdup_printf ("range start is not smaller than end for `%s'",
        G_VALUE_TYPE_NAME (value));

  if (vals == NULL) {
    gst_value_init_int64_range (value);
  }

  gst_value_set_int64_range_step (value, collect_values[0].v_int64,
      collect_values[1].v_int64, 1);

  return NULL;
}

static gchar *
gst_value_lcopy_int64_range (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  guint64 *int_range_start = collect_values[0].v_pointer;
  guint64 *int_range_end = collect_values[1].v_pointer;
  guint64 *int_range_step = collect_values[2].v_pointer;
  gint64 *vals = (gint64 *) value->data[0].v_pointer;

  if (!int_range_start)
    return g_strdup_printf ("start value location for `%s' passed as NULL",
        G_VALUE_TYPE_NAME (value));
  if (!int_range_end)
    return g_strdup_printf ("end value location for `%s' passed as NULL",
        G_VALUE_TYPE_NAME (value));
  if (!int_range_step)
    return g_strdup_printf ("step value location for `%s' passed as NULL",
        G_VALUE_TYPE_NAME (value));

  if (G_UNLIKELY (vals == NULL)) {
    return g_strdup_printf ("Uninitialised `%s' passed",
        G_VALUE_TYPE_NAME (value));
  }

  *int_range_start = INT64_RANGE_MIN (value);
  *int_range_end = INT64_RANGE_MAX (value);
  *int_range_step = INT64_RANGE_STEP (value);

  return NULL;
}

/**
 * gst_value_set_int64_range_step:
 * @value: a GValue initialized to GST_TYPE_INT64_RANGE
 * @start: the start of the range
 * @end: the end of the range
 * @step: the step of the range
 *
 * Sets @value to the range specified by @start, @end and @step.
 */
void
gst_value_set_int64_range_step (GValue * value, gint64 start, gint64 end,
    gint64 step)
{
  g_return_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value));
  g_return_if_fail (start < end);
  g_return_if_fail (step > 0);
  g_return_if_fail (start % step == 0);
  g_return_if_fail (end % step == 0);

  INT64_RANGE_MIN (value) = start / step;
  INT64_RANGE_MAX (value) = end / step;
  INT64_RANGE_STEP (value) = step;
}

/**
 * gst_value_set_int64_range:
 * @value: a GValue initialized to GST_TYPE_INT64_RANGE
 * @start: the start of the range
 * @end: the end of the range
 *
 * Sets @value to the range specified by @start and @end.
 */
void
gst_value_set_int64_range (GValue * value, gint64 start, gint64 end)
{
  gst_value_set_int64_range_step (value, start, end, 1);
}

/**
 * gst_value_get_int64_range_min:
 * @value: a GValue initialized to GST_TYPE_INT64_RANGE
 *
 * Gets the minimum of the range specified by @value.
 *
 * Returns: the minimum of the range
 */
gint64
gst_value_get_int64_range_min (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value), 0);

  return INT64_RANGE_MIN (value) * INT64_RANGE_STEP (value);
}

/**
 * gst_value_get_int64_range_max:
 * @value: a GValue initialized to GST_TYPE_INT64_RANGE
 *
 * Gets the maximum of the range specified by @value.
 *
 * Returns: the maximum of the range
 */
gint64
gst_value_get_int64_range_max (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value), 0);

  return INT64_RANGE_MAX (value) * INT64_RANGE_STEP (value);
}

/**
 * gst_value_get_int64_range_step:
 * @value: a GValue initialized to GST_TYPE_INT64_RANGE
 *
 * Gets the step of the range specified by @value.
 *
 * Returns: the step of the range
 */
gint64
gst_value_get_int64_range_step (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value), 0);

  return INT64_RANGE_STEP (value);
}

static void
gst_value_transform_int64_range_string (const GValue * src_value,
    GValue * dest_value)
{
  if (INT64_RANGE_STEP (src_value) == 1)
    dest_value->data[0].v_pointer =
        g_strdup_printf ("(gint64)[%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT "]",
        INT64_RANGE_MIN (src_value), INT64_RANGE_MAX (src_value));
  else
    dest_value->data[0].v_pointer =
        g_strdup_printf ("(gint64)[%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT
        ",%" G_GINT64_FORMAT "]",
        INT64_RANGE_MIN (src_value) * INT64_RANGE_STEP (src_value),
        INT64_RANGE_MAX (src_value) * INT64_RANGE_STEP (src_value),
        INT64_RANGE_STEP (src_value));
}

static gint
gst_value_compare_int64_range (const GValue * value1, const GValue * value2)
{
  /* calculate the number of values in each range */
  gint64 n1 = INT64_RANGE_MAX (value1) - INT64_RANGE_MIN (value1) + 1;
  gint64 n2 = INT64_RANGE_MAX (value2) - INT64_RANGE_MIN (value2) + 1;

  /* they must be equal */
  if (n1 != n2)
    return GST_VALUE_UNORDERED;

  /* if empty, equal */
  if (n1 == 0)
    return GST_VALUE_EQUAL;

  /* if more than one value, then it is only equal if the step is equal
     and bounds lie on the same value */
  if (n1 > 1) {
    if (INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2) &&
        INT64_RANGE_MIN (value1) == INT64_RANGE_MIN (value2) &&
        INT64_RANGE_MAX (value1) == INT64_RANGE_MAX (value2)) {
      return GST_VALUE_EQUAL;
    }
    return GST_VALUE_UNORDERED;
  } else {
    /* if just one, only if the value is equal */
    if (INT64_RANGE_MIN (value1) == INT64_RANGE_MIN (value2))
      return GST_VALUE_EQUAL;
    return GST_VALUE_UNORDERED;
  }
}

static gchar *
gst_value_serialize_int64_range (const GValue * value)
{
  if (INT64_RANGE_STEP (value) == 1)
    return g_strdup_printf ("[ %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT " ]",
        INT64_RANGE_MIN (value), INT64_RANGE_MAX (value));
  else
    return g_strdup_printf ("[ %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT ", %"
        G_GINT64_FORMAT " ]",
        INT64_RANGE_MIN (value) * INT64_RANGE_STEP (value),
        INT64_RANGE_MAX (value) * INT64_RANGE_STEP (value),
        INT64_RANGE_STEP (value));
}

static gboolean
gst_value_deserialize_int64_range (GValue * dest, const gchar * s)
{
  g_warning ("unimplemented");
  return FALSE;
}

/****************
 * double range *
 ****************/

static void
gst_value_init_double_range (GValue * value)
{
  value->data[0].v_double = 0;
  value->data[1].v_double = 0;
}

static void
gst_value_copy_double_range (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_double = src_value->data[0].v_double;
  dest_value->data[1].v_double = src_value->data[1].v_double;
}

static gchar *
gst_value_collect_double_range (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  if (n_collect_values != 2)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[0].v_double >= collect_values[1].v_double)
    return g_strdup_printf ("range start is not smaller than end for `%s'",
        G_VALUE_TYPE_NAME (value));

  value->data[0].v_double = collect_values[0].v_double;
  value->data[1].v_double = collect_values[1].v_double;

  return NULL;
}

static gchar *
gst_value_lcopy_double_range (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  gdouble *double_range_start = collect_values[0].v_pointer;
  gdouble *double_range_end = collect_values[1].v_pointer;

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

  *double_range_start = value->data[0].v_double;
  *double_range_end = value->data[1].v_double;

  return NULL;
}

/**
 * gst_value_set_double_range:
 * @value: a GValue initialized to GST_TYPE_DOUBLE_RANGE
 * @start: the start of the range
 * @end: the end of the range
 *
 * Sets @value to the range specified by @start and @end.
 */
void
gst_value_set_double_range (GValue * value, gdouble start, gdouble end)
{
  g_return_if_fail (GST_VALUE_HOLDS_DOUBLE_RANGE (value));
  g_return_if_fail (start < end);

  value->data[0].v_double = start;
  value->data[1].v_double = end;
}

/**
 * gst_value_get_double_range_min:
 * @value: a GValue initialized to GST_TYPE_DOUBLE_RANGE
 *
 * Gets the minimum of the range specified by @value.
 *
 * Returns: the minimum of the range
 */
gdouble
gst_value_get_double_range_min (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_DOUBLE_RANGE (value), 0);

  return value->data[0].v_double;
}

/**
 * gst_value_get_double_range_max:
 * @value: a GValue initialized to GST_TYPE_DOUBLE_RANGE
 *
 * Gets the maximum of the range specified by @value.
 *
 * Returns: the maximum of the range
 */
gdouble
gst_value_get_double_range_max (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_DOUBLE_RANGE (value), 0);

  return value->data[1].v_double;
}

static void
gst_value_transform_double_range_string (const GValue * src_value,
    GValue * dest_value)
{
  gchar s1[G_ASCII_DTOSTR_BUF_SIZE], s2[G_ASCII_DTOSTR_BUF_SIZE];

  dest_value->data[0].v_pointer = g_strdup_printf ("[%s,%s]",
      g_ascii_dtostr (s1, G_ASCII_DTOSTR_BUF_SIZE,
          src_value->data[0].v_double),
      g_ascii_dtostr (s2, G_ASCII_DTOSTR_BUF_SIZE,
          src_value->data[1].v_double));
}

static gint
gst_value_compare_double_range (const GValue * value1, const GValue * value2)
{
  if (value2->data[0].v_double == value1->data[0].v_double &&
      value2->data[1].v_double == value1->data[1].v_double)
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gchar *
gst_value_serialize_double_range (const GValue * value)
{
  gchar d1[G_ASCII_DTOSTR_BUF_SIZE];
  gchar d2[G_ASCII_DTOSTR_BUF_SIZE];

  g_ascii_dtostr (d1, G_ASCII_DTOSTR_BUF_SIZE, value->data[0].v_double);
  g_ascii_dtostr (d2, G_ASCII_DTOSTR_BUF_SIZE, value->data[1].v_double);
  return g_strdup_printf ("[ %s, %s ]", d1, d2);
}

static gboolean
gst_value_deserialize_double_range (GValue * dest, const gchar * s)
{
  g_warning ("unimplemented");
  return FALSE;
}

/****************
 * fraction range *
 ****************/

static void
gst_value_init_fraction_range (GValue * value)
{
  GValue *vals;
  GType ftype;

  ftype = GST_TYPE_FRACTION;

  value->data[0].v_pointer = vals = g_slice_alloc0 (2 * sizeof (GValue));
  g_value_init (&vals[0], ftype);
  g_value_init (&vals[1], ftype);
}

static void
gst_value_free_fraction_range (GValue * value)
{
  GValue *vals = (GValue *) value->data[0].v_pointer;

  if (vals != NULL) {
    /* we know the two values contain fractions without internal allocs */
    /* g_value_unset (&vals[0]); */
    /* g_value_unset (&vals[1]); */
    g_slice_free1 (2 * sizeof (GValue), vals);
    value->data[0].v_pointer = NULL;
  }
}

static void
gst_value_copy_fraction_range (const GValue * src_value, GValue * dest_value)
{
  GValue *vals = (GValue *) dest_value->data[0].v_pointer;
  GValue *src_vals = (GValue *) src_value->data[0].v_pointer;

  if (vals == NULL) {
    gst_value_init_fraction_range (dest_value);
    vals = dest_value->data[0].v_pointer;
  }
  if (src_vals != NULL) {
    g_value_copy (&src_vals[0], &vals[0]);
    g_value_copy (&src_vals[1], &vals[1]);
  }
}

static gchar *
gst_value_collect_fraction_range (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  GValue *vals = (GValue *) value->data[0].v_pointer;

  if (n_collect_values != 4)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[1].v_int == 0)
    return g_strdup_printf ("passed '0' as first denominator for `%s'",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[3].v_int == 0)
    return g_strdup_printf ("passed '0' as second denominator for `%s'",
        G_VALUE_TYPE_NAME (value));
  if (gst_util_fraction_compare (collect_values[0].v_int,
          collect_values[1].v_int, collect_values[2].v_int,
          collect_values[3].v_int) >= 0)
    return g_strdup_printf ("range start is not smaller than end for `%s'",
        G_VALUE_TYPE_NAME (value));

  if (vals == NULL) {
    gst_value_init_fraction_range (value);
    vals = value->data[0].v_pointer;
  }

  gst_value_set_fraction (&vals[0], collect_values[0].v_int,
      collect_values[1].v_int);
  gst_value_set_fraction (&vals[1], collect_values[2].v_int,
      collect_values[3].v_int);

  return NULL;
}

static gchar *
gst_value_lcopy_fraction_range (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  gint i;
  gint *dest_values[4];
  GValue *vals = (GValue *) value->data[0].v_pointer;

  if (G_UNLIKELY (n_collect_values != 4))
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));

  for (i = 0; i < 4; i++) {
    if (G_UNLIKELY (collect_values[i].v_pointer == NULL)) {
      return g_strdup_printf ("value location for `%s' passed as NULL",
          G_VALUE_TYPE_NAME (value));
    }
    dest_values[i] = collect_values[i].v_pointer;
  }

  if (G_UNLIKELY (vals == NULL)) {
    return g_strdup_printf ("Uninitialised `%s' passed",
        G_VALUE_TYPE_NAME (value));
  }

  dest_values[0][0] = gst_value_get_fraction_numerator (&vals[0]);
  dest_values[1][0] = gst_value_get_fraction_denominator (&vals[0]);
  dest_values[2][0] = gst_value_get_fraction_numerator (&vals[1]);
  dest_values[3][0] = gst_value_get_fraction_denominator (&vals[1]);
  return NULL;
}

/**
 * gst_value_set_fraction_range:
 * @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
 * @start: the start of the range (a GST_TYPE_FRACTION GValue)
 * @end: the end of the range (a GST_TYPE_FRACTION GValue)
 *
 * Sets @value to the range specified by @start and @end.
 */
void
gst_value_set_fraction_range (GValue * value, const GValue * start,
    const GValue * end)
{
  GValue *vals;

  g_return_if_fail (GST_VALUE_HOLDS_FRACTION_RANGE (value));
  g_return_if_fail (GST_VALUE_HOLDS_FRACTION (start));
  g_return_if_fail (GST_VALUE_HOLDS_FRACTION (end));
  g_return_if_fail (gst_util_fraction_compare (start->data[0].v_int,
          start->data[1].v_int, end->data[0].v_int, end->data[1].v_int) < 0);

  vals = (GValue *) value->data[0].v_pointer;
  if (vals == NULL) {
    gst_value_init_fraction_range (value);
    vals = value->data[0].v_pointer;
  }
  g_value_copy (start, &vals[0]);
  g_value_copy (end, &vals[1]);
}

/**
 * gst_value_set_fraction_range_full:
 * @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
 * @numerator_start: the numerator start of the range
 * @denominator_start: the denominator start of the range
 * @numerator_end: the numerator end of the range
 * @denominator_end: the denominator end of the range
 *
 * Sets @value to the range specified by @numerator_start/@denominator_start
 * and @numerator_end/@denominator_end.
 */
void
gst_value_set_fraction_range_full (GValue * value,
    gint numerator_start, gint denominator_start,
    gint numerator_end, gint denominator_end)
{
  GValue start = { 0 };
  GValue end = { 0 };

  g_return_if_fail (value != NULL);
  g_return_if_fail (denominator_start != 0);
  g_return_if_fail (denominator_end != 0);
  g_return_if_fail (gst_util_fraction_compare (numerator_start,
          denominator_start, numerator_end, denominator_end) < 0);

  g_value_init (&start, GST_TYPE_FRACTION);
  g_value_init (&end, GST_TYPE_FRACTION);

  gst_value_set_fraction (&start, numerator_start, denominator_start);
  gst_value_set_fraction (&end, numerator_end, denominator_end);
  gst_value_set_fraction_range (value, &start, &end);

  /* we know the two values contain fractions without internal allocs */
  /* g_value_unset (&start); */
  /* g_value_unset (&end);   */
}

/* FIXME 2.0: Don't leak the internal representation of fraction
 * ranges but instead return the numerator and denominator
 * separately.
 * This would allow to store fraction ranges as
 *  data[0] = (min_n << 32) | (min_d)
 *  data[1] = (max_n << 32) | (max_d)
 * without requiring an additional allocation for each value.
 */

/**
 * gst_value_get_fraction_range_min:
 * @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
 *
 * Gets the minimum of the range specified by @value.
 *
 * Returns: (nullable): the minimum of the range
 */
const GValue *
gst_value_get_fraction_range_min (const GValue * value)
{
  GValue *vals;

  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION_RANGE (value), NULL);

  vals = (GValue *) value->data[0].v_pointer;
  if (vals != NULL) {
    return &vals[0];
  }

  return NULL;
}

/**
 * gst_value_get_fraction_range_max:
 * @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
 *
 * Gets the maximum of the range specified by @value.
 *
 * Returns: (nullable): the maximum of the range
 */
const GValue *
gst_value_get_fraction_range_max (const GValue * value)
{
  GValue *vals;

  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION_RANGE (value), NULL);

  vals = (GValue *) value->data[0].v_pointer;
  if (vals != NULL) {
    return &vals[1];
  }

  return NULL;
}

static gchar *
gst_value_serialize_fraction_range (const GValue * value)
{
  GValue *vals = (GValue *) value->data[0].v_pointer;
  gchar *retval;

  if (vals == NULL) {
    retval = g_strdup ("[ 0/1, 0/1 ]");
  } else {
    gchar *start, *end;

    start = gst_value_serialize_fraction (&vals[0]);
    end = gst_value_serialize_fraction (&vals[1]);

    retval = g_strdup_printf ("[ %s, %s ]", start, end);
    g_free (start);
    g_free (end);
  }

  return retval;
}

static void
gst_value_transform_fraction_range_string (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_pointer =
      gst_value_serialize_fraction_range (src_value);
}

static gint
gst_value_compare_fraction_range (const GValue * value1, const GValue * value2)
{
  GValue *vals1, *vals2;
  GstValueCompareFunc compare;

  if (value2->data[0].v_pointer == value1->data[0].v_pointer)
    return GST_VALUE_EQUAL;     /* Only possible if both are NULL */

  if (value2->data[0].v_pointer == NULL || value1->data[0].v_pointer == NULL)
    return GST_VALUE_UNORDERED;

  vals1 = (GValue *) value1->data[0].v_pointer;
  vals2 = (GValue *) value2->data[0].v_pointer;
  if ((compare = gst_value_get_compare_func (&vals1[0]))) {
    if (gst_value_compare_with_func (&vals1[0], &vals2[0], compare) ==
        GST_VALUE_EQUAL &&
        gst_value_compare_with_func (&vals1[1], &vals2[1], compare) ==
        GST_VALUE_EQUAL)
      return GST_VALUE_EQUAL;
  }
  return GST_VALUE_UNORDERED;
}

static gboolean
gst_value_deserialize_fraction_range (GValue * dest, const gchar * s)
{
  g_warning ("unimplemented");
  return FALSE;
}

/***********
 * GstCaps *
 ***********/

/**
 * gst_value_set_caps:
 * @value: a GValue initialized to GST_TYPE_CAPS
 * @caps: (transfer none): the caps to set the value to
 *
 * Sets the contents of @value to @caps. A reference to the
 * provided @caps will be taken by the @value.
 */
void
gst_value_set_caps (GValue * value, const GstCaps * caps)
{
  g_return_if_fail (G_IS_VALUE (value));
  g_return_if_fail (G_VALUE_TYPE (value) == GST_TYPE_CAPS);
  g_return_if_fail (caps == NULL || GST_IS_CAPS (caps));

  g_value_set_boxed (value, caps);
}

/**
 * gst_value_get_caps:
 * @value: a GValue initialized to GST_TYPE_CAPS
 *
 * Gets the contents of @value. The reference count of the returned
 * #GstCaps will not be modified, therefore the caller must take one
 * before getting rid of the @value.
 *
 * Returns: (transfer none): the contents of @value
 */
const GstCaps *
gst_value_get_caps (const GValue * value)
{
  g_return_val_if_fail (G_IS_VALUE (value), NULL);
  g_return_val_if_fail (G_VALUE_TYPE (value) == GST_TYPE_CAPS, NULL);

  return (GstCaps *) g_value_get_boxed (value);
}

static gint
gst_value_compare_caps (const GValue * value1, const GValue * value2)
{
  GstCaps *caps1 = GST_CAPS (gst_value_get_caps (value1));
  GstCaps *caps2 = GST_CAPS (gst_value_get_caps (value2));

  if (gst_caps_is_equal (caps1, caps2))
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gchar *
gst_value_serialize_caps (const GValue * value)
{
  GstCaps *caps = g_value_get_boxed (value);
  return priv_gst_string_take_and_wrap (gst_caps_to_string (caps));
}

static gboolean
gst_value_deserialize_caps (GValue * dest, const gchar * s)
{
  GstCaps *caps;

  if (*s != '"') {
    caps = gst_caps_from_string (s);
  } else {
    gchar *str = gst_string_unwrap (s);

    if (G_UNLIKELY (!str))
      return FALSE;

    caps = gst_caps_from_string (str);
    g_free (str);
  }

  if (caps) {
    g_value_take_boxed (dest, caps);
    return TRUE;
  }
  return FALSE;
}

/********************************************
 * Serialization/deserialization of GValues *
 ********************************************/

static GstValueAbbreviation *
_priv_gst_value_get_abbrs (gint * n_abbrs)
{
  static GstValueAbbreviation *abbrs = NULL;
  static volatile gsize num = 0;

  if (g_once_init_enter (&num)) {
    /* dynamically generate the array */
    gsize _num;
    GstValueAbbreviation dyn_abbrs[] = {
      {"int", G_TYPE_INT}
      ,
      {"i", G_TYPE_INT}
      ,
      {"uint", G_TYPE_UINT}
      ,
      {"u", G_TYPE_UINT}
      ,
      {"float", G_TYPE_FLOAT}
      ,
      {"f", G_TYPE_FLOAT}
      ,
      {"double", G_TYPE_DOUBLE}
      ,
      {"d", G_TYPE_DOUBLE}
      ,
      {"buffer", GST_TYPE_BUFFER}
      ,
      {"fraction", GST_TYPE_FRACTION}
      ,
      {"boolean", G_TYPE_BOOLEAN}
      ,
      {"bool", G_TYPE_BOOLEAN}
      ,
      {"b", G_TYPE_BOOLEAN}
      ,
      {"string", G_TYPE_STRING}
      ,
      {"str", G_TYPE_STRING}
      ,
      {"s", G_TYPE_STRING}
      ,
      {"structure", GST_TYPE_STRUCTURE}
      ,
      {"date", G_TYPE_DATE}
      ,
      {"datetime", GST_TYPE_DATE_TIME}
      ,
      {"bitmask", GST_TYPE_BITMASK}
      ,
      {"flagset", GST_TYPE_FLAG_SET}
      ,
      {"sample", GST_TYPE_SAMPLE}
      ,
      {"taglist", GST_TYPE_TAG_LIST}
      ,
      {"type", G_TYPE_GTYPE}
      ,
      {"array", GST_TYPE_ARRAY}
      ,
      {"list", GST_TYPE_LIST}
    };
    _num = G_N_ELEMENTS (dyn_abbrs);
    /* permanently allocate and copy the array now */
    abbrs = g_new0 (GstValueAbbreviation, _num);
    memcpy (abbrs, dyn_abbrs, sizeof (GstValueAbbreviation) * _num);
    g_once_init_leave (&num, _num);
  }
  *n_abbrs = num;

  return abbrs;
}

/* given a type_name that could be a type abbreviation or a registered GType,
 * return a matching GType */
static GType
_priv_gst_value_gtype_from_abbr (const char *type_name)
{
  int i;
  GstValueAbbreviation *abbrs;
  gint n_abbrs;
  GType ret;

  g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);

  abbrs = _priv_gst_value_get_abbrs (&n_abbrs);

  for (i = 0; i < n_abbrs; i++) {
    if (strcmp (type_name, abbrs[i].type_name) == 0) {
      return abbrs[i].type;
    }
  }

  /* this is the fallback */
  ret = g_type_from_name (type_name);
  /* If not found, try it as a dynamic type */
  if (G_UNLIKELY (ret == 0))
    ret = gst_dynamic_type_factory_load (type_name);
  return ret;

}

const char *
_priv_gst_value_gtype_to_abbr (GType type)
{
  int i;
  GstValueAbbreviation *abbrs;
  gint n_abbrs;

  g_return_val_if_fail (type != G_TYPE_INVALID, NULL);

  abbrs = _priv_gst_value_get_abbrs (&n_abbrs);

  for (i = 0; i < n_abbrs; i++) {
    if (type == abbrs[i].type) {
      return abbrs[i].type_name;
    }
  }

  return g_type_name (type);
}

/*
 * _priv_gst_value_parse_string:
 * @s: string to parse
 * @end: out-pointer to char behind end of string
 * @next: out-pointer to start of unread data
 * @unescape: @TRUE if the substring is escaped.
 *
 * Find the end of a sub-string. If end == next, the string will not be
 * null-terminated. In all other cases it will be.
 *
 * Note: This function modifies the string in @s (if unescape == @TRUE).
 *
 * Returns: @TRUE if a sub-string was found and @FALSE if the string is not
 * terminated.
 */
gboolean
_priv_gst_value_parse_string (gchar * s, gchar ** end, gchar ** next,
    gboolean unescape)
{
  gchar *w;

  if (*s == 0)
    return FALSE;

  if (*s != '"') {
    int ret = _priv_gst_value_parse_simple_string (s, end);
    *next = *end;

    return ret;
  }

  /* Find the closing quotes */
  if (unescape) {
    w = s;
    s++;
    while (*s != '"') {
      if (G_UNLIKELY (*s == 0))
        return FALSE;
      if (G_UNLIKELY (*s == '\\')) {
        s++;
        if (G_UNLIKELY (*s == 0))
          return FALSE;
      }
      *w = *s;
      w++;
      s++;
    }
    s++;
  } else {
    s++;
    while (*s != '"') {
      if (G_UNLIKELY (*s == 0))
        return FALSE;
      if (G_UNLIKELY (*s == '\\')) {
        s++;
        if (G_UNLIKELY (*s == 0))
          return FALSE;
      }
      s++;
    }
    s++;
    w = s;
  }

  *end = w;
  *next = s;

  return TRUE;
}

static gboolean
_priv_gst_value_parse_range (gchar * s, gchar ** after, GValue * value,
    GType type)
{
  GValue value1 = { 0 };
  GValue value2 = { 0 };
  GValue value3 = { 0 };
  GType range_type;
  gboolean ret, have_step = FALSE;

  if (*s != '[')
    return FALSE;
  s++;

  ret = _priv_gst_value_parse_value (s, &s, &value1, type);
  if (!ret)
    return FALSE;

  while (g_ascii_isspace (*s))
    s++;

  if (*s != ',')
    return FALSE;
  s++;

  while (g_ascii_isspace (*s))
    s++;

  ret = _priv_gst_value_parse_value (s, &s, &value2, type);
  if (!ret)
    return FALSE;

  while (g_ascii_isspace (*s))
    s++;

  /* optional step for int and int64 */
  if (G_VALUE_TYPE (&value1) == G_TYPE_INT
      || G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
    if (*s == ',') {
      s++;

      while (g_ascii_isspace (*s))
        s++;

      ret = _priv_gst_value_parse_value (s, &s, &value3, type);
      if (!ret)
        return FALSE;

      while (g_ascii_isspace (*s))
        s++;

      have_step = TRUE;
    }
  }

  if (*s != ']')
    return FALSE;
  s++;

  if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
    return FALSE;
  if (have_step && G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value3))
    return FALSE;

  if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
    range_type = GST_TYPE_DOUBLE_RANGE;
    g_value_init (value, range_type);
    gst_value_set_double_range (value,
        gst_g_value_get_double_unchecked (&value1),
        gst_g_value_get_double_unchecked (&value2));
  } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
    range_type = GST_TYPE_INT_RANGE;
    g_value_init (value, range_type);
    if (have_step)
      gst_value_set_int_range_step (value,
          gst_g_value_get_int_unchecked (&value1),
          gst_g_value_get_int_unchecked (&value2),
          gst_g_value_get_int_unchecked (&value3));
    else
      gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1),
          gst_g_value_get_int_unchecked (&value2));
  } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT64) {
    range_type = GST_TYPE_INT64_RANGE;
    g_value_init (value, range_type);
    if (have_step)
      gst_value_set_int64_range_step (value,
          gst_g_value_get_int64_unchecked (&value1),
          gst_g_value_get_int64_unchecked (&value2),
          gst_g_value_get_int64_unchecked (&value3));
    else
      gst_value_set_int64_range (value,
          gst_g_value_get_int64_unchecked (&value1),
          gst_g_value_get_int64_unchecked (&value2));
  } else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) {
    range_type = GST_TYPE_FRACTION_RANGE;
    g_value_init (value, range_type);
    gst_value_set_fraction_range (value, &value1, &value2);
  } else {
    return FALSE;
  }

  *after = s;
  return TRUE;
}

static gboolean
_priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
    GType type, char begin, char end)
{
  GValue list_value = { 0 };
  gboolean ret;
  GArray *array;

  array = g_value_peek_pointer (value);

  if (*s != begin)
    return FALSE;
  s++;

  while (g_ascii_isspace (*s))
    s++;
  if (*s == end) {
    s++;
    *after = s;
    return TRUE;
  }

  ret = _priv_gst_value_parse_value (s, &s, &list_value, type);
  if (!ret)
    return FALSE;

  g_array_append_val (array, list_value);

  while (g_ascii_isspace (*s))
    s++;

  while (*s != end) {
    if (*s != ',')
      return FALSE;
    s++;

    while (g_ascii_isspace (*s))
      s++;

    memset (&list_value, 0, sizeof (list_value));
    ret = _priv_gst_value_parse_value (s, &s, &list_value, type);
    if (!ret)
      return FALSE;

    g_array_append_val (array, list_value);
    while (g_ascii_isspace (*s))
      s++;
  }

  s++;

  *after = s;
  return TRUE;
}

static gboolean
_priv_gst_value_parse_list (gchar * s, gchar ** after, GValue * value,
    GType type)
{
  return _priv_gst_value_parse_any_list (s, after, value, type, '{', '}');
}

static gboolean
_priv_gst_value_parse_array (gchar * s, gchar ** after, GValue * value,
    GType type)
{
  return _priv_gst_value_parse_any_list (s, after, value, type, '<', '>');
}

gboolean
_priv_gst_value_parse_simple_string (gchar * str, gchar ** end)
{
  char *s = str;

  while (G_LIKELY (GST_ASCII_IS_STRING (*s))) {
    s++;
  }

  *end = s;

  return (s != str);
}

gboolean
_priv_gst_value_parse_value (gchar * str,
    gchar ** after, GValue * value, GType default_type)
{
  gchar *type_name;
  gchar *type_end;
  gchar *value_s;
  gchar *value_end;
  gchar *s;
  gchar c;
  int ret = 0;
  GType type = default_type;

  s = str;
  while (g_ascii_isspace (*s))
    s++;

  /* check if there's a (type_name) 'cast' */
  type_name = NULL;
  if (*s == '(') {
    s++;
    while (g_ascii_isspace (*s))
      s++;
    type_name = s;
    if (G_UNLIKELY (!_priv_gst_value_parse_simple_string (s, &type_end)))
      return FALSE;
    s = type_end;
    while (g_ascii_isspace (*s))
      s++;
    if (G_UNLIKELY (*s != ')'))
      return FALSE;
    s++;
    while (g_ascii_isspace (*s))
      s++;

    c = *type_end;
    *type_end = 0;
    type = _priv_gst_value_gtype_from_abbr (type_name);
    GST_DEBUG ("trying type name '%s'", type_name);
    *type_end = c;

    if (G_UNLIKELY (type == G_TYPE_INVALID)) {
      GST_WARNING ("invalid type");
      return FALSE;
    }
  }

  while (g_ascii_isspace (*s))
    s++;
  if (*s == '[') {
    ret = _priv_gst_value_parse_range (s, &s, value, type);
  } else if (*s == '{') {
    g_value_init (value, GST_TYPE_LIST);
    ret = _priv_gst_value_parse_list (s, &s, value, type);
  } else if (*s == '<') {
    g_value_init (value, GST_TYPE_ARRAY);
    ret = _priv_gst_value_parse_array (s, &s, value, type);
  } else {
    value_s = s;

    if (G_UNLIKELY (type == G_TYPE_INVALID)) {
      GType try_types[] =
          { G_TYPE_INT, G_TYPE_DOUBLE, GST_TYPE_FRACTION, GST_TYPE_FLAG_SET,
        G_TYPE_BOOLEAN, G_TYPE_STRING
      };
      int i;

      if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s, TRUE)))
        return FALSE;
      /* Set NULL terminator for deserialization */
      c = *value_end;
      *value_end = '\0';

      for (i = 0; i < G_N_ELEMENTS (try_types); i++) {
        g_value_init (value, try_types[i]);
        ret = gst_value_deserialize (value, value_s);
        if (ret)
          break;
        g_value_unset (value);
      }
    } else {
      g_value_init (value, type);

      if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s,
                  (type != G_TYPE_STRING))))
        return FALSE;
      /* Set NULL terminator for deserialization */
      c = *value_end;
      *value_end = '\0';

      ret = gst_value_deserialize (value, value_s);
      if (G_UNLIKELY (!ret))
        g_value_unset (value);
    }
    *value_end = c;
  }

  *after = s;

  return ret;
}

/**************
 * GstSegment *
 **************/

static gchar *
gst_value_serialize_segment_internal (const GValue * value, gboolean escape)
{
  GstSegment *seg = g_value_get_boxed (value);
  gchar *t, *res;
  GstStructure *s;

  s = gst_structure_new ("GstSegment",
      "flags", GST_TYPE_SEGMENT_FLAGS, seg->flags,
      "rate", G_TYPE_DOUBLE, seg->rate,
      "applied-rate", G_TYPE_DOUBLE, seg->applied_rate,
      "format", GST_TYPE_FORMAT, seg->format,
      "base", G_TYPE_UINT64, seg->base,
      "offset", G_TYPE_UINT64, seg->offset,
      "start", G_TYPE_UINT64, seg->start,
      "stop", G_TYPE_UINT64, seg->stop,
      "time", G_TYPE_UINT64, seg->time,
      "position", G_TYPE_UINT64, seg->position,
      "duration", G_TYPE_UINT64, seg->duration, NULL);
  t = gst_structure_to_string (s);
  if (escape) {
    res = g_strdup_printf ("\"%s\"", t);
    g_free (t);
  } else {
    res = t;
  }
  gst_structure_free (s);

  return res;
}

static gchar *
gst_value_serialize_segment (const GValue * value)
{
  return gst_value_serialize_segment_internal (value, TRUE);
}

static gboolean
gst_value_deserialize_segment (GValue * dest, const gchar * s)
{
  GstStructure *str;
  GstSegment seg;
  gboolean res;

  str = gst_structure_from_string (s, NULL);
  if (str == NULL)
    return FALSE;

  res = gst_structure_get (str,
      "flags", GST_TYPE_SEGMENT_FLAGS, &seg.flags,
      "rate", G_TYPE_DOUBLE, &seg.rate,
      "applied-rate", G_TYPE_DOUBLE, &seg.applied_rate,
      "format", GST_TYPE_FORMAT, &seg.format,
      "base", G_TYPE_UINT64, &seg.base,
      "offset", G_TYPE_UINT64, &seg.offset,
      "start", G_TYPE_UINT64, &seg.start,
      "stop", G_TYPE_UINT64, &seg.stop,
      "time", G_TYPE_UINT64, &seg.time,
      "position", G_TYPE_UINT64, &seg.position,
      "duration", G_TYPE_UINT64, &seg.duration, NULL);
  gst_structure_free (str);

  if (res)
    g_value_set_boxed (dest, &seg);

  return res;
}

/****************
 * GstStructure *
 ****************/

/**
 * gst_value_set_structure:
 * @value: a GValue initialized to GST_TYPE_STRUCTURE
 * @structure: the structure to set the value to
 *
 * Sets the contents of @value to @structure.
 */
void
gst_value_set_structure (GValue * value, const GstStructure * structure)
{
  g_return_if_fail (G_IS_VALUE (value));
  g_return_if_fail (G_VALUE_TYPE (value) == GST_TYPE_STRUCTURE);
  g_return_if_fail (structure == NULL || GST_IS_STRUCTURE (structure));

  g_value_set_boxed (value, structure);
}

/**
 * gst_value_get_structure:
 * @value: a GValue initialized to GST_TYPE_STRUCTURE
 *
 * Gets the contents of @value.
 *
 * Returns: (transfer none): the contents of @value
 */
const GstStructure *
gst_value_get_structure (const GValue * value)
{
  g_return_val_if_fail (G_IS_VALUE (value), NULL);
  g_return_val_if_fail (G_VALUE_TYPE (value) == GST_TYPE_STRUCTURE, NULL);

  return (GstStructure *) g_value_get_boxed (value);
}

static gchar *
gst_value_serialize_structure (const GValue * value)
{
  GstStructure *structure = g_value_get_boxed (value);

  return priv_gst_string_take_and_wrap (gst_structure_to_string (structure));
}

static gboolean
gst_value_deserialize_structure (GValue * dest, const gchar * s)
{
  GstStructure *structure;

  if (*s != '"') {
    structure = gst_structure_from_string (s, NULL);
  } else {
    gchar *str = gst_string_unwrap (s);

    if (G_UNLIKELY (!str))
      return FALSE;

    structure = gst_structure_from_string (str, NULL);
    g_free (str);
  }

  if (G_LIKELY (structure)) {
    g_value_take_boxed (dest, structure);
    return TRUE;
  }
  return FALSE;
}

static gboolean
gst_value_compare_structure (const GValue * value1, const GValue * value2)
{
  GstStructure *structure1 = GST_STRUCTURE (g_value_get_boxed (value1));
  GstStructure *structure2 = GST_STRUCTURE (g_value_get_boxed (value2));

  if (structure1 == structure2)
    return GST_VALUE_EQUAL;

  if (!structure1 || !structure2)
    return GST_VALUE_UNORDERED;

  if (gst_structure_is_equal (structure1, structure2))
    return GST_VALUE_EQUAL;

  return GST_VALUE_UNORDERED;
}

/*******************
 * GstCapsFeatures *
 *******************/

/**
 * gst_value_set_caps_features:
 * @value: a GValue initialized to GST_TYPE_CAPS_FEATURES
 * @features: the features to set the value to
 *
 * Sets the contents of @value to @features.
 */
void
gst_value_set_caps_features (GValue * value, const GstCapsFeatures * features)
{
  g_return_if_fail (G_IS_VALUE (value));
  g_return_if_fail (G_VALUE_TYPE (value) == GST_TYPE_CAPS_FEATURES);
  g_return_if_fail (features == NULL || GST_IS_CAPS_FEATURES (features));

  g_value_set_boxed (value, features);
}

/**
 * gst_value_get_caps_features:
 * @value: a GValue initialized to GST_TYPE_CAPS_FEATURES
 *
 * Gets the contents of @value.
 *
 * Returns: (transfer none): the contents of @value
 */
const GstCapsFeatures *
gst_value_get_caps_features (const GValue * value)
{
  g_return_val_if_fail (G_IS_VALUE (value), NULL);
  g_return_val_if_fail (G_VALUE_TYPE (value) == GST_TYPE_CAPS_FEATURES, NULL);

  return (GstCapsFeatures *) g_value_get_boxed (value);
}

static gchar *
gst_value_serialize_caps_features (const GValue * value)
{
  GstCapsFeatures *features = g_value_get_boxed (value);

  return priv_gst_string_take_and_wrap (gst_caps_features_to_string (features));
}

static gboolean
gst_value_deserialize_caps_features (GValue * dest, const gchar * s)
{
  GstCapsFeatures *features;

  if (*s != '"') {
    features = gst_caps_features_from_string (s);
  } else {
    gchar *str = gst_string_unwrap (s);

    if (G_UNLIKELY (!str))
      return FALSE;

    features = gst_caps_features_from_string (str);
    g_free (str);
  }

  if (G_LIKELY (features)) {
    g_value_take_boxed (dest, features);
    return TRUE;
  }
  return FALSE;
}

/**************
 * GstTagList *
 **************/
static gint
gst_value_compare_tag_list (const GValue * value1, const GValue * value2)
{
  GstTagList *taglist1 = GST_TAG_LIST (g_value_get_boxed (value1));
  GstTagList *taglist2 = GST_TAG_LIST (g_value_get_boxed (value2));

  if (gst_tag_list_is_equal (taglist1, taglist2))
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gboolean
gst_value_deserialize_tag_list (GValue * dest, const gchar * s)
{
  GstTagList *taglist;

  if (*s != '"') {
    taglist = gst_tag_list_new_from_string (s);
  } else {
    gchar *str = gst_string_unwrap (s);

    if (G_UNLIKELY (!str))
      return FALSE;

    taglist = gst_tag_list_new_from_string (str);
    g_free (str);
  }

  if (G_LIKELY (taglist != NULL)) {
    g_value_take_boxed (dest, taglist);
    return TRUE;
  }
  return FALSE;
}

static gchar *
gst_value_serialize_tag_list (const GValue * value)
{
  GstTagList *taglist = g_value_get_boxed (value);

  return priv_gst_string_take_and_wrap (gst_tag_list_to_string (taglist));
}


/*************
 * GstBuffer *
 *************/

static gint
compare_buffer (GstBuffer * buf1, GstBuffer * buf2)
{
  gsize size1, size2;
  GstMapInfo info1, info2;
  gint result, mret;

  if (buf1 == buf2)
    return GST_VALUE_EQUAL;

  size1 = gst_buffer_get_size (buf1);
  size2 = gst_buffer_get_size (buf2);

  if (size1 != size2)
    return GST_VALUE_UNORDERED;

  if (size1 == 0)
    return GST_VALUE_EQUAL;

  if (!gst_buffer_map (buf1, &info1, GST_MAP_READ))
    return GST_VALUE_UNORDERED;

  if (!gst_buffer_map (buf2, &info2, GST_MAP_READ)) {
    gst_buffer_unmap (buf1, &info1);
    return GST_VALUE_UNORDERED;
  }

  mret = memcmp (info1.data, info2.data, info1.size);
  if (mret == 0)
    result = GST_VALUE_EQUAL;
  else if (mret < 0)
    result = GST_VALUE_LESS_THAN;
  else
    result = GST_VALUE_GREATER_THAN;

  gst_buffer_unmap (buf1, &info1);
  gst_buffer_unmap (buf2, &info2);

  return result;
}

static gint
gst_value_compare_buffer (const GValue * value1, const GValue * value2)
{
  GstBuffer *buf1 = gst_value_get_buffer (value1);
  GstBuffer *buf2 = gst_value_get_buffer (value2);

  return compare_buffer (buf1, buf2);
}

static gchar *
gst_value_serialize_buffer (const GValue * value)
{
  GstMapInfo info;
  guint8 *data;
  gint i;
  gchar *string;
  GstBuffer *buffer;

  buffer = gst_value_get_buffer (value);
  if (buffer == NULL)
    return NULL;

  if (!gst_buffer_map (buffer, &info, GST_MAP_READ))
    return NULL;

  data = info.data;

  string = g_malloc (info.size * 2 + 1);
  for (i = 0; i < info.size; i++) {
    sprintf (string + i * 2, "%02x", data[i]);
  }
  string[info.size * 2] = 0;

  gst_buffer_unmap (buffer, &info);

  return string;
}

static gboolean
gst_value_deserialize_buffer (GValue * dest, const gchar * s)
{
  GstBuffer *buffer;
  gint len;
  gchar ts[3];
  GstMapInfo info;
  guint8 *data;
  gint i;

  len = strlen (s);
  if (len & 1)
    goto wrong_length;

  buffer = gst_buffer_new_allocate (NULL, len / 2, NULL);
  if (!gst_buffer_map (buffer, &info, GST_MAP_WRITE))
    goto map_failed;
  data = info.data;

  for (i = 0; i < len / 2; i++) {
    if (!isxdigit ((int) s[i * 2]) || !isxdigit ((int) s[i * 2 + 1]))
      goto wrong_char;

    ts[0] = s[i * 2 + 0];
    ts[1] = s[i * 2 + 1];
    ts[2] = 0;

    data[i] = (guint8) strtoul (ts, NULL, 16);
  }
  gst_buffer_unmap (buffer, &info);

  gst_value_take_buffer (dest, buffer);

  return TRUE;

  /* ERRORS */
wrong_length:
  {
    return FALSE;
  }
map_failed:
  {
    return FALSE;
  }
wrong_char:
  {
    gst_buffer_unref (buffer);
    gst_buffer_unmap (buffer, &info);
    return FALSE;
  }
}

/*************
 * GstSample *
 *************/

/* This function is mostly used for comparing image/buffer tags in taglists */
static gint
gst_value_compare_sample (const GValue * value1, const GValue * value2)
{
  GstBuffer *buf1 = gst_sample_get_buffer (gst_value_get_sample (value1));
  GstBuffer *buf2 = gst_sample_get_buffer (gst_value_get_sample (value2));

  /* FIXME: should we take into account anything else such as caps? */
  return compare_buffer (buf1, buf2);
}

static gchar *
gst_value_serialize_sample (const GValue * value)
{
  const GstStructure *info_structure;
  GstSegment *segment;
  GstBuffer *buffer;
  GstCaps *caps;
  GstSample *sample;
  GValue val = { 0, };
  gchar *info_str, *caps_str, *tmp;
  gchar *buf_str, *seg_str, *s;

  sample = g_value_get_boxed (value);

  buffer = gst_sample_get_buffer (sample);
  if (buffer) {
    g_value_init (&val, GST_TYPE_BUFFER);
    g_value_set_boxed (&val, buffer);
    buf_str = gst_value_serialize_buffer (&val);
    g_value_unset (&val);
  } else {
    buf_str = g_strdup ("None");
  }

  caps = gst_sample_get_caps (sample);
  if (caps) {
    tmp = gst_caps_to_string (caps);
    caps_str = g_base64_encode ((guchar *) tmp, strlen (tmp) + 1);
    g_strdelimit (caps_str, "=", '_');
    g_free (tmp);
  } else {
    caps_str = g_strdup ("None");
  }

  segment = gst_sample_get_segment (sample);
  if (segment) {
    g_value_init (&val, GST_TYPE_SEGMENT);
    g_value_set_boxed (&val, segment);
    tmp = gst_value_serialize_segment_internal (&val, FALSE);
    seg_str = g_base64_encode ((guchar *) tmp, strlen (tmp) + 1);
    g_strdelimit (seg_str, "=", '_');
    g_free (tmp);
    g_value_unset (&val);
  } else {
    seg_str = g_strdup ("None");
  }

  info_structure = gst_sample_get_info (sample);
  if (info_structure) {
    tmp = gst_structure_to_string (info_structure);
    info_str = g_base64_encode ((guchar *) tmp, strlen (tmp) + 1);
    g_strdelimit (info_str, "=", '_');
    g_free (tmp);
  } else {
    info_str = g_strdup ("None");
  }

  s = g_strconcat (buf_str, ":", caps_str, ":", seg_str, ":", info_str, NULL);
  g_free (buf_str);
  g_free (caps_str);
  g_free (seg_str);
  g_free (info_str);

  return s;
}

static gboolean
gst_value_deserialize_sample (GValue * dest, const gchar * s)
{
  GValue bval = G_VALUE_INIT, sval = G_VALUE_INIT;
  GstStructure *info;
  GstSample *sample;
  GstCaps *caps = NULL;
  gboolean ret = FALSE;
  gchar **fields;
  gsize outlen;
  gint len;

  GST_TRACE ("deserialize '%s'", s);

  fields = g_strsplit (s, ":", -1);
  len = g_strv_length (fields);
  if (len != 4)
    goto wrong_length;

  g_value_init (&bval, GST_TYPE_BUFFER);
  g_value_init (&sval, GST_TYPE_SEGMENT);

  if (!gst_value_deserialize_buffer (&bval, fields[0]))
    goto fail;

  if (strcmp (fields[1], "None") != 0) {
    g_strdelimit (fields[1], "_", '=');
    g_base64_decode_inplace (fields[1], &outlen);
    GST_TRACE ("caps    : %s", fields[1]);
    caps = gst_caps_from_string (fields[1]);
    if (caps == NULL)
      goto fail;
  }

  if (strcmp (fields[2], "None") != 0) {
    g_strdelimit (fields[2], "_", '=');
    g_base64_decode_inplace (fields[2], &outlen);
    GST_TRACE ("segment : %s", fields[2]);
    if (!gst_value_deserialize_segment (&sval, fields[2]))
      goto fail;
  }

  if (strcmp (fields[3], "None") != 0) {
    g_strdelimit (fields[3], "_", '=');
    g_base64_decode_inplace (fields[3], &outlen);
    GST_TRACE ("info    : %s", fields[3]);
    info = gst_structure_from_string (fields[3], NULL);
    if (info == NULL)
      goto fail;
  } else {
    info = NULL;
  }

  sample = gst_sample_new (gst_value_get_buffer (&bval), caps,
      g_value_get_boxed (&sval), info);

  g_value_take_boxed (dest, sample);

  ret = TRUE;

fail:
  if (caps)
    gst_caps_unref (caps);
  g_value_unset (&bval);
  g_value_unset (&sval);

wrong_length:

  g_strfreev (fields);

  return ret;
}

/***********
 * boolean *
 ***********/

static gint
gst_value_compare_boolean (const GValue * value1, const GValue * value2)
{
  if ((value1->data[0].v_int != 0) == (value2->data[0].v_int != 0))
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gchar *
gst_value_serialize_boolean (const GValue * value)
{
  if (value->data[0].v_int) {
    return g_strdup ("true");
  }
  return g_strdup ("false");
}

static gboolean
gst_value_deserialize_boolean (GValue * dest, const gchar * s)
{
  gboolean ret = FALSE;

  if (g_ascii_strcasecmp (s, "true") == 0 ||
      g_ascii_strcasecmp (s, "yes") == 0 ||
      g_ascii_strcasecmp (s, "t") == 0 || strcmp (s, "1") == 0) {
    g_value_set_boolean (dest, TRUE);
    ret = TRUE;
  } else if (g_ascii_strcasecmp (s, "false") == 0 ||
      g_ascii_strcasecmp (s, "no") == 0 ||
      g_ascii_strcasecmp (s, "f") == 0 || strcmp (s, "0") == 0) {
    g_value_set_boolean (dest, FALSE);
    ret = TRUE;
  }

  return ret;
}

#define CREATE_SERIALIZATION_START(_type,_macro)                        \
static gint                                                             \
gst_value_compare_ ## _type                                             \
(const GValue * value1, const GValue * value2)                          \
{                                                                       \
  g ## _type val1 = g_value_get_ ## _type (value1);                     \
  g ## _type val2 = g_value_get_ ## _type (value2);                     \
  if (val1 > val2)                                                      \
    return GST_VALUE_GREATER_THAN;                                      \
  if (val1 < val2)                                                      \
    return GST_VALUE_LESS_THAN;                                         \
  return GST_VALUE_EQUAL;                                               \
}                                                                       \
                                                                        \
static gchar *                                                          \
gst_value_serialize_ ## _type (const GValue * value)                    \
{                                                                       \
  GValue val = { 0, };                                                  \
  g_value_init (&val, G_TYPE_STRING);                                   \
  if (!g_value_transform (value, &val))                                 \
    g_assert_not_reached ();                                            \
  /* NO_COPY_MADNESS!!! */                                              \
  return (char *) g_value_get_string (&val);                            \
}

/* deserialize the given s into to as a gint64.
 * check if the result is actually storeable in the given size number of
 * bytes.
 */
static gboolean
gst_value_deserialize_int_helper (gint64 * to, const gchar * s,
    gint64 min, gint64 max, gint size)
{
  gboolean ret = FALSE;
  gchar *end;
  guint64 mask = ~0;

  errno = 0;
  *to = g_ascii_strtoull (s, &end, 0);
  /* a range error is a definitive no-no */
  if (errno == ERANGE) {
    return FALSE;
  }

  if (*end == 0) {
    ret = TRUE;
  } else {
    if (g_ascii_strcasecmp (s, "little_endian") == 0) {
      *to = G_LITTLE_ENDIAN;
      ret = TRUE;
    } else if (g_ascii_strcasecmp (s, "big_endian") == 0) {
      *to = G_BIG_ENDIAN;
      ret = TRUE;
    } else if (g_ascii_strcasecmp (s, "byte_order") == 0) {
      *to = G_BYTE_ORDER;
      ret = TRUE;
    } else if (g_ascii_strcasecmp (s, "min") == 0) {
      *to = min;
      ret = TRUE;
    } else if (g_ascii_strcasecmp (s, "max") == 0) {
      *to = max;
      ret = TRUE;
    }
  }
  if (ret) {
    /* by definition, a gint64 fits into a gint64; so ignore those */
    if (size != sizeof (mask)) {
      if (*to >= 0) {
        /* for positive numbers, we create a mask of 1's outside of the range
         * and 0's inside the range.  An and will thus keep only 1 bits
         * outside of the range */
        mask <<= (size * 8);
        if ((mask & *to) != 0) {
          ret = FALSE;
        }
      } else {
        /* for negative numbers, we do a 2's complement version */
        mask <<= ((size * 8) - 1);
        if ((mask & *to) != mask) {
          ret = FALSE;
        }
      }
    }
  }
  return ret;
}

#define CREATE_SERIALIZATION(_type,_macro)                              \
CREATE_SERIALIZATION_START(_type,_macro)                                \
                                                                        \
static gboolean                                                         \
gst_value_deserialize_ ## _type (GValue * dest, const gchar *s)         \
{                                                                       \
  gint64 x;                                                             \
                                                                        \
  if (gst_value_deserialize_int_helper (&x, s, G_MIN ## _macro,         \
      G_MAX ## _macro, sizeof (g ## _type))) {                          \
    g_value_set_ ## _type (dest, /*(g ## _type)*/ x);                   \
    return TRUE;                                                        \
  } else {                                                              \
    return FALSE;                                                       \
  }                                                                     \
}

#define CREATE_USERIALIZATION(_type,_macro)                             \
CREATE_SERIALIZATION_START(_type,_macro)                                \
                                                                        \
static gboolean                                                         \
gst_value_deserialize_ ## _type (GValue * dest, const gchar *s)         \
{                                                                       \
  gint64 x;                                                             \
  gchar *end;                                                           \
  gboolean ret = FALSE;                                                 \
                                                                        \
  errno = 0;                                                            \
  x = g_ascii_strtoull (s, &end, 0);                                    \
  /* a range error is a definitive no-no */                             \
  if (errno == ERANGE) {                                                \
    return FALSE;                                                       \
  }                                                                     \
  /* the cast ensures the range check later on makes sense */           \
  x = (g ## _type) x;                                                   \
  if (*end == 0) {                                                      \
    ret = TRUE;                                                         \
  } else {                                                              \
    if (g_ascii_strcasecmp (s, "little_endian") == 0) {                 \
      x = G_LITTLE_ENDIAN;                                              \
      ret = TRUE;                                                       \
    } else if (g_ascii_strcasecmp (s, "big_endian") == 0) {             \
      x = G_BIG_ENDIAN;                                                 \
      ret = TRUE;                                                       \
    } else if (g_ascii_strcasecmp (s, "byte_order") == 0) {             \
      x = G_BYTE_ORDER;                                                 \
      ret = TRUE;                                                       \
    } else if (g_ascii_strcasecmp (s, "min") == 0) {                    \
      x = 0;                                                            \
      ret = TRUE;                                                       \
    } else if (g_ascii_strcasecmp (s, "max") == 0) {                    \
      x = G_MAX ## _macro;                                              \
      ret = TRUE;                                                       \
    }                                                                   \
  }                                                                     \
  if (ret) {                                                            \
    if (x > G_MAX ## _macro) {                                          \
      ret = FALSE;                                                      \
    } else {                                                            \
      g_value_set_ ## _type (dest, x);                                  \
    }                                                                   \
  }                                                                     \
  return ret;                                                           \
}

CREATE_SERIALIZATION (int, INT);
CREATE_SERIALIZATION (int64, INT64);
CREATE_SERIALIZATION (long, LONG);

CREATE_USERIALIZATION (uint, UINT);
CREATE_USERIALIZATION (uint64, UINT64);
CREATE_USERIALIZATION (ulong, ULONG);

/* FIXME 2.0: remove this again, plugins shouldn't have uchar properties */
#ifndef G_MAXUCHAR
#define G_MAXUCHAR 255
#endif
CREATE_USERIALIZATION (uchar, UCHAR);

/**********
 * double *
 **********/
static gint
gst_value_compare_double (const GValue * value1, const GValue * value2)
{
  if (value1->data[0].v_double > value2->data[0].v_double)
    return GST_VALUE_GREATER_THAN;
  if (value1->data[0].v_double < value2->data[0].v_double)
    return GST_VALUE_LESS_THAN;
  if (value1->data[0].v_double == value2->data[0].v_double)
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gchar *
gst_value_serialize_double (const GValue * value)
{
  gchar d[G_ASCII_DTOSTR_BUF_SIZE];

  g_ascii_dtostr (d, G_ASCII_DTOSTR_BUF_SIZE, value->data[0].v_double);
  return g_strdup (d);
}

static gboolean
gst_value_deserialize_double (GValue * dest, const gchar * s)
{
  gdouble x;
  gboolean ret = FALSE;
  gchar *end;

  x = g_ascii_strtod (s, &end);
  if (*end == 0) {
    ret = TRUE;
  } else {
    if (g_ascii_strcasecmp (s, "min") == 0) {
      x = -G_MAXDOUBLE;
      ret = TRUE;
    } else if (g_ascii_strcasecmp (s, "max") == 0) {
      x = G_MAXDOUBLE;
      ret = TRUE;
    }
  }
  if (ret) {
    g_value_set_double (dest, x);
  }
  return ret;
}

/*********
 * float *
 *********/

static gint
gst_value_compare_float (const GValue * value1, const GValue * value2)
{
  if (value1->data[0].v_float > value2->data[0].v_float)
    return GST_VALUE_GREATER_THAN;
  if (value1->data[0].v_float < value2->data[0].v_float)
    return GST_VALUE_LESS_THAN;
  if (value1->data[0].v_float == value2->data[0].v_float)
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gchar *
gst_value_serialize_float (const GValue * value)
{
  gchar d[G_ASCII_DTOSTR_BUF_SIZE];

  g_ascii_dtostr (d, G_ASCII_DTOSTR_BUF_SIZE, value->data[0].v_float);
  return g_strdup (d);
}

static gboolean
gst_value_deserialize_float (GValue * dest, const gchar * s)
{
  gdouble x;
  gboolean ret = FALSE;
  gchar *end;

  x = g_ascii_strtod (s, &end);
  if (*end == 0) {
    ret = TRUE;
  } else {
    if (g_ascii_strcasecmp (s, "min") == 0) {
      x = -G_MAXFLOAT;
      ret = TRUE;
    } else if (g_ascii_strcasecmp (s, "max") == 0) {
      x = G_MAXFLOAT;
      ret = TRUE;
    }
  }
  if (x > G_MAXFLOAT || x < -G_MAXFLOAT)
    ret = FALSE;
  if (ret) {
    g_value_set_float (dest, (float) x);
  }
  return ret;
}

/**********
 * string *
 **********/

static gint
gst_value_compare_string (const GValue * value1, const GValue * value2)
{
  if (G_UNLIKELY (!value1->data[0].v_pointer || !value2->data[0].v_pointer)) {
    /* if only one is NULL, no match - otherwise both NULL == EQUAL */
    if (value1->data[0].v_pointer != value2->data[0].v_pointer)
      return GST_VALUE_UNORDERED;
  } else {
    gint x = strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);

    if (x < 0)
      return GST_VALUE_LESS_THAN;
    if (x > 0)
      return GST_VALUE_GREATER_THAN;
  }

  return GST_VALUE_EQUAL;
}

static gint
gst_string_measure_wrapping (const gchar * s)
{
  gint len;
  gboolean wrap = FALSE;

  if (G_UNLIKELY (s == NULL))
    return -1;

  /* Special case: the actual string NULL needs wrapping */
  if (G_UNLIKELY (strcmp (s, "NULL") == 0))
    return 4;

  len = 0;
  while (*s) {
    if (GST_ASCII_IS_STRING (*s)) {
      len++;
    } else if (*s < 0x20 || *s >= 0x7f) {
      wrap = TRUE;
      len += 4;
    } else {
      wrap = TRUE;
      len += 2;
    }
    s++;
  }

  /* Wrap the string if we found something that needs
   * wrapping, or the empty string (len == 0) */
  return (wrap || len == 0) ? len : -1;
}

static gchar *
gst_string_wrap_inner (const gchar * s, gint len)
{
  gchar *d, *e;

  e = d = g_malloc (len + 3);

  *e++ = '\"';
  while (*s) {
    if (GST_ASCII_IS_STRING (*s)) {
      *e++ = *s++;
    } else if (*s < 0x20 || *s >= 0x7f) {
      *e++ = '\\';
      *e++ = '0' + ((*(guchar *) s) >> 6);
      *e++ = '0' + (((*s) >> 3) & 0x7);
      *e++ = '0' + ((*s++) & 0x7);
    } else {
      *e++ = '\\';
      *e++ = *s++;
    }
  }
  *e++ = '\"';
  *e = 0;

  g_assert (e - d <= len + 3);
  return d;
}

/* Do string wrapping/escaping */
static gchar *
gst_string_wrap (const gchar * s)
{
  gint len = gst_string_measure_wrapping (s);

  if (G_LIKELY (len < 0))
    return g_strdup (s);

  return gst_string_wrap_inner (s, len);
}

/* Same as above, but take ownership of the string */
gchar *
priv_gst_string_take_and_wrap (gchar * s)
{
  gchar *out;
  gint len = gst_string_measure_wrapping (s);

  if (G_LIKELY (len < 0))
    return s;

  out = gst_string_wrap_inner (s, len);
  g_free (s);

  return out;
}

/*
 * This function takes a string delimited with double quotes (")
 * and unescapes any \xxx octal numbers.
 *
 * If sequences of \y are found where y is not in the range of
 * 0->3, y is copied unescaped.
 *
 * If \xyy is found where x is an octal number but y is not, an
 * error is encountered and %NULL is returned.
 *
 * the input string must be \0 terminated.
 */
static gchar *
gst_string_unwrap (const gchar * s)
{
  gchar *ret;
  gchar *read, *write;

  /* NULL string returns NULL */
  if (s == NULL)
    return NULL;

  /* strings not starting with " are invalid */
  if (*s != '"')
    return NULL;

  /* make copy of original string to hold the result. This
   * string will always be smaller than the original */
  ret = g_strdup (s);
  read = ret;
  write = ret;

  /* need to move to the next position as we parsed the " */
  read++;

  while (*read) {
    if (GST_ASCII_IS_STRING (*read)) {
      /* normal chars are just copied */
      *write++ = *read++;
    } else if (*read == '"') {
      /* quote marks end of string */
      break;
    } else if (*read == '\\') {
      /* got an escape char, move to next position to read a tripplet
       * of octal numbers */
      read++;
      /* is the next char a possible first octal number? */
      if (*read >= '0' && *read <= '3') {
        /* parse other 2 numbers, if one of them is not in the range of
         * an octal number, we error. We also catch the case where a zero
         * byte is found here. */
        if (read[1] < '0' || read[1] > '7' || read[2] < '0' || read[2] > '7')
          goto beach;

        /* now convert the octal number to a byte again. */
        *write++ = ((read[0] - '0') << 6) +
            ((read[1] - '0') << 3) + (read[2] - '0');

        read += 3;
      } else {
        /* if we run into a \0 here, we definitely won't get a quote later */
        if (*read == 0)
          goto beach;

        /* else copy \X sequence */
        *write++ = *read++;
      }
    } else {
      /* weird character, error */
      goto beach;
    }
  }
  /* if the string is not ending in " and zero terminated, we error */
  if (*read != '"' || read[1] != '\0')
    goto beach;

  /* null terminate result string and return */
  *write = '\0';
  return ret;

beach:
  g_free (ret);
  return NULL;
}

static gchar *
gst_value_serialize_string (const GValue * value)
{
  return gst_string_wrap (value->data[0].v_pointer);
}

static gboolean
gst_value_deserialize_string (GValue * dest, const gchar * s)
{
  if (G_UNLIKELY (strcmp (s, "NULL") == 0)) {
    g_value_set_string (dest, NULL);
    return TRUE;
  } else if (G_LIKELY (*s != '"' || s[strlen (s) - 1] != '"')) {
    if (!g_utf8_validate (s, -1, NULL))
      return FALSE;
    g_value_set_string (dest, s);
    return TRUE;
  } else {
    /* strings delimited with double quotes should be unwrapped */
    gchar *str = gst_string_unwrap (s);
    if (G_UNLIKELY (!str))
      return FALSE;
    g_value_take_string (dest, str);
  }

  return TRUE;
}

/********
 * enum *
 ********/

static gint
gst_value_compare_enum (const GValue * value1, const GValue * value2)
{
  GEnumValue *en1, *en2;
  GEnumClass *klass1 = (GEnumClass *) g_type_class_ref (G_VALUE_TYPE (value1));
  GEnumClass *klass2 = (GEnumClass *) g_type_class_ref (G_VALUE_TYPE (value2));

  g_return_val_if_fail (klass1, GST_VALUE_UNORDERED);
  g_return_val_if_fail (klass2, GST_VALUE_UNORDERED);
  en1 = g_enum_get_value (klass1, g_value_get_enum (value1));
  en2 = g_enum_get_value (klass2, g_value_get_enum (value2));
  g_type_class_unref (klass1);
  g_type_class_unref (klass2);
  g_return_val_if_fail (en1, GST_VALUE_UNORDERED);
  g_return_val_if_fail (en2, GST_VALUE_UNORDERED);
  if (en1->value < en2->value)
    return GST_VALUE_LESS_THAN;
  if (en1->value > en2->value)
    return GST_VALUE_GREATER_THAN;

  return GST_VALUE_EQUAL;
}

static gchar *
gst_value_serialize_enum (const GValue * value)
{
  GEnumValue *en;
  GEnumClass *klass = (GEnumClass *) g_type_class_ref (G_VALUE_TYPE (value));

  g_return_val_if_fail (klass, NULL);
  en = g_enum_get_value (klass, g_value_get_enum (value));
  g_type_class_unref (klass);

  /* might be one of the custom formats registered later */
  if (G_UNLIKELY (en == NULL && G_VALUE_TYPE (value) == GST_TYPE_FORMAT)) {
    const GstFormatDefinition *format_def;

    format_def = gst_format_get_details ((GstFormat) g_value_get_enum (value));
    g_return_val_if_fail (format_def != NULL, NULL);
    return g_strdup (format_def->description);
  }

  g_return_val_if_fail (en, NULL);
  return g_strdup (en->value_name);
}

static gint
gst_value_deserialize_enum_iter_cmp (const GValue * format_def_value,
    const gchar * s)
{
  const GstFormatDefinition *format_def =
      g_value_get_pointer (format_def_value);

  if (g_ascii_strcasecmp (s, format_def->nick) == 0)
    return 0;

  return g_ascii_strcasecmp (s, format_def->description);
}

static gboolean
gst_value_deserialize_enum (GValue * dest, const gchar * s)
{
  GEnumValue *en;
  gchar *endptr = NULL;
  GEnumClass *klass = (GEnumClass *) g_type_class_ref (G_VALUE_TYPE (dest));

  g_return_val_if_fail (klass, FALSE);
  if (!(en = g_enum_get_value_by_name (klass, s))) {
    if (!(en = g_enum_get_value_by_nick (klass, s))) {
      gint i = strtol (s, &endptr, 0);

      if (endptr && *endptr == '\0') {
        en = g_enum_get_value (klass, i);
      }
    }
  }
  g_type_class_unref (klass);

  /* might be one of the custom formats registered later */
  if (G_UNLIKELY (en == NULL && G_VALUE_TYPE (dest) == GST_TYPE_FORMAT)) {
    GValue res = { 0, };
    const GstFormatDefinition *format_def;
    GstIterator *iter;
    gboolean found;

    iter = gst_format_iterate_definitions ();

    found = gst_iterator_find_custom (iter,
        (GCompareFunc) gst_value_deserialize_enum_iter_cmp, &res, (gpointer) s);

    if (found) {
      format_def = g_value_get_pointer (&res);
      g_return_val_if_fail (format_def != NULL, FALSE);
      g_value_set_enum (dest, (gint) format_def->value);
      g_value_unset (&res);
    }
    gst_iterator_free (iter);
    return found;
  }

  /* enum name/nick not found */
  if (en == NULL)
    return FALSE;

  g_value_set_enum (dest, en->value);
  return TRUE;
}

/********
 * flags *
 ********/

/* we just compare the value here */
static gint
gst_value_compare_gflags (const GValue * value1, const GValue * value2)
{
  guint fl1, fl2;
  GFlagsClass *klass1 =
      (GFlagsClass *) g_type_class_ref (G_VALUE_TYPE (value1));
  GFlagsClass *klass2 =
      (GFlagsClass *) g_type_class_ref (G_VALUE_TYPE (value2));

  g_return_val_if_fail (klass1, GST_VALUE_UNORDERED);
  g_return_val_if_fail (klass2, GST_VALUE_UNORDERED);
  fl1 = g_value_get_flags (value1);
  fl2 = g_value_get_flags (value2);
  g_type_class_unref (klass1);
  g_type_class_unref (klass2);
  if (fl1 < fl2)
    return GST_VALUE_LESS_THAN;
  if (fl1 > fl2)
    return GST_VALUE_GREATER_THAN;

  return GST_VALUE_EQUAL;
}

/* the different flags are serialized separated with a + */
static gchar *
gst_value_serialize_gflags (const GValue * value)
{
  guint flags;
  GFlagsValue *fl;
  GFlagsClass *klass = (GFlagsClass *) g_type_class_ref (G_VALUE_TYPE (value));
  gchar *result, *tmp;
  gboolean first = TRUE;

  g_return_val_if_fail (klass, NULL);

  flags = g_value_get_flags (value);

  /* if no flags are set, try to serialize to the _NONE string */
  if (!flags) {
    fl = g_flags_get_first_value (klass, flags);
    if (fl)
      return g_strdup (fl->value_name);
    else
      return g_strdup ("0");
  }

  /* some flags are set, so serialize one by one */
  result = g_strdup ("");
  while (flags) {
    fl = g_flags_get_first_value (klass, flags);
    if (fl != NULL) {
      tmp = g_strconcat (result, (first ? "" : "+"), fl->value_name, NULL);
      g_free (result);
      result = tmp;
      first = FALSE;

      /* clear flag */
      flags &= ~fl->value;
    }
  }
  g_type_class_unref (klass);

  return result;
}

static gboolean
gst_value_gflags_str_to_flags (GFlagsClass * klass, const gchar * s,
    guint * out_flags, guint * out_mask)
{
  GFlagsValue *fl;
  gchar delimiter;
  const gchar *pos = NULL;
  const gchar *next;
  gchar *cur_str, *endptr;
  guint flags = 0;
  guint mask = 0;
  guint val;

  g_return_val_if_fail (klass, FALSE);

  /* split into parts delimited with + or / and
   * compose the set of flags and mask. */
  pos = s;

  if (*pos == '\0')
    goto done;                  /* Empty string, nothing to do */

  /* As a special case if the first char isn't a delimiter, assume
   * it's a '+' - for GFlags strings, which don't start with a
   * delimiter, while GFlagSet always will */
  if (*pos == '/' || *pos == '+') {
    delimiter = *pos;
    pos++;
  } else {
    delimiter = '+';
  }

  do {
    /* Find the next delimiter */
    next = pos;
    while (*next != '\0' && *next != '+' && *next != '/')
      next++;
    cur_str = g_strndup (pos, next - pos);

    if ((fl = g_flags_get_value_by_name (klass, cur_str)))
      val = fl->value;
    else if ((fl = g_flags_get_value_by_nick (klass, cur_str)))
      val = fl->value;
    else {
      val = strtoul (cur_str, &endptr, 0);
      /* direct numeric value */
      if (endptr == NULL || *endptr != '\0') {
        g_free (cur_str);
        return FALSE;           /* Invalid numeric or string we can't convert */
      }
    }
    g_free (cur_str);

    if (val) {
      mask |= val;
      if (delimiter == '+')
        flags |= val;
    }

    /* Advance to the next delimiter */
    pos = next;
    delimiter = *pos;
    pos++;
  } while (delimiter != '\0');

done:
  if (out_flags)
    *out_flags = flags;
  if (out_mask)
    *out_mask = mask;

  return TRUE;
}


static gboolean
gst_value_deserialize_gflags (GValue * dest, const gchar * s)
{
  GFlagsClass *klass = (GFlagsClass *) g_type_class_ref (G_VALUE_TYPE (dest));
  gboolean res = FALSE;
  guint flags = 0;

  if (gst_value_gflags_str_to_flags (klass, s, &flags, NULL)) {
    g_value_set_flags (dest, flags);
    res = TRUE;
  }

  g_type_class_unref (klass);

  return res;
}

/*********
 * gtype *
 *********/

static gint
gst_value_compare_gtype (const GValue * value1, const GValue * value2)
{
  if (value1->data[0].v_pointer == value2->data[0].v_pointer)
    return GST_VALUE_EQUAL;
  return GST_VALUE_UNORDERED;
}

static gchar *
gst_value_serialize_gtype (const GValue * value)
{
  return g_strdup (g_type_name (g_value_get_gtype (value)));
}

static gboolean
gst_value_deserialize_gtype (GValue * dest, const gchar * s)
{
  GType t = g_type_from_name (s);
  gboolean ret = TRUE;

  if (t == G_TYPE_INVALID)
    ret = FALSE;
  if (ret) {
    g_value_set_gtype (dest, t);
  }
  return ret;
}

/****************
 * subset *
 ****************/

static gboolean
gst_value_is_subset_int_range_int_range (const GValue * value1,
    const GValue * value2)
{
  gint gcd;

  g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value2), FALSE);

  if (INT_RANGE_MIN (value1) * INT_RANGE_STEP (value1) <
      INT_RANGE_MIN (value2) * INT_RANGE_STEP (value2))
    return FALSE;
  if (INT_RANGE_MAX (value1) * INT_RANGE_STEP (value1) >
      INT_RANGE_MAX (value2) * INT_RANGE_STEP (value2))
    return FALSE;

  if (INT_RANGE_MIN (value2) == INT_RANGE_MAX (value2)) {
    if ((INT_RANGE_MIN (value2) * INT_RANGE_STEP (value2)) %
        INT_RANGE_STEP (value1))
      return FALSE;
    return TRUE;
  }

  gcd =
      gst_util_greatest_common_divisor (INT_RANGE_STEP (value1),
      INT_RANGE_STEP (value2));
  if (gcd != MIN (INT_RANGE_STEP (value1), INT_RANGE_STEP (value2)))
    return FALSE;

  return TRUE;
}

static gboolean
gst_value_is_subset_int64_range_int64_range (const GValue * value1,
    const GValue * value2)
{
  gint64 gcd;

  g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value2), FALSE);

  if (INT64_RANGE_MIN (value1) < INT64_RANGE_MIN (value2))
    return FALSE;
  if (INT64_RANGE_MAX (value1) > INT64_RANGE_MAX (value2))
    return FALSE;

  if (INT64_RANGE_MIN (value2) == INT64_RANGE_MAX (value2)) {
    if ((INT64_RANGE_MIN (value2) * INT64_RANGE_STEP (value2)) %
        INT64_RANGE_STEP (value1))
      return FALSE;
    return TRUE;
  }

  gcd =
      gst_util_greatest_common_divisor_int64 (INT64_RANGE_STEP (value1),
      INT64_RANGE_STEP (value2));
  if (gcd != MIN (INT64_RANGE_STEP (value1), INT64_RANGE_STEP (value2)))
    return FALSE;

  return TRUE;
}

/* A flag set is a subset of another if the superset allows the
 * flags of the subset */
static gboolean
gst_value_is_subset_flagset_flagset (const GValue * value1,
    const GValue * value2)
{
  guint f1, f2;
  guint m1, m2;

  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (value1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (value2), FALSE);

  f1 = value1->data[0].v_uint;
  f2 = value2->data[0].v_uint;

  m1 = value1->data[1].v_uint;
  m2 = value2->data[1].v_uint;

  /* Not a subset if masked bits of superset disagree */
  if ((f1 & m1) != (f2 & (m1 & m2)))
    return FALSE;

  return TRUE;
}

static gboolean
gst_value_is_subset_structure_structure (const GValue * value1,
    const GValue * value2)
{
  const GstStructure *s1, *s2;

  g_return_val_if_fail (GST_VALUE_HOLDS_STRUCTURE (value1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_STRUCTURE (value2), FALSE);

  s1 = gst_value_get_structure (value1);
  s2 = gst_value_get_structure (value2);

  return gst_structure_is_subset (s1, s2);
}

/**
 * gst_value_is_subset:
 * @value1: a #GValue
 * @value2: a #GValue
 *
 * Check that @value1 is a subset of @value2.
 *
 * Return: %TRUE is @value1 is a subset of @value2
 */
gboolean
gst_value_is_subset (const GValue * value1, const GValue * value2)
{
  /* special case for int/int64 ranges, since we cannot compute
     the difference for those when they have different steps,
     and it's actually a lot simpler to compute whether a range
     is a subset of another. */
  if (GST_VALUE_HOLDS_INT_RANGE (value1) && GST_VALUE_HOLDS_INT_RANGE (value2)) {
    return gst_value_is_subset_int_range_int_range (value1, value2);
  } else if (GST_VALUE_HOLDS_INT64_RANGE (value1)
      && GST_VALUE_HOLDS_INT64_RANGE (value2)) {
    return gst_value_is_subset_int64_range_int64_range (value1, value2);
  } else if (GST_VALUE_HOLDS_FLAG_SET (value1) &&
      GST_VALUE_HOLDS_FLAG_SET (value2)) {
    return gst_value_is_subset_flagset_flagset (value1, value2);
  } else if (GST_VALUE_HOLDS_STRUCTURE (value1)
      && GST_VALUE_HOLDS_STRUCTURE (value2)) {
    return gst_value_is_subset_structure_structure (value1, value2);
  }

  /*
   * 1 - [1,2] = empty
   * -> !subset
   *
   * [1,2] - 1 = 2
   *  -> 1 - [1,2] = empty
   *  -> subset
   *
   * [1,3] - [1,2] = 3
   * -> [1,2] - [1,3] = empty
   * -> subset
   *
   * {1,2} - {1,3} = 2
   * -> {1,3} - {1,2} = 3
   * -> !subset
   *
   *  First caps subtraction needs to return a non-empty set, second
   *  subtractions needs to give en empty set.
   *  Both substractions are switched below, as it's faster that way.
   */
  if (!gst_value_subtract (NULL, value1, value2)) {
    if (gst_value_subtract (NULL, value2, value1)) {
      return TRUE;
    }
  }
  return FALSE;
}

/*********
 * union *
 *********/

static gboolean
gst_value_union_int_int_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  gint v = src1->data[0].v_int;

  /* check if it's already in the range */
  if (INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2) <= v &&
      INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2) >= v &&
      v % INT_RANGE_STEP (src2) == 0) {
    if (dest)
      gst_value_init_and_copy (dest, src2);
    return TRUE;
  }

  /* check if it extends the range */
  if (v == (INT_RANGE_MIN (src2) - 1) * INT_RANGE_STEP (src2)) {
    if (dest) {
      guint64 new_min = INT_RANGE_MIN (src2) - 1;
      guint64 new_max = INT_RANGE_MAX (src2);

      gst_value_init_and_copy (dest, src2);
      dest->data[0].v_uint64 = (new_min << 32) | (new_max);
    }
    return TRUE;
  }
  if (v == (INT_RANGE_MAX (src2) + 1) * INT_RANGE_STEP (src2)) {
    if (dest) {
      guint64 new_min = INT_RANGE_MIN (src2);
      guint64 new_max = INT_RANGE_MAX (src2) + 1;

      gst_value_init_and_copy (dest, src2);
      dest->data[0].v_uint64 = (new_min << 32) | (new_max);
    }
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_value_union_int_range_int_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  /* We can union in several special cases:
     1 - one is a subset of another
     2 - same step and not disjoint
     3 - different step, at least one with one value which matches a 'next' or 'previous'
     - anything else ?
   */

  /* 1 - subset */
  if (gst_value_is_subset_int_range_int_range (src1, src2)) {
    if (dest)
      gst_value_init_and_copy (dest, src2);
    return TRUE;
  }
  if (gst_value_is_subset_int_range_int_range (src2, src1)) {
    if (dest)
      gst_value_init_and_copy (dest, src1);
    return TRUE;
  }

  /* 2 - same step and not disjoint */
  if (INT_RANGE_STEP (src1) == INT_RANGE_STEP (src2)) {
    if ((INT_RANGE_MIN (src1) <= INT_RANGE_MAX (src2) + 1 &&
            INT_RANGE_MAX (src1) >= INT_RANGE_MIN (src2) - 1) ||
        (INT_RANGE_MIN (src2) <= INT_RANGE_MAX (src1) + 1 &&
            INT_RANGE_MAX (src2) >= INT_RANGE_MIN (src1) - 1)) {
      if (dest) {
        gint step = INT_RANGE_STEP (src1);
        gint min = step * MIN (INT_RANGE_MIN (src1), INT_RANGE_MIN (src2));
        gint max = step * MAX (INT_RANGE_MAX (src1), INT_RANGE_MAX (src2));
        g_value_init (dest, GST_TYPE_INT_RANGE);
        gst_value_set_int_range_step (dest, min, max, step);
      }
      return TRUE;
    }
  }

  /* 3 - single value matches next or previous */
  if (INT_RANGE_STEP (src1) != INT_RANGE_STEP (src2)) {
    gint n1 = INT_RANGE_MAX (src1) - INT_RANGE_MIN (src1) + 1;
    gint n2 = INT_RANGE_MAX (src2) - INT_RANGE_MIN (src2) + 1;
    if (n1 == 1 || n2 == 1) {
      const GValue *range_value = NULL;
      gint scalar = 0;
      if (n1 == 1) {
        range_value = src2;
        scalar = INT_RANGE_MIN (src1) * INT_RANGE_STEP (src1);
      } else if (n2 == 1) {
        range_value = src1;
        scalar = INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2);
      }

      if (scalar ==
          (INT_RANGE_MIN (range_value) - 1) * INT_RANGE_STEP (range_value)) {
        if (dest) {
          guint64 new_min = (guint)
              ((INT_RANGE_MIN (range_value) -
                  1) * INT_RANGE_STEP (range_value));
          guint64 new_max = (guint)
              (INT_RANGE_MAX (range_value) * INT_RANGE_STEP (range_value));

          gst_value_init_and_copy (dest, range_value);
          dest->data[0].v_uint64 = (new_min << 32) | (new_max);
        }
        return TRUE;
      } else if (scalar ==
          (INT_RANGE_MAX (range_value) + 1) * INT_RANGE_STEP (range_value)) {
        if (dest) {
          guint64 new_min = (guint)
              (INT_RANGE_MIN (range_value) * INT_RANGE_STEP (range_value));
          guint64 new_max = (guint)
              ((INT_RANGE_MAX (range_value) +
                  1) * INT_RANGE_STEP (range_value));
          gst_value_init_and_copy (dest, range_value);
          dest->data[0].v_uint64 = (new_min << 32) | (new_max);
        }
        return TRUE;
      }
    }
  }

  /* If we get there, we did not find a way to make a union that can be
     represented with our simplistic model. */
  return FALSE;
}

static gboolean
gst_value_union_flagset_flagset (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  /* We can union 2 flag sets where they do not disagree on
   * required (masked) flag bits */
  guint64 f1, f2;
  guint64 m1, m2;

  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (src1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (src2), FALSE);

  f1 = src1->data[0].v_uint;
  f2 = src2->data[0].v_uint;

  m1 = src1->data[1].v_uint;
  m2 = src2->data[1].v_uint;

  /* Can't union if masked bits disagree */
  if ((f1 & (m1 & m2)) != (f2 & (m1 & m2)))
    return FALSE;

  if (dest) {
    g_value_init (dest, GST_TYPE_FLAG_SET);
    /* Copy masked bits from src2 to src1 */
    f1 &= ~m2;
    f1 |= (f2 & m2);
    m1 |= m2;
    gst_value_set_flagset (dest, f1, m1);
  }

  return TRUE;
}

/* iterating over the result taking the union with the other structure's value */
static gboolean
structure_field_union_into (GQuark field_id, GValue * val, gpointer user_data)
{
  GstStructure *other = user_data;
  const GValue *other_value;
  GValue res_value = G_VALUE_INIT;

  other_value = gst_structure_id_get_value (other, field_id);
  /* no value in the other struct, just keep this value */
  if (!other_value)
    return TRUE;

  if (!gst_value_union (&res_value, val, other_value))
    return FALSE;

  g_value_unset (val);
  gst_value_move (val, &res_value);
  return TRUE;
}

/* iterating over the other source structure adding missing values */
static gboolean
structure_field_union_from (GQuark field_id, const GValue * other_val,
    gpointer user_data)
{
  GstStructure *result = user_data;
  const GValue *result_value;

  result_value = gst_structure_id_get_value (result, field_id);
  if (!result_value)
    gst_structure_id_set_value (result, field_id, other_val);

  return TRUE;
}

static gboolean
gst_value_union_structure_structure (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  const GstStructure *s1, *s2;
  GstStructure *result;
  gboolean ret;

  g_return_val_if_fail (GST_VALUE_HOLDS_STRUCTURE (src1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_STRUCTURE (src2), FALSE);

  s1 = gst_value_get_structure (src1);
  s2 = gst_value_get_structure (src2);

  /* Can't join two structures with different names into a single structure */
  if (!gst_structure_has_name (s1, gst_structure_get_name (s2))) {
    gst_value_list_concat (dest, src1, src2);
    return TRUE;
  }

  result = gst_structure_copy (s1);
  ret =
      gst_structure_map_in_place (result, structure_field_union_into,
      (gpointer) s2);
  if (!ret)
    goto out;
  ret =
      gst_structure_foreach (s2, structure_field_union_from, (gpointer) result);

  if (ret) {
    g_value_init (dest, GST_TYPE_STRUCTURE);
    gst_value_set_structure (dest, result);
  }

out:
  gst_structure_free (result);
  return ret;
}

/****************
 * intersection *
 ****************/

static gboolean
gst_value_intersect_int_int_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  if (INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2) <= src1->data[0].v_int &&
      INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2) >= src1->data[0].v_int &&
      src1->data[0].v_int % INT_RANGE_STEP (src2) == 0) {
    if (dest)
      gst_value_init_and_copy (dest, src1);
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_value_intersect_int_range_int_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  gint min;
  gint max;
  gint step;

  step =
      INT_RANGE_STEP (src1) /
      gst_util_greatest_common_divisor (INT_RANGE_STEP (src1),
      INT_RANGE_STEP (src2));
  if (G_MAXINT32 / INT_RANGE_STEP (src2) < step)
    return FALSE;
  step *= INT_RANGE_STEP (src2);

  min =
      MAX (INT_RANGE_MIN (src1) * INT_RANGE_STEP (src1),
      INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2));
  min = (min + step - 1) / step * step;
  max =
      MIN (INT_RANGE_MAX (src1) * INT_RANGE_STEP (src1),
      INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2));
  max = max / step * step;

  if (min < max) {
    if (dest) {
      g_value_init (dest, GST_TYPE_INT_RANGE);
      gst_value_set_int_range_step (dest, min, max, step);
    }
    return TRUE;
  }
  if (min == max) {
    if (dest) {
      g_value_init (dest, G_TYPE_INT);
      g_value_set_int (dest, min);
    }
    return TRUE;
  }

  return FALSE;
}

#define INT64_RANGE_MIN_VAL(v) (INT64_RANGE_MIN (v) * INT64_RANGE_STEP (v))
#define INT64_RANGE_MAX_VAL(v) (INT64_RANGE_MAX (v) * INT64_RANGE_STEP (v))

static gboolean
gst_value_intersect_int64_int64_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  if (INT64_RANGE_MIN_VAL (src2) <= src1->data[0].v_int64 &&
      INT64_RANGE_MAX_VAL (src2) >= src1->data[0].v_int64 &&
      src1->data[0].v_int64 % INT64_RANGE_STEP (src2) == 0) {
    if (dest)
      gst_value_init_and_copy (dest, src1);
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_value_intersect_int64_range_int64_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  gint64 min;
  gint64 max;
  gint64 step;

  step =
      INT64_RANGE_STEP (src1) /
      gst_util_greatest_common_divisor_int64 (INT64_RANGE_STEP (src1),
      INT64_RANGE_STEP (src2));
  if (G_MAXINT64 / INT64_RANGE_STEP (src2) < step)
    return FALSE;
  step *= INT64_RANGE_STEP (src2);

  min =
      MAX (INT64_RANGE_MIN (src1) * INT64_RANGE_STEP (src1),
      INT64_RANGE_MIN (src2) * INT64_RANGE_STEP (src2));
  min = (min + step - 1) / step * step;
  max =
      MIN (INT64_RANGE_MAX (src1) * INT64_RANGE_STEP (src1),
      INT64_RANGE_MAX (src2) * INT64_RANGE_STEP (src2));
  max = max / step * step;

  if (min < max) {
    if (dest) {
      g_value_init (dest, GST_TYPE_INT64_RANGE);
      gst_value_set_int64_range_step (dest, min, max, step);
    }
    return TRUE;
  }
  if (min == max) {
    if (dest) {
      g_value_init (dest, G_TYPE_INT64);
      g_value_set_int64 (dest, min);
    }
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_value_intersect_double_double_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  if (src2->data[0].v_double <= src1->data[0].v_double &&
      src2->data[1].v_double >= src1->data[0].v_double) {
    if (dest)
      gst_value_init_and_copy (dest, src1);
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_value_intersect_double_range_double_range (GValue * dest,
    const GValue * src1, const GValue * src2)
{
  gdouble min;
  gdouble max;

  min = MAX (src1->data[0].v_double, src2->data[0].v_double);
  max = MIN (src1->data[1].v_double, src2->data[1].v_double);

  if (min < max) {
    if (dest) {
      g_value_init (dest, GST_TYPE_DOUBLE_RANGE);
      gst_value_set_double_range (dest, min, max);
    }
    return TRUE;
  }
  if (min == max) {
    if (dest) {
      g_value_init (dest, G_TYPE_DOUBLE);
      g_value_set_int (dest, (int) min);
    }
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_value_intersect_list (GValue * dest, const GValue * value1,
    const GValue * value2)
{
  guint i, size;
  GValue intersection = { 0, };
  gboolean ret = FALSE;

  size = VALUE_LIST_SIZE (value1);
  for (i = 0; i < size; i++) {
    const GValue *cur = VALUE_LIST_GET_VALUE (value1, i);

    /* quicker version when we don't need the resulting set */
    if (!dest) {
      if (gst_value_intersect (NULL, cur, value2)) {
        ret = TRUE;
        break;
      }
      continue;
    }

    if (gst_value_intersect (&intersection, cur, value2)) {
      /* append value */
      if (!ret) {
        gst_value_move (dest, &intersection);
        ret = TRUE;
      } else if (GST_VALUE_HOLDS_LIST (dest)) {
        _gst_value_list_append_and_take_value (dest, &intersection);
      } else {
        GValue temp;

        gst_value_move (&temp, dest);
        gst_value_list_merge (dest, &temp, &intersection);
        g_value_unset (&temp);
        g_value_unset (&intersection);
      }
    }
  }

  return ret;
}

static gboolean
gst_value_intersect_array (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  guint size;
  guint n;
  GValue val = { 0 };

  /* only works on similar-sized arrays */
  size = gst_value_array_get_size (src1);
  if (size != gst_value_array_get_size (src2))
    return FALSE;

  /* quicker value when we don't need the resulting set */
  if (!dest) {
    for (n = 0; n < size; n++) {
      if (!gst_value_intersect (NULL, gst_value_array_get_value (src1, n),
              gst_value_array_get_value (src2, n))) {
        return FALSE;
      }
    }
    return TRUE;
  }

  g_value_init (dest, GST_TYPE_ARRAY);

  for (n = 0; n < size; n++) {
    if (!gst_value_intersect (&val, gst_value_array_get_value (src1, n),
            gst_value_array_get_value (src2, n))) {
      g_value_unset (dest);
      return FALSE;
    }
    _gst_value_array_append_and_take_value (dest, &val);
  }

  return TRUE;
}

static gboolean
gst_value_intersect_fraction_fraction_range (GValue * dest, const GValue * src1,
    const GValue * src2)
{
  gint res1, res2;
  GValue *vals;
  GstValueCompareFunc compare;

  vals = src2->data[0].v_pointer;

  if (vals == NULL)
    return FALSE;

  if ((compare = gst_value_get_compare_func (src1))) {
    res1 = gst_value_compare_with_func (&vals[0], src1, compare);
    res2 = gst_value_compare_with_func (&vals[1], src1, compare);

    if ((res1 == GST_VALUE_EQUAL || res1 == GST_VALUE_LESS_THAN) &&
        (res2 == GST_VALUE_EQUAL || res2 == GST_VALUE_GREATER_THAN)) {
      if (dest)
        gst_value_init_and_copy (dest, src1);
      return TRUE;
    }
  }

  return FALSE;
}

static gboolean
gst_value_intersect_fraction_range_fraction_range (GValue * dest,
    const GValue * src1, const GValue * src2)
{
  GValue *min;
  GValue *max;
  gint res;
  GValue *vals1, *vals2;
  GstValueCompareFunc compare;

  vals1 = src1->data[0].v_pointer;
  vals2 = src2->data[0].v_pointer;
  g_return_val_if_fail (vals1 != NULL && vals2 != NULL, FALSE);

  if ((compare = gst_value_get_compare_func (&vals1[0]))) {
    /* min = MAX (src1.start, src2.start) */
    res = gst_value_compare_with_func (&vals1[0], &vals2[0], compare);
    g_return_val_if_fail (res != GST_VALUE_UNORDERED, FALSE);
    if (res == GST_VALUE_LESS_THAN)
      min = &vals2[0];          /* Take the max of the 2 */
    else
      min = &vals1[0];

    /* max = MIN (src1.end, src2.end) */
    res = gst_value_compare_with_func (&vals1[1], &vals2[1], compare);
    g_return_val_if_fail (res != GST_VALUE_UNORDERED, FALSE);
    if (res == GST_VALUE_GREATER_THAN)
      max = &vals2[1];          /* Take the min of the 2 */
    else
      max = &vals1[1];

    res = gst_value_compare_with_func (min, max, compare);
    g_return_val_if_fail (res != GST_VALUE_UNORDERED, FALSE);
    if (res == GST_VALUE_LESS_THAN) {
      if (dest) {
        g_value_init (dest, GST_TYPE_FRACTION_RANGE);
        vals1 = dest->data[0].v_pointer;
        g_value_copy (min, &vals1[0]);
        g_value_copy (max, &vals1[1]);
      }
      return TRUE;
    }
    if (res == GST_VALUE_EQUAL) {
      if (dest)
        gst_value_init_and_copy (dest, min);
      return TRUE;
    }
  }

  return FALSE;
}

/* Two flagsets intersect if the masked bits in both
 * flagsets are exactly equal */
static gboolean
gst_value_intersect_flagset_flagset (GValue * dest,
    const GValue * src1, const GValue * src2)
{
  guint f1, f2;
  guint m1, m2;
  GType type1, type2, flagset_type;

  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (src1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (src2), FALSE);

  f1 = src1->data[0].v_uint;
  f2 = src2->data[0].v_uint;

  m1 = src1->data[1].v_uint;
  m2 = src2->data[1].v_uint;

  /* Don't intersect if masked bits disagree */
  if ((f1 & (m1 & m2)) != (f2 & (m1 & m2)))
    return FALSE;

  /* Allow intersection with the generic FlagSet type, on one
   * side, but not 2 different subtypes - that makes no sense */
  type1 = G_VALUE_TYPE (src1);
  type2 = G_VALUE_TYPE (src2);
  flagset_type = GST_TYPE_FLAG_SET;

  if (type1 != type2 && type1 != flagset_type && type2 != flagset_type)
    return FALSE;

  if (dest) {
    GType dest_type;

    /* Prefer an output type that matches a sub-type,
     * rather than the generic type */
    if (type1 != flagset_type)
      dest_type = type1;
    else
      dest_type = type2;

    g_value_init (dest, dest_type);

    /* The compatible set is all the bits from src1 that it
     * cares about and all the bits from src2 that it cares
     * about. */
    dest->data[0].v_uint = (f1 & m1) | (f2 & m2);
    dest->data[1].v_uint = m1 | m2;
  }

  return TRUE;
}

static gboolean
gst_value_intersect_structure_structure (GValue * dest,
    const GValue * src1, const GValue * src2)
{
  const GstStructure *s1, *s2;
  GstStructure *d1;

  s1 = gst_value_get_structure (src1);
  s2 = gst_value_get_structure (src2);

  d1 = gst_structure_intersect (s1, s2);
  if (!d1)
    return FALSE;

  if (dest) {
    g_value_init (dest, GST_TYPE_STRUCTURE);
    gst_value_set_structure (dest, d1);
  }

  gst_structure_free (d1);
  return TRUE;
}

/***************
 * subtraction *
 ***************/

static gboolean
gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gint min = gst_value_get_int_range_min (subtrahend);
  gint max = gst_value_get_int_range_max (subtrahend);
  gint step = gst_value_get_int_range_step (subtrahend);
  gint val = g_value_get_int (minuend);

  if (step == 0)
    return FALSE;

  /* subtracting a range from an int only works if the int is not in the
   * range */
  if (val < min || val > max || val % step) {
    /* and the result is the int */
    if (dest)
      gst_value_init_and_copy (dest, minuend);
    return TRUE;
  }
  return FALSE;
}

/* creates a new int range based on input values.
 */
static gboolean
gst_value_create_new_range (GValue * dest, gint min1, gint max1, gint min2,
    gint max2, gint step)
{
  GValue v1 = { 0, };
  GValue v2 = { 0, };
  GValue *pv1, *pv2;            /* yeah, hungarian! */

  g_return_val_if_fail (step > 0, FALSE);
  g_return_val_if_fail (min1 % step == 0, FALSE);
  g_return_val_if_fail (max1 % step == 0, FALSE);
  g_return_val_if_fail (min2 % step == 0, FALSE);
  g_return_val_if_fail (max2 % step == 0, FALSE);

  if (min1 <= max1 && min2 <= max2) {
    pv1 = &v1;
    pv2 = &v2;
  } else if (min1 <= max1) {
    pv1 = dest;
    pv2 = NULL;
  } else if (min2 <= max2) {
    pv1 = NULL;
    pv2 = dest;
  } else {
    return FALSE;
  }

  if (!dest)
    return TRUE;

  if (min1 < max1) {
    g_value_init (pv1, GST_TYPE_INT_RANGE);
    gst_value_set_int_range_step (pv1, min1, max1, step);
  } else if (min1 == max1) {
    g_value_init (pv1, G_TYPE_INT);
    g_value_set_int (pv1, min1);
  }
  if (min2 < max2) {
    g_value_init (pv2, GST_TYPE_INT_RANGE);
    gst_value_set_int_range_step (pv2, min2, max2, step);
  } else if (min2 == max2) {
    g_value_init (pv2, G_TYPE_INT);
    g_value_set_int (pv2, min2);
  }

  if (min1 <= max1 && min2 <= max2) {
    gst_value_list_concat_and_take_values (dest, pv1, pv2);
  }
  return TRUE;
}

static gboolean
gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gint min = gst_value_get_int_range_min (minuend);
  gint max = gst_value_get_int_range_max (minuend);
  gint step = gst_value_get_int_range_step (minuend);
  gint val = g_value_get_int (subtrahend);

  g_return_val_if_fail (min < max, FALSE);

  if (step == 0)
    return FALSE;

  /* value is outside of the range, return range unchanged */
  if (val < min || val > max || val % step) {
    if (dest)
      gst_value_init_and_copy (dest, minuend);
    return TRUE;
  } else {
    /* max must be MAXINT too as val <= max */
    if (val >= G_MAXINT - step + 1) {
      max -= step;
      val -= step;
    }
    /* min must be MININT too as val >= max */
    if (val <= G_MININT + step - 1) {
      min += step;
      val += step;
    }
    if (dest)
      gst_value_create_new_range (dest, min, val - step, val + step, max, step);
  }
  return TRUE;
}

static gboolean
gst_value_subtract_int_range_int_range (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gint min1 = gst_value_get_int_range_min (minuend);
  gint max1 = gst_value_get_int_range_max (minuend);
  gint step1 = gst_value_get_int_range_step (minuend);
  gint min2 = gst_value_get_int_range_min (subtrahend);
  gint max2 = gst_value_get_int_range_max (subtrahend);
  gint step2 = gst_value_get_int_range_step (subtrahend);
  gint step;

  if (step1 != step2) {
    /* ENOIMPL */
    g_assert (FALSE);
    return FALSE;
  }
  step = step1;

  if (step == 0)
    return FALSE;

  if (max2 >= max1 && min2 <= min1) {
    return FALSE;
  } else if (max2 >= max1) {
    return gst_value_create_new_range (dest, min1, MIN (min2 - step, max1),
        step, 0, step);
  } else if (min2 <= min1) {
    return gst_value_create_new_range (dest, MAX (max2 + step, min1), max1,
        step, 0, step);
  } else {
    return gst_value_create_new_range (dest, min1, MIN (min2 - step, max1),
        MAX (max2 + step, min1), max1, step);
  }
}

static gboolean
gst_value_subtract_int64_int64_range (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gint64 min = gst_value_get_int64_range_min (subtrahend);
  gint64 max = gst_value_get_int64_range_max (subtrahend);
  gint64 step = gst_value_get_int64_range_step (subtrahend);
  gint64 val = g_value_get_int64 (minuend);

  if (step == 0)
    return FALSE;
  /* subtracting a range from an int64 only works if the int64 is not in the
   * range */
  if (val < min || val > max || val % step) {
    /* and the result is the int64 */
    if (dest)
      gst_value_init_and_copy (dest, minuend);
    return TRUE;
  }
  return FALSE;
}

/* creates a new int64 range based on input values.
 */
static gboolean
gst_value_create_new_int64_range (GValue * dest, gint64 min1, gint64 max1,
    gint64 min2, gint64 max2, gint64 step)
{
  GValue v1 = { 0, };
  GValue v2 = { 0, };
  GValue *pv1, *pv2;            /* yeah, hungarian! */

  g_return_val_if_fail (step > 0, FALSE);
  g_return_val_if_fail (min1 % step == 0, FALSE);
  g_return_val_if_fail (max1 % step == 0, FALSE);
  g_return_val_if_fail (min2 % step == 0, FALSE);
  g_return_val_if_fail (max2 % step == 0, FALSE);

  if (min1 <= max1 && min2 <= max2) {
    pv1 = &v1;
    pv2 = &v2;
  } else if (min1 <= max1) {
    pv1 = dest;
    pv2 = NULL;
  } else if (min2 <= max2) {
    pv1 = NULL;
    pv2 = dest;
  } else {
    return FALSE;
  }

  if (!dest)
    return TRUE;

  if (min1 < max1) {
    g_value_init (pv1, GST_TYPE_INT64_RANGE);
    gst_value_set_int64_range_step (pv1, min1, max1, step);
  } else if (min1 == max1) {
    g_value_init (pv1, G_TYPE_INT64);
    g_value_set_int64 (pv1, min1);
  }
  if (min2 < max2) {
    g_value_init (pv2, GST_TYPE_INT64_RANGE);
    gst_value_set_int64_range_step (pv2, min2, max2, step);
  } else if (min2 == max2) {
    g_value_init (pv2, G_TYPE_INT64);
    g_value_set_int64 (pv2, min2);
  }

  if (min1 <= max1 && min2 <= max2) {
    gst_value_list_concat_and_take_values (dest, pv1, pv2);
  }
  return TRUE;
}

static gboolean
gst_value_subtract_int64_range_int64 (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gint64 min = gst_value_get_int64_range_min (minuend);
  gint64 max = gst_value_get_int64_range_max (minuend);
  gint64 step = gst_value_get_int64_range_step (minuend);
  gint64 val = g_value_get_int64 (subtrahend);

  g_return_val_if_fail (min < max, FALSE);

  if (step == 0)
    return FALSE;

  /* value is outside of the range, return range unchanged */
  if (val < min || val > max || val % step) {
    if (dest)
      gst_value_init_and_copy (dest, minuend);
    return TRUE;
  } else {
    /* max must be MAXINT64 too as val <= max */
    if (val >= G_MAXINT64 - step + 1) {
      max -= step;
      val -= step;
    }
    /* min must be MININT64 too as val >= max */
    if (val <= G_MININT64 + step - 1) {
      min += step;
      val += step;
    }
    if (dest)
      gst_value_create_new_int64_range (dest, min, val - step, val + step, max,
          step);
  }
  return TRUE;
}

static gboolean
gst_value_subtract_int64_range_int64_range (GValue * dest,
    const GValue * minuend, const GValue * subtrahend)
{
  gint64 min1 = gst_value_get_int64_range_min (minuend);
  gint64 max1 = gst_value_get_int64_range_max (minuend);
  gint64 step1 = gst_value_get_int64_range_step (minuend);
  gint64 min2 = gst_value_get_int64_range_min (subtrahend);
  gint64 max2 = gst_value_get_int64_range_max (subtrahend);
  gint64 step2 = gst_value_get_int64_range_step (subtrahend);
  gint64 step;

  if (step1 != step2) {
    /* ENOIMPL */
    g_assert (FALSE);
    return FALSE;
  }

  if (step1 == 0)
    return FALSE;

  step = step1;

  if (max2 >= max1 && min2 <= min1) {
    return FALSE;
  } else if (max2 >= max1) {
    return gst_value_create_new_int64_range (dest, min1, MIN (min2 - step,
            max1), step, 0, step);
  } else if (min2 <= min1) {
    return gst_value_create_new_int64_range (dest, MAX (max2 + step, min1),
        max1, step, 0, step);
  } else {
    return gst_value_create_new_int64_range (dest, min1, MIN (min2 - step,
            max1), MAX (max2 + step, min1), max1, step);
  }
}

static gboolean
gst_value_subtract_double_double_range (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gdouble min = gst_value_get_double_range_min (subtrahend);
  gdouble max = gst_value_get_double_range_max (subtrahend);
  gdouble val = g_value_get_double (minuend);

  if (val < min || val > max) {
    if (dest)
      gst_value_init_and_copy (dest, minuend);
    return TRUE;
  }
  return FALSE;
}

static gboolean
gst_value_subtract_double_range_double (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  /* since we don't have open ranges, we cannot create a hole in
   * a double range. We return the original range */
  if (dest)
    gst_value_init_and_copy (dest, minuend);
  return TRUE;
}

static gboolean
gst_value_subtract_double_range_double_range (GValue * dest,
    const GValue * minuend, const GValue * subtrahend)
{
  /* since we don't have open ranges, we have to approximate */
  /* done like with ints */
  gdouble min1 = gst_value_get_double_range_min (minuend);
  gdouble max2 = gst_value_get_double_range_max (minuend);
  gdouble max1 = MIN (gst_value_get_double_range_min (subtrahend), max2);
  gdouble min2 = MAX (gst_value_get_double_range_max (subtrahend), min1);
  GValue v1 = { 0, };
  GValue v2 = { 0, };
  GValue *pv1, *pv2;            /* yeah, hungarian! */

  if (min1 < max1 && min2 < max2) {
    pv1 = &v1;
    pv2 = &v2;
  } else if (min1 < max1) {
    pv1 = dest;
    pv2 = NULL;
  } else if (min2 < max2) {
    pv1 = NULL;
    pv2 = dest;
  } else {
    return FALSE;
  }

  if (!dest)
    return TRUE;

  if (min1 < max1) {
    g_value_init (pv1, GST_TYPE_DOUBLE_RANGE);
    gst_value_set_double_range (pv1, min1, max1);
  }
  if (min2 < max2) {
    g_value_init (pv2, GST_TYPE_DOUBLE_RANGE);
    gst_value_set_double_range (pv2, min2, max2);
  }

  if (min1 < max1 && min2 < max2) {
    gst_value_list_concat_and_take_values (dest, pv1, pv2);
  }
  return TRUE;
}

static gboolean
gst_value_subtract_from_list (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  guint i, size;
  GValue subtraction = { 0, };
  gboolean ret = FALSE;

  size = VALUE_LIST_SIZE (minuend);
  for (i = 0; i < size; i++) {
    const GValue *cur = VALUE_LIST_GET_VALUE (minuend, i);

    /* quicker version when we can discard the result */
    if (!dest) {
      if (gst_value_subtract (NULL, cur, subtrahend)) {
        ret = TRUE;
        break;
      }
      continue;
    }

    if (gst_value_subtract (&subtraction, cur, subtrahend)) {
      if (!ret) {
        gst_value_move (dest, &subtraction);
        ret = TRUE;
      } else if (G_VALUE_TYPE (dest) == GST_TYPE_LIST
          && G_VALUE_TYPE (&subtraction) != GST_TYPE_LIST) {
        _gst_value_list_append_and_take_value (dest, &subtraction);
      } else {
        GValue temp;

        gst_value_move (&temp, dest);
        gst_value_list_concat_and_take_values (dest, &temp, &subtraction);
      }
    }
  }
  return ret;
}

static gboolean
gst_value_subtract_list (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  guint i, size;
  GValue data[2] = { {0,}, {0,} };
  GValue *subtraction = &data[0], *result = &data[1];

  gst_value_init_and_copy (result, minuend);
  size = VALUE_LIST_SIZE (subtrahend);
  for (i = 0; i < size; i++) {
    const GValue *cur = VALUE_LIST_GET_VALUE (subtrahend, i);

    if (gst_value_subtract (subtraction, result, cur)) {
      GValue *temp = result;

      result = subtraction;
      subtraction = temp;
      g_value_unset (subtraction);
    } else {
      g_value_unset (result);
      return FALSE;
    }
  }
  if (dest) {
    gst_value_move (dest, result);
  } else {
    g_value_unset (result);
  }
  return TRUE;
}

static gboolean
gst_value_subtract_fraction_fraction_range (GValue * dest,
    const GValue * minuend, const GValue * subtrahend)
{
  const GValue *min = gst_value_get_fraction_range_min (subtrahend);
  const GValue *max = gst_value_get_fraction_range_max (subtrahend);
  GstValueCompareFunc compare;

  if ((compare = gst_value_get_compare_func (minuend))) {
    /* subtracting a range from an fraction only works if the fraction
     * is not in the range */
    if (gst_value_compare_with_func (minuend, min, compare) ==
        GST_VALUE_LESS_THAN ||
        gst_value_compare_with_func (minuend, max, compare) ==
        GST_VALUE_GREATER_THAN) {
      /* and the result is the value */
      if (dest)
        gst_value_init_and_copy (dest, minuend);
      return TRUE;
    }
  }
  return FALSE;
}

static gboolean
gst_value_subtract_fraction_range_fraction (GValue * dest,
    const GValue * minuend, const GValue * subtrahend)
{
  /* since we don't have open ranges, we cannot create a hole in
   * a range. We return the original range */
  if (dest)
    gst_value_init_and_copy (dest, minuend);
  return TRUE;
}

static gboolean
gst_value_subtract_fraction_range_fraction_range (GValue * dest,
    const GValue * minuend, const GValue * subtrahend)
{
  /* since we don't have open ranges, we have to approximate */
  /* done like with ints and doubles. Creates a list of 2 fraction ranges */
  const GValue *min1 = gst_value_get_fraction_range_min (minuend);
  const GValue *max2 = gst_value_get_fraction_range_max (minuend);
  const GValue *max1 = gst_value_get_fraction_range_min (subtrahend);
  const GValue *min2 = gst_value_get_fraction_range_max (subtrahend);
  gint cmp1, cmp2;
  GValue v1 = { 0, };
  GValue v2 = { 0, };
  GValue *pv1, *pv2;            /* yeah, hungarian! */
  GstValueCompareFunc compare;

  g_return_val_if_fail (min1 != NULL && max1 != NULL, FALSE);
  g_return_val_if_fail (min2 != NULL && max2 != NULL, FALSE);

  compare = gst_value_get_compare_func (min1);
  g_return_val_if_fail (compare, FALSE);

  cmp1 = gst_value_compare_with_func (max2, max1, compare);
  g_return_val_if_fail (cmp1 != GST_VALUE_UNORDERED, FALSE);
  if (cmp1 == GST_VALUE_LESS_THAN)
    max1 = max2;
  cmp1 = gst_value_compare_with_func (min1, min2, compare);
  g_return_val_if_fail (cmp1 != GST_VALUE_UNORDERED, FALSE);
  if (cmp1 == GST_VALUE_GREATER_THAN)
    min2 = min1;

  cmp1 = gst_value_compare_with_func (min1, max1, compare);
  cmp2 = gst_value_compare_with_func (min2, max2, compare);

  if (cmp1 == GST_VALUE_LESS_THAN && cmp2 == GST_VALUE_LESS_THAN) {
    pv1 = &v1;
    pv2 = &v2;
  } else if (cmp1 == GST_VALUE_LESS_THAN) {
    pv1 = dest;
    pv2 = NULL;
  } else if (cmp2 == GST_VALUE_LESS_THAN) {
    pv1 = NULL;
    pv2 = dest;
  } else {
    return FALSE;
  }

  if (!dest)
    return TRUE;

  if (cmp1 == GST_VALUE_LESS_THAN) {
    g_value_init (pv1, GST_TYPE_FRACTION_RANGE);
    gst_value_set_fraction_range (pv1, min1, max1);
  }
  if (cmp2 == GST_VALUE_LESS_THAN) {
    g_value_init (pv2, GST_TYPE_FRACTION_RANGE);
    gst_value_set_fraction_range (pv2, min2, max2);
  }

  if (cmp1 == GST_VALUE_LESS_THAN && cmp2 == GST_VALUE_LESS_THAN) {
    gst_value_list_concat_and_take_values (dest, pv1, pv2);
  }
  return TRUE;
}

/**************
 * comparison *
 **************/

/*
 * gst_value_get_compare_func:
 * @value1: a value to get the compare function for
 *
 * Determines the compare function to be used with values of the same type as
 * @value1. The function can be given to gst_value_compare_with_func().
 *
 * Returns: A #GstValueCompareFunc value
 */
static GstValueCompareFunc
gst_value_get_compare_func (const GValue * value1)
{
  GstValueTable *table, *best = NULL;
  guint i;
  GType type1;

  type1 = G_VALUE_TYPE (value1);

  /* this is a fast check */
  best = gst_value_hash_lookup_type (type1);

  /* slower checks */
  if (G_UNLIKELY (!best || !best->compare)) {
    guint len = gst_value_table->len;

    best = NULL;
    for (i = 0; i < len; i++) {
      table = &g_array_index (gst_value_table, GstValueTable, i);
      if (table->compare && g_type_is_a (type1, table->type)) {
        if (!best || g_type_is_a (table->type, best->type))
          best = table;
      }
    }
  }
  if (G_LIKELY (best))
    return best->compare;

  return NULL;
}

static inline gboolean
gst_value_can_compare_unchecked (const GValue * value1, const GValue * value2)
{
  if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
    return FALSE;

  return gst_value_get_compare_func (value1) != NULL;
}

/**
 * gst_value_can_compare:
 * @value1: a value to compare
 * @value2: another value to compare
 *
 * Determines if @value1 and @value2 can be compared.
 *
 * Returns: %TRUE if the values can be compared
 */
gboolean
gst_value_can_compare (const GValue * value1, const GValue * value2)
{
  g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
  g_return_val_if_fail (G_IS_VALUE (value2), FALSE);

  return gst_value_can_compare_unchecked (value1, value2);
}

static gboolean
gst_value_list_equals_range (const GValue * list, const GValue * value)
{
  const GValue *first;
  guint list_size, n;

  g_assert (G_IS_VALUE (list));
  g_assert (G_IS_VALUE (value));
  g_assert (GST_VALUE_HOLDS_LIST (list));

  /* TODO: compare against an empty list ? No type though... */
  list_size = VALUE_LIST_SIZE (list);
  if (list_size == 0)
    return FALSE;

  /* compare the basic types - they have to match */
  first = VALUE_LIST_GET_VALUE (list, 0);
#define CHECK_TYPES(type,prefix) \
  (prefix##_VALUE_HOLDS_##type(first) && GST_VALUE_HOLDS_##type##_RANGE (value))
  if (CHECK_TYPES (INT, G)) {
    const gint rmin = gst_value_get_int_range_min (value);
    const gint rmax = gst_value_get_int_range_max (value);
    const gint rstep = gst_value_get_int_range_step (value);
    if (rstep == 0)
      return FALSE;
    /* note: this will overflow for min 0 and max INT_MAX, but this
       would only be equal to a list of INT_MAX elements, which seems
       very unlikely */
    if (list_size != rmax / rstep - rmin / rstep + 1)
      return FALSE;
    for (n = 0; n < list_size; ++n) {
      gint v = g_value_get_int (VALUE_LIST_GET_VALUE (list, n));
      if (v < rmin || v > rmax || v % rstep) {
        return FALSE;
      }
    }
    return TRUE;
  } else if (CHECK_TYPES (INT64, G)) {
    const gint64 rmin = gst_value_get_int64_range_min (value);
    const gint64 rmax = gst_value_get_int64_range_max (value);
    const gint64 rstep = gst_value_get_int64_range_step (value);
    GST_DEBUG ("List/range of int64s");
    if (rstep == 0)
      return FALSE;
    if (list_size != rmax / rstep - rmin / rstep + 1)
      return FALSE;
    for (n = 0; n < list_size; ++n) {
      gint64 v = g_value_get_int64 (VALUE_LIST_GET_VALUE (list, n));
      if (v < rmin || v > rmax || v % rstep)
        return FALSE;
    }
    return TRUE;
  }
#undef CHECK_TYPES

  /* other combinations don't make sense for equality */
  return FALSE;
}

/* "Pure" variant of gst_value_compare which is guaranteed to
 * not have list arguments and therefore does basic comparisions
 */
static inline gint
_gst_value_compare_nolist (const GValue * value1, const GValue * value2)
{
  GstValueCompareFunc compare;

  if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
    return GST_VALUE_UNORDERED;

  compare = gst_value_get_compare_func (value1);
  if (compare) {
    return compare (value1, value2);
  }

  g_critical ("unable to compare values of type %s\n",
      g_type_name (G_VALUE_TYPE (value1)));
  return GST_VALUE_UNORDERED;
}

/**
 * gst_value_compare:
 * @value1: a value to compare
 * @value2: another value to compare
 *
 * Compares @value1 and @value2.  If @value1 and @value2 cannot be
 * compared, the function returns GST_VALUE_UNORDERED.  Otherwise,
 * if @value1 is greater than @value2, GST_VALUE_GREATER_THAN is returned.
 * If @value1 is less than @value2, GST_VALUE_LESS_THAN is returned.
 * If the values are equal, GST_VALUE_EQUAL is returned.
 *
 * Returns: comparison result
 */
gint
gst_value_compare (const GValue * value1, const GValue * value2)
{
  gboolean value1_is_list;
  gboolean value2_is_list;

  g_return_val_if_fail (G_IS_VALUE (value1), GST_VALUE_LESS_THAN);
  g_return_val_if_fail (G_IS_VALUE (value2), GST_VALUE_GREATER_THAN);

  value1_is_list = G_VALUE_TYPE (value1) == GST_TYPE_LIST;
  value2_is_list = G_VALUE_TYPE (value2) == GST_TYPE_LIST;

  /* Special cases: lists and scalar values ("{ 1 }" and "1" are equal),
     as well as lists and ranges ("{ 1, 2 }" and "[ 1, 2 ]" are equal) */
  if (value1_is_list && !value2_is_list) {
    gint i, n, ret;

    if (gst_value_list_equals_range (value1, value2)) {
      return GST_VALUE_EQUAL;
    }

    n = gst_value_list_get_size (value1);
    if (n == 0)
      return GST_VALUE_UNORDERED;

    for (i = 0; i < n; i++) {
      const GValue *elt;

      elt = gst_value_list_get_value (value1, i);
      ret = gst_value_compare (elt, value2);
      if (ret != GST_VALUE_EQUAL && n == 1)
        return ret;
      else if (ret != GST_VALUE_EQUAL)
        return GST_VALUE_UNORDERED;
    }

    return GST_VALUE_EQUAL;
  } else if (value2_is_list && !value1_is_list) {
    gint i, n, ret;

    if (gst_value_list_equals_range (value2, value1)) {
      return GST_VALUE_EQUAL;
    }

    n = gst_value_list_get_size (value2);
    if (n == 0)
      return GST_VALUE_UNORDERED;

    for (i = 0; i < n; i++) {
      const GValue *elt;

      elt = gst_value_list_get_value (value2, i);
      ret = gst_value_compare (elt, value1);
      if (ret != GST_VALUE_EQUAL && n == 1)
        return ret;
      else if (ret != GST_VALUE_EQUAL)
        return GST_VALUE_UNORDERED;
    }

    return GST_VALUE_EQUAL;
  }

  /* And now handle the generic case */
  return _gst_value_compare_nolist (value1, value2);
}

/*
 * gst_value_compare_with_func:
 * @value1: a value to compare
 * @value2: another value to compare
 * @compare: compare function
 *
 * Compares @value1 and @value2 using the @compare function. Works like
 * gst_value_compare() but allows to save time determining the compare function
 * a multiple times.
 *
 * Returns: comparison result
 */
static gint
gst_value_compare_with_func (const GValue * value1, const GValue * value2,
    GstValueCompareFunc compare)
{
  g_assert (compare);

  if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
    return GST_VALUE_UNORDERED;

  return compare (value1, value2);
}

/* union */

/**
 * gst_value_can_union:
 * @value1: a value to union
 * @value2: another value to union
 *
 * Determines if @value1 and @value2 can be non-trivially unioned.
 * Any two values can be trivially unioned by adding both of them
 * to a GstValueList.  However, certain types have the possibility
 * to be unioned in a simpler way.  For example, an integer range
 * and an integer can be unioned if the integer is a subset of the
 * integer range.  If there is the possibility that two values can
 * be unioned, this function returns %TRUE.
 *
 * Returns: %TRUE if there is a function allowing the two values to
 * be unioned.
 */
gboolean
gst_value_can_union (const GValue * value1, const GValue * value2)
{
  GstValueUnionInfo *union_info;
  guint i, len;

  g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
  g_return_val_if_fail (G_IS_VALUE (value2), FALSE);

  len = gst_value_union_funcs->len;

  for (i = 0; i < len; i++) {
    union_info = &g_array_index (gst_value_union_funcs, GstValueUnionInfo, i);
    if (union_info->type1 == G_VALUE_TYPE (value1) &&
        union_info->type2 == G_VALUE_TYPE (value2))
      return TRUE;
    if (union_info->type1 == G_VALUE_TYPE (value2) &&
        union_info->type2 == G_VALUE_TYPE (value1))
      return TRUE;
  }

  return FALSE;
}

/**
 * gst_value_union:
 * @dest: (out caller-allocates): the destination value
 * @value1: a value to union
 * @value2: another value to union
 *
 * Creates a GValue corresponding to the union of @value1 and @value2.
 *
 * Returns: %TRUE if the union succeeded.
 */
gboolean
gst_value_union (GValue * dest, const GValue * value1, const GValue * value2)
{
  const GstValueUnionInfo *union_info;
  guint i, len;
  GType type1, type2;

  g_return_val_if_fail (dest != NULL, FALSE);
  g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
  g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
  g_return_val_if_fail (gst_value_list_or_array_are_compatible (value1, value2),
      FALSE);

  len = gst_value_union_funcs->len;
  type1 = G_VALUE_TYPE (value1);
  type2 = G_VALUE_TYPE (value2);

  for (i = 0; i < len; i++) {
    union_info = &g_array_index (gst_value_union_funcs, GstValueUnionInfo, i);
    if (union_info->type1 == type1 && union_info->type2 == type2) {
      return union_info->func (dest, value1, value2);
    }
    if (union_info->type1 == type2 && union_info->type2 == type1) {
      return union_info->func (dest, value2, value1);
    }
  }

  gst_value_list_concat (dest, value1, value2);
  return TRUE;
}

/* gst_value_register_union_func: (skip)
 * @type1: a type to union
 * @type2: another type to union
 * @func: a function that implements creating a union between the two types
 *
 * Registers a union function that can create a union between #GValue items
 * of the type @type1 and @type2.
 *
 * Union functions should be registered at startup before any pipelines are
 * started, as gst_value_register_union_func() is not thread-safe and cannot
 * be used at the same time as gst_value_union() or gst_value_can_union().
 */
static void
gst_value_register_union_func (GType type1, GType type2, GstValueUnionFunc func)
{
  GstValueUnionInfo union_info;

  union_info.type1 = type1;
  union_info.type2 = type2;
  union_info.func = func;

  g_array_append_val (gst_value_union_funcs, union_info);
}

/* intersection */

/**
 * gst_value_can_intersect:
 * @value1: a value to intersect
 * @value2: another value to intersect
 *
 * Determines if intersecting two values will produce a valid result.
 * Two values will produce a valid intersection if they have the same
 * type.
 *
 * Returns: %TRUE if the values can intersect
 */
gboolean
gst_value_can_intersect (const GValue * value1, const GValue * value2)
{
  GstValueIntersectInfo *intersect_info;
  guint i, len;
  GType type1, type2;

  g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
  g_return_val_if_fail (G_IS_VALUE (value2), FALSE);

  type1 = G_VALUE_TYPE (value1);
  type2 = G_VALUE_TYPE (value2);

  /* practically all GstValue types have a compare function (_can_compare=TRUE)
   * GstStructure and GstCaps have not, but are intersectable */
  if (type1 == type2)
    return TRUE;

  /* special cases */
  if (type1 == GST_TYPE_LIST || type2 == GST_TYPE_LIST)
    return TRUE;

  if (G_UNLIKELY (GST_VALUE_HOLDS_FLAG_SET (value1) &&
          GST_VALUE_HOLDS_FLAG_SET (value2))) {
    GType type1, type2, flagset_type;

    type1 = G_VALUE_TYPE (value1);
    type2 = G_VALUE_TYPE (value2);
    flagset_type = GST_TYPE_FLAG_SET;

    /* Allow intersection with the generic FlagSet type, on one
     * side, but not 2 different subtypes - that makes no sense */
    if (type1 == type2 || type1 == flagset_type || type2 == flagset_type)
      return TRUE;
  }

  /* check registered intersect functions */
  len = gst_value_intersect_funcs->len;
  for (i = 0; i < len; i++) {
    intersect_info = &g_array_index (gst_value_intersect_funcs,
        GstValueIntersectInfo, i);
    if ((intersect_info->type1 == type1 && intersect_info->type2 == type2) ||
        (intersect_info->type1 == type2 && intersect_info->type2 == type1))
      return TRUE;
  }

  return gst_value_can_compare_unchecked (value1, value2);
}

/**
 * gst_value_intersect:
 * @dest: (out caller-allocates) (transfer full) (allow-none):
 *   a uninitialized #GValue that will hold the calculated
 *   intersection value. May be %NULL if the resulting set if not
 *   needed.
 * @value1: a value to intersect
 * @value2: another value to intersect
 *
 * Calculates the intersection of two values.  If the values have
 * a non-empty intersection, the value representing the intersection
 * is placed in @dest, unless %NULL.  If the intersection is non-empty,
 * @dest is not modified.
 *
 * Returns: %TRUE if the intersection is non-empty
 */
gboolean
gst_value_intersect (GValue * dest, const GValue * value1,
    const GValue * value2)
{
  GstValueIntersectInfo *intersect_info;
  guint i, len;
  GType type1, type2;

  g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
  g_return_val_if_fail (G_IS_VALUE (value2), FALSE);

  type1 = G_VALUE_TYPE (value1);
  type2 = G_VALUE_TYPE (value2);

  /* special cases first */
  if (type1 == GST_TYPE_LIST)
    return gst_value_intersect_list (dest, value1, value2);
  if (type2 == GST_TYPE_LIST)
    return gst_value_intersect_list (dest, value2, value1);

  if (_gst_value_compare_nolist (value1, value2) == GST_VALUE_EQUAL) {
    if (dest)
      gst_value_init_and_copy (dest, value1);
    return TRUE;
  }

  len = gst_value_intersect_funcs->len;
  for (i = 0; i < len; i++) {
    intersect_info = &g_array_index (gst_value_intersect_funcs,
        GstValueIntersectInfo, i);
    if (intersect_info->type1 == type1 && intersect_info->type2 == type2) {
      return intersect_info->func (dest, value1, value2);
    }
    if (intersect_info->type1 == type2 && intersect_info->type2 == type1) {
      return intersect_info->func (dest, value2, value1);
    }
  }

  /* Failed to find a direct intersection, check if these are
   * GstFlagSet sub-types. */
  if (G_UNLIKELY (GST_VALUE_HOLDS_FLAG_SET (value1) &&
          GST_VALUE_HOLDS_FLAG_SET (value2))) {
    return gst_value_intersect_flagset_flagset (dest, value1, value2);
  }

  return FALSE;
}



/* gst_value_register_intersect_func: (skip)
 * @type1: the first type to intersect
 * @type2: the second type to intersect
 * @func: the intersection function
 *
 * Registers a function that is called to calculate the intersection
 * of the values having the types @type1 and @type2.
 *
 * Intersect functions should be registered at startup before any pipelines are
 * started, as gst_value_register_intersect_func() is not thread-safe and
 * cannot be used at the same time as gst_value_intersect() or
 * gst_value_can_intersect().
 */
static void
gst_value_register_intersect_func (GType type1, GType type2,
    GstValueIntersectFunc func)
{
  GstValueIntersectInfo intersect_info;

  intersect_info.type1 = type1;
  intersect_info.type2 = type2;
  intersect_info.func = func;

  g_array_append_val (gst_value_intersect_funcs, intersect_info);
}


/* subtraction */

/**
 * gst_value_subtract:
 * @dest: (out caller-allocates) (allow-none): the destination value
 *     for the result if the subtraction is not empty. May be %NULL,
 *     in which case the resulting set will not be computed, which can
 *     give a fair speedup.
 * @minuend: the value to subtract from
 * @subtrahend: the value to subtract
 *
 * Subtracts @subtrahend from @minuend and stores the result in @dest.
 * Note that this means subtraction as in sets, not as in mathematics.
 *
 * Returns: %TRUE if the subtraction is not empty
 */
gboolean
gst_value_subtract (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  GstValueSubtractInfo *info;
  guint i, len;
  GType mtype, stype;

  g_return_val_if_fail (G_IS_VALUE (minuend), FALSE);
  g_return_val_if_fail (G_IS_VALUE (subtrahend), FALSE);

  mtype = G_VALUE_TYPE (minuend);
  stype = G_VALUE_TYPE (subtrahend);

  /* special cases first */
  if (mtype == GST_TYPE_LIST)
    return gst_value_subtract_from_list (dest, minuend, subtrahend);
  if (stype == GST_TYPE_LIST)
    return gst_value_subtract_list (dest, minuend, subtrahend);

  len = gst_value_subtract_funcs->len;
  for (i = 0; i < len; i++) {
    info = &g_array_index (gst_value_subtract_funcs, GstValueSubtractInfo, i);
    if (info->minuend == mtype && info->subtrahend == stype) {
      return info->func (dest, minuend, subtrahend);
    }
  }

  if (_gst_value_compare_nolist (minuend, subtrahend) != GST_VALUE_EQUAL) {
    if (dest)
      gst_value_init_and_copy (dest, minuend);
    return TRUE;
  }

  return FALSE;
}

#if 0
gboolean
gst_value_subtract (GValue * dest, const GValue * minuend,
    const GValue * subtrahend)
{
  gboolean ret = gst_value_subtract2 (dest, minuend, subtrahend);

  g_printerr ("\"%s\"  -  \"%s\"  =  \"%s\"\n", gst_value_serialize (minuend),
      gst_value_serialize (subtrahend),
      ret ? gst_value_serialize (dest) : "---");
  return ret;
}
#endif

/**
 * gst_value_can_subtract:
 * @minuend: the value to subtract from
 * @subtrahend: the value to subtract
 *
 * Checks if it's possible to subtract @subtrahend from @minuend.
 *
 * Returns: %TRUE if a subtraction is possible
 */
gboolean
gst_value_can_subtract (const GValue * minuend, const GValue * subtrahend)
{
  GstValueSubtractInfo *info;
  guint i, len;
  GType mtype, stype;

  g_return_val_if_fail (G_IS_VALUE (minuend), FALSE);
  g_return_val_if_fail (G_IS_VALUE (subtrahend), FALSE);

  mtype = G_VALUE_TYPE (minuend);
  stype = G_VALUE_TYPE (subtrahend);

  /* special cases */
  if (mtype == GST_TYPE_LIST || stype == GST_TYPE_LIST)
    return TRUE;
  if (mtype == GST_TYPE_STRUCTURE || stype == GST_TYPE_STRUCTURE)
    return FALSE;

  len = gst_value_subtract_funcs->len;
  for (i = 0; i < len; i++) {
    info = &g_array_index (gst_value_subtract_funcs, GstValueSubtractInfo, i);
    if (info->minuend == mtype && info->subtrahend == stype)
      return TRUE;
  }

  return gst_value_can_compare_unchecked (minuend, subtrahend);
}

/* gst_value_register_subtract_func: (skip)
 * @minuend_type: type of the minuend
 * @subtrahend_type: type of the subtrahend
 * @func: function to use
 *
 * Registers @func as a function capable of subtracting the values of
 * @subtrahend_type from values of @minuend_type.
 *
 * Subtract functions should be registered at startup before any pipelines are
 * started, as gst_value_register_subtract_func() is not thread-safe and
 * cannot be used at the same time as gst_value_subtract().
 */
static void
gst_value_register_subtract_func (GType minuend_type, GType subtrahend_type,
    GstValueSubtractFunc func)
{
  GstValueSubtractInfo info;

  g_return_if_fail (!gst_type_is_fixed (minuend_type)
      || !gst_type_is_fixed (subtrahend_type));

  info.minuend = minuend_type;
  info.subtrahend = subtrahend_type;
  info.func = func;

  g_array_append_val (gst_value_subtract_funcs, info);
}

/**
 * gst_value_register:
 * @table: structure containing functions to register
 *
 * Registers functions to perform calculations on #GValue items of a given
 * type. Each type can only be added once.
 */
void
gst_value_register (const GstValueTable * table)
{
  GstValueTable *found;

  g_return_if_fail (table != NULL);

  g_array_append_val (gst_value_table, *table);

  found = gst_value_hash_lookup_type (table->type);
  if (found)
    g_warning ("adding type %s multiple times", g_type_name (table->type));

  /* FIXME: we're not really doing the const justice, we assume the table is
   * static */
  gst_value_hash_add_type (table->type, table);
}

/**
 * gst_value_init_and_copy:
 * @dest: (out caller-allocates): the target value
 * @src: the source value
 *
 * Initialises the target value to be of the same type as source and then copies
 * the contents from source to target.
 */
void
gst_value_init_and_copy (GValue * dest, const GValue * src)
{
  g_return_if_fail (G_IS_VALUE (src));
  g_return_if_fail (dest != NULL);

  g_value_init (dest, G_VALUE_TYPE (src));
  g_value_copy (src, dest);
}

/* move src into dest and clear src */
static void
gst_value_move (GValue * dest, GValue * src)
{
  g_assert (G_IS_VALUE (src));
  g_assert (dest != NULL);

  *dest = *src;
  memset (src, 0, sizeof (GValue));
}

/**
 * gst_value_serialize:
 * @value: a #GValue to serialize
 *
 * tries to transform the given @value into a string representation that allows
 * getting back this string later on using gst_value_deserialize().
 *
 * Free-function: g_free
 *
 * Returns: (transfer full) (nullable): the serialization for @value
 * or %NULL if none exists
 */
gchar *
gst_value_serialize (const GValue * value)
{
  guint i, len;
  GValue s_val = { 0 };
  GstValueTable *table, *best;
  gchar *s;
  GType type;

  g_return_val_if_fail (G_IS_VALUE (value), NULL);

  type = G_VALUE_TYPE (value);

  best = gst_value_hash_lookup_type (type);

  if (G_UNLIKELY (!best || !best->serialize)) {
    len = gst_value_table->len;
    best = NULL;
    for (i = 0; i < len; i++) {
      table = &g_array_index (gst_value_table, GstValueTable, i);
      if (table->serialize && g_type_is_a (type, table->type)) {
        if (!best || g_type_is_a (table->type, best->type))
          best = table;
      }
    }
  }
  if (G_LIKELY (best))
    return best->serialize (value);

  g_value_init (&s_val, G_TYPE_STRING);
  if (g_value_transform (value, &s_val)) {
    s = gst_string_wrap (g_value_get_string (&s_val));
  } else {
    s = NULL;
  }
  g_value_unset (&s_val);

  return s;
}

/**
 * gst_value_deserialize:
 * @dest: (out caller-allocates): #GValue to fill with contents of
 *     deserialization
 * @src: string to deserialize
 *
 * Tries to deserialize a string into the type specified by the given GValue.
 * If the operation succeeds, %TRUE is returned, %FALSE otherwise.
 *
 * Returns: %TRUE on success
 */
gboolean
gst_value_deserialize (GValue * dest, const gchar * src)
{
  GstValueTable *table, *best;
  guint i, len;
  GType type;

  g_return_val_if_fail (src != NULL, FALSE);
  g_return_val_if_fail (G_IS_VALUE (dest), FALSE);

  type = G_VALUE_TYPE (dest);

  best = gst_value_hash_lookup_type (type);
  if (G_UNLIKELY (!best || !best->deserialize)) {
    len = gst_value_table->len;
    best = NULL;
    for (i = 0; i < len; i++) {
      table = &g_array_index (gst_value_table, GstValueTable, i);
      if (table->deserialize && g_type_is_a (type, table->type)) {
        if (!best || g_type_is_a (table->type, best->type))
          best = table;
      }
    }
  }
  if (G_LIKELY (best))
    return best->deserialize (dest, src);

  return FALSE;
}

static gboolean
structure_field_is_fixed (GQuark field_id, const GValue * val,
    gpointer user_data)
{
  return gst_value_is_fixed (val);
}

/**
 * gst_value_is_fixed:
 * @value: the #GValue to check
 *
 * Tests if the given GValue, if available in a GstStructure (or any other
 * container) contains a "fixed" (which means: one value) or an "unfixed"
 * (which means: multiple possible values, such as data lists or data
 * ranges) value.
 *
 * Returns: true if the value is "fixed".
 */

gboolean
gst_value_is_fixed (const GValue * value)
{
  GType type;

  g_return_val_if_fail (G_IS_VALUE (value), FALSE);

  type = G_VALUE_TYPE (value);

  /* the most common types are just basic plain glib types */
  if (type <= G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_GLIB_LAST)) {
    return TRUE;
  }

  if (type == GST_TYPE_ARRAY) {
    gint size, n;
    const GValue *kid;

    /* check recursively */
    size = gst_value_array_get_size (value);
    for (n = 0; n < size; n++) {
      kid = gst_value_array_get_value (value, n);
      if (!gst_value_is_fixed (kid))
        return FALSE;
    }
    return TRUE;
  } else if (GST_VALUE_HOLDS_FLAG_SET (value)) {
    /* Flagsets are only fixed if there are no 'don't care' bits */
    return (gst_value_get_flagset_mask (value) == GST_FLAG_SET_MASK_EXACT);
  } else if (GST_VALUE_HOLDS_STRUCTURE (value)) {
    return gst_structure_foreach (gst_value_get_structure (value),
        structure_field_is_fixed, NULL);
  }
  return gst_type_is_fixed (type);
}

/**
 * gst_value_fixate:
 * @dest: the #GValue destination
 * @src: the #GValue to fixate
 *
 * Fixate @src into a new value @dest.
 * For ranges, the first element is taken. For lists and arrays, the
 * first item is fixated and returned.
 * If @src is already fixed, this function returns %FALSE.
 *
 * Returns: %TRUE if @dest contains a fixated version of @src.
 */
gboolean
gst_value_fixate (GValue * dest, const GValue * src)
{
  g_return_val_if_fail (G_IS_VALUE (src), FALSE);
  g_return_val_if_fail (dest != NULL, FALSE);

  if (G_VALUE_TYPE (src) == GST_TYPE_INT_RANGE) {
    g_value_init (dest, G_TYPE_INT);
    g_value_set_int (dest, gst_value_get_int_range_min (src));
  } else if (G_VALUE_TYPE (src) == GST_TYPE_DOUBLE_RANGE) {
    g_value_init (dest, G_TYPE_DOUBLE);
    g_value_set_double (dest, gst_value_get_double_range_min (src));
  } else if (G_VALUE_TYPE (src) == GST_TYPE_FRACTION_RANGE) {
    gst_value_init_and_copy (dest, gst_value_get_fraction_range_min (src));
  } else if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
    GValue temp = { 0 };

    /* list could be empty */
    if (gst_value_list_get_size (src) <= 0)
      return FALSE;

    gst_value_init_and_copy (&temp, gst_value_list_get_value (src, 0));

    if (!gst_value_fixate (dest, &temp)) {
      gst_value_move (dest, &temp);
    } else {
      g_value_unset (&temp);
    }
  } else if (G_VALUE_TYPE (src) == GST_TYPE_ARRAY) {
    gboolean res = FALSE;
    guint n, len;

    len = gst_value_array_get_size (src);
    g_value_init (dest, GST_TYPE_ARRAY);
    for (n = 0; n < len; n++) {
      GValue kid = { 0 };
      const GValue *orig_kid = gst_value_array_get_value (src, n);

      if (!gst_value_fixate (&kid, orig_kid))
        gst_value_init_and_copy (&kid, orig_kid);
      else
        res = TRUE;
      _gst_value_array_append_and_take_value (dest, &kid);
    }

    if (!res)
      g_value_unset (dest);

    return res;
  } else if (GST_VALUE_HOLDS_FLAG_SET (src)) {
    guint flags;

    if (gst_value_get_flagset_mask (src) == GST_FLAG_SET_MASK_EXACT)
      return FALSE;             /* Already fixed */

    flags = gst_value_get_flagset_flags (src);
    g_value_init (dest, G_VALUE_TYPE (src));
    gst_value_set_flagset (dest, flags, GST_FLAG_SET_MASK_EXACT);
    return TRUE;
  } else if (GST_VALUE_HOLDS_STRUCTURE (src)) {
    const GstStructure *str = (GstStructure *) gst_value_get_structure (src);
    GstStructure *kid;

    if (!str)
      return FALSE;

    kid = gst_structure_copy (str);
    gst_structure_fixate (kid);
    g_value_init (dest, GST_TYPE_STRUCTURE);
    gst_value_set_structure (dest, kid);
    gst_structure_free (kid);
    return TRUE;
  } else {
    return FALSE;
  }
  return TRUE;
}


/************
 * fraction *
 ************/

/* helper functions */
static void
gst_value_init_fraction (GValue * value)
{
  value->data[0].v_int = 0;
  value->data[1].v_int = 1;
}

static void
gst_value_copy_fraction (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_int = src_value->data[0].v_int;
  dest_value->data[1].v_int = src_value->data[1].v_int;
}

static gchar *
gst_value_collect_fraction (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  if (n_collect_values != 2)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[1].v_int == 0)
    return g_strdup_printf ("passed '0' as denominator for `%s'",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[0].v_int < -G_MAXINT)
    return
        g_strdup_printf
        ("passed value smaller than -G_MAXINT as numerator for `%s'",
        G_VALUE_TYPE_NAME (value));
  if (collect_values[1].v_int < -G_MAXINT)
    return
        g_strdup_printf
        ("passed value smaller than -G_MAXINT as denominator for `%s'",
        G_VALUE_TYPE_NAME (value));

  gst_value_set_fraction (value,
      collect_values[0].v_int, collect_values[1].v_int);

  return NULL;
}

static gchar *
gst_value_lcopy_fraction (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  gint *numerator = collect_values[0].v_pointer;
  gint *denominator = collect_values[1].v_pointer;

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

  *numerator = value->data[0].v_int;
  *denominator = value->data[1].v_int;

  return NULL;
}

/**
 * gst_value_set_fraction:
 * @value: a GValue initialized to #GST_TYPE_FRACTION
 * @numerator: the numerator of the fraction
 * @denominator: the denominator of the fraction
 *
 * Sets @value to the fraction specified by @numerator over @denominator.
 * The fraction gets reduced to the smallest numerator and denominator,
 * and if necessary the sign is moved to the numerator.
 */
void
gst_value_set_fraction (GValue * value, gint numerator, gint denominator)
{
  gint gcd = 0;

  g_return_if_fail (GST_VALUE_HOLDS_FRACTION (value));
  g_return_if_fail (denominator != 0);
  g_return_if_fail (denominator >= -G_MAXINT);
  g_return_if_fail (numerator >= -G_MAXINT);

  /* normalize sign */
  if (denominator < 0) {
    numerator = -numerator;
    denominator = -denominator;
  }

  /* check for reduction */
  gcd = gst_util_greatest_common_divisor (numerator, denominator);
  if (gcd) {
    numerator /= gcd;
    denominator /= gcd;
  }

  g_assert (denominator > 0);

  value->data[0].v_int = numerator;
  value->data[1].v_int = denominator;
}

/**
 * gst_value_get_fraction_numerator:
 * @value: a GValue initialized to #GST_TYPE_FRACTION
 *
 * Gets the numerator of the fraction specified by @value.
 *
 * Returns: the numerator of the fraction.
 */
gint
gst_value_get_fraction_numerator (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (value), 0);

  return value->data[0].v_int;
}

/**
 * gst_value_get_fraction_denominator:
 * @value: a GValue initialized to #GST_TYPE_FRACTION
 *
 * Gets the denominator of the fraction specified by @value.
 *
 * Returns: the denominator of the fraction.
 */
gint
gst_value_get_fraction_denominator (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (value), 1);

  return value->data[1].v_int;
}

/**
 * gst_value_fraction_multiply:
 * @product: a GValue initialized to #GST_TYPE_FRACTION
 * @factor1: a GValue initialized to #GST_TYPE_FRACTION
 * @factor2: a GValue initialized to #GST_TYPE_FRACTION
 *
 * Multiplies the two #GValue items containing a #GST_TYPE_FRACTION and sets
 * @product to the product of the two fractions.
 *
 * Returns: %FALSE in case of an error (like integer overflow), %TRUE otherwise.
 */
gboolean
gst_value_fraction_multiply (GValue * product, const GValue * factor1,
    const GValue * factor2)
{
  gint n1, n2, d1, d2;
  gint res_n, res_d;

  g_return_val_if_fail (product != NULL, FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (factor1), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (factor2), FALSE);

  n1 = factor1->data[0].v_int;
  n2 = factor2->data[0].v_int;
  d1 = factor1->data[1].v_int;
  d2 = factor2->data[1].v_int;

  if (!gst_util_fraction_multiply (n1, d1, n2, d2, &res_n, &res_d))
    return FALSE;

  gst_value_set_fraction (product, res_n, res_d);

  return TRUE;
}

/**
 * gst_value_fraction_subtract:
 * @dest: a GValue initialized to #GST_TYPE_FRACTION
 * @minuend: a GValue initialized to #GST_TYPE_FRACTION
 * @subtrahend: a GValue initialized to #GST_TYPE_FRACTION
 *
 * Subtracts the @subtrahend from the @minuend and sets @dest to the result.
 *
 * Returns: %FALSE in case of an error (like integer overflow), %TRUE otherwise.
 */
gboolean
gst_value_fraction_subtract (GValue * dest,
    const GValue * minuend, const GValue * subtrahend)
{
  gint n1, n2, d1, d2;
  gint res_n, res_d;

  g_return_val_if_fail (dest != NULL, FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (minuend), FALSE);
  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (subtrahend), FALSE);

  n1 = minuend->data[0].v_int;
  n2 = subtrahend->data[0].v_int;
  d1 = minuend->data[1].v_int;
  d2 = subtrahend->data[1].v_int;

  if (!gst_util_fraction_add (n1, d1, -n2, d2, &res_n, &res_d))
    return FALSE;
  gst_value_set_fraction (dest, res_n, res_d);

  return TRUE;
}

static gchar *
gst_value_serialize_fraction (const GValue * value)
{
  gint32 numerator = value->data[0].v_int;
  gint32 denominator = value->data[1].v_int;
  gboolean positive = TRUE;

  /* get the sign and make components absolute */
  if (numerator < 0) {
    numerator = -numerator;
    positive = !positive;
  }
  if (denominator < 0) {
    denominator = -denominator;
    positive = !positive;
  }

  return g_strdup_printf ("%s%d/%d",
      positive ? "" : "-", numerator, denominator);
}

static gboolean
gst_value_deserialize_fraction (GValue * dest, const gchar * s)
{
  gint num, den;
  gint num_chars;

  if (G_UNLIKELY (s == NULL))
    return FALSE;

  if (G_UNLIKELY (dest == NULL || !GST_VALUE_HOLDS_FRACTION (dest)))
    return FALSE;

  if (sscanf (s, "%d/%d%n", &num, &den, &num_chars) >= 2) {
    if (s[num_chars] != 0)
      return FALSE;
    if (den == 0)
      return FALSE;

    gst_value_set_fraction (dest, num, den);
    return TRUE;
  } else if (g_ascii_strcasecmp (s, "1/max") == 0) {
    gst_value_set_fraction (dest, 1, G_MAXINT);
    return TRUE;
  } else if (sscanf (s, "%d%n", &num, &num_chars) >= 1) {
    if (s[num_chars] != 0)
      return FALSE;
    gst_value_set_fraction (dest, num, 1);
    return TRUE;
  } else if (g_ascii_strcasecmp (s, "min") == 0) {
    gst_value_set_fraction (dest, -G_MAXINT, 1);
    return TRUE;
  } else if (g_ascii_strcasecmp (s, "max") == 0) {
    gst_value_set_fraction (dest, G_MAXINT, 1);
    return TRUE;
  }

  return FALSE;
}

static void
gst_value_transform_fraction_string (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_pointer = gst_value_serialize_fraction (src_value);
}

static void
gst_value_transform_string_fraction (const GValue * src_value,
    GValue * dest_value)
{
  if (!gst_value_deserialize_fraction (dest_value,
          src_value->data[0].v_pointer))
    /* If the deserialize fails, ensure we leave the fraction in a
     * valid, if incorrect, state */
    gst_value_set_fraction (dest_value, 0, 1);
}

static void
gst_value_transform_double_fraction (const GValue * src_value,
    GValue * dest_value)
{
  gdouble src = g_value_get_double (src_value);
  gint n, d;

  gst_util_double_to_fraction (src, &n, &d);
  gst_value_set_fraction (dest_value, n, d);
}

static void
gst_value_transform_float_fraction (const GValue * src_value,
    GValue * dest_value)
{
  gfloat src = g_value_get_float (src_value);
  gint n, d;

  gst_util_double_to_fraction (src, &n, &d);
  gst_value_set_fraction (dest_value, n, d);
}

static void
gst_value_transform_fraction_double (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_double = ((double) src_value->data[0].v_int) /
      ((double) src_value->data[1].v_int);
}

static void
gst_value_transform_fraction_float (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_float = ((float) src_value->data[0].v_int) /
      ((float) src_value->data[1].v_int);
}

static gint
gst_value_compare_fraction (const GValue * value1, const GValue * value2)
{
  gint n1, n2;
  gint d1, d2;
  gint ret;

  n1 = value1->data[0].v_int;
  n2 = value2->data[0].v_int;
  d1 = value1->data[1].v_int;
  d2 = value2->data[1].v_int;

  /* fractions are reduced when set, so we can quickly see if they're equal */
  if (n1 == n2 && d1 == d2)
    return GST_VALUE_EQUAL;

  if (d1 == 0 && d2 == 0)
    return GST_VALUE_UNORDERED;
  else if (d1 == 0)
    return GST_VALUE_GREATER_THAN;
  else if (d2 == 0)
    return GST_VALUE_LESS_THAN;

  ret = gst_util_fraction_compare (n1, d1, n2, d2);
  if (ret == -1)
    return GST_VALUE_LESS_THAN;
  else if (ret == 1)
    return GST_VALUE_GREATER_THAN;

  /* Equality can't happen here because we check for that
   * first already */
  g_return_val_if_reached (GST_VALUE_UNORDERED);
}

/*********
 * GDate *
 *********/

static gint
gst_value_compare_date (const GValue * value1, const GValue * value2)
{
  const GDate *date1 = (const GDate *) g_value_get_boxed (value1);
  const GDate *date2 = (const GDate *) g_value_get_boxed (value2);
  guint32 j1, j2;

  if (date1 == date2)
    return GST_VALUE_EQUAL;

  if ((date1 == NULL || !g_date_valid (date1))
      && (date2 != NULL && g_date_valid (date2))) {
    return GST_VALUE_LESS_THAN;
  }

  if ((date2 == NULL || !g_date_valid (date2))
      && (date1 != NULL && g_date_valid (date1))) {
    return GST_VALUE_GREATER_THAN;
  }

  if (date1 == NULL || date2 == NULL || !g_date_valid (date1)
      || !g_date_valid (date2)) {
    return GST_VALUE_UNORDERED;
  }

  j1 = g_date_get_julian (date1);
  j2 = g_date_get_julian (date2);

  if (j1 == j2)
    return GST_VALUE_EQUAL;
  else if (j1 < j2)
    return GST_VALUE_LESS_THAN;
  else
    return GST_VALUE_GREATER_THAN;
}

static gchar *
gst_value_serialize_date (const GValue * val)
{
  const GDate *date = (const GDate *) g_value_get_boxed (val);

  if (date == NULL || !g_date_valid (date))
    return g_strdup ("9999-99-99");

  return g_strdup_printf ("%04u-%02u-%02u", g_date_get_year (date),
      g_date_get_month (date), g_date_get_day (date));
}

static gboolean
gst_value_deserialize_date (GValue * dest, const gchar * s)
{
  guint year, month, day;

  if (!s || sscanf (s, "%04u-%02u-%02u", &year, &month, &day) != 3)
    return FALSE;

  if (!g_date_valid_dmy (day, month, year))
    return FALSE;

  g_value_take_boxed (dest, g_date_new_dmy (day, month, year));
  return TRUE;
}

/*************
 * GstDateTime *
 *************/

static gint
gst_value_compare_date_time (const GValue * value1, const GValue * value2)
{
  const GstDateTime *date1 = (const GstDateTime *) g_value_get_boxed (value1);
  const GstDateTime *date2 = (const GstDateTime *) g_value_get_boxed (value2);

  if (date1 == date2)
    return GST_VALUE_EQUAL;

  if ((date1 == NULL) && (date2 != NULL)) {
    return GST_VALUE_LESS_THAN;
  }
  if ((date2 == NULL) && (date1 != NULL)) {
    return GST_VALUE_LESS_THAN;
  }

  /* returns GST_VALUE_* */
  return __gst_date_time_compare (date1, date2);
}

static gchar *
gst_value_serialize_date_time (const GValue * val)
{
  GstDateTime *date = (GstDateTime *) g_value_get_boxed (val);

  if (date == NULL)
    return g_strdup ("null");

  return __gst_date_time_serialize (date, TRUE);
}

static gboolean
gst_value_deserialize_date_time (GValue * dest, const gchar * s)
{
  GstDateTime *datetime;

  if (!s || strcmp (s, "null") == 0) {
    return FALSE;
  }

  datetime = gst_date_time_new_from_iso8601_string (s);
  if (datetime != NULL) {
    g_value_take_boxed (dest, datetime);
    return TRUE;
  }
  GST_WARNING ("Failed to deserialize date time string '%s'", s);
  return FALSE;
}

static void
gst_value_transform_date_string (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_pointer = gst_value_serialize_date (src_value);
}

static void
gst_value_transform_string_date (const GValue * src_value, GValue * dest_value)
{
  gst_value_deserialize_date (dest_value, src_value->data[0].v_pointer);
}


/************
 * bitmask *
 ************/

/* helper functions */
static void
gst_value_init_bitmask (GValue * value)
{
  value->data[0].v_uint64 = 0;
}

static void
gst_value_copy_bitmask (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_uint64 = src_value->data[0].v_uint64;
}

static gchar *
gst_value_collect_bitmask (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  if (n_collect_values != 1)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));

  gst_value_set_bitmask (value, (guint64) collect_values[0].v_int64);

  return NULL;
}

static gchar *
gst_value_lcopy_bitmask (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  guint64 *bitmask = collect_values[0].v_pointer;

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

  *bitmask = value->data[0].v_uint64;

  return NULL;
}

/**
 * gst_value_set_bitmask:
 * @value: a GValue initialized to #GST_TYPE_BITMASK
 * @bitmask: the bitmask
 *
 * Sets @value to the bitmask specified by @bitmask.
 */
void
gst_value_set_bitmask (GValue * value, guint64 bitmask)
{
  g_return_if_fail (GST_VALUE_HOLDS_BITMASK (value));

  value->data[0].v_uint64 = bitmask;
}

/**
 * gst_value_get_bitmask:
 * @value: a GValue initialized to #GST_TYPE_BITMASK
 *
 * Gets the bitmask specified by @value.
 *
 * Returns: the bitmask.
 */
guint64
gst_value_get_bitmask (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_BITMASK (value), 0);

  return value->data[0].v_uint64;
}

static gchar *
gst_value_serialize_bitmask (const GValue * value)
{
  guint64 bitmask = value->data[0].v_uint64;

  return g_strdup_printf ("0x%016" G_GINT64_MODIFIER "x", bitmask);
}

static gboolean
gst_value_deserialize_bitmask (GValue * dest, const gchar * s)
{
  gchar *endptr = NULL;
  guint64 val;

  if (G_UNLIKELY (s == NULL))
    return FALSE;

  if (G_UNLIKELY (dest == NULL || !GST_VALUE_HOLDS_BITMASK (dest)))
    return FALSE;

  errno = 0;
  val = g_ascii_strtoull (s, &endptr, 16);
  if (val == G_MAXUINT64 && (errno == ERANGE || errno == EINVAL))
    return FALSE;
  if (val == 0 && endptr == s)
    return FALSE;

  gst_value_set_bitmask (dest, val);

  return TRUE;
}

static void
gst_value_transform_bitmask_string (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_pointer = gst_value_serialize_bitmask (src_value);
}

static void
gst_value_transform_string_bitmask (const GValue * src_value,
    GValue * dest_value)
{
  if (!gst_value_deserialize_bitmask (dest_value, src_value->data[0].v_pointer))
    gst_value_set_bitmask (dest_value, 0);
}

static void
gst_value_transform_uint64_bitmask (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_uint64 = src_value->data[0].v_uint64;
}

static void
gst_value_transform_bitmask_uint64 (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_uint64 = src_value->data[0].v_uint64;
}

static gint
gst_value_compare_bitmask (const GValue * value1, const GValue * value2)
{
  guint64 v1, v2;

  v1 = value1->data[0].v_uint64;
  v2 = value2->data[0].v_uint64;

  if (v1 == v2)
    return GST_VALUE_EQUAL;

  return GST_VALUE_UNORDERED;
}

/************
 * flagset *
 ************/

/* helper functions */
static void
gst_value_init_flagset (GValue * value)
{
  value->data[0].v_uint = 0;
  value->data[1].v_uint = 0;
}

static void
gst_value_copy_flagset (const GValue * src_value, GValue * dest_value)
{
  dest_value->data[0].v_uint = src_value->data[0].v_uint;
  dest_value->data[1].v_uint = src_value->data[1].v_uint;
}

static gchar *
gst_value_collect_flagset (GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  if (n_collect_values != 2)
    return g_strdup_printf ("not enough value locations for `%s' passed",
        G_VALUE_TYPE_NAME (value));

  gst_value_set_flagset (value,
      (guint) collect_values[0].v_int, (guint) collect_values[1].v_int);

  return NULL;
}

static gchar *
gst_value_lcopy_flagset (const GValue * value, guint n_collect_values,
    GTypeCValue * collect_values, guint collect_flags)
{
  guint *flags = collect_values[0].v_pointer;
  guint *mask = collect_values[1].v_pointer;

  *flags = value->data[0].v_uint;
  *mask = value->data[1].v_uint;

  return NULL;
}

/**
 * gst_value_set_flagset:
 * @value: a GValue initialized to %GST_TYPE_FLAG_SET
 * @flags: The value of the flags set or unset
 * @mask: The mask indicate which flags bits must match for comparisons
 *
 * Sets @value to the flags and mask values provided in @flags and @mask.
 * The @flags value indicates the values of flags, the @mask represents
 * which bits in the flag value have been set, and which are "don't care"
 *
 * Since: 1.6
 */
void
gst_value_set_flagset (GValue * value, guint flags, guint mask)
{
  g_return_if_fail (GST_VALUE_HOLDS_FLAG_SET (value));

  /* Normalise and only keep flags mentioned in the mask */
  value->data[0].v_uint = flags & mask;
  value->data[1].v_uint = mask;
}

/**
 * gst_value_get_flagset_flags:
 * @value: a GValue initialized to #GST_TYPE_FLAG_SET
 *
 * Retrieve the flags field of a GstFlagSet @value.
 *
 * Returns: the flags field of the flagset instance.
 *
 * Since: 1.6
 */
guint
gst_value_get_flagset_flags (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (value), 0);

  return value->data[0].v_uint;
}

/**
 * gst_value_get_flagset_mask:
 * @value: a GValue initialized to #GST_TYPE_FLAG_SET
 *
 * Retrieve the mask field of a GstFlagSet @value.
 *
 * Returns: the mask field of the flagset instance.
 *
 * Since: 1.6
 */
guint
gst_value_get_flagset_mask (const GValue * value)
{
  g_return_val_if_fail (GST_VALUE_HOLDS_FLAG_SET (value), 1);

  return value->data[1].v_uint;
}

static gchar *
gst_value_serialize_flagset (const GValue * value)
{
  guint flags = value->data[0].v_uint;
  guint mask = value->data[1].v_uint;
  GstFlagSetClass *set_klass =
      (GstFlagSetClass *) g_type_class_ref (G_VALUE_TYPE (value));
  gchar *result;

  result = g_strdup_printf ("%x:%x", flags, mask);

  /* If this flag set class has an associated GFlags GType, and some
   * bits in the mask, serialize the bits in human-readable form to
   * aid debugging */
  if (mask && set_klass->flags_type) {
    GFlagsClass *flags_klass =
        (GFlagsClass *) (g_type_class_ref (set_klass->flags_type));
    GFlagsValue *fl;
    gchar *tmp;
    gboolean first = TRUE;

    g_return_val_if_fail (flags_klass, NULL);

    /* some bits in the mask are set, so serialize one by one, according
     * to whether that bit is set or cleared in the flags value */
    while (mask) {
      fl = g_flags_get_first_value (flags_klass, mask);
      if (fl == NULL) {
        /* No more bits match in the flags mask - time to stop */
        mask = 0;
        break;
      }

      tmp = g_strconcat (result,
          first ? ":" : "",
          (flags & fl->value) ? "+" : "/", fl->value_nick, NULL);
      g_free (result);
      result = tmp;
      first = FALSE;

      /* clear flag */
      mask &= ~fl->value;
    }
    g_type_class_unref (flags_klass);

  }
  g_type_class_unref (set_klass);

  return result;
}

static gboolean
is_valid_flags_string (const gchar * s)
{
  /* We're looking to match +this/that+other-thing/not-this-thing type strings */
  return g_regex_match_simple ("^([\\+\\/][\\w\\d-]+)+$", s, G_REGEX_CASELESS,
      0);
}

static gboolean
gst_value_deserialize_flagset (GValue * dest, const gchar * s)
{
  gboolean res = FALSE;
  guint flags, mask;
  gchar *cur, *next;

  if (G_UNLIKELY (s == NULL))
    return FALSE;

  if (G_UNLIKELY (dest == NULL || !GST_VALUE_HOLDS_FLAG_SET (dest)))
    return FALSE;

  /* Flagset strings look like %x:%x - hex flags : hex bitmask,
   * 32-bit each, or like a concatenated list of flag nicks,
   * with either '+' or '/' in front. The first form
   * may optionally be followed by ':' and a set of text flag descriptions
   * for easier debugging */

  /* Try and interpret as hex form first, as it's the most efficient */
  /* Read the flags first */
  flags = strtoul (s, &next, 16);
  if (G_UNLIKELY ((flags == 0 && errno == EINVAL) || s == next))
    goto try_as_flags_string;
  /* Next char should be a colon */
  if (next[0] == ':')
    next++;

  /* Read the mask */
  cur = next;
  mask = strtoul (cur, &next, 16);
  if (G_UNLIKELY ((mask == 0 && errno == EINVAL) || cur == next))
    goto try_as_flags_string;

  /* Next char should be NULL terminator, or a ':'. If ':', we need the flag string after */
  if (G_UNLIKELY (next[0] == 0)) {
    res = TRUE;
    goto done;
  }

  if (next[0] != ':')
    return FALSE;

  s = next + 1;

  if (g_str_equal (g_type_name (G_VALUE_TYPE (dest)), "GstFlagSet")) {
    /* If we're parsing a generic flag set, that can mean we're guessing
     * at the type in deserialising a GstStructure so at least check that
     * we have a valid-looking string, so we don't cause deserialisation of
     * other types of strings like 00:01:00:00 - https://bugzilla.gnome.org/show_bug.cgi?id=779755 */
    if (is_valid_flags_string (s)) {
      res = TRUE;
      goto done;
    }
    return FALSE;
  }

  /* Otherwise, we already got a hex string for a valid non-generic flagset type */
  res = TRUE;
  goto done;

try_as_flags_string:

  {
    const gchar *set_class = g_type_name (G_VALUE_TYPE (dest));
    GFlagsClass *flags_klass = NULL;
    const gchar *end;

    if (g_str_equal (set_class, "GstFlagSet")) {
      /* There's no hope to parse the fields of generic flag set if we didn't already
       * catch a hex-string above */
      return FALSE;
    }

    /* Flags class is the FlagSet class with 'Set' removed from the end */
    end = g_strrstr (set_class, "Set");

    if (end != NULL) {
      gchar *class_name = g_strndup (set_class, end - set_class);
      GType flags_type = g_type_from_name (class_name);
      if (flags_type == 0) {
        GST_TRACE ("Looking for dynamic type %s", class_name);
        gst_dynamic_type_factory_load (class_name);
      }

      if (flags_type != 0) {
        flags_klass = g_type_class_ref (flags_type);
        GST_TRACE ("Going to parse %s as %s", s, class_name);
      }
      g_free (class_name);
    }

    if (flags_klass) {
      res = gst_value_gflags_str_to_flags (flags_klass, s, &flags, &mask);
      g_type_class_unref (flags_klass);
    }
  }

done:
  if (res)
    gst_value_set_flagset (dest, flags, mask);
  return res;

}

static void
gst_value_transform_flagset_string (const GValue * src_value,
    GValue * dest_value)
{
  dest_value->data[0].v_pointer = gst_value_serialize_flagset (src_value);
}

static void
gst_value_transform_string_flagset (const GValue * src_value,
    GValue * dest_value)
{
  if (!gst_value_deserialize_flagset (dest_value, src_value->data[0].v_pointer)) {
    /* If the deserialize fails, ensure we leave the flags in a
     * valid, if incorrect, state */
    gst_value_set_flagset (dest_value, 0, 0);
  }
}

static gint
gst_value_compare_flagset (const GValue * value1, const GValue * value2)
{
  guint v1, v2;
  guint m1, m2;

  v1 = value1->data[0].v_uint;
  v2 = value2->data[0].v_uint;

  m1 = value1->data[1].v_uint;
  m2 = value2->data[1].v_uint;

  if (v1 == v2 && m1 == m2)
    return GST_VALUE_EQUAL;

  return GST_VALUE_UNORDERED;
}

/***********************
 * GstAllocationParams *
 ***********************/
static gint
gst_value_compare_allocation_params (const GValue * value1,
    const GValue * value2)
{
  GstAllocationParams *v1, *v2;

  v1 = value1->data[0].v_pointer;
  v2 = value2->data[0].v_pointer;

  if (v1 == NULL && v1 == v2)
    return GST_VALUE_EQUAL;

  if (v1 == NULL || v2 == NULL)
    return GST_VALUE_UNORDERED;

  if (v1->flags == v2->flags && v1->align == v2->align &&
      v1->prefix == v2->prefix && v1->padding == v2->padding)
    return GST_VALUE_EQUAL;

  return GST_VALUE_UNORDERED;
}


/************
 * GObject *
 ************/

static gint
gst_value_compare_object (const GValue * value1, const GValue * value2)
{
  gpointer v1, v2;

  v1 = value1->data[0].v_pointer;
  v2 = value2->data[0].v_pointer;

  if (v1 == v2)
    return GST_VALUE_EQUAL;

  return GST_VALUE_UNORDERED;
}

static void
gst_value_transform_object_string (const GValue * src_value,
    GValue * dest_value)
{
  GstObject *obj;
  gchar *str;

  obj = g_value_get_object (src_value);
  if (obj) {
    str =
        g_strdup_printf ("(%s) %s", G_OBJECT_TYPE_NAME (obj),
        GST_OBJECT_NAME (obj));
  } else {
    str = g_strdup ("NULL");
  }

  dest_value->data[0].v_pointer = str;
}

static GTypeInfo _info = {
  0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL,
};

static GTypeFundamentalInfo _finfo = {
  0
};

#define FUNC_VALUE_GET_TYPE_CLASSED(type, name, csize, flags)   \
GType _gst_ ## type ## _type = 0;                               \
                                                                \
GType gst_ ## type ## _get_type (void)                          \
{                                                               \
  static volatile GType gst_ ## type ## _type = 0;              \
                                                                \
  if (g_once_init_enter (&gst_ ## type ## _type)) {             \
    GType _type;                                                \
    _info.class_size = csize;                                   \
    _finfo.type_flags = flags;                                  \
    _info.value_table = & _gst_ ## type ## _value_table;        \
    _type = g_type_register_fundamental (                       \
        g_type_fundamental_next (),                             \
        name, &_info, &_finfo, 0);                              \
    _gst_ ## type ## _type = _type;                             \
    g_once_init_leave(&gst_ ## type ## _type, _type);           \
  }                                                             \
                                                                \
  return gst_ ## type ## _type;                                 \
}

#define FUNC_VALUE_GET_TYPE(type, name) \
  FUNC_VALUE_GET_TYPE_CLASSED(type, name, 0, 0)

static const GTypeValueTable _gst_int_range_value_table = {
  gst_value_init_int_range,
  NULL,
  gst_value_copy_int_range,
  NULL,
  (char *) "ii",
  gst_value_collect_int_range, (char *) "pp", gst_value_lcopy_int_range
};

FUNC_VALUE_GET_TYPE (int_range, "GstIntRange");

static const GTypeValueTable _gst_int64_range_value_table = {
  gst_value_init_int64_range,
  gst_value_free_int64_range,
  gst_value_copy_int64_range,
  NULL,
  (char *) "qq",
  gst_value_collect_int64_range,
  (char *) "pp", gst_value_lcopy_int64_range
};

FUNC_VALUE_GET_TYPE (int64_range, "GstInt64Range");

static const GTypeValueTable _gst_double_range_value_table = {
  gst_value_init_double_range,
  NULL,
  gst_value_copy_double_range,
  NULL,
  (char *) "dd",
  gst_value_collect_double_range,
  (char *) "pp", gst_value_lcopy_double_range
};

FUNC_VALUE_GET_TYPE (double_range, "GstDoubleRange");

static const GTypeValueTable _gst_fraction_range_value_table = {
  gst_value_init_fraction_range,
  gst_value_free_fraction_range,
  gst_value_copy_fraction_range,
  NULL,
  (char *) "iiii",
  gst_value_collect_fraction_range,
  (char *) "pppp", gst_value_lcopy_fraction_range
};

FUNC_VALUE_GET_TYPE (fraction_range, "GstFractionRange");

static const GTypeValueTable _gst_value_list_value_table = {
  gst_value_init_list_or_array,
  gst_value_free_list_or_array,
  gst_value_copy_list_or_array,
  gst_value_list_or_array_peek_pointer,
  (char *) "p",
  gst_value_collect_list_or_array,
  (char *) "p", gst_value_lcopy_list_or_array
};

FUNC_VALUE_GET_TYPE (value_list, "GstValueList");

static const GTypeValueTable _gst_value_array_value_table = {
  gst_value_init_list_or_array,
  gst_value_free_list_or_array,
  gst_value_copy_list_or_array,
  gst_value_list_or_array_peek_pointer,
  (char *) "p",
  gst_value_collect_list_or_array,
  (char *) "p", gst_value_lcopy_list_or_array
};

FUNC_VALUE_GET_TYPE (value_array, "GstValueArray");

static const GTypeValueTable _gst_fraction_value_table = {
  gst_value_init_fraction,
  NULL,
  gst_value_copy_fraction,
  NULL,
  (char *) "ii",
  gst_value_collect_fraction, (char *) "pp", gst_value_lcopy_fraction
};

FUNC_VALUE_GET_TYPE (fraction, "GstFraction");

static const GTypeValueTable _gst_bitmask_value_table = {
  gst_value_init_bitmask,
  NULL,
  gst_value_copy_bitmask,
  NULL,
  (char *) "q",
  gst_value_collect_bitmask, (char *) "p", gst_value_lcopy_bitmask
};

FUNC_VALUE_GET_TYPE (bitmask, "GstBitmask");

static const GTypeValueTable _gst_flagset_value_table = {
  gst_value_init_flagset,
  NULL,
  gst_value_copy_flagset,
  NULL,
  (char *) "ii",
  gst_value_collect_flagset, (char *) "pp", gst_value_lcopy_flagset
};

FUNC_VALUE_GET_TYPE_CLASSED (flagset, "GstFlagSet",
    sizeof (GstFlagSetClass), G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE);

GType
gst_g_thread_get_type (void)
{
  return G_TYPE_THREAD;
}

#define SERIAL_VTABLE(t,c,s,d) { t, c, s, d }

#define REGISTER_SERIALIZATION_CONST(_gtype, _type)                     \
G_STMT_START {                                                          \
  static const GstValueTable gst_value =                                \
    SERIAL_VTABLE (_gtype, gst_value_compare_ ## _type,                 \
    gst_value_serialize_ ## _type, gst_value_deserialize_ ## _type);    \
  gst_value_register (&gst_value);                                      \
} G_STMT_END

#define REGISTER_SERIALIZATION(_gtype, _type)                           \
G_STMT_START {                                                          \
  static GstValueTable gst_value =                                      \
    SERIAL_VTABLE (0, gst_value_compare_ ## _type,                      \
    gst_value_serialize_ ## _type, gst_value_deserialize_ ## _type);    \
  gst_value.type = _gtype;                                              \
  gst_value_register (&gst_value);                                      \
} G_STMT_END

#define REGISTER_SERIALIZATION_NO_COMPARE(_gtype, _type)                \
G_STMT_START {                                                          \
  static GstValueTable gst_value =                                      \
    SERIAL_VTABLE (0, NULL,                                             \
    gst_value_serialize_ ## _type, gst_value_deserialize_ ## _type);    \
  gst_value.type = _gtype;                                              \
  gst_value_register (&gst_value);                                      \
} G_STMT_END

#define REGISTER_SERIALIZATION_COMPARE_ONLY(_gtype, _type)              \
G_STMT_START {                                                          \
  static GstValueTable gst_value =                                      \
    SERIAL_VTABLE (0, gst_value_compare_ ## _type,                      \
        NULL, NULL);                                                    \
  gst_value.type = _gtype;                                              \
  gst_value_register (&gst_value);                                      \
} G_STMT_END

/* These initial sizes are used for the tables
 * below, and save a couple of reallocs at startup */

static const gint GST_VALUE_TABLE_DEFAULT_SIZE = 40;
static const gint GST_VALUE_UNION_TABLE_DEFAULT_SIZE = 8;
static const gint GST_VALUE_INTERSECT_TABLE_DEFAULT_SIZE = 16;
static const gint GST_VALUE_SUBTRACT_TABLE_DEFAULT_SIZE = 16;

void
_priv_gst_value_initialize (void)
{
  gst_value_table =
      g_array_sized_new (FALSE, FALSE, sizeof (GstValueTable),
      GST_VALUE_TABLE_DEFAULT_SIZE);
  gst_value_hash = g_hash_table_new (NULL, NULL);
  gst_value_union_funcs = g_array_sized_new (FALSE, FALSE,
      sizeof (GstValueUnionInfo), GST_VALUE_UNION_TABLE_DEFAULT_SIZE);
  gst_value_intersect_funcs = g_array_sized_new (FALSE, FALSE,
      sizeof (GstValueIntersectInfo), GST_VALUE_INTERSECT_TABLE_DEFAULT_SIZE);
  gst_value_subtract_funcs = g_array_sized_new (FALSE, FALSE,
      sizeof (GstValueSubtractInfo), GST_VALUE_SUBTRACT_TABLE_DEFAULT_SIZE);

  REGISTER_SERIALIZATION (gst_int_range_get_type (), int_range);
  REGISTER_SERIALIZATION (gst_int64_range_get_type (), int64_range);
  REGISTER_SERIALIZATION (gst_double_range_get_type (), double_range);
  REGISTER_SERIALIZATION (gst_fraction_range_get_type (), fraction_range);
  REGISTER_SERIALIZATION (gst_value_list_get_type (), value_list);
  REGISTER_SERIALIZATION (gst_value_array_get_type (), value_array);
  REGISTER_SERIALIZATION (g_value_array_get_type (), g_value_array);
  REGISTER_SERIALIZATION (gst_buffer_get_type (), buffer);
  REGISTER_SERIALIZATION (gst_sample_get_type (), sample);
  REGISTER_SERIALIZATION (gst_fraction_get_type (), fraction);
  REGISTER_SERIALIZATION (gst_caps_get_type (), caps);
  REGISTER_SERIALIZATION (gst_tag_list_get_type (), tag_list);
  REGISTER_SERIALIZATION (G_TYPE_DATE, date);
  REGISTER_SERIALIZATION (gst_date_time_get_type (), date_time);
  REGISTER_SERIALIZATION (gst_bitmask_get_type (), bitmask);
  REGISTER_SERIALIZATION (gst_structure_get_type (), structure);
  REGISTER_SERIALIZATION (gst_flagset_get_type (), flagset);

  REGISTER_SERIALIZATION_NO_COMPARE (gst_segment_get_type (), segment);
  REGISTER_SERIALIZATION_NO_COMPARE (gst_caps_features_get_type (),
      caps_features);

  REGISTER_SERIALIZATION_COMPARE_ONLY (gst_allocation_params_get_type (),
      allocation_params);
  REGISTER_SERIALIZATION_COMPARE_ONLY (G_TYPE_OBJECT, object);

  REGISTER_SERIALIZATION_CONST (G_TYPE_DOUBLE, double);
  REGISTER_SERIALIZATION_CONST (G_TYPE_FLOAT, float);

  REGISTER_SERIALIZATION_CONST (G_TYPE_STRING, string);
  REGISTER_SERIALIZATION_CONST (G_TYPE_BOOLEAN, boolean);
  REGISTER_SERIALIZATION_CONST (G_TYPE_ENUM, enum);

  REGISTER_SERIALIZATION_CONST (G_TYPE_FLAGS, gflags);

  REGISTER_SERIALIZATION_CONST (G_TYPE_INT, int);

  REGISTER_SERIALIZATION_CONST (G_TYPE_INT64, int64);
  REGISTER_SERIALIZATION_CONST (G_TYPE_LONG, long);

  REGISTER_SERIALIZATION_CONST (G_TYPE_UINT, uint);
  REGISTER_SERIALIZATION_CONST (G_TYPE_UINT64, uint64);
  REGISTER_SERIALIZATION_CONST (G_TYPE_ULONG, ulong);

  REGISTER_SERIALIZATION_CONST (G_TYPE_UCHAR, uchar);

  REGISTER_SERIALIZATION (G_TYPE_GTYPE, gtype);

  g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
      gst_value_transform_int_range_string);
  g_value_register_transform_func (GST_TYPE_INT64_RANGE, G_TYPE_STRING,
      gst_value_transform_int64_range_string);
  g_value_register_transform_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_STRING,
      gst_value_transform_double_range_string);
  g_value_register_transform_func (GST_TYPE_FRACTION_RANGE, G_TYPE_STRING,
      gst_value_transform_fraction_range_string);
  g_value_register_transform_func (GST_TYPE_LIST, G_TYPE_STRING,
      gst_value_transform_list_string);
  g_value_register_transform_func (GST_TYPE_LIST, G_TYPE_VALUE_ARRAY,
      gst_value_transform_any_list_g_value_array);
  g_value_register_transform_func (GST_TYPE_ARRAY, G_TYPE_STRING,
      gst_value_transform_array_string);
  g_value_register_transform_func (GST_TYPE_ARRAY, G_TYPE_VALUE_ARRAY,
      gst_value_transform_any_list_g_value_array);
  g_value_register_transform_func (G_TYPE_VALUE_ARRAY, G_TYPE_STRING,
      gst_value_transform_g_value_array_string);
  g_value_register_transform_func (G_TYPE_VALUE_ARRAY, GST_TYPE_ARRAY,
      gst_value_transform_g_value_array_any_list);
  g_value_register_transform_func (G_TYPE_VALUE_ARRAY, GST_TYPE_LIST,
      gst_value_transform_g_value_array_any_list);
  g_value_register_transform_func (GST_TYPE_FRACTION, G_TYPE_STRING,
      gst_value_transform_fraction_string);
  g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_FRACTION,
      gst_value_transform_string_fraction);
  g_value_register_transform_func (GST_TYPE_FRACTION, G_TYPE_DOUBLE,
      gst_value_transform_fraction_double);
  g_value_register_transform_func (GST_TYPE_FRACTION, G_TYPE_FLOAT,
      gst_value_transform_fraction_float);
  g_value_register_transform_func (G_TYPE_DOUBLE, GST_TYPE_FRACTION,
      gst_value_transform_double_fraction);
  g_value_register_transform_func (G_TYPE_FLOAT, GST_TYPE_FRACTION,
      gst_value_transform_float_fraction);
  g_value_register_transform_func (G_TYPE_DATE, G_TYPE_STRING,
      gst_value_transform_date_string);
  g_value_register_transform_func (G_TYPE_STRING, G_TYPE_DATE,
      gst_value_transform_string_date);
  g_value_register_transform_func (GST_TYPE_OBJECT, G_TYPE_STRING,
      gst_value_transform_object_string);
  g_value_register_transform_func (GST_TYPE_BITMASK, G_TYPE_UINT64,
      gst_value_transform_bitmask_uint64);
  g_value_register_transform_func (GST_TYPE_BITMASK, G_TYPE_STRING,
      gst_value_transform_bitmask_string);
  g_value_register_transform_func (G_TYPE_UINT64, GST_TYPE_BITMASK,
      gst_value_transform_uint64_bitmask);
  g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_BITMASK,
      gst_value_transform_string_bitmask);

  g_value_register_transform_func (GST_TYPE_FLAG_SET, G_TYPE_STRING,
      gst_value_transform_flagset_string);
  g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_FLAG_SET,
      gst_value_transform_string_flagset);

  gst_value_register_intersect_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
      gst_value_intersect_int_int_range);
  gst_value_register_intersect_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
      gst_value_intersect_int_range_int_range);
  gst_value_register_intersect_func (G_TYPE_INT64, GST_TYPE_INT64_RANGE,
      gst_value_intersect_int64_int64_range);
  gst_value_register_intersect_func (GST_TYPE_INT64_RANGE,
      GST_TYPE_INT64_RANGE, gst_value_intersect_int64_range_int64_range);
  gst_value_register_intersect_func (G_TYPE_DOUBLE, GST_TYPE_DOUBLE_RANGE,
      gst_value_intersect_double_double_range);
  gst_value_register_intersect_func (GST_TYPE_DOUBLE_RANGE,
      GST_TYPE_DOUBLE_RANGE, gst_value_intersect_double_range_double_range);
  gst_value_register_intersect_func (GST_TYPE_ARRAY, GST_TYPE_ARRAY,
      gst_value_intersect_array);
  gst_value_register_intersect_func (GST_TYPE_FRACTION,
      GST_TYPE_FRACTION_RANGE, gst_value_intersect_fraction_fraction_range);
  gst_value_register_intersect_func (GST_TYPE_FRACTION_RANGE,
      GST_TYPE_FRACTION_RANGE,
      gst_value_intersect_fraction_range_fraction_range);
  gst_value_register_intersect_func (GST_TYPE_FLAG_SET, GST_TYPE_FLAG_SET,
      gst_value_intersect_flagset_flagset);
  gst_value_register_intersect_func (GST_TYPE_STRUCTURE, GST_TYPE_STRUCTURE,
      gst_value_intersect_structure_structure);

  gst_value_register_subtract_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
      gst_value_subtract_int_int_range);
  gst_value_register_subtract_func (GST_TYPE_INT_RANGE, G_TYPE_INT,
      gst_value_subtract_int_range_int);
  gst_value_register_subtract_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
      gst_value_subtract_int_range_int_range);
  gst_value_register_subtract_func (G_TYPE_INT64, GST_TYPE_INT64_RANGE,
      gst_value_subtract_int64_int64_range);
  gst_value_register_subtract_func (GST_TYPE_INT64_RANGE, G_TYPE_INT64,
      gst_value_subtract_int64_range_int64);
  gst_value_register_subtract_func (GST_TYPE_INT64_RANGE,
      GST_TYPE_INT64_RANGE, gst_value_subtract_int64_range_int64_range);
  gst_value_register_subtract_func (G_TYPE_DOUBLE, GST_TYPE_DOUBLE_RANGE,
      gst_value_subtract_double_double_range);
  gst_value_register_subtract_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_DOUBLE,
      gst_value_subtract_double_range_double);
  gst_value_register_subtract_func (GST_TYPE_DOUBLE_RANGE,
      GST_TYPE_DOUBLE_RANGE, gst_value_subtract_double_range_double_range);
  gst_value_register_subtract_func (GST_TYPE_FRACTION,
      GST_TYPE_FRACTION_RANGE, gst_value_subtract_fraction_fraction_range);
  gst_value_register_subtract_func (GST_TYPE_FRACTION_RANGE,
      GST_TYPE_FRACTION, gst_value_subtract_fraction_range_fraction);
  gst_value_register_subtract_func (GST_TYPE_FRACTION_RANGE,
      GST_TYPE_FRACTION_RANGE,
      gst_value_subtract_fraction_range_fraction_range);

  /* see bug #317246, #64994, #65041 */
  {
    volatile GType date_type = G_TYPE_DATE;

    g_type_name (date_type);
  }

  gst_value_register_union_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
      gst_value_union_int_int_range);
  gst_value_register_union_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
      gst_value_union_int_range_int_range);
  gst_value_register_union_func (GST_TYPE_FLAG_SET, GST_TYPE_FLAG_SET,
      gst_value_union_flagset_flagset);
  gst_value_register_union_func (GST_TYPE_STRUCTURE, GST_TYPE_STRUCTURE,
      gst_value_union_structure_structure);

#if GST_VERSION_NANO == 1
  /* If building from git master, check starting array sizes matched actual size
   * so we can keep the defines in sync and save a few reallocs on startup */
  if (gst_value_table->len > GST_VALUE_TABLE_DEFAULT_SIZE) {
    GST_ERROR ("Wrong initial gst_value_table size. "
        "Please set GST_VALUE_TABLE_DEFAULT_SIZE to %u in gstvalue.c",
        gst_value_table->len);
  }
  if (gst_value_union_funcs->len > GST_VALUE_UNION_TABLE_DEFAULT_SIZE) {
    GST_ERROR ("Wrong initial gst_value_union_funcs table size. "
        "Please set GST_VALUE_UNION_TABLE_DEFAULT_SIZE to %u in gstvalue.c",
        gst_value_union_funcs->len);
  }
  if (gst_value_intersect_funcs->len > GST_VALUE_INTERSECT_TABLE_DEFAULT_SIZE) {
    GST_ERROR ("Wrong initial gst_value_intersect_funcs table size. "
        "Please set GST_VALUE_INTERSECT_TABLE_DEFAULT_SIZE to %u in gstvalue.c",
        gst_value_intersect_funcs->len);
  }
  if (gst_value_subtract_funcs->len > GST_VALUE_SUBTRACT_TABLE_DEFAULT_SIZE) {
    GST_ERROR ("Wrong initial gst_value_subtract_funcs table size. "
        "Please set GST_VALUE_SUBTRACT_TABLE_DEFAULT_SIZE to %u in gstvalue.c",
        gst_value_subtract_funcs->len);
  }
#endif

#if 0
  /* Implement these if needed */
  gst_value_register_union_func (GST_TYPE_FRACTION, GST_TYPE_FRACTION_RANGE,
      gst_value_union_fraction_fraction_range);
  gst_value_register_union_func (GST_TYPE_FRACTION_RANGE,
      GST_TYPE_FRACTION_RANGE, gst_value_union_fraction_range_fraction_range);
#endif
}

static void
gst_flagset_class_init (gpointer g_class, gpointer class_data)
{
  GstFlagSetClass *f_class = (GstFlagSetClass *) (g_class);
  f_class->flags_type = (GType) GPOINTER_TO_SIZE (class_data);
}

/**
 * gst_flagset_register:
 * @flags_type: a #GType of a #G_TYPE_FLAGS type.
 *
 * Create a new sub-class of #GST_TYPE_FLAG_SET
 * which will pretty-print the human-readable flags
 * when serializing, for easier debugging.
 *
 * Since: 1.6
 */
GType
gst_flagset_register (GType flags_type)
{
  GTypeInfo info = {
    sizeof (GstFlagSetClass),
    NULL, NULL,
    (GClassInitFunc) gst_flagset_class_init,
    NULL, GSIZE_TO_POINTER (flags_type), 0, 0, NULL, NULL
  };
  GType t;
  gchar *class_name;

  g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), 0);

  class_name = g_strdup_printf ("%sSet", g_type_name (flags_type));

  t = g_type_register_static (GST_TYPE_FLAG_SET,
      g_intern_string (class_name), &info, 0);
  g_free (class_name);

  return t;
}
