/**
 * g_variant_get_size:
 * @value: a #GVariant instance
 *
 * Determines the number of bytes that would be required to store @value
 * with g_variant_store().
 *
 * If @value has a fixed-sized type then this function always returned
 * that fixed size.
 *
 * In the case that @value is already in serialised form or the size has
 * already been calculated (ie: this function has been called before)
 * then this function is O(1).  Otherwise, the size is calculated, an
 * operation which is approximately O(n) in the number of values
 * involved.
 *
 * Returns: the serialised size of @value
 *
 * Since: 2.24
 **/
gsize
g_variant_get_size (GVariant *value)
{
  g_variant_lock (value);
  g_variant_ensure_size (value);
  g_variant_unlock (value);

  return value->size;
}
/* < private >
 * g_variant_ensure_serialised:
 * @value: a #GVariant
 *
 * Ensures that @value is in serialised form.
 *
 * If @value is in tree form then this function ensures that the
 * serialised size is known and then allocates a buffer of that size and
 * serialises the instance into the buffer.  The 'children' array is
 * then released and the instance is set to serialised form based on the
 * contents of the buffer.
 *
 * The current thread must hold the lock on @value.
 */
static void
g_variant_ensure_serialised (GVariant *value)
{
  g_assert (value->state & STATE_LOCKED);

  if (~value->state & STATE_SERIALISED)
    {
      GBytes *bytes;
      gpointer data;

      g_variant_ensure_size (value);
      data = g_malloc (value->size);
      g_variant_serialise (value, data);

      g_variant_release_children (value);

      bytes = g_bytes_new_take (data, value->size);
      value->contents.serialised.data = g_bytes_get_data (bytes, NULL);
      value->contents.serialised.bytes = bytes;
      value->state |= STATE_SERIALISED;
    }
}
Exemple #3
0
/* < private >
 * g_variant_ensure_serialised:
 * @value: a #GVariant
 *
 * Ensures that @value is in serialised form.
 *
 * If @value is in tree form then this function ensures that the
 * serialised size is known and then allocates a buffer of that size and
 * serialises the instance into the buffer.  The 'children' array is
 * then released and the instance is set to serialised form based on the
 * contents of the buffer.
 *
 * The current thread must hold the lock on @value.
 */
static void
g_variant_ensure_serialised (GVariant *value)
{
  g_assert (value->state & STATE_LOCKED);

  if (~value->state & STATE_SERIALISED)
    {
      GBuffer *buffer;
      gpointer data;

      g_variant_ensure_size (value);
      data = g_malloc (value->size);
      g_variant_serialise (value, data);

      g_variant_release_children (value);

      buffer = g_buffer_new_take_data (data, value->size);
      value->contents.serialised.data = buffer->data;
      value->contents.serialised.buffer = buffer;
      value->state |= STATE_SERIALISED;
    }
}
/* < private >
 * g_variant_fill_gvs:
 * @serialised: a pointer to a #GVariantSerialised
 * @data: a #GVariant instance
 *
 * This is the callback that is passed by a tree-form container instance
 * to the serialiser.  This callback gets called on each child of the
 * container.  Each child is responsible for performing the following
 * actions:
 *
 *  - reporting its type
 *
 *  - reporting its serialised size (requires knowing the size first)
 *
 *  - possibly storing its serialised form into the provided buffer
 */
static void
g_variant_fill_gvs (GVariantSerialised *serialised,
                    gpointer            data)
{
  GVariant *value = data;

  g_variant_lock (value);
  g_variant_ensure_size (value);
  g_variant_unlock (value);

  if (serialised->type_info == NULL)
    serialised->type_info = value->type_info;
  g_assert (serialised->type_info == value->type_info);

  if (serialised->size == 0)
    serialised->size = value->size;
  g_assert (serialised->size == value->size);

  if (serialised->data)
    /* g_variant_store() is a public API, so it
     * it will reacquire the lock if it needs to.
     */
    g_variant_store (value, serialised->data);
}