/*
 * plist.c
 * Builds plist XML structures
 *
 * Copyright (c) 2009-2019 Nikias Bassen, All Rights Reserved.
 * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved.
 * Copyright (c) 2008 Zach C., 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
 */

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

#define _GNU_SOURCE 1
#include <string.h>
#include "plist.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <float.h>

#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif

#include <node.h>
#include <hashtable.h>
#include <ptrarray.h>

extern void plist_xml_init(void);
extern void plist_xml_deinit(void);
extern void plist_bin_init(void);
extern void plist_bin_deinit(void);

static void internal_plist_init(void)
{
    plist_bin_init();
    plist_xml_init();
}

static void internal_plist_deinit(void)
{
    plist_bin_deinit();
    plist_xml_deinit();
}

#ifdef WIN32
typedef volatile struct {
    LONG lock;
    int state;
} thread_once_t;

static thread_once_t init_once = {0, 0};
static thread_once_t deinit_once = {0, 0};

static void thread_once(thread_once_t *once_control, void (*init_routine)(void))
{
    while (InterlockedExchange(&(once_control->lock), 1) != 0) {
        Sleep(1);
    }
    if (!once_control->state) {
        once_control->state = 1;
        init_routine();
    }
    InterlockedExchange(&(once_control->lock), 0);
}
#else
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
static pthread_once_t deinit_once = PTHREAD_ONCE_INIT;
#define thread_once pthread_once
#endif

#ifndef HAVE_ATTRIBUTE_CONSTRUCTOR
  #if defined(__llvm__) || defined(__GNUC__)
    #define HAVE_ATTRIBUTE_CONSTRUCTOR
  #endif
#endif

#ifdef HAVE_ATTRIBUTE_CONSTRUCTOR
static void __attribute__((constructor)) libplist_initialize(void)
{
    thread_once(&init_once, internal_plist_init);
}

static void __attribute__((destructor)) libplist_deinitialize(void)
{
    thread_once(&deinit_once, internal_plist_deinit);
}
#elif defined(WIN32)
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        thread_once(&init_once, internal_plist_init);
        break;
    case DLL_PROCESS_DETACH:
        thread_once(&deinit_once, internal_plist_deinit);
        break;
    default:
        break;
    }
    return 1;
}
#else
#warning No compiler support for constructor/destructor attributes, some features might not be available.
#endif

#ifndef HAVE_MEMMEM
// see https://sourceware.org/legacy-ml/libc-alpha/2007-12/msg00000.html

#ifndef _LIBC
# define __builtin_expect(expr, val)   (expr)
#endif

#undef memmem

/* Return the first occurrence of NEEDLE in HAYSTACK. */
void* memmem(const void* haystack, size_t haystack_len, const void* needle, size_t needle_len)
{
    /* not really Rabin-Karp, just using additive hashing */
    char* haystack_ = (char*)haystack;
    char* needle_ = (char*)needle;
    int hash = 0;  /* this is the static hash value of the needle */
    int hay_hash = 0;  /* rolling hash over the haystack */
    char* last;
    size_t i;

    if (haystack_len < needle_len)
        return NULL;

    if (!needle_len)
        return haystack_;

    /* initialize hashes */
    for (i = needle_len; i; --i) {
        hash += *needle_++;
        hay_hash += *haystack_++;
    }

    /* iterate over the haystack */
    haystack_ = (char*)haystack;
    needle_ = (char*)needle;
    last = haystack_+(haystack_len - needle_len + 1);
    for (; haystack_ < last; ++haystack_) {
        if (__builtin_expect(hash == hay_hash, 0)
              && *haystack_ == *needle_ /* prevent calling memcmp, was a optimization from existing glibc */
              && !memcmp (haystack_, needle_, needle_len)) {
            return haystack_;
        }
        /* roll the hash */
        hay_hash -= *haystack_;
        hay_hash += *(haystack_+needle_len);
    }
    return NULL;
}
#endif

PLIST_API int plist_is_binary(const char *plist_data, uint32_t length)
{
    if (length < 8) {
        return 0;
    }

    return (memcmp(plist_data, "bplist00", 8) == 0);
}


PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist)
{
    int res = -1;
    if (!plist) {
        return PLIST_ERR_INVALID_ARG;
    }
    *plist = NULL;
    if (!plist_data || length < 8) {
        return PLIST_ERR_INVALID_ARG;
    }
    if (plist_is_binary(plist_data, length)) {
        res = plist_from_bin(plist_data, length, plist);
    } else {
        res = plist_from_xml(plist_data, length, plist);
    }
    return res;
}

plist_t plist_new_node(plist_data_t data)
{
    return (plist_t) node_create(NULL, data);
}

plist_data_t plist_get_data(plist_t node)
{
    if (!node)
        return NULL;
    return ((node_t*)node)->data;
}

plist_data_t plist_new_plist_data(void)
{
    plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1);
    return data;
}

static unsigned int dict_key_hash(const void *data)
{
    plist_data_t keydata = (plist_data_t)data;
    unsigned int hash = 5381;
    size_t i;
    char *str = keydata->strval;
    for (i = 0; i < keydata->length; str++, i++) {
        hash = ((hash << 5) + hash) + *str;
    }
    return hash;
}

static int dict_key_compare(const void* a, const void* b)
{
    plist_data_t data_a = (plist_data_t)a;
    plist_data_t data_b = (plist_data_t)b;
    if (data_a->strval == NULL || data_b->strval == NULL) {
        return FALSE;
    }
    if (data_a->length != data_b->length) {
        return FALSE;
    }
    return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE;
}

void plist_free_data(plist_data_t data)
{
    if (data)
    {
        switch (data->type)
        {
        case PLIST_KEY:
        case PLIST_STRING:
            free(data->strval);
            break;
        case PLIST_DATA:
            free(data->buff);
            break;
        case PLIST_ARRAY:
            ptr_array_free(data->hashtable);
            break;
        case PLIST_DICT:
            hash_table_destroy(data->hashtable);
            break;
        default:
            break;
        }
        free(data);
    }
}

static int plist_free_node(node_t* node)
{
    plist_data_t data = NULL;
    int node_index = node_detach(node->parent, node);
    data = plist_get_data(node);
    plist_free_data(data);
    node->data = NULL;

    node_t *ch;
    for (ch = node_first_child(node); ch; ) {
        node_t *next = node_next_sibling(ch);
        plist_free_node(ch);
        ch = next;
    }

    node_destroy(node);

    return node_index;
}

PLIST_API plist_t plist_new_dict(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DICT;
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_array(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_ARRAY;
    return plist_new_node(data);
}

//These nodes should not be handled by users
static plist_t plist_new_key(const char *val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_KEY;
    data->strval = strdup(val);
    data->length = strlen(val);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_string(const char *val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_STRING;
    data->strval = strdup(val);
    data->length = strlen(val);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_bool(uint8_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_BOOLEAN;
    data->boolval = val;
    data->length = sizeof(uint8_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_uint(uint64_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_UINT;
    data->intval = val;
    data->length = sizeof(uint64_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_uid(uint64_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_UID;
    data->intval = val;
    data->length = sizeof(uint64_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_real(double val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_REAL;
    data->realval = val;
    data->length = sizeof(double);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_data(const char *val, uint64_t length)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DATA;
    data->buff = (uint8_t *) malloc(length);
    memcpy(data->buff, val, length);
    data->length = length;
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DATE;
    data->realval = (double)sec + (double)usec / 1000000;
    data->length = sizeof(double);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_null(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_NULL;
    data->intval = 0;
    data->length = 0;
    return plist_new_node(data);
}

PLIST_API void plist_free(plist_t plist)
{
    if (plist)
    {
        plist_free_node(plist);
    }
}

PLIST_API void plist_mem_free(void* ptr)
{
    if (ptr)
    {
        free(ptr);
    }
}

static plist_t plist_copy_node(node_t *node)
{
    plist_type node_type = PLIST_NONE;
    plist_t newnode = NULL;
    plist_data_t data = plist_get_data(node);
    plist_data_t newdata = plist_new_plist_data();

    assert(data);				// plist should always have data
    assert(newdata);

    memcpy(newdata, data, sizeof(struct plist_data_s));

    node_type = plist_get_node_type(node);
    switch (node_type) {
        case PLIST_DATA:
            newdata->buff = (uint8_t *) malloc(data->length);
            memcpy(newdata->buff, data->buff, data->length);
            break;
        case PLIST_KEY:
        case PLIST_STRING:
            newdata->strval = strdup(data->strval);
            break;
        case PLIST_ARRAY:
            if (data->hashtable) {
                ptrarray_t* pa = ptr_array_new(((ptrarray_t*)data->hashtable)->capacity);
                assert(pa);
                newdata->hashtable = pa;
            }
            break;
        case PLIST_DICT:
            if (data->hashtable) {
                hashtable_t* ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
                assert(ht);
                newdata->hashtable = ht;
            }
            break;
        default:
            break;
    }
    newnode = plist_new_node(newdata);

    node_t *ch;
    unsigned int node_index = 0;
    for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
        /* copy child node */
        plist_t newch = plist_copy_node(ch);
        /* attach to new parent node */
        node_attach(newnode, newch);
        /* if needed, add child node to lookup table of parent node */
        switch (node_type) {
            case PLIST_ARRAY:
                if (newdata->hashtable) {
                    ptr_array_add((ptrarray_t*)newdata->hashtable, newch);
                }
                break;
            case PLIST_DICT:
                if (newdata->hashtable && (node_index % 2 != 0)) {
                    hash_table_insert((hashtable_t*)newdata->hashtable, (node_prev_sibling((node_t*)newch))->data, newch);
                }
                break;
            default:
                break;
        }
        node_index++;
    }
    return newnode;
}

PLIST_API plist_t plist_copy(plist_t node)
{
    return node ? plist_copy_node(node) : NULL;
}

PLIST_API uint32_t plist_array_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        ret = node_n_children(node);
    }
    return ret;
}

PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n)
{
    plist_t ret = NULL;
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        ptrarray_t *pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
        if (pa) {
            ret = (plist_t)ptr_array_index(pa, n);
        } else {
            ret = (plist_t)node_nth_child(node, n);
        }
    }
    return ret;
}

PLIST_API uint32_t plist_array_get_item_index(plist_t node)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_ARRAY == plist_get_node_type(father))
    {
        return node_child_position(father, node);
    }
    return UINT_MAX;
}

static void _plist_array_post_insert(plist_t node, plist_t item, long n)
{
    ptrarray_t *pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
    if (pa) {
        /* store pointer to item in array */
        ptr_array_insert(pa, item, n);
    } else {
        if (((node_t*)node)->count > 100) {
            /* make new lookup array */
            pa = ptr_array_new(128);
            plist_t current = NULL;
            for (current = (plist_t)node_first_child(node);
                 pa && current;
                 current = (plist_t)node_next_sibling(current))
            {
                ptr_array_add(pa, current);
            }
            ((plist_data_t)((node_t*)node)->data)->hashtable = pa;
        }
    }
}

PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        plist_t old_item = plist_array_get_item(node, n);
        if (old_item)
        {
            int idx = plist_free_node(old_item);
            assert(idx >= 0);
            if (idx < 0) {
                return;
            }
            node_insert(node, idx, item);
            ptrarray_t* pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
            if (pa) {
                ptr_array_set(pa, item, idx);
            }
        }
    }
}

PLIST_API void plist_array_append_item(plist_t node, plist_t item)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        node_attach(node, item);
        _plist_array_post_insert(node, item, -1);
    }
}

PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        node_insert(node, n, item);
        _plist_array_post_insert(node, item, (long)n);
    }
}

PLIST_API void plist_array_remove_item(plist_t node, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        plist_t old_item = plist_array_get_item(node, n);
        if (old_item)
        {
            ptrarray_t* pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
            if (pa) {
                ptr_array_remove(pa, n);
            }
            plist_free(old_item);
        }
    }
}

PLIST_API void plist_array_item_remove(plist_t node)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_ARRAY == plist_get_node_type(father))
    {
        int n = node_child_position(father, node);
        if (n < 0) return;
        ptrarray_t* pa = ((plist_data_t)((node_t*)father)->data)->hashtable;
        if (pa) {
            ptr_array_remove(pa, n);
        }
        plist_free(node);
    }
}

PLIST_API void plist_array_new_iter(plist_t node, plist_array_iter *iter)
{
    if (iter)
    {
        *iter = malloc(sizeof(node_t*));
        *((node_t**)(*iter)) = node_first_child(node);
    }
}

PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item)
{
    node_t** iter_node = (node_t**)iter;

    if (item)
    {
        *item = NULL;
    }

    if (node && PLIST_ARRAY == plist_get_node_type(node) && *iter_node)
    {
        if (item)
        {
            *item = (plist_t)(*iter_node);
        }
        *iter_node = node_next_sibling(*iter_node);
    }
}

PLIST_API uint32_t plist_dict_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        ret = node_n_children(node) / 2;
    }
    return ret;
}

PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
{
    if (iter)
    {
        *iter = malloc(sizeof(node_t*));
        *((node_t**)(*iter)) = node_first_child(node);
    }
}

PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
{
    node_t** iter_node = (node_t**)iter;

    if (key)
    {
        *key = NULL;
    }
    if (val)
    {
        *val = NULL;
    }

    if (node && PLIST_DICT == plist_get_node_type(node) && *iter_node)
    {
        if (key)
        {
            plist_get_key_val((plist_t)(*iter_node), key);
        }
        *iter_node = node_next_sibling(*iter_node);
        if (val)
        {
            *val = (plist_t)(*iter_node);
        }
        *iter_node = node_next_sibling(*iter_node);
    }
}

PLIST_API void plist_dict_get_item_key(plist_t node, char **key)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_DICT == plist_get_node_type(father))
    {
        plist_get_key_val( (plist_t) node_prev_sibling(node), key);
    }
}

PLIST_API plist_t plist_dict_item_get_key(plist_t node)
{
    plist_t ret = NULL;
    plist_t father = plist_get_parent(node);
    if (PLIST_DICT == plist_get_node_type(father))
    {
        ret = (plist_t)node_prev_sibling(node);
    }
    return ret;
}

PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key)
{
    plist_t ret = NULL;

    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        plist_data_t data = plist_get_data(node);
        hashtable_t *ht = (hashtable_t*)data->hashtable;
        if (ht) {
            struct plist_data_s sdata;
            sdata.strval = (char*)key;
            sdata.length = strlen(key);
            ret = (plist_t)hash_table_lookup(ht, &sdata);
        } else {
            plist_t current = NULL;
            for (current = (plist_t)node_first_child(node);
                current;
                current = (plist_t)node_next_sibling(node_next_sibling(current)))
            {
                data = plist_get_data(current);
                assert( PLIST_KEY == plist_get_node_type(current) );

                if (data && !strcmp(key, data->strval))
                {
                    ret = (plist_t)node_next_sibling(current);
                    break;
                }
            }
        }
    }
    return ret;
}

PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item)
{
    if (node && PLIST_DICT == plist_get_node_type(node)) {
        node_t* old_item = plist_dict_get_item(node, key);
        plist_t key_node = NULL;
        if (old_item) {
            int idx = plist_free_node(old_item);
            assert(idx >= 0);
            if (idx < 0) {
                return;
            }
            node_insert(node, idx, item);
            key_node = node_prev_sibling(item);
        } else {
            key_node = plist_new_key(key);
            node_attach(node, key_node);
            node_attach(node, item);
        }

        hashtable_t *ht = ((plist_data_t)((node_t*)node)->data)->hashtable;
        if (ht) {
            /* store pointer to item in hash table */
            hash_table_insert(ht, (plist_data_t)((node_t*)key_node)->data, item);
        } else {
            if (((node_t*)node)->count > 500) {
                /* make new hash table */
                ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
                /* calculate the hashes for all entries we have so far */
                plist_t current = NULL;
                for (current = (plist_t)node_first_child(node);
                     ht && current;
                     current = (plist_t)node_next_sibling(node_next_sibling(current)))
                {
                    hash_table_insert(ht, ((node_t*)current)->data, node_next_sibling(current));
                }
                ((plist_data_t)((node_t*)node)->data)->hashtable = ht;
            }
        }
    }
}

PLIST_API void plist_dict_insert_item(plist_t node, const char* key, plist_t item)
{
    plist_dict_set_item(node, key, item);
}

PLIST_API void plist_dict_remove_item(plist_t node, const char* key)
{
    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        plist_t old_item = plist_dict_get_item(node, key);
        if (old_item)
        {
            plist_t key_node = node_prev_sibling(old_item);
            hashtable_t* ht = ((plist_data_t)((node_t*)node)->data)->hashtable;
            if (ht) {
                hash_table_remove(ht, ((node_t*)key_node)->data);
            }
            plist_free(key_node);
            plist_free(old_item);
        }
    }
}

PLIST_API void plist_dict_merge(plist_t *target, plist_t source)
{
	if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT))
		return;

	char* key = NULL;
	plist_dict_iter it = NULL;
	plist_t subnode = NULL;
	plist_dict_new_iter(source, &it);
	if (!it)
		return;

	do {
		plist_dict_next_item(source, it, &key, &subnode);
		if (!key)
			break;

		plist_dict_set_item(*target, key, plist_copy(subnode));
		free(key);
		key = NULL;
	} while (1);
	free(it);
}

PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
{
    plist_t current = plist;
    plist_type type = PLIST_NONE;
    uint32_t i = 0;

    for (i = 0; i < length && current; i++)
    {
        type = plist_get_node_type(current);

        if (type == PLIST_ARRAY)
        {
            uint32_t n = va_arg(v, uint32_t);
            current = plist_array_get_item(current, n);
        }
        else if (type == PLIST_DICT)
        {
            const char* key = va_arg(v, const char*);
            current = plist_dict_get_item(current, key);
        }
    }
    return current;
}

PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...)
{
    plist_t ret = NULL;
    va_list v;

    va_start(v, length);
    ret = plist_access_pathv(plist, length, v);
    va_end(v);
    return ret;
}

static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length)
{
    plist_data_t data = NULL;

    if (!node)
        return;

    data = plist_get_data(node);

    *type = data->type;
    *length = data->length;

    switch (*type)
    {
    case PLIST_BOOLEAN:
        *((char *) value) = data->boolval;
        break;
    case PLIST_UINT:
    case PLIST_UID:
        *((uint64_t *) value) = data->intval;
        break;
    case PLIST_REAL:
    case PLIST_DATE:
        *((double *) value) = data->realval;
        break;
    case PLIST_KEY:
    case PLIST_STRING:
        *((char **) value) = strdup(data->strval);
        break;
    case PLIST_DATA:
        *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t));
        memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t));
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

PLIST_API plist_t plist_get_parent(plist_t node)
{
    return node ? (plist_t) ((node_t*) node)->parent : NULL;
}

PLIST_API plist_type plist_get_node_type(plist_t node)
{
    if (node)
    {
        plist_data_t data = plist_get_data(node);
        if (data)
            return data->type;
    }
    return PLIST_NONE;
}

PLIST_API void plist_get_key_val(plist_t node, char **val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_KEY != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    if (!*val)
        return;
    assert(length == strlen(*val));
}

PLIST_API void plist_get_string_val(plist_t node, char **val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_STRING != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    if (!*val)
        return;
    assert(length == strlen(*val));
}

PLIST_API const char* plist_get_string_ptr(plist_t node, uint64_t* length)
{
    if (!node)
        return NULL;
    plist_type type = plist_get_node_type(node);
    if (PLIST_STRING != type)
        return NULL;
    plist_data_t data = plist_get_data(node);
    if (length)
        *length = data->length;
    return (const char*)data->strval;
}

PLIST_API void plist_get_bool_val(plist_t node, uint8_t * val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_BOOLEAN != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint8_t));
}

PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_UINT != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint64_t) || length == 16);
}

PLIST_API void plist_get_uid_val(plist_t node, uint64_t * val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_UID != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint64_t));
}

PLIST_API void plist_get_real_val(plist_t node, double *val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_REAL != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(double));
}

PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length)
{
    if (!node || !val || !length)
        return;
    plist_type type = plist_get_node_type(node);
    if (PLIST_DATA != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, length);
}

PLIST_API const char* plist_get_data_ptr(plist_t node, uint64_t* length)
{
    if (!node || !length)
        return NULL;
    plist_type type = plist_get_node_type(node);
    if (PLIST_DATA != type)
        return NULL;
    plist_data_t data = plist_get_data(node);
    *length = data->length;
    return (const char*)data->buff;
}

PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
{
    if (!node)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    double val = 0;
    if (PLIST_DATE != type)
        return;
    plist_get_type_and_value(node, &type, (void *) &val, &length);
    assert(length == sizeof(double));
    if (sec)
        *sec = (int32_t)val;
    if (usec)
        *usec = (int32_t)fabs((val - (int64_t)val) * 1000000);
}

int plist_data_compare(const void *a, const void *b)
{
    plist_data_t val_a = NULL;
    plist_data_t val_b = NULL;

    if (!a || !b)
        return FALSE;

    if (!((node_t*) a)->data || !((node_t*) b)->data)
        return FALSE;

    val_a = plist_get_data((plist_t) a);
    val_b = plist_get_data((plist_t) b);

    if (val_a->type != val_b->type)
        return FALSE;

    switch (val_a->type)
    {
    case PLIST_BOOLEAN:
    case PLIST_UINT:
    case PLIST_REAL:
    case PLIST_DATE:
    case PLIST_UID:
        if (val_a->length != val_b->length)
            return FALSE;
        return val_a->intval == val_b->intval;	//it is an union so this is sufficient

    case PLIST_KEY:
    case PLIST_STRING:
        return strcmp(val_a->strval, val_b->strval) == 0;

    case PLIST_DATA:
        if (val_a->length != val_b->length)
            return FALSE;
        return memcmp(val_a->buff, val_b->buff, val_a->length) == 0;

    case PLIST_ARRAY:
    case PLIST_DICT:
        //compare pointer
        return a == b;

    default:
        break;
    }
    return FALSE;
}

PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r)
{
    return plist_data_compare(node_l, node_r);
}

static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length)
{
    //free previous allocated buffer
    plist_data_t data = plist_get_data(node);
    assert(data);				// a node should always have data attached

    switch (data->type)
    {
    case PLIST_KEY:
    case PLIST_STRING:
        free(data->strval);
        data->strval = NULL;
        break;
    case PLIST_DATA:
        free(data->buff);
        data->buff = NULL;
        break;
    default:
        break;
    }

    //now handle value

    data->type = type;
    data->length = length;

    switch (type)
    {
    case PLIST_BOOLEAN:
        data->boolval = *((char *) value);
        break;
    case PLIST_UINT:
    case PLIST_UID:
        data->intval = *((uint64_t *) value);
        break;
    case PLIST_REAL:
    case PLIST_DATE:
        data->realval = *((double *) value);
        break;
    case PLIST_KEY:
    case PLIST_STRING:
        data->strval = strdup((char *) value);
        break;
    case PLIST_DATA:
        data->buff = (uint8_t *) malloc(length);
        memcpy(data->buff, value, length);
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

PLIST_API void plist_set_key_val(plist_t node, const char *val)
{
    plist_t father = plist_get_parent(node);
    plist_t item = plist_dict_get_item(father, val);
    if (item) {
        return;
    }
    plist_set_element_val(node, PLIST_KEY, val, strlen(val));
}

PLIST_API void plist_set_string_val(plist_t node, const char *val)
{
    plist_set_element_val(node, PLIST_STRING, val, strlen(val));
}

PLIST_API void plist_set_bool_val(plist_t node, uint8_t val)
{
    plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t));
}

PLIST_API void plist_set_uint_val(plist_t node, uint64_t val)
{
    plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t));
}

PLIST_API void plist_set_uid_val(plist_t node, uint64_t val)
{
    plist_set_element_val(node, PLIST_UID, &val, sizeof(uint64_t));
}

PLIST_API void plist_set_real_val(plist_t node, double val)
{
    plist_set_element_val(node, PLIST_REAL, &val, sizeof(double));
}

PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length)
{
    plist_set_element_val(node, PLIST_DATA, val, length);
}

PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec)
{
    double val = (double)sec + (double)usec / 1000000;
    plist_set_element_val(node, PLIST_DATE, &val, sizeof(struct timeval));
}

PLIST_API int plist_bool_val_is_true(plist_t boolnode)
{
    if (!PLIST_IS_BOOLEAN(boolnode)) {
        return 0;
    }
    uint8_t bv = 0;
    plist_get_bool_val(boolnode, &bv);
    return (bv == 1);
}

PLIST_API int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval)
{
    if (!PLIST_IS_UINT(uintnode)) {
        return -1;
    }
    uint64_t uintval = 0;
    plist_get_uint_val(uintnode, &uintval);
    if (uintval == cmpval) {
        return 0;
    }

    if (uintval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_uid_val_compare(plist_t uidnode, uint64_t cmpval)
{
    if (!PLIST_IS_UID(uidnode)) {
        return -1;
    }
    uint64_t uidval = 0;
    plist_get_uid_val(uidnode, &uidval);
    if (uidval == cmpval) {
        return 0;
    }

    if (uidval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_real_val_compare(plist_t realnode, double cmpval)
{
    if (!PLIST_IS_REAL(realnode)) {
        return -1;
    }
    double a = 0;
    double b = cmpval;
    plist_get_real_val(realnode, &a);
    double abs_a = fabs(a);
    double abs_b = fabs(b);
    double diff = fabs(a - b);
    if (a == b) {
        return 0;
    }

    if (a == 0 || b == 0 || (abs_a + abs_b < DBL_MIN)) {
        if (diff < (DBL_EPSILON * DBL_MIN)) {
            return 0;
        }

        if (a < b) {
            return -1;
        }
    } else {
        if ((diff / fmin(abs_a + abs_b, DBL_MAX)) < DBL_EPSILON) {
            return 0;
        }

        if (a < b) {
            return -1;
        }
    }
    return 1;
}

PLIST_API int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec)
{
    if (!PLIST_IS_DATE(datenode)) {
        return -1;
    }
    int32_t sec = 0;
    int32_t usec = 0;
    plist_get_date_val(datenode, &sec, &usec);
    uint64_t dateval = ((int64_t)sec << 32) | usec;
    uint64_t cmpval = ((int64_t)cmpsec << 32) | cmpusec;
    if (dateval == cmpval) {
        return 0;
    }

    if (dateval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_string_val_compare(plist_t strnode, const char* cmpval)
{
    if (!PLIST_IS_STRING(strnode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(strnode);
    return strcmp(data->strval, cmpval);
}

PLIST_API int plist_string_val_compare_with_size(plist_t strnode, const char* cmpval, size_t n)
{
    if (!PLIST_IS_STRING(strnode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(strnode);
    return strncmp(data->strval, cmpval, n);
}

PLIST_API int plist_string_val_contains(plist_t strnode, const char* substr)
{
    if (!PLIST_IS_STRING(strnode)) {
        return 0;
    }
    plist_data_t data = plist_get_data(strnode);
    return (strstr(data->strval, substr) != NULL);
}

PLIST_API int plist_key_val_compare(plist_t keynode, const char* cmpval)
{
    if (!PLIST_IS_KEY(keynode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(keynode);
    return strcmp(data->strval, cmpval);
}

PLIST_API int plist_key_val_compare_with_size(plist_t keynode, const char* cmpval, size_t n)
{
    if (!PLIST_IS_KEY(keynode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(keynode);
    return strncmp(data->strval, cmpval, n);
}

PLIST_API int plist_key_val_contains(plist_t keynode, const char* substr)
{
    if (!PLIST_IS_KEY(keynode)) {
        return 0;
    }
    plist_data_t data = plist_get_data(keynode);
    return (strstr(data->strval, substr) != NULL);
}

PLIST_API int plist_data_val_compare(plist_t datanode, const uint8_t* cmpval, size_t n)
{
    if (!PLIST_IS_DATA(datanode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datanode);
    if (data->length < n) {
        return -1;
    }

    if (data->length > n) {
        return 1;
    }

    return memcmp(data->buff, cmpval, n);
}

PLIST_API int plist_data_val_compare_with_size(plist_t datanode, const uint8_t* cmpval, size_t n)
{
    if (!PLIST_IS_DATA(datanode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datanode);
    if (data->length < n) {
        return -1;
    }
    return memcmp(data->buff, cmpval, n);
}

PLIST_API int plist_data_val_contains(plist_t datanode, const uint8_t* cmpval, size_t n)
{
    if (!PLIST_IS_DATA(datanode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datanode);
    return (memmem(data->buff, data->length, cmpval, n) != NULL);
}
