/*
 * plist.c
 * Binary plist implementation
 *
 * Copyright (c) 2008 Jonathan Beck 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 Street, Fifth Floor, Boston, MA  02110-1301  USA 
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <plist/plist.h>
#include "plist.h"

/* Magic marker and size. */
#define BPLIST_MAGIC		((uint8_t*)"bplist")
#define BPLIST_MAGIC_SIZE	6

#define BPLIST_VERSION		((uint8_t*)"00")
#define BPLIST_VERSION_SIZE	2


#define BPLIST_TRL_SIZE 	26
#define BPLIST_TRL_OFFSIZE_IDX 	0
#define BPLIST_TRL_PARMSIZE_IDX 1
#define BPLIST_TRL_NUMOBJ_IDX 	2
#define BPLIST_TRL_ROOTOBJ_IDX 	10
#define BPLIST_TRL_OFFTAB_IDX 	18

enum {
	BPLIST_NULL = 0x00,
	BPLIST_FALSE = 0x08,
	BPLIST_TRUE = 0x09,
	BPLIST_FILL = 0x0F,			/* will be used for length grabbing */
	BPLIST_UINT = 0x10,
	BPLIST_REAL = 0x20,
	BPLIST_DATE = 0x30,
	BPLIST_DATA = 0x40,
	BPLIST_STRING = 0x50,
	BPLIST_UNICODE = 0x60,
	BPLIST_UID = 0x70,
	BPLIST_ARRAY = 0xA0,
	BPLIST_SET = 0xC0,
	BPLIST_DICT = 0xD0,
	BPLIST_MASK = 0xF0
};

static void byte_convert(uint8_t * address, size_t size)
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
	uint8_t i = 0, j = 0;
	uint8_t tmp = 0;

	for (i = 0; i < (size / 2); i++) {
		tmp = address[i];
		j = ((size - 1) + 0) - i;
		address[i] = address[j];
		address[j] = tmp;
	}
#endif
}

static uint32_t uint24_from_be(char *buff)
{
	uint32_t ret = 0;
	char *tmp = (char*) &ret;
	memcpy(tmp + 1, buff, 3 * sizeof(char));
	byte_convert(tmp, sizeof(uint32_t));
	return ret;
}

#define UINT_TO_HOST(x, n) \
		(n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \
		(n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \
		(n == 3 ? uint24_from_be( (char*)x ) : \
		(n == 2 ? GUINT16_FROM_BE( *(uint16_t *)(x) ) : \
		*(uint8_t *)(x) ))))

#define be64dec(x) GUINT64_FROM_BE( *(uint64_t*)(x) )

#define get_needed_bytes(x) \
		( ((uint64_t)x) < (1ULL << 8) ? 1 : \
		( ((uint64_t)x) < (1ULL << 16) ? 2 : \
		( ((uint64_t)x) < (1ULL << 24) ? 3 : \
		( ((uint64_t)x) < (1ULL << 32) ? 4 : 8))))

#define get_real_bytes(x) (x == (float) x ? 4 : 8)


static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
{
	plist_data_t data = plist_new_plist_data();

	size = 1 << size;			// make length less misleading
	switch (size) {
	case sizeof(uint8_t):
	case sizeof(uint16_t):
	case sizeof(uint32_t):
	case sizeof(uint64_t):
		memcpy(&data->intval, bnode, size);
		data->intval = UINT_TO_HOST(&data->intval, size);
		break;
	default:
		free(data);
		return NULL;
	};

	*next_object = bnode + size;
	data->type = PLIST_UINT;
	data->length = sizeof(uint64_t);

	return g_node_new(data);
}

static plist_t parse_real_node(char *bnode, uint8_t size)
{
	plist_data_t data = plist_new_plist_data();
	float floatval = 0.0;

	size = 1 << size;			// make length less misleading
	switch (size) {
	case sizeof(float):
		floatval = *(float*)bnode;
		byte_convert((uint8_t*)&floatval, sizeof(float));
		data->realval = floatval;
		break;
	case sizeof(double):
		data->realval = *(double*)bnode;
		byte_convert((uint8_t*)&(data->realval), sizeof(double));
		break;
	default:
		free(data);
		return NULL;
	}
	data->type = PLIST_REAL;
	data->length = sizeof(double);

	return g_node_new(data);
}

static plist_t parse_date_node(char *bnode, uint8_t size)
{
	plist_t node = parse_real_node(bnode, size);
	plist_data_t data = plist_get_data(node);

	double time_real = data->realval;
	data->timeval.tv_sec = (glong) time_real;
	data->timeval.tv_usec = (time_real - (glong) time_real) * G_USEC_PER_SEC;
	data->type = PLIST_DATE;
	data->length = sizeof(GTimeVal);

	return node;
}

static plist_t parse_string_node(char *bnode, uint64_t size)
{
	plist_data_t data = plist_new_plist_data();

	data->type = PLIST_STRING;
	data->strval = (char *) malloc(sizeof(char) * (size + 1));
	memcpy(data->strval, bnode, size);
	data->strval[size] = '\0';
	data->length = strlen(data->strval);

	return g_node_new(data);
}

static plist_t parse_unicode_node(char *bnode, uint64_t size)
{
	plist_data_t data = plist_new_plist_data();
	uint64_t i = 0;
	data->type = PLIST_UNICODE;
	data->unicodeval = (gunichar2 *) malloc(sizeof(gunichar2) * (size + 1));
	memcpy(data->unicodeval, bnode, sizeof(gunichar2) * size);
	data->unicodeval[sizeof(gunichar2) * size] = '\0';
	data->length = size;
	for (i = 0; i <= size; i++)
		byte_convert((uint8_t*)(data->unicodeval + i), sizeof(gunichar2));
	return g_node_new(data);
}

static plist_t parse_data_node(char *bnode, uint64_t size)
{
	plist_data_t data = plist_new_plist_data();

	data->type = PLIST_DATA;
	data->length = size;
	data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size);
	memcpy(data->buff, bnode, sizeof(uint8_t) * size);

	return g_node_new(data);
}

static plist_t parse_dict_node(char *bnode, uint64_t size, uint32_t ref_size)
{
	plist_data_t data = plist_new_plist_data();

	data->type = PLIST_DICT;
	data->length = size;
	data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size * 2);
	memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size * 2);

	return g_node_new(data);
}

static plist_t parse_array_node(char *bnode, uint64_t size, uint32_t ref_size)
{
	plist_data_t data = plist_new_plist_data();

	data->type = PLIST_ARRAY;
	data->length = size;
	data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size);
	memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size);

	return g_node_new(data);
}



static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object)
{
	uint16_t type = 0;
	uint64_t size = 0;

	if (!object)
		return NULL;

	type = (*object) & 0xF0;
	size = (*object) & 0x0F;
	object++;

	switch (type) {

	case BPLIST_NULL:
		switch (size) {

		case BPLIST_TRUE:
			{
				plist_data_t data = plist_new_plist_data();
				data->type = PLIST_BOOLEAN;
				data->boolval = TRUE;
				return g_node_new(data);
			}

		case BPLIST_FALSE:
			{
				plist_data_t data = plist_new_plist_data();
				data->type = PLIST_BOOLEAN;
				data->boolval = FALSE;
				return g_node_new(data);
			}

		case BPLIST_NULL:
		default:
			return NULL;
		}

	case BPLIST_UINT:
		return parse_uint_node(object, size, next_object);

	case BPLIST_REAL:
		return parse_real_node(object, size);

	case BPLIST_DATE:
		if (3 != size)
			return NULL;
		else
			return parse_date_node(object, size);

	case BPLIST_DATA:
		if (0x0F == size) {
			plist_t size_node = parse_bin_node(object, dict_size, &object);
			if (plist_get_node_type(size_node) != PLIST_UINT)
				return NULL;
			plist_get_uint_val(size_node, &size);
			plist_free(size_node);
		}
		return parse_data_node(object, size);

	case BPLIST_STRING:
		if (0x0F == size) {
			plist_t size_node = parse_bin_node(object, dict_size, &object);
			if (plist_get_node_type(size_node) != PLIST_UINT)
				return NULL;
			plist_get_uint_val(size_node, &size);
			plist_free(size_node);
		}
		return parse_string_node(object, size);

	case BPLIST_UNICODE:
		if (0x0F == size) {
			plist_t size_node = parse_bin_node(object, dict_size, &object);
			if (plist_get_node_type(size_node) != PLIST_UINT)
				return NULL;
			plist_get_uint_val(size_node, &size);
			plist_free(size_node);
		}
		return parse_unicode_node(object, size);

	case BPLIST_UID:
	case BPLIST_ARRAY:
		if (0x0F == size) {
			plist_t size_node = parse_bin_node(object, dict_size, &object);
			if (plist_get_node_type(size_node) != PLIST_UINT)
				return NULL;
			plist_get_uint_val(size_node, &size);
			plist_free(size_node);
		}
		return parse_array_node(object, size, dict_size);

	case BPLIST_SET:
	case BPLIST_DICT:
		if (0x0F == size) {
			plist_t size_node = parse_bin_node(object, dict_size, &object);
			if (plist_get_node_type(size_node) != PLIST_UINT)
				return NULL;
			plist_get_uint_val(size_node, &size);
			plist_free(size_node);
		}
		return parse_dict_node(object, size, dict_size);
	default:
		return NULL;
	}
	return NULL;
}

static gpointer copy_plist_data(gconstpointer src, gpointer data)
{
	plist_data_t srcdata = (plist_data_t) src;
	plist_data_t dstdata = plist_new_plist_data();

	dstdata->type = srcdata->type;
	dstdata->length = srcdata->length;
	switch (dstdata->type) {
	case PLIST_BOOLEAN:
		dstdata->boolval = srcdata->boolval;
		break;
	case PLIST_UINT:
		dstdata->intval = srcdata->intval;
		break;
	case PLIST_DATE:
		dstdata->timeval.tv_sec = srcdata->timeval.tv_sec;
		dstdata->timeval.tv_usec = srcdata->timeval.tv_usec;
		break;
	case PLIST_REAL:
		dstdata->realval = srcdata->realval;
		break;
	case PLIST_KEY:
	case PLIST_STRING:
		dstdata->strval = strdup(srcdata->strval);
		break;
	case PLIST_UNICODE:
		dstdata->unicodeval = (gunichar2 *) malloc(srcdata->length * sizeof(gunichar2));
		memcpy(dstdata->unicodeval, srcdata->unicodeval, srcdata->length * sizeof(gunichar2));
		break;
	case PLIST_DATA:
	case PLIST_ARRAY:
		dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length);
		memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length);
		break;
	case PLIST_DICT:
		dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length * 2);
		memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length * 2);
		break;
	default:
		break;
	}

	return dstdata;
}

void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
{
	char *trailer = NULL;

	uint8_t offset_size = 0;
	uint8_t dict_param_size = 0;
	uint64_t num_objects = 0;
	uint64_t root_object = 0;
	uint64_t offset_table_index = 0;

	plist_t *nodeslist = NULL;
	uint64_t i = 0;
	uint64_t current_offset = 0;
	char *offset_table = NULL;
	uint32_t j = 0, str_i = 0, str_j = 0;
	uint32_t index1 = 0, index2 = 0;


	//first check we have enough data
	if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE))
		return;
	//check that plist_bin in actually a plist
	if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0)
		return;
	//check for known version
	if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0)
		return;

	//now parse trailer
	trailer = plist_bin + (length - BPLIST_TRL_SIZE);

	offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX];
	dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX];
	num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX);
	root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX);
	offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX);

	if (num_objects == 0)
		return;

	//allocate serialized array of nodes
	nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects);

	if (!nodeslist)
		return;

	//parse serialized nodes
	offset_table = plist_bin + offset_table_index;
	for (i = 0; i < num_objects; i++) {
		char *obj = NULL;
		current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size);

		obj = plist_bin + current_offset;
		nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj);
	}

	//setup children for structured types
	for (i = 0; i < num_objects; i++) {

		plist_data_t data = plist_get_data(nodeslist[i]);

		switch (data->type) {
		case PLIST_DICT:
			for (j = 0; j < data->length; j++) {
				str_i = j * dict_param_size;
				str_j = (j + data->length) * dict_param_size;

				index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size);
				index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size);

				//first one is actually a key
				plist_get_data(nodeslist[index1])->type = PLIST_KEY;

				if (index1 < num_objects) {
					if (G_NODE_IS_ROOT(nodeslist[index1]))
						g_node_append(nodeslist[i], nodeslist[index1]);
					else
						g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL));
				}

				if (index2 < num_objects) {
					if (G_NODE_IS_ROOT(nodeslist[index2]))
						g_node_append(nodeslist[i], nodeslist[index2]);
					else
						g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index2], copy_plist_data, NULL));
				}
			}

			free(data->buff);
			break;

		case PLIST_ARRAY:
			for (j = 0; j < data->length; j++) {
				str_j = j * dict_param_size;
				index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size);

				if (index1 < num_objects) {
					if (G_NODE_IS_ROOT(nodeslist[index1]))
						g_node_append(nodeslist[i], nodeslist[index1]);
					else
						g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL));
				}
			}
			free(data->buff);
			break;
		default:
			break;
		}
	}

	*plist = nodeslist[root_object];
	free(nodeslist);
}

static guint plist_data_hash(gconstpointer key)
{
	plist_data_t data = plist_get_data((plist_t) key);

	guint hash = data->type;
	guint i = 0;

	char *buff = NULL;
	guint size = 0;

	switch (data->type) {
	case PLIST_BOOLEAN:
	case PLIST_UINT:
	case PLIST_REAL:
		buff = (char *) &data->intval;	//works also for real as we use an union
		size = 8;
		break;
	case PLIST_KEY:
	case PLIST_STRING:
		buff = data->strval;
		size = strlen(buff);
		break;
	case PLIST_UNICODE:
		buff = (char *) data->unicodeval;
		size = data->length;
		break;
	case PLIST_DATA:
	case PLIST_ARRAY:
	case PLIST_DICT:
		//for these types only hash pointer
		buff = (char *) &key;
		size = sizeof(gconstpointer);
		break;
	case PLIST_DATE:
		buff = (char *) &(data->timeval);
		size = data->length;
		break;
	default:
		break;
	}

	//now perform hash
	for (i = 0; i < size; buff++, i++)
		hash = hash << 7 ^ (*buff);

	return hash;
}



struct serialize_s {
	GPtrArray *objects;
	GHashTable *ref_table;
};

static void serialize_plist(GNode * node, gpointer data)
{
	uint64_t *index_val = NULL;
	struct serialize_s *ser = (struct serialize_s *) data;
	uint64_t current_index = ser->objects->len;

	//first check that node is not yet in objects
	gpointer val = g_hash_table_lookup(ser->ref_table, node);
	if (val) {
		//data is already in table
		return;
	}
	//insert new ref
	index_val = (uint64_t *) malloc(sizeof(uint64_t));
	*index_val = current_index;
	g_hash_table_insert(ser->ref_table, node, index_val);

	//now append current node to object array
	g_ptr_array_add(ser->objects, node);

	//now recurse on children
	g_node_children_foreach(node, G_TRAVERSE_ALL, serialize_plist, data);
	return;
}

static gboolean free_index(gpointer key, gpointer value, gpointer user_data)
{
	free((uint64_t *) value);
	return TRUE;
}

#define Log2(x) (x == 8 ? 3 : (x == 4 ? 2 : (x == 2 ? 1 : 0)))

static void write_int(GByteArray * bplist, uint64_t val)
{
	uint64_t size = get_needed_bytes(val);
	uint8_t *buff = NULL;
	//do not write 3bytes int node
	if (size == 3)
		size++;
	buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
	buff[0] = BPLIST_UINT | Log2(size);
	memcpy(buff + 1, &val, size);
	byte_convert(buff + 1, size);
	g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
	free(buff);
}

static void write_real(GByteArray * bplist, double val)
{
	uint64_t size = get_real_bytes(*((uint64_t *) & val));	//cheat to know used space
	uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
	buff[0] = BPLIST_REAL | Log2(size);
	if (size == sizeof(double)) {
		memcpy(buff + 1, &val, size);
	} else if (size == sizeof(float)) {
		float tmpval = (float) val;
		memcpy(buff + 1, &tmpval, size);
	}
	byte_convert(buff + 1, size);
	g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
	free(buff);
}

static void write_date(GByteArray * bplist, double val)
{
	uint64_t size = 8;			//dates always use 8 bytes
	uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
	buff[0] = BPLIST_DATE | Log2(size);
	memcpy(buff + 1, &val, size);
	byte_convert(buff + 1, size);
	g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
	free(buff);
}

static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size)
{
	uint8_t *buff = NULL;
	uint8_t marker = mark | (size < 15 ? size : 0xf);
	g_byte_array_append(bplist, &marker, sizeof(uint8_t));
	if (size >= 15) {
		GByteArray *int_buff = g_byte_array_new();
		write_int(int_buff, size);
		g_byte_array_append(bplist, int_buff->data, int_buff->len);
		g_byte_array_free(int_buff, TRUE);
	}
	buff = (uint8_t *) malloc(size);
	memcpy(buff, val, size);
	g_byte_array_append(bplist, buff, size);
	free(buff);
}

static void write_data(GByteArray * bplist, uint8_t * val, uint64_t size)
{
	write_raw_data(bplist, BPLIST_DATA, val, size);
}

static void write_string(GByteArray * bplist, char *val)
{
	uint64_t size = strlen(val);
	write_raw_data(bplist, BPLIST_STRING, (uint8_t *) val, size);
}

static void write_unicode(GByteArray * bplist, gunichar2 * val, uint64_t size)
{
	uint64_t i = 0;
	uint64_t size2 = size * sizeof(gunichar2);
	uint8_t *buff = (uint8_t *) malloc(size2);
	memcpy(buff, val, size2);
	for (i = 0; i < size; i++)
		byte_convert(buff + i * sizeof(gunichar2), sizeof(gunichar2));
	write_raw_data(bplist, BPLIST_STRING, buff, size2);
}

static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size)
{
	uint64_t idx = 0;
	uint8_t *buff = NULL;

	GNode *cur = NULL;
	uint64_t i = 0;

	uint64_t size = g_node_n_children(node);
	uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf);
	g_byte_array_append(bplist, &marker, sizeof(uint8_t));
	if (size >= 15) {
		GByteArray *int_buff = g_byte_array_new();
		write_int(int_buff, size);
		g_byte_array_append(bplist, int_buff->data, int_buff->len);
		g_byte_array_free(int_buff, TRUE);
	}

	buff = (uint8_t *) malloc(size * dict_param_size);

	for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) {
		idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur));
		memcpy(buff + i * dict_param_size, &idx, dict_param_size);
		byte_convert(buff + i * dict_param_size, dict_param_size);
	}

	//now append to bplist
	g_byte_array_append(bplist, buff, size * dict_param_size);
	free(buff);

}

static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size)
{
	uint64_t idx1 = 0;
	uint64_t idx2 = 0;
	uint8_t *buff = NULL;

	GNode *cur = NULL;
	uint64_t i = 0;

	uint64_t size = g_node_n_children(node) / 2;
	uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf);
	g_byte_array_append(bplist, &marker, sizeof(uint8_t));
	if (size >= 15) {
		GByteArray *int_buff = g_byte_array_new();
		write_int(int_buff, size);
		g_byte_array_append(bplist, int_buff->data, int_buff->len);
		g_byte_array_free(int_buff, TRUE);
	}

	buff = (uint8_t *) malloc(size * 2 * dict_param_size);

	for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) {
		idx1 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur));
		memcpy(buff + i * dict_param_size, &idx1, dict_param_size);
		byte_convert(buff + i * dict_param_size, dict_param_size);

		idx2 = *(uint64_t *)(g_hash_table_lookup(ref_table, cur->next));
		memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size);
		byte_convert(buff + (i + size) * dict_param_size, dict_param_size);
	}

	//now append to bplist
	g_byte_array_append(bplist, buff, size * 2 * dict_param_size);
	free(buff);

}

void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
{
	GPtrArray *objects = NULL;
	GHashTable *ref_table = NULL;
	struct serialize_s ser_s;
	uint8_t offset_size = 0;
	uint8_t dict_param_size = 0;
	uint64_t num_objects = 0;
	uint64_t root_object = 0;
	uint64_t offset_table_index = 0;
	GByteArray *bplist_buff = NULL;
	uint64_t i = 0;
	uint8_t *buff = NULL;
	uint64_t *offsets = NULL;
	uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 };
	uint8_t trailer[BPLIST_TRL_SIZE];

	//check for valid input
	if (!plist || !plist_bin || *plist_bin || !length)
		return;

	//list of objects
	objects = g_ptr_array_new();
	//hashtable to write only once same nodes
	ref_table = g_hash_table_new(plist_data_hash, plist_data_compare);

	//serialize plist
	ser_s.objects = objects;
	ser_s.ref_table = ref_table;
	serialize_plist(plist, &ser_s);

	//now stream to output buffer
	offset_size = 0;			//unknown yet
	dict_param_size = get_needed_bytes(objects->len);
	num_objects = objects->len;
	root_object = 0;			//root is first in list
	offset_table_index = 0;		//unknown yet

	//setup a dynamic bytes array to store bplist in
	bplist_buff = g_byte_array_new();

	//set magic number and version
	g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE);
	g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE);

	//write objects and table
	offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t));
	for (i = 0; i < num_objects; i++) {

		plist_data_t data = plist_get_data(g_ptr_array_index(objects, i));
		offsets[i] = bplist_buff->len;

		switch (data->type) {
		case PLIST_BOOLEAN:
			buff = (uint8_t *) malloc(sizeof(uint8_t));
			buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE;
			g_byte_array_append(bplist_buff, buff, sizeof(uint8_t));
			free(buff);
			break;

		case PLIST_UINT:
			write_int(bplist_buff, data->intval);
			break;

		case PLIST_REAL:
			write_real(bplist_buff, data->realval);
			break;

		case PLIST_KEY:
		case PLIST_STRING:
			write_string(bplist_buff, data->strval);
			break;
		case PLIST_UNICODE:
			write_unicode(bplist_buff, data->unicodeval, data->length);
			break;
		case PLIST_DATA:
			write_data(bplist_buff, data->buff, data->length);
		case PLIST_ARRAY:
			write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size);
			break;
		case PLIST_DICT:
			write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size);
			break;
		case PLIST_DATE:
			write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC);
			break;
		default:
			break;
		}
	}

	//free intermediate objects
	g_hash_table_foreach_remove(ref_table, free_index, NULL);
	g_ptr_array_free(objects, TRUE);
	g_hash_table_destroy(ref_table);

	//write offsets
	offset_size = get_needed_bytes(bplist_buff->len);
	offset_table_index = bplist_buff->len;
	for (i = 0; i < num_objects; i++) {
		uint8_t *offsetbuff = (uint8_t *) malloc(offset_size);
		memcpy(offsetbuff, offsets + i, offset_size);
		byte_convert(offsetbuff, offset_size);
		g_byte_array_append(bplist_buff, offsetbuff, offset_size);
		free(offsetbuff);
	}

	//experimental pad to reflect apple's files
	g_byte_array_append(bplist_buff, pad, 6);

	//setup trailer
	num_objects = GUINT64_FROM_BE(num_objects);
	root_object = GUINT64_FROM_BE(root_object);
	offset_table_index = GUINT64_FROM_BE(offset_table_index);

	memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t));
	memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t));
	memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t));
	memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t));
	memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t));

	g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE);

	//duplicate buffer
	*plist_bin = (char *) malloc(bplist_buff->len);
	memcpy(*plist_bin, bplist_buff->data, bplist_buff->len);
	*length = bplist_buff->len;

	g_byte_array_free(bplist_buff, TRUE);
	free(offsets);
}
