/*
 * 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 float_byte_convert(uint8_t * address, size_t size)
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN && !defined (__VFP_FP__)
    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
}

union plist_uint_ptr
{
    void *src;
    uint8_t *u8ptr;
    uint16_t *u16ptr;
    uint32_t *u32ptr;
    uint64_t *u64ptr;
};

#define get_unaligned(ptr)			  \
  ({                                              \
    struct __attribute__((packed)) {		  \
      typeof(*(ptr)) __v;			  \
    } *__p = (void *) (ptr);			  \
    __p->__v;					  \
  })


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(union plist_uint_ptr buf)
{
    union plist_uint_ptr tmp;
    uint32_t ret = 0;

    tmp.src = &ret;

    memcpy(tmp.u8ptr + 1, buf.u8ptr, 3 * sizeof(char));

    byte_convert(tmp.u8ptr, sizeof(uint32_t));
    return ret;
}

#define UINT_TO_HOST(x, n) \
	({ \
		union plist_uint_ptr __up; \
		__up.src = x; \
		(n == 8 ? GUINT64_FROM_BE( get_unaligned(__up.u64ptr) ) : \
		(n == 4 ? GUINT32_FROM_BE( get_unaligned(__up.u32ptr) ) : \
		(n == 3 ? uint24_from_be( __up ) : \
		(n == 2 ? GUINT16_FROM_BE( get_unaligned(__up.u16ptr) ) : \
		*__up.u8ptr )))); \
	})

#define be64dec(x) \
	({ \
		union plist_uint_ptr __up; \
		__up.src = x; \
		GUINT64_FROM_BE( get_unaligned(__up.u64ptr) ); \
	})

#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;
    uint8_t* buf;

    size = 1 << size;			// make length less misleading
    buf = malloc (size);
    memcpy (buf, bnode, size);
    switch (size)
    {
    case sizeof(float):
        float_byte_convert(buf, size);
        floatval = *(float *) buf;
        data->realval = floatval;
        break;
    case sizeof(double):
        float_byte_convert(buf, size);
        data->realval = *(double *) buf;
        break;
    default:
        free(data);
        return NULL;
    }
    free (buf);
    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++;

#if G_BYTE_ORDER == G_BIG_ENDIAN
    val = val << ((sizeof(uint64_t) - size) * 8);
#endif

    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(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);
    }
    float_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);
    float_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));
#if G_BYTE_ORDER == G_BIG_ENDIAN
	idx = idx << ((sizeof(uint64_t) - dict_param_size) * 8);
#endif
        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));
#if G_BYTE_ORDER == G_BIG_ENDIAN
	idx1 = idx1 << ((sizeof(uint64_t) - dict_param_size) * 8);
#endif
        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));
#if G_BYTE_ORDER == G_BIG_ENDIAN
	idx2 = idx2 << ((sizeof(uint64_t) - dict_param_size) * 8);
#endif
        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);

#if G_BYTE_ORDER == G_BIG_ENDIAN
	offsets[i] = offsets[i] << ((sizeof(uint64_t) - offset_size) * 8);
#endif

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