/*
 * Copyright © 2008 Ryan Lortie
 * Copyright © 2010 Codethink Limited
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include "gvarianttypeinfo.h"

#include <glib/gtestutils.h>
#include <glib/gthread.h>
#include <glib/gslice.h>
#include <glib/ghash.h>

/* < private >
 * GVariantTypeInfo:
 *
 * This structure contains the necessary information to facilitate the
 * serialisation and fast deserialisation of a given type of GVariant
 * value.  A GVariant instance holds a pointer to one of these
 * structures to provide for efficient operation.
 *
 * The GVariantTypeInfo structures for all of the base types, plus the
 * "variant" type are stored in a read-only static array.
 *
 * For container types, a hash table and reference counting is used to
 * ensure that only one of these structures exists for any given type.
 * In general, a container GVariantTypeInfo will exist for a given type
 * only if one or more GVariant instances of that type exist or if
 * another GVariantTypeInfo has that type as a subtype.  For example, if
 * a process contains a single GVariant instance with type "(asv)", then
 * container GVariantTypeInfo structures will exist for "(asv)" and
 * for "as" (note that "s" and "v" always exist in the static array).
 *
 * The trickiest part of GVariantTypeInfo (and in fact, the major reason
 * for its existence) is the storage of somewhat magical constants that
 * allow for O(1) lookups of items in tuples.  This is described below.
 *
 * 'container_class' is set to 'a' or 'r' if the GVariantTypeInfo is
 * contained inside of an ArrayInfo or TupleInfo, respectively.  This
 * allows the storage of the necessary additional information.
 *
 * 'fixed_size' is set to the fixed size of the type, if applicable, or
 * 0 otherwise (since no type has a fixed size of 0).
 *
 * 'alignment' is set to one less than the alignment requirement for
 * this type.  This makes many operations much more convenient.
 */
struct _GVariantTypeInfo
{
  gsize fixed_size;
  guchar alignment;
  guchar container_class;
};

/* Container types are reference counted.  They also need to have their
 * type string stored explicitly since it is not merely a single letter.
 */
typedef struct
{
  GVariantTypeInfo info;

  gchar *type_string;
  gint ref_count;
} ContainerInfo;

/* For 'array' and 'maybe' types, we store some extra information on the
 * end of the GVariantTypeInfo struct -- the element type (ie: "s" for
 * "as").  The container GVariantTypeInfo structure holds a reference to
 * the element typeinfo.
 */
typedef struct
{
  ContainerInfo container;

  GVariantTypeInfo *element;
} ArrayInfo;

/* For 'tuple' and 'dict entry' types, we store extra information for
 * each member -- its type and how to find it inside the serialised data
 * in O(1) time using 4 variables -- 'i', 'a', 'b', and 'c'.  See the
 * comment on GVariantMemberInfo in gvarianttypeinfo.h.
 */
typedef struct
{
  ContainerInfo container;

  GVariantMemberInfo *members;
  gsize n_members;
} TupleInfo;


/* Hard-code the base types in a constant array */
static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
#define fixed_aligned(x)  x, x - 1
#define not_a_type             0,
#define unaligned         0, 0
#define aligned(x)        0, x - 1
  /* 'b' */ { fixed_aligned(1) },   /* boolean */
  /* 'c' */ { not_a_type },
  /* 'd' */ { fixed_aligned(8) },   /* double */
  /* 'e' */ { not_a_type },
  /* 'f' */ { not_a_type },
  /* 'g' */ { unaligned        },   /* signature string */
  /* 'h' */ { fixed_aligned(4) },   /* file handle (int32) */
  /* 'i' */ { fixed_aligned(4) },   /* int32 */
  /* 'j' */ { not_a_type },
  /* 'k' */ { not_a_type },
  /* 'l' */ { not_a_type },
  /* 'm' */ { not_a_type },
  /* 'n' */ { fixed_aligned(2) },   /* int16 */
  /* 'o' */ { unaligned        },   /* object path string */
  /* 'p' */ { not_a_type },
  /* 'q' */ { fixed_aligned(2) },   /* uint16 */
  /* 'r' */ { not_a_type },
  /* 's' */ { unaligned        },   /* string */
  /* 't' */ { fixed_aligned(8) },   /* uint64 */
  /* 'u' */ { fixed_aligned(4) },   /* uint32 */
  /* 'v' */ { aligned(8)       },   /* variant */
  /* 'w' */ { not_a_type },
  /* 'x' */ { fixed_aligned(8) },   /* int64 */
  /* 'y' */ { fixed_aligned(1) },   /* byte */
#undef fixed_aligned
#undef not_a_type
#undef unaligned
#undef aligned
};

/* We need to have type strings to return for the base types.  We store
 * those in another array.  Since all base type strings are single
 * characters this is easy.  By not storing pointers to strings into the
 * GVariantTypeInfo itself, we save a bunch of relocations.
 */
static const char g_variant_type_info_basic_chars[24][2] = {
  "b", " ", "d", " ", " ", "g", "h", "i", " ", " ", " ", " ",
  "n", "o", " ", "q", " ", "s", "t", "u", "v", " ", "x", "y"
};

/* sanity checks to make debugging easier */
static void
g_variant_type_info_check (const GVariantTypeInfo *info,
                           char                    container_class)
{
  g_assert (!container_class || info->container_class == container_class);

  /* alignment can only be one of these */
  g_assert (info->alignment == 0 || info->alignment == 1 ||
            info->alignment == 3 || info->alignment == 7);

  if (info->container_class)
    {
      ContainerInfo *container = (ContainerInfo *) info;

      /* extra checks for containers */
      g_assert_cmpint (container->ref_count, >, 0);
      g_assert (container->type_string != NULL);
    }
  else
    {
      gint index;

      /* if not a container, then ensure that it is a valid member of
       * the basic types table
       */
      index = info - g_variant_type_info_basic_table;

      g_assert (G_N_ELEMENTS (g_variant_type_info_basic_table) == 24);
      g_assert (G_N_ELEMENTS (g_variant_type_info_basic_chars) == 24);
      g_assert (0 <= index && index < 24);
      g_assert (g_variant_type_info_basic_chars[index][0] != ' ');
    }
}

/* < private >
 * g_variant_type_info_get_type_string:
 * @info: a #GVariantTypeInfo
 *
 * Gets the type string for @info.  The string is nul-terminated.
 */
const gchar *
g_variant_type_info_get_type_string (GVariantTypeInfo *info)
{
  g_variant_type_info_check (info, 0);

  if (info->container_class)
    {
      ContainerInfo *container = (ContainerInfo *) info;

      /* containers have their type string stored inside them */
      return container->type_string;
    }
  else
    {
      gint index;

      /* look up the type string in the base type array.  the call to
       * g_variant_type_info_check() above already ensured validity.
       */
      index = info - g_variant_type_info_basic_table;

      return g_variant_type_info_basic_chars[index];
    }
}

/* < private >
 * g_variant_type_info_query:
 * @info: a #GVariantTypeInfo
 * @alignment: (allow-none): the location to store the alignment, or %NULL
 * @fixed_size: (allow-none): the location to store the fixed size, or %NULL
 *
 * Queries @info to determine the alignment requirements and fixed size
 * (if any) of the type.
 *
 * @fixed_size, if non-%NULL is set to the fixed size of the type, or 0
 * to indicate that the type is a variable-sized type.  No type has a
 * fixed size of 0.
 *
 * @alignment, if non-%NULL, is set to one less than the required
 * alignment of the type.  For example, for a 32bit integer, @alignment
 * would be set to 3.  This allows you to round an integer up to the
 * proper alignment by performing the following efficient calculation:
 *
 *   offset += ((-offset) & alignment);
 */
void
g_variant_type_info_query (GVariantTypeInfo *info,
                           guint            *alignment,
                           gsize            *fixed_size)
{
  g_variant_type_info_check (info, 0);

  if (alignment)
    *alignment = info->alignment;

  if (fixed_size)
    *fixed_size = info->fixed_size;
}

/* == array == */
#define GV_ARRAY_INFO_CLASS 'a'
static ArrayInfo *
GV_ARRAY_INFO (GVariantTypeInfo *info)
{
  g_variant_type_info_check (info, GV_ARRAY_INFO_CLASS);

  return (ArrayInfo *) info;
}

static void
array_info_free (GVariantTypeInfo *info)
{
  ArrayInfo *array_info;

  g_assert (info->container_class == GV_ARRAY_INFO_CLASS);
  array_info = (ArrayInfo *) info;

  g_variant_type_info_unref (array_info->element);
  g_slice_free (ArrayInfo, array_info);
}

static ContainerInfo *
array_info_new (const GVariantType *type)
{
  ArrayInfo *info;

  info = g_slice_new (ArrayInfo);
  info->container.info.container_class = GV_ARRAY_INFO_CLASS;

  info->element = g_variant_type_info_get (g_variant_type_element (type));
  info->container.info.alignment = info->element->alignment;
  info->container.info.fixed_size = 0;

  return (ContainerInfo *) info;
}

/* < private >
 * g_variant_type_info_element:
 * @info: a #GVariantTypeInfo for an array or maybe type
 *
 * Returns the element type for the array or maybe type.  A reference is
 * not added, so the caller must add their own.
 */
GVariantTypeInfo *
g_variant_type_info_element (GVariantTypeInfo *info)
{
  return GV_ARRAY_INFO (info)->element;
}

/* < private >
 * g_variant_type_query_element:
 * @info: a #GVariantTypeInfo for an array or maybe type
 * @alignment: (allow-none): the location to store the alignment, or %NULL
 * @fixed_size: (allow-none): the location to store the fixed size, or %NULL
 *
 * Returns the alignment requires and fixed size (if any) for the
 * element type of the array.  This call is a convenience wrapper around
 * g_variant_type_info_element() and g_variant_type_info_query().
 */
void
g_variant_type_info_query_element (GVariantTypeInfo *info,
                                   guint            *alignment,
                                   gsize            *fixed_size)
{
  g_variant_type_info_query (GV_ARRAY_INFO (info)->element,
                             alignment, fixed_size);
}

/* == tuple == */
#define GV_TUPLE_INFO_CLASS 'r'
static TupleInfo *
GV_TUPLE_INFO (GVariantTypeInfo *info)
{
  g_variant_type_info_check (info, GV_TUPLE_INFO_CLASS);

  return (TupleInfo *) info;
}

static void
tuple_info_free (GVariantTypeInfo *info)
{
  TupleInfo *tuple_info;
  gint i;

  g_assert (info->container_class == GV_TUPLE_INFO_CLASS);
  tuple_info = (TupleInfo *) info;

  for (i = 0; i < tuple_info->n_members; i++)
    g_variant_type_info_unref (tuple_info->members[i].type_info);

  g_slice_free1 (sizeof (GVariantMemberInfo) * tuple_info->n_members,
                 tuple_info->members);
  g_slice_free (TupleInfo, tuple_info);
}

static void
tuple_allocate_members (const GVariantType  *type,
                        GVariantMemberInfo **members,
                        gsize               *n_members)
{
  const GVariantType *item_type;
  gsize i = 0;

  *n_members = g_variant_type_n_items (type);
  *members = g_slice_alloc (sizeof (GVariantMemberInfo) * *n_members);

  item_type = g_variant_type_first (type);
  while (item_type)
    {
      GVariantMemberInfo *member = &(*members)[i++];

      member->type_info = g_variant_type_info_get (item_type);
      item_type = g_variant_type_next (item_type);

      if (member->type_info->fixed_size)
        member->ending_type = G_VARIANT_MEMBER_ENDING_FIXED;
      else if (item_type == NULL)
        member->ending_type = G_VARIANT_MEMBER_ENDING_LAST;
      else
        member->ending_type = G_VARIANT_MEMBER_ENDING_OFFSET;
    }

  g_assert (i == *n_members);
}

/* this is g_variant_type_info_query for a given member of the tuple.
 * before the access is done, it is ensured that the item is within
 * range and %FALSE is returned if not.
 */
static gboolean
tuple_get_item (TupleInfo          *info,
                GVariantMemberInfo *item,
                gsize              *d,
                gsize              *e)
{
  if (&info->members[info->n_members] == item)
    return FALSE;

  *d = item->type_info->alignment;
  *e = item->type_info->fixed_size;
  return TRUE;
}

/* Read the documentation for #GVariantMemberInfo in gvarianttype.h
 * before attempting to understand this.
 *
 * This function adds one set of "magic constant" values (for one item
 * in the tuple) to the table.
 *
 * The algorithm in tuple_generate_table() calculates values of 'a', 'b'
 * and 'c' for each item, such that the procedure for finding the item
 * is to start at the end of the previous variable-sized item, add 'a',
 * then round up to the nearest multiple of 'b', then then add 'c'.
 * Note that 'b' is stored in the usual "one less than" form.  ie:
 *
 *   start = ROUND_UP(prev_end + a, (b + 1)) + c;
 *
 * We tweak these values a little to allow for a slightly easier
 * computation and more compact storage.
 */
static void
tuple_table_append (GVariantMemberInfo **items,
                    gsize                i,
                    gsize                a,
                    gsize                b,
                    gsize                c)
{
  GVariantMemberInfo *item = (*items)++;

  /* We can shift multiples of the alignment size from 'c' into 'a'.
   * As long as we're shifting whole multiples, it won't affect the
   * result.  This means that we can take the "aligned" portion off of
   * 'c' and add it into 'a'.
   *
   *  Imagine (for sake of clarity) that ROUND_10 rounds up to the
   *  nearest 10.  It is clear that:
   *
   *   ROUND_10(a) + c == ROUND_10(a + 10*(c / 10)) + (c % 10)
   *
   * ie: remove the 10s portion of 'c' and add it onto 'a'.
   *
   * To put some numbers on it, imagine we start with a = 34 and c = 27:
   *
   *  ROUND_10(34) + 27 = 40 + 27 = 67
   *
   * but also, we can split 27 up into 20 and 7 and do this:
   *
   *  ROUND_10(34 + 20) + 7 = ROUND_10(54) + 7 = 60 + 7 = 67
   *                ^^    ^
   * without affecting the result.  We do that here.
   *
   * This reduction in the size of 'c' means that we can store it in a
   * gchar instead of a gsize.  Due to how the structure is packed, this
   * ends up saving us 'two pointer sizes' per item in each tuple when
   * allocating using GSlice.
   */
  a += ~b & c;    /* take the "aligned" part of 'c' and add to 'a' */
  c &= b;         /* chop 'c' to contain only the unaligned part */


  /* Finally, we made one last adjustment.  Recall:
   *
   *   start = ROUND_UP(prev_end + a, (b + 1)) + c;
   *
   * Forgetting the '+ c' for the moment:
   *
   *   ROUND_UP(prev_end + a, (b + 1));
   *
   * we can do a "round up" operation by adding 1 less than the amount
   * to round up to, then rounding down.  ie:
   *
   *   #define ROUND_UP(x, y)    ROUND_DOWN(x + (y-1), y)
   *
   * Of course, for rounding down to a power of two, we can just mask
   * out the appropriate number of low order bits:
   *
   *   #define ROUND_DOWN(x, y)  (x & ~(y - 1))
   *
   * Which gives us
   *
   *   #define ROUND_UP(x, y)    (x + (y - 1) & ~(y - 1))
   *
   * but recall that our alignment value 'b' is already "one less".
   * This means that to round 'prev_end + a' up to 'b' we can just do:
   *
   *   ((prev_end + a) + b) & ~b
   *
   * Associativity, and putting the 'c' back on:
   *
   *   (prev_end + (a + b)) & ~b + c
   *
   * Now, since (a + b) is constant, we can just add 'b' to 'a' now and
   * store that as the number to add to prev_end.  Then we use ~b as the
   * number to take a bitwise 'and' with.  Finally, 'c' is added on.
   *
   * Note, however, that all the low order bits of the 'aligned' value
   * are masked out and that all of the high order bits of 'c' have been
   * "moved" to 'a' (in the previous step).  This means that there are
   * no overlapping bits in the addition -- so we can do a bitwise 'or'
   * equivalently.
   *
   * This means that we can now compute the start address of a given
   * item in the tuple using the algorithm given in the documentation
   * for #GVariantMemberInfo:
   *
   *   item_start = ((prev_end + a) & b) | c;
   */

  item->i = i;
  item->a = a + b;
  item->b = ~b;
  item->c = c;
}

static gsize
tuple_align (gsize offset,
             guint alignment)
{
  return offset + ((-offset) & alignment);
}

/* This function is the heart of the algorithm for calculating 'i', 'a',
 * 'b' and 'c' for each item in the tuple.
 *
 * Imagine we want to find the start of the "i" in the type "(su(qx)ni)".
 * That's a string followed by a uint32, then a tuple containing a
 * uint16 and a int64, then an int16, then our "i".  In order to get to
 * our "i" we:
 *
 * Start at the end of the string, align to 4 (for the uint32), add 4.
 * Align to 8, add 16 (for the tuple).  Align to 2, add 2 (for the
 * int16).  Then we're there.  It turns out that, given 3 simple rules,
 * we can flatten this iteration into one addition, one alignment, then
 * one more addition.
 *
 * The loop below plays through each item in the tuple, querying its
 * alignment and fixed_size into 'd' and 'e', respectively.  At all
 * times the variables 'a', 'b', and 'c' are maintained such that in
 * order to get to the current point, you add 'a', align to 'b' then add
 * 'c'.  'b' is kept in "one less than" form.  For each item, the proper
 * alignment is applied to find the values of 'a', 'b' and 'c' to get to
 * the start of that item.  Those values are recorded into the table.
 * The fixed size of the item (if applicable) is then added on.
 *
 * These 3 rules are how 'a', 'b' and 'c' are modified for alignment and
 * addition of fixed size.  They have been proven correct but are
 * presented here, without proof:
 *
 *  1) in order to "align to 'd'" where 'd' is less than or equal to the
 *     largest level of alignment seen so far ('b'), you align 'c' to
 *     'd'.
 *  2) in order to "align to 'd'" where 'd' is greater than the largest
 *     level of alignment seen so far, you add 'c' aligned to 'b' to the
 *     value of 'a', set 'b' to 'd' (ie: increase the 'largest alignment
 *     seen') and reset 'c' to 0.
 *  3) in order to "add 'e'", just add 'e' to 'c'.
 */
static void
tuple_generate_table (TupleInfo *info)
{
  GVariantMemberInfo *items = info->members;
  gsize i = -1, a = 0, b = 0, c = 0, d, e;

  /* iterate over each item in the tuple.
   *   'd' will be the alignment of the item (in one-less form)
   *   'e' will be the fixed size (or 0 for variable-size items)
   */
  while (tuple_get_item (info, items, &d, &e))
    {
      /* align to 'd' */
      if (d <= b)
        c = tuple_align (c, d);                   /* rule 1 */
      else
        a += tuple_align (c, b), b = d, c = 0;    /* rule 2 */

      /* the start of the item is at this point (ie: right after we
       * have aligned for it).  store this information in the table.
       */
      tuple_table_append (&items, i, a, b, c);

      /* "move past" the item by adding in its size. */
      if (e == 0)
        /* variable size:
         *
         * we'll have an offset stored to mark the end of this item, so
         * just bump the offset index to give us a new starting point
         * and reset all the counters.
         */
        i++, a = b = c = 0;
      else
        /* fixed size */
        c += e;                                   /* rule 3 */
    }
}

static void
tuple_set_base_info (TupleInfo *info)
{
  GVariantTypeInfo *base = &info->container.info;

  if (info->n_members > 0)
    {
      GVariantMemberInfo *m;

      /* the alignment requirement of the tuple is the alignment
       * requirement of its largest item.
       */
      base->alignment = 0;
      for (m = info->members; m < &info->members[info->n_members]; m++)
        /* can find the max of a list of "one less than" powers of two
         * by 'or'ing them
         */
        base->alignment |= m->type_info->alignment;

      m--; /* take 'm' back to the last item */

      /* the structure only has a fixed size if no variable-size
       * offsets are stored and the last item is fixed-sized too (since
       * an offset is never stored for the last item).
       */
      if (m->i == -1 && m->type_info->fixed_size)
        /* in that case, the fixed size can be found by finding the
         * start of the last item (in the usual way) and adding its
         * fixed size.
         *
         * if a tuple has a fixed size then it is always a multiple of
         * the alignment requirement (to make packing into arrays
         * easier) so we round up to that here.
         */
        base->fixed_size =
          tuple_align (((m->a & m->b) | m->c) + m->type_info->fixed_size,
                       base->alignment);
      else
        /* else, the tuple is not fixed size */
        base->fixed_size = 0;
    }
  else
    {
      /* the empty tuple: '()'.
       *
       * has a size of 1 and an no alignment requirement.
       *
       * It has a size of 1 (not 0) for two practical reasons:
       *
       *  1) So we can determine how many of them are in an array
       *     without dividing by zero or without other tricks.
       *
       *  2) Even if we had some trick to know the number of items in
       *     the array (as GVariant did at one time) this would open a
       *     potential denial of service attack: an attacker could send
       *     you an extremely small array (in terms of number of bytes)
       *     containing trillions of zero-sized items.  If you iterated
       *     over this array you would effectively infinite-loop your
       *     program.  By forcing a size of at least one, we bound the
       *     amount of computation done in response to a message to a
       *     reasonable function of the size of that message.
       */
      base->alignment = 0;
      base->fixed_size = 1;
    }
}

static ContainerInfo *
tuple_info_new (const GVariantType *type)
{
  TupleInfo *info;

  info = g_slice_new (TupleInfo);
  info->container.info.container_class = GV_TUPLE_INFO_CLASS;

  tuple_allocate_members (type, &info->members, &info->n_members);
  tuple_generate_table (info);
  tuple_set_base_info (info);

  return (ContainerInfo *) info;
}

/* < private >
 * g_variant_type_info_n_members:
 * @info: a #GVariantTypeInfo for a tuple or dictionary entry type
 *
 * Returns the number of members in a tuple or dictionary entry type.
 * For a dictionary entry this will always be 2.
 */
gsize
g_variant_type_info_n_members (GVariantTypeInfo *info)
{
  return GV_TUPLE_INFO (info)->n_members;
}

/* < private >
 * g_variant_type_info_member_info:
 * @info: a #GVariantTypeInfo for a tuple or dictionary entry type
 * @index: the member to fetch information for
 *
 * Returns the #GVariantMemberInfo for a given member.  See
 * documentation for that structure for why you would want this
 * information.
 *
 * @index must refer to a valid child (ie: strictly less than
 * g_variant_type_info_n_members() returns).
 */
const GVariantMemberInfo *
g_variant_type_info_member_info (GVariantTypeInfo *info,
                                 gsize             index)
{
  TupleInfo *tuple_info = GV_TUPLE_INFO (info);

  if (index < tuple_info->n_members)
    return &tuple_info->members[index];

  return NULL;
}

/* == new/ref/unref == */
static GRecMutex g_variant_type_info_lock;
static GHashTable *g_variant_type_info_table;

/* < private >
 * g_variant_type_info_get:
 * @type: a #GVariantType
 *
 * Returns a reference to a #GVariantTypeInfo for @type.
 *
 * If an info structure already exists for this type, a new reference is
 * returned.  If not, the required calculations are performed and a new
 * info structure is returned.
 *
 * It is appropriate to call g_variant_type_info_unref() on the return
 * value.
 */
GVariantTypeInfo *
g_variant_type_info_get (const GVariantType *type)
{
  char type_char;

  type_char = g_variant_type_peek_string (type)[0];

  if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE ||
      type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY ||
      type_char == G_VARIANT_TYPE_INFO_CHAR_TUPLE ||
      type_char == G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY)
    {
      GVariantTypeInfo *info;
      gchar *type_string;

      type_string = g_variant_type_dup_string (type);

      g_rec_mutex_lock (&g_variant_type_info_lock);

      if (g_variant_type_info_table == NULL)
        g_variant_type_info_table = g_hash_table_new (g_str_hash,
                                                      g_str_equal);
      info = g_hash_table_lookup (g_variant_type_info_table, type_string);

      if (info == NULL)
        {
          ContainerInfo *container;

          if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE ||
              type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY)
            {
              container = array_info_new (type);
            }
          else /* tuple or dict entry */
            {
              container = tuple_info_new (type);
            }

          info = (GVariantTypeInfo *) container;
          container->type_string = type_string;
          container->ref_count = 1;

          g_hash_table_insert (g_variant_type_info_table, type_string, info);
          type_string = NULL;
        }
      else
        g_variant_type_info_ref (info);

      g_rec_mutex_unlock (&g_variant_type_info_lock);
      g_variant_type_info_check (info, 0);
      g_free (type_string);

      return info;
    }
  else
    {
      const GVariantTypeInfo *info;
      int index;

      index = type_char - 'b';
      g_assert (G_N_ELEMENTS (g_variant_type_info_basic_table) == 24);
      g_assert_cmpint (0, <=, index);
      g_assert_cmpint (index, <, 24);

      info = g_variant_type_info_basic_table + index;
      g_variant_type_info_check (info, 0);

      return (GVariantTypeInfo *) info;
    }
}

/* < private >
 * g_variant_type_info_ref:
 * @info: a #GVariantTypeInfo
 *
 * Adds a reference to @info.
 */
GVariantTypeInfo *
g_variant_type_info_ref (GVariantTypeInfo *info)
{
  g_variant_type_info_check (info, 0);

  if (info->container_class)
    {
      ContainerInfo *container = (ContainerInfo *) info;

      g_assert_cmpint (container->ref_count, >, 0);
      g_atomic_int_inc (&container->ref_count);
    }

  return info;
}

/* < private >
 * g_variant_type_info_unref:
 * @info: a #GVariantTypeInfo
 *
 * Releases a reference held on @info.  This may result in @info being
 * freed.
 */
void
g_variant_type_info_unref (GVariantTypeInfo *info)
{
  g_variant_type_info_check (info, 0);

  if (info->container_class)
    {
      ContainerInfo *container = (ContainerInfo *) info;

      g_rec_mutex_lock (&g_variant_type_info_lock);
      if (g_atomic_int_dec_and_test (&container->ref_count))
        {
          g_hash_table_remove (g_variant_type_info_table,
                               container->type_string);
          if (g_hash_table_size (g_variant_type_info_table) == 0)
            {
              g_hash_table_unref (g_variant_type_info_table);
              g_variant_type_info_table = NULL;
            }
          g_rec_mutex_unlock (&g_variant_type_info_lock);

          g_free (container->type_string);

          if (info->container_class == GV_ARRAY_INFO_CLASS)
            array_info_free (info);

          else if (info->container_class == GV_TUPLE_INFO_CLASS)
            tuple_info_free (info);

          else
            g_assert_not_reached ();
        }
      else
        g_rec_mutex_unlock (&g_variant_type_info_lock);
    }
}

void
g_variant_type_info_assert_no_infos (void)
{
  g_assert (g_variant_type_info_table == NULL);
}
