/*
 * 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 <libxml/encoding.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;
    uint8_t *tmp = (uint8_t *) &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;
    gunichar2 *unicodestr = NULL;
    gchar *tmpstr = NULL;
    glong items_read = 0;
    glong items_written = 0;
    GError *error = NULL;

    data->type = PLIST_STRING;
    unicodestr = (gunichar2 *) malloc(sizeof(gunichar2) * size);
    memcpy(unicodestr, bnode, sizeof(gunichar2) * size);
    for (i = 0; i < size; i++)
        byte_convert((uint8_t *) (unicodestr + i), sizeof(gunichar2));

    tmpstr = g_utf16_to_utf8(unicodestr, size, &items_read, &items_written, &error);
    free(unicodestr);

    data->type = PLIST_STRING;
    data->strval = (char *) malloc(sizeof(char) * (items_written + 1));
    memcpy(data->strval, tmpstr, items_written);
    data->strval[items_written] = '\0';
    data->length = strlen(data->strval);
    g_free(tmpstr);
    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;
            data->length = 1;
            return g_node_new(data);
        }

        case BPLIST_FALSE:
        {
            plist_data_t data = plist_new_plist_data();
            data->type = PLIST_BOOLEAN;
            data->boolval = FALSE;
            data->length = 1;
            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_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 = (char *) (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 = (char *) (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 = (char *) (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_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];
    //for string
    glong len = 0;
    int type = 0;
    glong items_read = 0;
    glong items_written = 0;
    GError *error = NULL;
    gunichar2 *unicodestr = NULL;

    //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:
            len = strlen(data->strval);
            type = xmlDetectCharEncoding((const unsigned char *)data->strval, len);
            if (XML_CHAR_ENCODING_UTF8 == type)
            {
                unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error);
                write_unicode(bplist_buff, unicodestr, items_written);
                g_free(unicodestr);
            }
            else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
            {
                write_string(bplist_buff, data->strval);
            }
            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);
}
