/*
 *
 *  Embedded Linux library
 *
 *  Copyright (C) 2011-2014  Intel Corporation. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <endian.h>
#include <limits.h>

#include "private.h"
#include "useful.h"
#include "util.h"
#include "queue.h"
#include "string.h"
#include "log.h"
#include "dbus.h"
#include "dbus-private.h"
#include "gvariant-private.h"

static const char *simple_types = "sogybnqiuxtdh";
static const char *variable_types = "sogav";
static const char *fixed_types = "bynqhiuxtd";

/*
 * The alignment of a container type is equal to the largest alignment of
 * any potential child of that container. This means that, even if an array
 * of 32-bit integers is empty, it still must be aligned to the nearest
 * multiple of 4 bytes. It also means that the variant type (described below)
 * has an alignment of 8 (since it could potentially contain a value of any
 * other type and the maximum alignment is 8).
 */
static int get_basic_alignment(const char type)
{
	switch (type) {
	case 'b':
		return 1;
	case 'y':
		return 1;
	case 'n':
	case 'q':
		return 2;
	case 'i':
	case 'u':
		return 4;
	case 'x':
	case 't':
	case 'd':
		return 8;
	case 's':
	case 'g':
	case 'o':
		return 1;
	case 'h':
		return 4;
	case 'v':
		return 8;
	default:
		return 0;
	}
}

static int get_basic_fixed_size(const char type)
{
	switch (type) {
	case 'b':
		return 1;
	case 'y':
		return 1;
	case 'n':
	case 'q':
		return 2;
	case 'i':
	case 'u':
		return 4;
	case 'x':
	case 't':
	case 'd':
		return 8;
	case 'h':
		return 4;
	default:
		return 0;
	}
}

static const char *validate_next_type(const char *sig, int *out_alignment)
{
	char s = *sig;
	int alignment;

	if (s == '\0')
		return NULL;

	if (strchr(simple_types, s) || s == 'v') {
		*out_alignment = get_basic_alignment(s);
		return sig + 1;
	}

	switch (s) {
	case 'a':
		return validate_next_type(++sig, out_alignment);

	case '{':
		s = *++sig;

		/* Dictionary keys can only be simple types */
		if (!strchr(simple_types, s))
			return NULL;

		alignment = get_basic_alignment(s);

		sig = validate_next_type(sig + 1, out_alignment);

		if (!sig)
			return NULL;

		if (*sig != '}')
			return NULL;

		if (alignment > *out_alignment)
			*out_alignment = alignment;

		return sig + 1;

	case '(':
	{
		int max_alignment = 1, alignment;

		sig++;

		while (sig && *sig != ')') {
			sig = validate_next_type(sig, &alignment);

			if (alignment > max_alignment)
				max_alignment = alignment;
		}

		if (!sig)
			return NULL;

		if (*sig != ')')
			return NULL;

		*out_alignment = max_alignment;

		return sig + 1;
	}
	}

	return NULL;
}

bool _gvariant_valid_signature(const char *sig)
{
	const char *s = sig;
	int a;

	if (strlen(sig) > 255)
		return false;

	do {
		s = validate_next_type(s, &a);

		if (!s)
			return false;
	} while (*s);

	return true;
}

int _gvariant_num_children(const char *sig)
{
	const char *s = sig;
	int a;
	int num_children = 0;

	if (strlen(sig) > 255)
		return false;

	do {
		s = validate_next_type(s, &a);

		if (!s)
			return -1;

		num_children += 1;
	} while (*s);

	return num_children;
}

int _gvariant_get_alignment(const char *sig)
{
	int max_alignment = 1, alignment;
	const char *s = sig;

	/* 8 is the largest alignment possible, so quit if we reach it */
	while (*s && max_alignment != 8) {
		s = validate_next_type(s, &alignment);
		if (!s)
			return 0;

		if (alignment > max_alignment)
			max_alignment = alignment;
	}

	return max_alignment;
}

bool _gvariant_is_fixed_size(const char *sig)
{
	while (*sig != 0) {
		if (strchr(variable_types, sig[0]))
			return false;

		sig += 1;
	}

	return true;
}

int _gvariant_get_fixed_size(const char *sig)
{
	const char *s = sig;
	const char *p;
	int size = 0;
	int alignment;
	int max_alignment = 1;
	int r;

	while (*s) {
		if (strchr(variable_types, *s))
			return 0;

		if (strchr(fixed_types, *s)) {
			alignment = get_basic_alignment(*s);

			if (alignment > max_alignment)
				max_alignment = alignment;

			size = align_len(size, alignment);
			size += get_basic_fixed_size(*s);
			s++;
			continue;
		}

		if (*s == '}' || *s == ')')
			break;

		p = validate_next_type(s, &alignment);

		if (!p)
			return 0;

		if (alignment > max_alignment)
			max_alignment = alignment;

		size = align_len(size, alignment);

		/* Handle special case of unit type */
		if (s[0] == '(' && s[1] == ')')
			r = 1;
		else
			r = _gvariant_get_fixed_size(s + 1);

		if (r == 0)
			return 0;

		size += r;
		s = p;
	}

	size = align_len(size, max_alignment);

	return size;
}

static inline size_t offset_length(size_t size, size_t n_offsets)
{
	if (size + n_offsets <= 0xff)
		return 1;
	if (size + n_offsets * 2 <= 0xffff)
		return 2;
	if (size + n_offsets * 4 <= 0xffffffff)
		return 4;
	return 8;
}

static inline size_t read_word_le(const void *p, size_t sz) {
	union {
		uint16_t u16;
		uint32_t u32;
		uint64_t u64;
	} x;

	if (sz == 1)
		return *(uint8_t *) p;

	memcpy(&x, p, sz);

	if (sz == 2)
		return le16toh(x.u16);
	if (sz == 4)
		return le32toh(x.u32);
	return le64toh(x.u64);
}

static inline void write_word_le(void *p, size_t value, size_t sz) {
	union {
		uint16_t u16;
		uint32_t u32;
		uint64_t u64;
	} x;

	if (sz == 1) {
		*(uint8_t *) p = value;
		return;
	}

	if (sz == 2)
		x.u16 = htole16((uint16_t) value);
	else if (sz == 4)
		x.u32 = htole32((uint32_t) value);
	else
		x.u64 = htole64((uint64_t) value);

	memcpy(p, &x, sz);
}

static bool gvariant_iter_init_internal(struct l_dbus_message_iter *iter,
					struct l_dbus_message *message,
					enum dbus_container_type type,
					const char *sig_start,
					const char *sig_end, const void *data,
					size_t len)
{
	const char *p;
	int i;
	int v;
	char subsig[256];
	unsigned int num_variable = 0;
	unsigned int offset_len = offset_length(len, 0);
	size_t last_offset;
	struct gvariant_type_info {
		uint8_t sig_start;
		uint8_t sig_end;
		bool fixed_size : 1;
		unsigned int alignment : 4;
		size_t end;		/* Index past the end of the type */
	} *children;
	int n_children;

	if (sig_end) {
		size_t len = sig_end - sig_start;
		memcpy(subsig, sig_start, len);
		subsig[len] = '\0';
	} else
		strcpy(subsig, sig_start);

	iter->message = message;
	iter->sig_start = sig_start;
	iter->sig_len = strlen(subsig);
	iter->sig_pos = 0;
	iter->data = data;
	iter->len = len;
	iter->pos = 0;

	if (subsig[0] != '\0') {
		n_children = _gvariant_num_children(subsig);
		if (n_children < 0)
			return false;

		children = l_new(struct gvariant_type_info, n_children);
	} else {
		n_children = 0;

		children = NULL;
	}

	for (p = sig_start, i = 0; i < n_children; i++) {
		int alignment;
		size_t size;
		size_t len;

		children[i].sig_start = p - sig_start;
		p = validate_next_type(p, &alignment);
		children[i].sig_end = p - sig_start;

		len = children[i].sig_end - children[i].sig_start;
		memcpy(subsig, sig_start + children[i].sig_start, len);
		subsig[len] = '\0';

		children[i].alignment = alignment;
		children[i].fixed_size = _gvariant_is_fixed_size(subsig);

		if (children[i].fixed_size) {
			size = _gvariant_get_fixed_size(subsig);
			children[i].end = size;
		} else if (i + 1 < n_children)
			num_variable += 1;
	}

	if (len < num_variable * offset_len)
		goto fail;

	last_offset = len - num_variable * offset_len;

	if (num_variable > 0)
		iter->offsets = iter->data + len - offset_len;
	else
		iter->offsets = NULL;

	for (i = 0, v = 0; i < n_children; i++) {
		size_t o;

		if (children[i].fixed_size) {
			if (i == 0)
				continue;

			o = align_len(children[i-1].end,
					children[i].alignment);
			children[i].end += o;

			if (children[i].end > len)
				goto fail;

			continue;
		}

		if (num_variable == 0) {
			children[i].end = last_offset;
			continue;
		}

		v += 1;
		children[i].end = read_word_le(data + len - offset_len * v,
						offset_len);
		num_variable -= 1;

		if (children[i].end > len)
			goto fail;
	}

	iter->container_type = type;

	if (type == DBUS_CONTAINER_TYPE_ARRAY &&
			!children[0].fixed_size) {
		size_t offset = read_word_le(iter->data + iter->len -
						offset_len, offset_len);
		iter->offsets = iter->data + offset;
	}

	l_free(children);

	return true;

fail:
	l_free(children);
	return false;
}

bool _gvariant_iter_init(struct l_dbus_message_iter *iter,
				struct l_dbus_message *message,
				const char *sig_start, const char *sig_end,
				const void *data, size_t len)
{
	return gvariant_iter_init_internal(iter, message,
						DBUS_CONTAINER_TYPE_STRUCT,
						sig_start, sig_end, data, len);
}

static const void *next_item(struct l_dbus_message_iter *iter,
							size_t *out_item_size)
{
	const void *start;
	const char *p;
	char sig[256];
	int alignment;
	bool fixed_size;
	bool last_member;
	unsigned int sig_len;
	unsigned int offset_len;

	memcpy(sig, iter->sig_start + iter->sig_pos,
			iter->sig_len - iter->sig_pos);
	sig[iter->sig_len - iter->sig_pos] = '\0';

	/*
	 * Find the next type and make a note whether it is the last in the
	 * structure.  Arrays will always have a single complete type, so
	 * last_member will always be true.
	 */
	p = validate_next_type(sig, &alignment);
	if (!p)
		return NULL;

	sig_len = p - sig;

	last_member = *p == '\0';
	sig[sig_len] = '\0';

	fixed_size = _gvariant_is_fixed_size(sig);

	if (iter->container_type != DBUS_CONTAINER_TYPE_ARRAY)
		iter->sig_pos += sig_len;

	iter->pos = align_len(iter->pos, alignment);

	if (fixed_size) {
		*out_item_size = _gvariant_get_fixed_size(sig);
		goto done;
	}

	if (iter->container_type != DBUS_CONTAINER_TYPE_ARRAY && last_member) {
		unsigned int len = iter->len;

		offset_len = offset_length(iter->len, 0);

		if (iter->offsets && iter->offsets + offset_len <
				iter->data + len)
			len = iter->offsets + offset_len - iter->data;

		*out_item_size = len - iter->pos;
		goto done;
	}

	if (iter->offsets >= iter->data + iter->len)
			return NULL;

	offset_len = offset_length(iter->len, 0);
	*out_item_size = read_word_le(iter->offsets, offset_len) - iter->pos;

	/* In structures the offsets are in reverse order */
	if (iter->container_type == DBUS_CONTAINER_TYPE_ARRAY)
		iter->offsets += offset_len;
	else
		iter->offsets -= offset_len;

done:
	start = iter->data + iter->pos;

	if (start >= iter->data + iter->len)
		return NULL;

	iter->pos += *out_item_size;

	return start;
}

bool _gvariant_iter_next_entry_basic(struct l_dbus_message_iter *iter,
					char type, void *out)
{
	size_t item_size = 0;
	const void *start;
	uint8_t uint8_val;
	uint16_t uint16_val;
	uint32_t uint32_val;
	uint64_t uint64_val;
	int16_t int16_val;
	int32_t int32_val;
	int64_t int64_val;

	if (iter->pos >= iter->len)
		return false;

	if (iter->sig_start[iter->sig_pos] != type)
		return false;

	start = next_item(iter, &item_size);
	if (!start)
		return false;

	switch (type) {
	case 'o':
	case 's':
	case 'g':
	{
		const void *end = memchr(start, 0, item_size);

		if (!end)
			return false;

		*(const char**) out = start;
		break;
	}
	case 'b':
		uint8_val = l_get_u8(start);
		*(bool *) out = !!uint8_val;
		break;
	case 'y':
		uint8_val = l_get_u8(start);
		*(uint8_t *) out = uint8_val;
		break;
	case 'n':
		int16_val = l_get_s16(start);
		*(int16_t *) out = int16_val;
		break;
	case 'q':
		uint16_val = l_get_u16(start);
		*(uint16_t *) out = uint16_val;
		break;
	case 'i':
		int32_val = l_get_s32(start);
		*(int32_t *) out = int32_val;
		break;
	case 'h':
	case 'u':
		uint32_val = l_get_u32(start);
		*(uint32_t *) out = uint32_val;
		break;
	case 'x':
		int64_val = l_get_s64(start);
		*(int64_t *) out = int64_val;
		break;
	case 't':
		uint64_val = l_get_u64(start);
		*(uint64_t *) out = uint64_val;
		break;
	case 'd':
		uint64_val = l_get_u64(start);
		*(uint64_t *) out = uint64_val;
		break;
	}

	return true;
}

bool _gvariant_iter_enter_struct(struct l_dbus_message_iter *iter,
					struct l_dbus_message_iter *structure)
{
	bool is_dict = iter->sig_start[iter->sig_pos] == '{';
	bool is_struct = iter->sig_start[iter->sig_pos] == '(';
	const char *sig_start = iter->sig_start + iter->sig_pos + 1;
	const char *sig_end;
	const void *start;
	size_t item_size;
	enum dbus_container_type type;

	if (!is_dict && !is_struct)
		return false;

	start = next_item(iter, &item_size);
	if (!start)
		return false;

	/* For ARRAY containers the sig_pos is never incremented */
	if (iter->container_type == DBUS_CONTAINER_TYPE_ARRAY)
		sig_end = iter->sig_start + iter->sig_len - 1;
	else
		sig_end = iter->sig_start + iter->sig_pos - 1;

	type = is_dict ? DBUS_CONTAINER_TYPE_DICT_ENTRY :
			DBUS_CONTAINER_TYPE_STRUCT;

	return gvariant_iter_init_internal(structure, iter->message,
						type, sig_start, sig_end,
						start, item_size);
}

bool _gvariant_iter_enter_variant(struct l_dbus_message_iter *iter,
					struct l_dbus_message_iter *variant)
{
	size_t item_size;
	const void *start, *end, *nul;
	char signature[256];

	if (iter->sig_start[iter->sig_pos] != 'v')
		return false;

	start = next_item(iter, &item_size);
	if (!start)
		return false;

	/* Find the signature */
	end = start + item_size;
	nul = memrchr(start, 0, end - start);

	if (!nul)
		return false;

	if (end - nul - 1 > 255)
		return false;

	memcpy(signature, nul + 1, end - nul - 1);
	signature[end - nul - 1] = '\0';

	if (_gvariant_num_children(signature) != 1)
		return false;

	return gvariant_iter_init_internal(variant, iter->message,
						DBUS_CONTAINER_TYPE_VARIANT,
						nul + 1, end,
						start, nul - start);
}

bool _gvariant_iter_enter_array(struct l_dbus_message_iter *iter,
					struct l_dbus_message_iter *array)
{
	const char *sig_start;
	const char *sig_end;
	size_t item_size;
	const void *start;

	if (iter->sig_start[iter->sig_pos] != 'a')
		return false;

	sig_start = iter->sig_start + iter->sig_pos + 1;

	start = next_item(iter, &item_size);
	if (!start)
		return false;

	/* For ARRAY containers the sig_pos is never incremented */
	if (iter->container_type == DBUS_CONTAINER_TYPE_ARRAY)
		sig_end = iter->sig_start + iter->sig_len;
	else
		sig_end = iter->sig_start + iter->sig_pos;

	return gvariant_iter_init_internal(array, iter->message,
						DBUS_CONTAINER_TYPE_ARRAY,
						sig_start, sig_end,
						start, item_size);
}

bool _gvariant_iter_skip_entry(struct l_dbus_message_iter *iter)
{
	size_t size;

	if (!next_item(iter, &size))
		return false;

	return true;
}

struct dbus_builder {
	struct l_string *signature;
	void *body;
	size_t body_size;
	size_t body_pos;
	struct l_queue *containers;
	struct {
		struct container *container;
		int sig_end;
		size_t body_pos;
		size_t offset_index;
		bool variable_is_last : 1;
	} mark;
};

struct container {
	size_t *offsets;
	size_t offsets_size;
	size_t offset_index;
	size_t start;
	bool variable_is_last : 1;
	enum dbus_container_type type;
	char signature[256];
	uint8_t sigindex;
};

static inline size_t grow_body(struct dbus_builder *builder,
					size_t len, unsigned int alignment)
{
	size_t size = align_len(builder->body_pos, alignment);

	if (size + len > builder->body_size) {
		builder->body = l_realloc(builder->body, size + len);
		builder->body_size = size + len;
	}

	if (size - builder->body_pos > 0)
		memset(builder->body + builder->body_pos, 0,
			size - builder->body_pos);

	builder->body_pos = size + len;

	return size;
}

static inline bool grow_offsets(struct container *container)
{
	size_t needed;

	if (container->offset_index < container->offsets_size)
		return true;

	needed = container->offsets_size * 2;

	if (needed > USHRT_MAX)
		return false;

	if (needed == 0)
		needed = 8;

	container->offsets = l_realloc(container->offsets,
						needed * sizeof(size_t));
	container->offsets_size = needed;

	return true;
}

static struct container *container_new(enum dbus_container_type type,
					const char *signature, size_t start)
{
	struct container *ret;

	ret = l_new(struct container, 1);

	ret->type = type;
	strcpy(ret->signature, signature);
	ret->start = start;

	return ret;
}

static void container_free(struct container *container)
{
	l_free(container->offsets);
	l_free(container);
}

static void container_append_struct_offsets(struct container *container,
					struct dbus_builder *builder)
{
	size_t offset_size;
	int i;
	size_t start;

	if (container->variable_is_last)
		container->offset_index -= 1;

	if (container->offset_index == 0)
		return;

	offset_size = offset_length(builder->body_pos,
						container->offset_index);
	i = container->offset_index - 1;

	start = grow_body(builder, offset_size * container->offset_index, 1);

	for (i = container->offset_index - 1; i >= 0; i--) {
		write_word_le(builder->body + start,
				container->offsets[i], offset_size);
		start += offset_size;
	}
}

static void container_append_array_offsets(struct container *container,
					struct dbus_builder *builder)
{
	size_t offset_size;
	unsigned int i;
	size_t start;

	if (container->offset_index == 0)
		return;

	offset_size = offset_length(builder->body_pos,
						container->offset_index);
	start = grow_body(builder, offset_size * container->offset_index, 1);

	for (i = 0; i < container->offset_index; i++) {
		write_word_le(builder->body + start,
				container->offsets[i], offset_size);
		start += offset_size;
	}
}

struct dbus_builder *_gvariant_builder_new(void *body, size_t body_size)
{
	struct dbus_builder *builder;
	struct container *root;

	builder = l_new(struct dbus_builder, 1);
	builder->signature = l_string_new(63);

	builder->containers = l_queue_new();
	root = container_new(DBUS_CONTAINER_TYPE_STRUCT, "", 0);
	l_queue_push_head(builder->containers, root);

	builder->body = body;
	builder->body_size = body_size;
	builder->body_pos = body_size;

	builder->mark.container = root;

	return builder;
}

void _gvariant_builder_free(struct dbus_builder *builder)
{
	if (unlikely(!builder))
		return;

	l_string_free(builder->signature);
	l_queue_destroy(builder->containers,
				(l_queue_destroy_func_t) container_free);
	l_free(builder->body);

	l_free(builder);
}

static bool enter_struct_dict_common(struct dbus_builder *builder,
					const char *signature,
					enum dbus_container_type type,
					const char open,
					const char close)
{
	size_t qlen = l_queue_length(builder->containers);
	struct container *container = l_queue_peek_head(builder->containers);
	int alignment;
	size_t start;

	if (qlen == 1) {
		if (l_string_length(builder->signature) +
				strlen(signature) + 2 > 255)
			return false;
	} else {
		/* Verify Signatures Match */
		char expect[256];
		const char *start;
		const char *end;

		start = container->signature + container->sigindex;
		end = validate_next_type(start, &alignment) - 1;

		if (*start != open || *end != close)
			return false;

		memcpy(expect, start + 1, end - start - 1);
		expect[end - start - 1] = '\0';

		if (strcmp(expect, signature))
			return false;
	}

	alignment = _gvariant_get_alignment(signature);
	start = grow_body(builder, 0, alignment);

	container = container_new(type, signature, start);
	l_queue_push_head(builder->containers, container);

	return true;
}

bool _gvariant_builder_enter_struct(struct dbus_builder *builder,
					const char *signature)
{
	if (signature[0] && !_gvariant_valid_signature(signature))
		return false;

	return enter_struct_dict_common(builder, signature,
					DBUS_CONTAINER_TYPE_STRUCT, '(', ')');
}

bool _gvariant_builder_enter_dict(struct dbus_builder *builder,
					const char *signature)
{
	if (_gvariant_num_children(signature) != 2)
		return false;

	if (!strchr(simple_types, signature[0]))
		return false;

	return enter_struct_dict_common(builder, signature,
					DBUS_CONTAINER_TYPE_DICT_ENTRY,
					'{', '}');
}

static bool leave_struct_dict_common(struct dbus_builder *builder,
					enum dbus_container_type type,
					const char open,
					const char close)
{
	struct container *container = l_queue_peek_head(builder->containers);
	size_t qlen = l_queue_length(builder->containers);
	struct container *parent;

	if (unlikely(qlen <= 1))
		return false;

	if (unlikely(container->type != type))
		return false;

	l_queue_pop_head(builder->containers);
	qlen -= 1;
	parent = l_queue_peek_head(builder->containers);

	if (_gvariant_is_fixed_size(container->signature)) {
		int alignment = _gvariant_get_alignment(container->signature);
		grow_body(builder, 0, alignment);

		/* Empty struct or "unit type" is encoded as a zero byte */
		if (container->signature[0] == '\0') {
			size_t start = grow_body(builder, 1, 1);

			memset(builder->body + start, 0, 1);
		}

		parent->variable_is_last = false;
	} else {
		size_t offset;

		if (!grow_offsets(parent))
			return false;

		container_append_struct_offsets(container, builder);
		offset = builder->body_pos - parent->start;
		parent->offsets[parent->offset_index++] = offset;
		parent->variable_is_last = true;
	}

	if (qlen == 1)
		l_string_append_printf(builder->signature, "%c%s%c",
						open,
						container->signature,
						close);
	else if (parent->type != DBUS_CONTAINER_TYPE_ARRAY)
		parent->sigindex += strlen(container->signature) + 2;

	container_free(container);

	return true;
}

bool _gvariant_builder_leave_struct(struct dbus_builder *builder)
{
	return leave_struct_dict_common(builder, DBUS_CONTAINER_TYPE_STRUCT,
					'(', ')');
}

bool _gvariant_builder_leave_dict(struct dbus_builder *builder)
{
	return leave_struct_dict_common(builder,
					DBUS_CONTAINER_TYPE_DICT_ENTRY,
					'{', '}');
}

bool _gvariant_builder_enter_variant(struct dbus_builder *builder,
					const char *signature)
{
	size_t qlen = l_queue_length(builder->containers);
	struct container *container = l_queue_peek_head(builder->containers);
	size_t start;

	if (_gvariant_num_children(signature) != 1)
		return false;

	if (qlen == 1) {
		if (l_string_length(builder->signature) + 1 > 255)
			return false;
	} else if (container->signature[container->sigindex] != 'v')
		return false;

	start = grow_body(builder, 0, 8);

	container = container_new(DBUS_CONTAINER_TYPE_VARIANT,
					signature, start);
	l_queue_push_head(builder->containers, container);

	return true;
}

bool _gvariant_builder_leave_variant(struct dbus_builder *builder)
{
	struct container *container = l_queue_peek_head(builder->containers);
	size_t qlen = l_queue_length(builder->containers);
	struct container *parent;
	size_t start;
	size_t siglen;
	size_t offset;

	if (unlikely(qlen <= 1))
		return false;

	if (unlikely(container->type != DBUS_CONTAINER_TYPE_VARIANT))
		return false;

	l_queue_pop_head(builder->containers);
	qlen -= 1;
	parent = l_queue_peek_head(builder->containers);

	siglen = strlen(container->signature);
	start = grow_body(builder, siglen + 1, 1);
	memset(builder->body + start, 0, 1);
	memcpy(builder->body + start + 1, container->signature, siglen);

	if (!grow_offsets(parent))
		return false;

	offset = builder->body_pos - parent->start;
	parent->offsets[parent->offset_index++] = offset;
	parent->variable_is_last = true;

	if (qlen == 1)
		l_string_append_c(builder->signature, 'v');
	else if (parent->type != DBUS_CONTAINER_TYPE_ARRAY)
		parent->sigindex += 1;

	container_free(container);

	return true;
}

bool _gvariant_builder_enter_array(struct dbus_builder *builder,
					const char *signature)
{
	size_t qlen = l_queue_length(builder->containers);
	struct container *container = l_queue_peek_head(builder->containers);
	size_t start;
	int alignment;

	if (_gvariant_num_children(signature) != 1)
		return false;

	if (qlen == 1) {
		if (l_string_length(builder->signature) +
				strlen(signature) + 1 > 255)
			return false;
	} else {
		/* Verify Signatures Match */
		char expect[256];
		const char *start;
		const char *end;

		start = container->signature + container->sigindex;
		end = validate_next_type(start, &alignment);

		if (*start != 'a')
			return false;

		memcpy(expect, start + 1, end - start - 1);
		expect[end - start - 1] = '\0';

		if (strcmp(expect, signature))
			return false;
	}

	alignment = _gvariant_get_alignment(signature);
	start = grow_body(builder, 0, alignment);

	container = container_new(DBUS_CONTAINER_TYPE_ARRAY, signature, start);
	l_queue_push_head(builder->containers, container);

	return true;
}

bool _gvariant_builder_leave_array(struct dbus_builder *builder)
{
	struct container *container = l_queue_peek_head(builder->containers);
	size_t qlen = l_queue_length(builder->containers);
	struct container *parent;
	size_t offset;

	if (unlikely(qlen <= 1))
		return false;

	if (unlikely(container->type != DBUS_CONTAINER_TYPE_ARRAY))
		return false;

	l_queue_pop_head(builder->containers);
	qlen -= 1;
	parent = l_queue_peek_head(builder->containers);

	if (!_gvariant_is_fixed_size(container->signature))
		container_append_array_offsets(container, builder);

	if (!grow_offsets(parent))
		return false;

	offset = builder->body_pos - parent->start;
	parent->offsets[parent->offset_index++] = offset;
	parent->variable_is_last = true;

	if (qlen == 1)
		l_string_append_printf(builder->signature, "a%s",
							container->signature);
	else if (parent->type != DBUS_CONTAINER_TYPE_ARRAY)
		parent->sigindex += strlen(container->signature) + 1;

	container_free(container);

	return true;
}

bool _gvariant_builder_append_basic(struct dbus_builder *builder,
					char type, const void *value)
{
	struct container *container = l_queue_peek_head(builder->containers);
	size_t start;
	unsigned int alignment;
	size_t len;
	size_t offset;

	if (unlikely(!builder))
		return false;

	if (unlikely(!strchr(simple_types, type)))
		return false;

	alignment = get_basic_alignment(type);
	if (!alignment)
		return false;

	if (l_queue_length(builder->containers) == 1)
		l_string_append_c(builder->signature, type);
	else if (container->signature[container->sigindex] != type)
		return false;

	len = get_basic_fixed_size(type);

	if (len) {
		start = grow_body(builder, len, alignment);
		memcpy(builder->body + start, value, len);
		container->variable_is_last = false;

		if (container->type != DBUS_CONTAINER_TYPE_ARRAY)
			container->sigindex += 1;

		return true;
	}

	if (!grow_offsets(container))
		return false;

	len = strlen(value) + 1;
	start = grow_body(builder, len, alignment);
	memcpy(builder->body + start, value, len);

	offset = builder->body_pos - container->start;
	container->offsets[container->offset_index++] = offset;
	container->variable_is_last = true;

	if (container->type != DBUS_CONTAINER_TYPE_ARRAY)
		container->sigindex += 1;

	return true;
}

bool _gvariant_builder_mark(struct dbus_builder *builder)
{
	struct container *container = l_queue_peek_head(builder->containers);

	builder->mark.container = container;

	if (l_queue_length(builder->containers) == 1)
		builder->mark.sig_end = l_string_length(builder->signature);
	else
		builder->mark.sig_end = container->sigindex;

	builder->mark.body_pos = builder->body_pos;
	builder->mark.offset_index = container->offset_index;
	builder->mark.variable_is_last = container->variable_is_last;

	return true;
}

bool _gvariant_builder_rewind(struct dbus_builder *builder)
{
	struct container *container;

	while ((container = l_queue_peek_head(builder->containers)) !=
				builder->mark.container) {
		container_free(container);
		l_queue_pop_head(builder->containers);
	}

	builder->body_pos = builder->mark.body_pos;
	container->offset_index = builder->mark.offset_index;
	container->variable_is_last = builder->mark.variable_is_last;

	if (l_queue_length(builder->containers) == 1)
		l_string_truncate(builder->signature, builder->mark.sig_end);
	else
		container->sigindex = builder->mark.sig_end;

	return true;
}

char *_gvariant_builder_finish(struct dbus_builder *builder,
				void **body, size_t *body_size)
{
	char *signature;
	struct container *root;
	uint8_t *variant_buf;
	size_t size;

	if (unlikely(!builder))
		return NULL;

	if (unlikely(l_queue_length(builder->containers) != 1))
		return NULL;

	root = l_queue_peek_head(builder->containers);

	signature = l_string_unwrap(builder->signature);
	builder->signature = NULL;

	if (_gvariant_is_fixed_size(signature)) {
		int alignment = _gvariant_get_alignment(signature);
		grow_body(builder, 0, alignment);

		/* Empty struct or "unit type" is encoded as a zero byte */
		if (signature[0] == '\0') {
			size_t start = grow_body(builder, 1, 1);

			memset(builder->body + start, 0, 1);
		}
	} else
		container_append_struct_offsets(root, builder);

	/*
	 * Make sure there's enough space after the body for the variant
	 * signature written here but not included in the body size and
	 * one framing offset value to be written in
	 * _gvariant_message_finalize.
	 */
	size = 3 + strlen(signature) + 8;
	if (builder->body_pos + size > builder->body_size)
		builder->body = l_realloc(builder->body,
						builder->body_pos + size);

	variant_buf = builder->body + builder->body_pos;
	*variant_buf++ = 0;
	*variant_buf++ = '(';
	variant_buf = mempcpy(variant_buf, signature, strlen(signature));
	*variant_buf++ = ')';

	*body = builder->body;
	*body_size = builder->body_pos;
	builder->body = NULL;
	builder->body_size = 0;

	return signature;
}

/*
 * Write the header's framing offset after the body variant which is the
 * last piece of data in the message after the header, the padding and
 * the builder has written the message body.
 */
size_t _gvariant_message_finalize(size_t header_end,
					void *body, size_t body_size,
					const char *signature)
{
	size_t offset_start;
	size_t offset_size;

	offset_start = body_size + 3 + strlen(signature);

	offset_size = offset_length(align_len(header_end, 8) + offset_start, 1);

	write_word_le(body + offset_start, header_end, offset_size);

	return align_len(header_end, 8) + offset_start + offset_size;
}
