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