/*
 * plist.c
 * Builds plist XML structures
 *
 * Copyright (c) 2009-2023 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>
#include <ctype.h>
#include <inttypes.h>

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

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

#include "common.h"

#ifdef _MSC_VER
typedef SSIZE_T ssize_t;
#endif

#ifdef DEBUG
static int plist_debug = 0;
#define PLIST_ERR(...) if (plist_debug > 0) { fprintf(stderr, "libplist ERROR: " __VA_ARGS__); }
#else
#define PLIST_ERR(...)
#endif

#ifndef bswap16
#define bswap16(x)   ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
#endif

#ifndef bswap32
#define bswap32(x)   ((((x) & 0xFF000000) >> 24) \
                    | (((x) & 0x00FF0000) >>  8) \
                    | (((x) & 0x0000FF00) <<  8) \
                    | (((x) & 0x000000FF) << 24))
#endif

#ifndef bswap64
#define bswap64(x)   ((((x) & 0xFF00000000000000ull) >> 56) \
                    | (((x) & 0x00FF000000000000ull) >> 40) \
                    | (((x) & 0x0000FF0000000000ull) >> 24) \
                    | (((x) & 0x000000FF00000000ull) >>  8) \
                    | (((x) & 0x00000000FF000000ull) <<  8) \
                    | (((x) & 0x0000000000FF0000ull) << 24) \
                    | (((x) & 0x000000000000FF00ull) << 40) \
                    | (((x) & 0x00000000000000FFull) << 56))
#endif

#ifndef le16toh
#ifdef __BIG_ENDIAN__
#define le16toh(x) bswap16(x)
#else
#define le16toh(x) (x)
#endif
#endif

#ifndef le32toh
#ifdef __BIG_ENDIAN__
#define le32toh(x) bswap32(x)
#else
#define le32toh(x) (x)
#endif
#endif

#ifndef le64toh
#ifdef __BIG_ENDIAN__
#define le64toh(x) bswap64(x)
#else
#define le64toh(x) (x)
#endif
#endif

// Reference: https://stackoverflow.com/a/2390626/1806760
// Initializer/finalizer sample for MSVC and GCC/Clang.
// 2010-2016 Joe Lowe. Released into the public domain.

#ifdef __cplusplus
    #define INITIALIZER(f) \
        static void f(void); \
        struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
        static void f(void)
#elif defined(_MSC_VER)
    #pragma section(".CRT$XCU",read)
    #define INITIALIZER2_(f,p) \
        static void f(void); \
        __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
        __pragma(comment(linker,"/include:" p #f "_")) \
        static void f(void)
    #ifdef _WIN64
        #define INITIALIZER(f) INITIALIZER2_(f,"")
    #else
        #define INITIALIZER(f) INITIALIZER2_(f,"_")
    #endif
#else
    #define INITIALIZER(f) \
        static void f(void) __attribute__((__constructor__)); \
        static void f(void)
#endif

extern void plist_xml_init(void);
extern void plist_xml_deinit(void);
extern void plist_bin_init(void);
extern void plist_bin_deinit(void);
extern void plist_json_init(void);
extern void plist_json_deinit(void);
extern void plist_ostep_init(void);
extern void plist_ostep_deinit(void);

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

INITIALIZER(internal_plist_init)
{
    plist_bin_init();
    plist_xml_init();
    plist_json_init();
    plist_ostep_init();
    atexit(internal_plist_deinit);
}

#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

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

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

#define SKIP_WS(blob, pos, len) \
    while (pos < len && ((blob[pos] == ' ') || (blob[pos] == '\t') || (blob[pos] == '\r') || (blob[pos] == '\n'))) pos++;
#define FIND_NEXT(blob, pos, len, chr) \
    while (pos < len && (blob[pos] != chr)) pos++;

plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format)
{
    plist_err_t res = PLIST_ERR_UNKNOWN;
    if (!plist) {
        return PLIST_ERR_INVALID_ARG;
    }
    *plist = NULL;
    if (!plist_data || length == 0) {
        return PLIST_ERR_INVALID_ARG;
    }
    plist_format_t fmt = PLIST_FORMAT_NONE;
    if (format) *format = PLIST_FORMAT_NONE;
    if (plist_is_binary(plist_data, length)) {
        res = plist_from_bin(plist_data, length, plist);
        fmt = PLIST_FORMAT_BINARY;
    } else {
        uint32_t pos = 0;
        int is_json = 0;
        int is_xml = 0;
        /* skip whitespace */
        SKIP_WS(plist_data, pos, length);
        if (pos >= length) {
            return PLIST_ERR_PARSE;
        }
        if (plist_data[pos] == '<' && (length-pos > 3) && !isxdigit(plist_data[pos+1]) && !isxdigit(plist_data[pos+2]) && !isxdigit(plist_data[pos+3])) {
            is_xml = 1;
        } else if (plist_data[pos] == '[') {
            /* only valid for json */
            is_json = 1;
        } else if (plist_data[pos] == '(') {
            /* only valid for openstep */
        } else if (plist_data[pos] == '{') {
            /* this could be json or openstep */
            pos++;
            SKIP_WS(plist_data, pos, length);
            if (pos >= length) {
                return PLIST_ERR_PARSE;
            }
            if (plist_data[pos] == '"') {
                /* still could be both */
                pos++;
                while (pos < length) {
                    FIND_NEXT(plist_data, pos, length, '"');
                    if (plist_data[pos-1] != '\\') {
                        break;
                    }
                    pos++;
                }
                if (pos >= length) {
                    return PLIST_ERR_PARSE;
                }
                if (plist_data[pos] == '"') {
                    pos++;
                    SKIP_WS(plist_data, pos, length);
                    if (pos >= length) {
                        return PLIST_ERR_PARSE;
                    }
                    if (plist_data[pos] == ':') {
                        /* this is definitely json */
                        is_json = 1;
                    }
                }
            }
        }
        if (is_xml) {
            res = plist_from_xml(plist_data, length, plist);
            fmt = PLIST_FORMAT_XML;
        } else if (is_json) {
            res = plist_from_json(plist_data, length, plist);
            fmt = PLIST_FORMAT_JSON;
        } else {
            res = plist_from_openstep(plist_data, length, plist);
            fmt = PLIST_FORMAT_OSTEP;
        }
    }
    if (format && res == PLIST_ERR_SUCCESS) {
        *format = fmt;
    }
    return res;
}

plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format)
{
    if (!filename || !plist) {
        return PLIST_ERR_INVALID_ARG;
    }
    FILE *f = fopen(filename, "rb");
    if (!f) {
        return PLIST_ERR_IO;
    }
    struct stat fst;
    fstat(fileno(f), &fst);
    if ((uint64_t)fst.st_size > UINT32_MAX) {
        return PLIST_ERR_NO_MEM;
    }
    uint32_t total = (uint32_t)fst.st_size;
    if (total == 0) {
        return PLIST_ERR_PARSE;
    }
    char *buf = (char*)malloc(total);
    if (!buf) {
        fclose(f);
        return PLIST_ERR_NO_MEM;
    }
    uint32_t done = 0;
    while (done < total) {
        ssize_t r = fread(buf + done, 1, total - done, f);
        if (r <= 0) {
            break;
        }
        done += r;
    }
    fclose(f);
    if (done < total) {
        free(buf);
        return PLIST_ERR_IO;
    }
    plist_err_t res = plist_from_memory(buf, total, plist, format);
    free(buf);
    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 (plist_data_t)((node_t)node)->data;
}

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

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

static void _plist_free_data(plist_data_t data)
{
    if (!data) return;
    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;
        case PLIST_ARRAY:
            ptr_array_free((ptrarray_t*)data->hashtable);
            data->hashtable = NULL;
            break;
        case PLIST_DICT: {
            hashtable_t *ht = (hashtable_t*)data->hashtable;
            // PLIST_DICT hashtables must not own/free values; values are freed via node tree.
            assert(!ht || ht->free_func == NULL);
            if (ht) ht->free_func = NULL;
            hash_table_destroy(ht);
            data->hashtable = NULL;
            break;
        }
        default:
            break;
    }
}

void plist_free_data(plist_data_t data)
{
    if (!data) return;
    _plist_free_data(data);
    free(data);
}

static int plist_free_children(node_t root)
{
    if (!root) return NODE_ERR_INVALID_ARG;

    if (!node_first_child(root)) {
        return NODE_ERR_SUCCESS;
    }

    size_t cap = 64, sp = 0;
    node_t *stack = (node_t*)malloc(cap * sizeof(*stack));
    if (!stack) return NODE_ERR_NO_MEM;

    // Push *direct* children onto the stack, detached from root.
    for (;;) {
        node_t ch = node_first_child(root);
        if (!ch) break;

        int di = node_detach(root, ch);
        if (di < 0) {
            free(stack);
            return di;
        }

        if (sp == cap) {
            cap += 64;
            node_t *tmp = (node_t*)realloc(stack, cap * sizeof(*stack));
            if (!tmp) {
                free(stack);
                return NODE_ERR_NO_MEM;
            }
            stack = tmp;
        }
        stack[sp++] = ch;
    }

    // Now free the detached subtree nodes (and their descendants).
    while (sp) {
        node_t node = stack[sp - 1];
        node_t ch = node_first_child(node);
        if (ch) {
            int di = node_detach(node, ch);
            if (di < 0) {
                free(stack);
                return di;
            }

            if (sp == cap) {
                cap += 64;
                node_t *tmp = (node_t*)realloc(stack, cap * sizeof(*stack));
                if (!tmp) {
                    free(stack);
                    return NODE_ERR_NO_MEM;
                }
                stack = tmp;
            }
            stack[sp++] = ch;
            continue;
        }

        plist_data_t data = plist_get_data(node);
        plist_free_data(data);
        node->data = NULL;

        node_destroy(node);

        sp--;
    }

    free(stack);
    return NODE_ERR_SUCCESS;
}

static int plist_free_node(node_t root)
{
    if (!root) return NODE_ERR_INVALID_ARG;

    int root_index = -1;

    if (root->parent) {
        root_index = node_detach(root->parent, root);
        if (root_index < 0) {
            return root_index;
        }
    }

    int r = plist_free_children(root);
    if (r < 0) {
        // root is already detached; caller should treat as error.
        return r;
    }

    plist_data_t data = plist_get_data(root);
    plist_free_data(data);
    root->data = NULL;

    node_destroy(root);

    return root_index;
}

plist_t plist_new_dict(void)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_DICT;
    return plist_new_node(data);
}

plist_t plist_new_array(void)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    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();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_KEY;
    data->strval = strdup(val);
    if (!data->strval) {
        plist_free_data(data);
        PLIST_ERR("%s: strdup failed\n", __func__);
        return NULL;
    } else {
        data->length = strlen(val);
    }
    return plist_new_node(data);
}

plist_t plist_new_string(const char *val)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_STRING;
    data->strval = strdup(val);
    if (!data->strval) {
        plist_free_data(data);
        PLIST_ERR("%s: strdup failed\n", __func__);
        return NULL;
    } else {
        data->length = strlen(val);
    }
    return plist_new_node(data);
}

plist_t plist_new_bool(uint8_t val)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_BOOLEAN;
    data->boolval = val;
    data->length = sizeof(uint8_t);
    return plist_new_node(data);
}

plist_t plist_new_uint(uint64_t val)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_INT;
    data->intval = val;
    data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t);
    return plist_new_node(data);
}

plist_t plist_new_int(int64_t val)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_INT;
    data->intval = val;
    data->length = sizeof(uint64_t);
    return plist_new_node(data);
}

plist_t plist_new_uid(uint64_t val)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_UID;
    data->intval = val;
    data->length = sizeof(uint64_t);
    return plist_new_node(data);
}

plist_t plist_new_real(double val)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_REAL;
    data->realval = val;
    data->length = sizeof(double);
    return plist_new_node(data);
}

plist_t plist_new_data(const char *val, uint64_t length)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_DATA;
    if (val && length) {
        data->buff = (uint8_t *) malloc(length);
        if (!data->buff) {
            PLIST_ERR("%s: failed to allocate %" PRIu64 " bytes\n", __func__, length);
            return NULL;
        }
        memcpy(data->buff, val, length);
    }
    data->length = length;
    return plist_new_node(data);
}

plist_t plist_new_date(int32_t sec, int32_t usec)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_DATE;
    data->realval = (double)sec + (double)usec / 1000000;
    data->length = sizeof(double);
    return plist_new_node(data);
}

plist_t plist_new_unix_date(int64_t sec)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_DATE;
    data->realval = (double)sec - MAC_EPOCH;
    data->length = sizeof(double);
    return plist_new_node(data);
}

plist_t plist_new_null(void)
{
    plist_data_t data = plist_new_plist_data();
    if (!data) {
        PLIST_ERR("%s: failed to allocate plist data\n", __func__);
        return NULL;
    }
    data->type = PLIST_NULL;
    data->intval = 0;
    data->length = 0;
    return plist_new_node(data);
}

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

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

static int plist_copy_node_shallow(node_t node, plist_t *out_newnode, plist_data_t *out_newdata, plist_type *out_type)
{
    if (!node || !out_newnode || !out_newdata || !out_type) return NODE_ERR_INVALID_ARG;

    plist_data_t data = plist_get_data(node);
    if (!data) return NODE_ERR_INVALID_ARG;

    plist_data_t newdata = plist_new_plist_data();
    if (!newdata) return NODE_ERR_NO_MEM;

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

    plist_type node_type = plist_get_node_type(node);
    switch (node_type) {
        case PLIST_DATA:
            if (data->buff) {
                newdata->buff = (uint8_t*)malloc(data->length);
                if (!newdata->buff) {
                    plist_free_data(newdata);
                    return NODE_ERR_NO_MEM;
                }
                memcpy(newdata->buff, data->buff, data->length);
            } else {
                newdata->buff = NULL;
                newdata->length = 0;
            }
            break;

        case PLIST_KEY:
        case PLIST_STRING:
            if (data->strval) {
                size_t n = strlen(data->strval);
                newdata->strval = (char*)malloc(n+1);
                if (!newdata->strval) {
                    plist_free_data(newdata);
                    return NODE_ERR_NO_MEM;
                }
                memcpy(newdata->strval, data->strval, n+1);
                newdata->length = (uint64_t)n;
            } else {
                newdata->strval = NULL;
                newdata->length = 0;
            }
            break;

        case PLIST_ARRAY:
            if (data->hashtable) {
                ptrarray_t* pa = ptr_array_new(((ptrarray_t*)data->hashtable)->capacity);
                if (!pa) {
                    plist_free_data(newdata);
                    return NODE_ERR_NO_MEM;
                }
                newdata->hashtable = pa;
            }
            break;

        case PLIST_DICT:
            if (data->hashtable) {
                hashtable_t* ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
                if (!ht) {
                    plist_free_data(newdata);
                    return NODE_ERR_NO_MEM;
                }
                newdata->hashtable = ht;
            }
            break;

        default:
            break;
    }

    plist_t newnode = plist_new_node(newdata);
    if (!newnode) {
        plist_free_data(newdata);
        return NODE_ERR_NO_MEM;
    }

    *out_newnode = newnode;
    *out_newdata = newdata;
    *out_type = node_type;
    return NODE_ERR_SUCCESS;
}

static plist_t plist_copy_node(node_t root)
{
    typedef struct copy_frame {
        node_t       orig;        // original node
        plist_t      copy;        // copied node
        plist_data_t copydata;    // copied node's data (for cache updates)
        plist_type   type;        // copied node type
        node_t       next_child;  // next child of orig to process
        unsigned int node_index;  // child index (for dict key/value odd/even)
        int          depth;       // optional depth tracking
    } copy_frame_t;

    if (!root) return NULL;

    // shallow-copy root first
    plist_t newroot = NULL;
    plist_data_t newroot_data = NULL;
    plist_type newroot_type = PLIST_NONE;

    int r = plist_copy_node_shallow(root, &newroot, &newroot_data, &newroot_type);
    if (r != NODE_ERR_SUCCESS) {
        PLIST_ERR("%s: shallow node copy failed (%d)\n", __func__, r);
        return NULL;
    }

    // stack of frames
    size_t cap = 64, sp = 0;
    copy_frame_t *st = (copy_frame_t*)malloc(cap * sizeof(*st));
    if (!st) {
        plist_free_node((node_t)newroot);
        return NULL;
    }

    copy_frame_t cf;
    cf.orig = root;
    cf.copy = newroot;
    cf.copydata = newroot_data;
    cf.type = newroot_type;
    cf.next_child = node_first_child(root);
    cf.node_index = 0;
    cf.depth = 0;
    st[sp++] = cf;

    while (sp) {
        copy_frame_t *f = &st[sp - 1];

        if (f->depth > NODE_MAX_DEPTH) {
            plist_free_node((node_t)newroot);
            free(st);
            PLIST_ERR("%s: maximum nesting depth exceeded\n", __func__);
            return NULL;
        }

        // done with this node?
        if (!f->next_child) {
            sp--;
            continue;
        }

        // take next child and advance iterator
        node_t ch = f->next_child;
        f->next_child = node_next_sibling(ch);

        // shallow copy child
        plist_t newch = NULL;
        plist_data_t newch_data = NULL;
        plist_type newch_type = PLIST_NONE;

        r = plist_copy_node_shallow(ch, &newch, &newch_data, &newch_type);
        if (r != NODE_ERR_SUCCESS) {
            plist_free_node((node_t)newroot);
            free(st);
            PLIST_ERR("%s: shallow node copy failed (%d)\n", __func__, r);
            return NULL;
        }

        // attach child to copied parent
        r = node_attach((node_t)f->copy, (node_t)newch);
        if (r != NODE_ERR_SUCCESS) {
            plist_free_node((node_t)newch);
            plist_free_node((node_t)newroot);
            free(st);
            PLIST_ERR("%s: failed to attach child to copied parent (%d)\n", __func__, r);
            return NULL;
        }

        // update lookup cache on the *parent* copy
        switch (f->type) {
            case PLIST_ARRAY:
                if (f->copydata->hashtable) {
                    if (ptr_array_add((ptrarray_t*)f->copydata->hashtable, newch) < 0) {
                        ptr_array_free((ptrarray_t*)f->copydata->hashtable);
                        f->copydata->hashtable = NULL;
                    }
                }
                break;

            case PLIST_DICT:
                if (f->copydata->hashtable && (f->node_index % 2 != 0)) {
                    node_t new_key = node_prev_sibling((node_t)newch);
                    if (new_key) {
                        hash_table_insert((hashtable_t*)f->copydata->hashtable, new_key->data, newch);
                    }
                }
                break;

            default:
                break;
        }

        f->node_index++;

        // push child frame to process its children
        if (sp == cap) {
            cap += 64;
            copy_frame_t *tmp = (copy_frame_t*)realloc(st, cap * sizeof(*st));
            if (!tmp) {
                plist_free_node((node_t)newroot);
                free(st);
                PLIST_ERR("%s: out of memory when reallocating\n", __func__);
                return NULL;
            }
            st = tmp;
        }

        copy_frame_t nf;
        nf.orig = ch;
        nf.copy = newch;
        nf.copydata = newch_data;
        nf.type = newch_type;
        nf.next_child = node_first_child(ch);
        nf.node_index = 0;
        nf.depth = f->depth + 1;
        st[sp++] = nf;
    }

    free(st);
    return newroot;
}

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

uint32_t plist_array_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (PLIST_IS_ARRAY(node)) {
        ret = node_n_children((node_t)node);
    }
    return ret;
}

plist_t plist_array_get_item(plist_t node, uint32_t n)
{
    plist_t ret = NULL;
    if (PLIST_IS_ARRAY(node) && n < INT_MAX) {
        ptrarray_t *pa = (ptrarray_t*)((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_t)node, n);
        }
    }
    return ret;
}

uint32_t plist_array_get_item_index(plist_t node)
{
    plist_t parent = plist_get_parent(node);
    if (PLIST_IS_ARRAY(parent)) {
        return node_child_position((node_t)parent, (node_t)node);
    }
    return UINT_MAX;
}

static void _plist_array_post_insert(plist_t node, plist_t item, long n)
{
    ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;
    if (pa) {
        /* store pointer to item in array */
        if (ptr_array_insert(pa, item, n) < 0) {
            /* lookup array would be out of sync, drop it */
            ptr_array_free(pa);
            ((plist_data_t)((node_t)node)->data)->hashtable = NULL;
        }
        return;
    }

    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_t)node);
            pa && current;
            current = (plist_t)node_next_sibling((node_t)current))
       {
           if (ptr_array_add(pa, current) < 0) {
               ptr_array_free(pa);
               pa = NULL;
           }
       }
       ((plist_data_t)((node_t)node)->data)->hashtable = pa;
    }
}

static void _plist_array_post_set(plist_t node, plist_t item, long n)
{
    ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;

    if (pa) {
        if (n < 0 || n >= pa->len) {
           PLIST_ERR("%s: cache index out of range (n=%ld len=%ld)\n", __func__, n, pa->len);
           return;
        }
        ptr_array_set(pa, item, n);
        return;
    }

    if (((node_t)node)->count > 100) {
        pa = ptr_array_new(128);
        plist_t current = NULL;
        for (current = (plist_t)node_first_child((node_t)node);
             pa && current;
             current = (plist_t)node_next_sibling((node_t)current))
        {
            ptr_array_add(pa, current);
        }
        ((plist_data_t)((node_t)node)->data)->hashtable = pa;

        // Now that it exists (and is filled), apply the set (will no-op if out of range)
        if (pa) {
            ptr_array_set(pa, item, n);
        }
    }
}

plist_err_t plist_array_set_item(plist_t node, plist_t item, uint32_t n)
{
    if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) {
        PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n);
        return PLIST_ERR_INVALID_ARG;
    }
    node_t it = (node_t)item;
    if (it->parent != NULL) {
        assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first");
        PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__);
        return PLIST_ERR_INVALID_ARG;
    }
    plist_t old_item = plist_array_get_item(node, n);
    if (!old_item) return PLIST_ERR_INVALID_ARG;

    int idx = node_detach((node_t)node, (node_t)old_item);
    if (idx < 0) {
        PLIST_ERR("%s: Failed to detach old item (err=%d)\n", __func__, idx);
        return PLIST_ERR_UNKNOWN;
    }

    int r = node_insert((node_t)node, (unsigned)idx, (node_t)item);
    if (r != NODE_ERR_SUCCESS) {
        int rb = node_insert((node_t)node, (unsigned)idx, (node_t)old_item);
        if (rb == NODE_ERR_SUCCESS) {
            _plist_array_post_set(node, old_item, idx); // restore cache correctly
            PLIST_ERR("%s: failed to insert replacement (idx=%d err=%d); rollback succeeded\n", __func__, idx, r);
            return (r == NODE_ERR_NO_MEM) ? PLIST_ERR_NO_MEM : PLIST_ERR_UNKNOWN;
        } else {
            PLIST_ERR("%s: insert failed (err=%d) and rollback failed (err=%d); array now missing element at idx=%d\n", __func__, r, rb, idx);
            return PLIST_ERR_UNKNOWN;
        }
    }

    _plist_array_post_set(node, item, idx); // update cache
    plist_free_node((node_t)old_item);

    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_array_append_item(plist_t node, plist_t item)
{
    if (!PLIST_IS_ARRAY(node) || !item) {
        PLIST_ERR("invalid argument passed to %s (node=%p, item=%p)\n", __func__, node, item);
        return PLIST_ERR_INVALID_ARG;
    }
    node_t it = (node_t)item;
    if (it->parent != NULL) {
        assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first");
        PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__);
        return PLIST_ERR_INVALID_ARG;
    }

    int r = node_attach((node_t)node, (node_t)item);
    if (r != NODE_ERR_SUCCESS) {
        PLIST_ERR("%s: failed to append item (err=%d)\n", __func__, r);
        return PLIST_ERR_UNKNOWN;
    }
    _plist_array_post_insert(node, item, -1);

    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
{
    if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) {
        PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n);
        return PLIST_ERR_INVALID_ARG;
    }
    node_t it = (node_t)item;
    if (it->parent != NULL) {
        assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first");
        PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__);
        return PLIST_ERR_INVALID_ARG;
    }

    int r = node_insert((node_t)node, n, (node_t)item);
    if (r != NODE_ERR_SUCCESS) {
        PLIST_ERR("%s: Failed to insert item at index %u (err=%d)\n", __func__, n, r);
        return PLIST_ERR_UNKNOWN;
    }
    _plist_array_post_insert(node, item, (long)n);

    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_array_remove_item(plist_t node, uint32_t n)
{
    if (!PLIST_IS_ARRAY(node) || n >= INT_MAX || n > plist_array_get_size(node)) {
        PLIST_ERR("invalid argument passed to %s (node=%p, n=%u)\n", __func__, node, n);
        return PLIST_ERR_INVALID_ARG;
    }

    plist_t old_item = plist_array_get_item(node, n);
    if (!old_item) {
        PLIST_ERR("item not found at index %u\n", n);
        return PLIST_ERR_INVALID_ARG;
    }
    ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;
    if (pa) {
        ptr_array_remove(pa, n);
    }
    plist_free(old_item);

    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_array_item_remove(plist_t item)
{
    plist_t parent = plist_get_parent(item);
    if (PLIST_IS_ARRAY(parent)) {
        int n = node_child_position((node_t)parent, (node_t)item);
        if (n < 0) return PLIST_ERR_INVALID_ARG;
        ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)parent)->data)->hashtable;
        if (pa) {
            ptr_array_remove(pa, n);
        }
        plist_free(item);
    }
    return PLIST_ERR_SUCCESS;
}

typedef struct {
    node_t cur;
} plist_array_iter_private;

void plist_array_new_iter(plist_t node, plist_array_iter *iter)
{
    if (!iter) return;
    *iter = NULL;
    if (!PLIST_IS_ARRAY(node)) return;

    plist_array_iter_private* it = (plist_array_iter_private*)malloc(sizeof(*it));
    if (!it) return;
    it->cur = node_first_child((node_t)node);
    *iter = (plist_array_iter)it;
}

void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item)
{
    if (item) *item = NULL;
    if (!iter) return;
    if (!PLIST_IS_ARRAY(node)) return;

    plist_array_iter_private* it = (plist_array_iter_private*)iter;
    node_t cur = it->cur;
    if (!cur) return;

    if (item) {
        *item = (plist_t)cur;
    }
    it->cur = node_next_sibling(cur);
}

void plist_array_free_iter(plist_array_iter iter)
{
    free(iter);
}

uint32_t plist_dict_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (PLIST_IS_DICT(node)) {
        ret = node_n_children((node_t)node) / 2;
    }
    return ret;
}

typedef struct {
    node_t cur;
} plist_dict_iter_private;

void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
{
    if (!iter) return;
    *iter = NULL;
    if (!PLIST_IS_DICT(node)) return;

    plist_dict_iter_private* it = (plist_dict_iter_private*)malloc(sizeof(*it));
    if (!it) return;
    it->cur = node_first_child((node_t)node);
    *iter = (plist_dict_iter)it;
}

void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
{
    if (key) *key = NULL;
    if (val) *val = NULL;
    if (!iter) return;
    if (!PLIST_IS_DICT(node)) return;

    plist_dict_iter_private* it = (plist_dict_iter_private*)iter;

    node_t k = it->cur;
    if (!k) return;

    if (!PLIST_IS_KEY((plist_t)k)) {
        // malformed dict, terminate iteration
        it->cur = NULL;
        return;
    }

    node_t v = node_next_sibling(k);
    if (!v) {
        // key without value, terminate iteration
        it->cur = NULL;
        return;
    }

    if (key) {
        plist_get_key_val((plist_t)k, key);
    }
    if (val) {
        *val = (plist_t)v;
    }
    it->cur = node_next_sibling(v);
}

void plist_dict_free_iter(plist_dict_iter iter)
{
    free(iter);
}

void plist_dict_get_item_key(plist_t node, char **key)
{
    plist_t parent = plist_get_parent(node);
    if (PLIST_IS_DICT(parent)) {
        plist_get_key_val( (plist_t) node_prev_sibling((node_t)node), key);
    }
}

plist_t plist_dict_item_get_key(plist_t node)
{
    plist_t ret = NULL;
    plist_t parent = plist_get_parent(node);
    if (PLIST_IS_DICT(parent)) {
        ret = (plist_t)node_prev_sibling((node_t)node);
    }
    return ret;
}

plist_t plist_dict_get_item(plist_t node, const char* key)
{
    plist_t ret = NULL;
    if (!PLIST_IS_DICT(node) || !key) {
        PLIST_ERR("invalid argument passed to %s (node=%p, key=%p)\n", __func__, node, key);
        return NULL;
    }
    plist_data_t data = plist_get_data(node);
    if (!data) {
        PLIST_ERR("%s: invalid node\n", __func__);
        return NULL;
    }
    size_t keylen = strlen(key);
    hashtable_t *ht = (hashtable_t*)data->hashtable;
    if (ht) {
        struct plist_data_s sdata = { 0 };
        sdata.strval = (char*)key;
        sdata.length = keylen;
        return (plist_t)hash_table_lookup(ht, &sdata);
    } else {
        plist_t k = NULL;
        for (k = (plist_t)node_first_child((node_t)node); k; ) {
            plist_t v = (plist_t)node_next_sibling(k);
            if (!v) break;
            data = plist_get_data(k);
            assert(PLIST_IS_KEY(k));
            if (!PLIST_IS_KEY(k) || !data || !data->strval) {
                PLIST_ERR("invalid key node at %p\n", k);
                break;
            }
            if (data->length == keylen && !memcmp(key, data->strval, keylen+1)) {
                ret = v;
                break;
            }
            k = node_next_sibling(v);
        }
    }
    return ret;
}

plist_err_t plist_dict_set_item(plist_t node, const char* key, plist_t item)
{
    if (!PLIST_IS_DICT(node) || !key || !item) {
        PLIST_ERR("invalid argument passed to %s (node=%p, key=%p, item=%p)\n", __func__, node, key, item);
        return PLIST_ERR_INVALID_ARG;
    }
    node_t it = (node_t)item;
    if (it->parent != NULL) {
        assert(it->parent == NULL && "item already has a parent");
        PLIST_ERR("%s: item already has a parent\n", __func__);
        return PLIST_ERR_INVALID_ARG;
    }

    hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable;

    plist_t old_item = plist_dict_get_item(node, key);
    plist_t key_node = NULL;

    if (old_item) {
        // --- REPLACE EXISTING VALUE ---
        node_t old_val = (node_t)old_item;
        node_t old_key = node_prev_sibling(old_val);
        if (!old_key) {
            PLIST_ERR("%s: corrupt dict (value without key)\n", __func__);
            return PLIST_ERR_UNKNOWN;
        }
        if (!PLIST_IS_KEY((plist_t)old_key)) {
            PLIST_ERR("%s: corrupt dict ('key' node is not PLIST_KEY\n", __func__);
            return PLIST_ERR_UNKNOWN;
        }

        // detach old value (do NOT free yet)
        int idx = node_detach((node_t)node, old_val);
        if (idx < 0) {
            PLIST_ERR("%s: failed to detach old value (err=%d)\n", __func__, idx);
            return PLIST_ERR_UNKNOWN;
        }

        // insert new value at same position
        int r = node_insert((node_t)node, (unsigned)idx, (node_t)item);
        if (r != NODE_ERR_SUCCESS) {
            // rollback: reinsert old value
            int rb = node_insert((node_t)node, (unsigned)idx, old_val);
            if (rb == NODE_ERR_SUCCESS && ht) {
                hash_table_insert(ht, ((node_t)old_key)->data, old_item);
            }
            PLIST_ERR("%s: failed to replace dict value (err=%d)\n", __func__, r);
            return PLIST_ERR_UNKNOWN;
        }
        key_node = old_key;

        // update hash table
        if (ht) {
            hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item);
        }

        // now it’s safe to free old value
        plist_free_node(old_val);
    } else {
        // --- INSERT NEW KEY/VALUE PAIR ---
        key_node = plist_new_key(key);
        if (!key_node) return PLIST_ERR_NO_MEM;

        int r = node_attach((node_t)node, (node_t)key_node);
        if (r != NODE_ERR_SUCCESS) {
            plist_free_node((node_t)key_node);
            PLIST_ERR("%s: failed to attach dict key (err=%d)\n", __func__, r);
            return PLIST_ERR_UNKNOWN;
        }
        r = node_attach((node_t)node, (node_t)item);
        if (r != NODE_ERR_SUCCESS) {
            // rollback key insertion
            node_detach((node_t)node, (node_t)key_node);
            plist_free_node((node_t)key_node);
            PLIST_ERR("%s: failed to attach dict value (err=%d)\n", __func__, r);
            return PLIST_ERR_UNKNOWN;
        }

        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_t)node);
                 ht && current;
                 current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
            {
                hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current));
            }
            ((plist_data_t)((node_t)node)->data)->hashtable = ht;
        }
    }
    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_remove_item(plist_t node, const char* key)
{
    if (!PLIST_IS_DICT(node) || !key) {
        PLIST_ERR("invalid argument passed to %s (node=%p, key=%p)\n", __func__, node, key);
        return PLIST_ERR_INVALID_ARG;
    }

    plist_t old_item = plist_dict_get_item(node, key);
    if (!old_item) {
        PLIST_ERR("item not found for key '%s'\n", key);
        return PLIST_ERR_INVALID_ARG;
    }

    plist_t key_node = node_prev_sibling((node_t)old_item);
    hashtable_t* ht = (hashtable_t*)((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);

    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_merge(plist_t *target, plist_t source)
{
	if (!target || !PLIST_IS_DICT(*target) || !PLIST_IS_DICT(source))
		return PLIST_ERR_INVALID_ARG;

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

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

uint8_t plist_dict_get_bool(plist_t dict, const char *key)
{
	uint8_t bval = 0;
	uint64_t uintval = 0;
	const char *strval = NULL;
	uint64_t strsz = 0;
	plist_t node = plist_dict_get_item(dict, key);
	if (!node) {
		return 0;
	}
	switch (plist_get_node_type(node)) {
	case PLIST_BOOLEAN:
		plist_get_bool_val(node, &bval);
		break;
	case PLIST_INT:
		plist_get_uint_val(node, &uintval);
		bval = (uintval) ? 1 : 0;
		break;
	case PLIST_STRING:
		strval = plist_get_string_ptr(node, NULL);
		if (strval) {
			if (strcmp(strval, "true") == 0) {
				bval = 1;
			} else if (strcmp(strval, "false") == 0) {
				bval = 0;
			} else {
				PLIST_ERR("%s: invalid string '%s' for string to boolean conversion\n", __func__, strval);
			}
		}
		break;
	case PLIST_DATA:
		strval = (const char*)plist_get_data_ptr(node, &strsz);
		if (strval) {
			if (strsz == 1) {
				bval = (strval[0]) ? 1 : 0;
			} else {
				PLIST_ERR("%s: invalid size %" PRIu64 " for data to boolean conversion\n", __func__, strsz);
			}
		}
		break;
	default:
		break;
	}
	return bval;
}

int64_t plist_dict_get_int(plist_t dict, const char *key)
{
	int64_t intval = 0;
	const char *strval = NULL;
	uint64_t strsz = 0;
	plist_t node = plist_dict_get_item(dict, key);
	if (!node) {
		return intval;
	}
	switch (plist_get_node_type(node)) {
	case PLIST_INT:
		plist_get_int_val(node, &intval);
		break;
	case PLIST_STRING:
		strval = plist_get_string_ptr(node, NULL);
		if (strval) {
			intval = strtoll(strval, NULL, 0);
		}
		break;
	case PLIST_DATA:
		strval = (const char*)plist_get_data_ptr(node, &strsz);
		if (strval) {
			if (strsz == 8) {
				intval = le64toh(*(int64_t*)strval);
			} else if (strsz == 4) {
				intval = le32toh(*(int32_t*)strval);
			} else if (strsz == 2) {
				intval = le16toh(*(int16_t*)strval);
			} else if (strsz == 1) {
				intval = strval[0];
			} else {
				PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz);
			}
		}
		break;
	default:
		break;
	}
	return intval;
}


uint64_t plist_dict_get_uint(plist_t dict, const char *key)
{
	uint64_t uintval = 0;
	const char *strval = NULL;
	uint64_t strsz = 0;
	plist_t node = plist_dict_get_item(dict, key);
	if (!node) {
		return uintval;
	}
	switch (plist_get_node_type(node)) {
	case PLIST_INT:
		plist_get_uint_val(node, &uintval);
		break;
	case PLIST_STRING:
		strval = plist_get_string_ptr(node, NULL);
		if (strval) {
			uintval = strtoull(strval, NULL, 0);
		}
		break;
	case PLIST_DATA:
		strval = (const char*)plist_get_data_ptr(node, &strsz);
		if (strval) {
			if (strsz == 8) {
				uintval = le64toh(*(uint64_t*)strval);
			} else if (strsz == 4) {
				uintval = le32toh(*(uint32_t*)strval);
			} else if (strsz == 2) {
				uintval = le16toh(*(uint16_t*)strval);
			} else if (strsz == 1) {
				uintval = strval[0];
			} else {
				PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz);
			}
		}
		break;
	default:
		break;
	}
	return uintval;
}

plist_err_t plist_dict_copy_item(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
{
	plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
	if (!node) {
		return PLIST_ERR_INVALID_ARG;
	}
	plist_dict_set_item(target_dict, key, plist_copy(node));
	return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_copy_bool(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
{
	if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
		return PLIST_ERR_INVALID_ARG;
	}
	uint8_t bval = plist_dict_get_bool(source_dict, (alt_source_key) ? alt_source_key : key);
	plist_dict_set_item(target_dict, key, plist_new_bool(bval));
	return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_copy_int(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
{
	if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
		return PLIST_ERR_INVALID_ARG;
	}
	int64_t i64val = plist_dict_get_int(source_dict, (alt_source_key) ? alt_source_key : key);
	plist_dict_set_item(target_dict, key, plist_new_int(i64val));
	return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_copy_uint(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
{
	if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
		return PLIST_ERR_INVALID_ARG;
	}
	uint64_t u64val = plist_dict_get_uint(source_dict, (alt_source_key) ? alt_source_key : key);
	plist_dict_set_item(target_dict, key, plist_new_uint(u64val));
	return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_copy_data(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
{
	plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
	if (!PLIST_IS_DATA(node)) {
		return PLIST_ERR_INVALID_ARG;
	}
	plist_dict_set_item(target_dict, key, plist_copy(node));
	return PLIST_ERR_SUCCESS;
}

plist_err_t plist_dict_copy_string(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
{
	plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
	if (!PLIST_IS_STRING(node)) {
		return PLIST_ERR_INVALID_ARG;
	}
	plist_dict_set_item(target_dict, key, plist_copy(node));
	return PLIST_ERR_SUCCESS;
}

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_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 || !type || !value || !length)
        return;

    data = plist_get_data(node);
    if (!data) return;

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

    switch (*type)
    {
    case PLIST_BOOLEAN:
        *((char *) value) = data->boolval;
        break;
    case PLIST_INT:
    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);
        if (!*((char **) value)) {
            PLIST_ERR("%s: strdup failed\n", __func__);
            return;
        }
        break;
    case PLIST_DATA:
        *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t));
        if (!*((uint8_t **) value)) {
            PLIST_ERR("%s: malloc failed\n", __func__);
            return;
        }
        memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t));
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

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

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

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

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

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

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

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_INT != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint64_t) || length == 16);
}

void plist_get_int_val(plist_t node, int64_t * val)
{
    plist_get_uint_val(node, (uint64_t*)val);
}

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

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

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

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

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)
    {
	val = fabs((val - (int64_t)val) * 1000000);
        *usec = (int32_t)val;
    }
}

void plist_get_unix_date_val(plist_t node, int64_t *sec)
{
    if (!node || !sec)
        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));
    *sec = (int64_t)val + MAC_EPOCH;
}

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 TRUE;

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

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

    if (val_a == NULL && val_b == NULL)
        return TRUE;

    if (val_a == NULL || val_b == NULL)
        return FALSE;

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

    switch (val_a->type)
    {
    case PLIST_BOOLEAN:
    case PLIST_NULL:
    case PLIST_INT:
    case PLIST_REAL:
    case PLIST_DATE:
    case PLIST_UID:
        return val_a->length == val_b->length
            && val_a->intval == val_b->intval;	// it is a union so this is sufficient

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

    case PLIST_DATA: {
        if (val_a->length != val_b->length)
            return FALSE;
        if (val_a->length == 0)
            return TRUE;
        return memcmp(val_a->buff, val_b->buff, val_a->length) == 0;
    }
    case PLIST_ARRAY:
    case PLIST_DICT:
        //compare pointer
        return a == b;

    default:
        return FALSE;
    }
}

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

static plist_err_t plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length)
{
    //free previous allocated data
    plist_data_t data = plist_get_data(node);
    if (!data) { // a node should always have data attached
        PLIST_ERR("%s: Failed to allocate plist data\n", __func__);
        return PLIST_ERR_NO_MEM;
    }

    if (node_first_child((node_t)node)) {
        int r = plist_free_children((node_t)node);
        if (r < 0) return PLIST_ERR_UNKNOWN;
    }
    _plist_free_data(data);

    //now handle value

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

    switch (type)
    {
    case PLIST_BOOLEAN:
        data->boolval = *((char *) value);
        break;
    case PLIST_INT:
    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);
        if (!data->strval) {
            PLIST_ERR("%s: strdup failed\n", __func__);
            return PLIST_ERR_NO_MEM;
        }
        break;
    case PLIST_DATA:
        data->buff = (uint8_t *) malloc(length);
        if (!data->buff) {
            PLIST_ERR("%s: malloc failed\n", __func__);
            return PLIST_ERR_NO_MEM;
        }
        memcpy(data->buff, value, length);
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
    return PLIST_ERR_SUCCESS;
}

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

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

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

void plist_set_uint_val(plist_t node, uint64_t val)
{
    plist_set_element_val(node, PLIST_INT, &val, (val > INT64_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t));
}

void plist_set_int_val(plist_t node, int64_t val)
{
    plist_set_element_val(node, PLIST_INT, &val, sizeof(uint64_t));
}

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

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

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

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

void plist_set_unix_date_val(plist_t node, int64_t sec)
{
    double val = (double)(sec - MAC_EPOCH);
    plist_set_element_val(node, PLIST_DATE, &val, sizeof(double));
}

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

int plist_int_val_is_negative(plist_t intnode)
{
    if (!PLIST_IS_INT(intnode)) {
        return 0;
    }
    plist_data_t data = plist_get_data(intnode);
    if (data->length == 16) {
        return 0;
    }
    if ((int64_t)data->intval < 0) {
        return 1;
    }
    return 0;
}

int plist_int_val_compare(plist_t uintnode, int64_t cmpval)
{
    if (!PLIST_IS_INT(uintnode)) {
        return -1;
    }
    int64_t uintval = 0;
    plist_get_int_val(uintnode, &uintval);
    if (uintval == cmpval) {
        return 0;
    }

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

    return 1;
}

int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval)
{
    if (!PLIST_IS_INT(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;
}

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

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

int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec)
{
    if (!PLIST_IS_DATE(datenode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datenode);
    assert(data->length == sizeof(double));
    double val = data->realval;
    int32_t sec = (int32_t)val;
    val = fabs((val - (int64_t)val) * 1000000);
    int32_t usec = (int32_t)val;
    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;
}

int plist_unix_date_val_compare(plist_t datenode, int64_t cmpval)
{
    if (!PLIST_IS_DATE(datenode)) {
        return -1;
    }
    int64_t dateval = 0;
    plist_get_unix_date_val(datenode, &dateval);
    if (dateval == cmpval) {
        return 0;
    }

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

    return 1;
}

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

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

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

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

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

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

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

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

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

extern void plist_xml_set_debug(int debug);
extern void plist_bin_set_debug(int debug);
extern void plist_json_set_debug(int debug);
extern void plist_ostep_set_debug(int debug);

void plist_set_debug(int debug)
{
#if DEBUG
    plist_debug = debug;
#endif
    plist_xml_set_debug(debug);
    plist_bin_set_debug(debug);
    plist_json_set_debug(debug);
    plist_ostep_set_debug(debug);
}

void plist_sort(plist_t plist)
{
    if (!plist) {
        return;
    }
    if (PLIST_IS_ARRAY(plist)) {
        uint32_t n = plist_array_get_size(plist);
        uint32_t i = 0;
        for (i = 0; i < n; i++) {
            plist_sort(plist_array_get_item(plist, i));
        }
    } else if (PLIST_IS_DICT(plist)) {
        node_t node = (node_t)plist;
        node_t ch;
        if (!node_first_child(node)) {
            return;
        }
        for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
            ch = node_next_sibling(ch);
            plist_sort((plist_t)ch);
        }
        #define KEY_DATA(x) (x->data)
        #define NEXT_KEY(x) (x->next->next)
        #define KEY_STRVAL(x) ((plist_data_t)(KEY_DATA(x)))->strval
        int swapped = 0;
        do {
            swapped = 0;
            node_t lptr = NULL;
            node_t cur_key = node_first_child((node_t)plist);

            while (NEXT_KEY(cur_key) != lptr) {
                node_t next_key = NEXT_KEY(cur_key);
                if (strcmp(KEY_STRVAL(cur_key), KEY_STRVAL(next_key)) > 0) {
                    node_t cur_val = cur_key->next;
                    node_t next_val = next_key->next;
                    // we need to swap 2 consecutive nodes with the 2 after them
                    // a -> b -> [c] -> [d] -> [e] -> [f] -> g -> h
                    //              cur           next
                    // swapped:
                    // a -> b -> [e] -> [f] -> [c] -> [d] -> g -> h
                    //              next           cur
                    node_t tmp_prev = cur_key->prev;
                    node_t tmp_next = next_val->next;
                    cur_key->prev = next_val;
                    cur_val->next = tmp_next;
                    next_val->next = cur_key;
                    next_key->prev = tmp_prev;
                    if (tmp_prev) {
                        tmp_prev->next = next_key;
                    } else {
                        ((node_t)plist)->children->begin = next_key;
                    }
                    if (tmp_next) {
                        tmp_next->prev = cur_val;
                    } else {
                        ((node_t)plist)->children->end = cur_val;
                    }
                    cur_key = next_key;
                    swapped = 1;
                }
                cur_key = NEXT_KEY(cur_key);
            }
            lptr = cur_key;
        } while (swapped);
    }
}

plist_err_t plist_write_to_string(plist_t plist, char **output, uint32_t* length, plist_format_t format, plist_write_options_t options)
{
    plist_err_t err = PLIST_ERR_UNKNOWN;
    switch (format) {
        case PLIST_FORMAT_XML:
            err = plist_to_xml(plist, output, length);
            break;
        case PLIST_FORMAT_JSON:
            err = plist_to_json_with_options(plist, output, length, options);
            break;
        case PLIST_FORMAT_OSTEP:
            err = plist_to_openstep_with_options(plist, output, length, options);
            break;
        case PLIST_FORMAT_PRINT:
            err = plist_write_to_string_default(plist, output, length, options);
            break;
        case PLIST_FORMAT_LIMD:
            err = plist_write_to_string_limd(plist, output, length, options);
            break;
        case PLIST_FORMAT_PLUTIL:
            err = plist_write_to_string_plutil(plist, output, length, options);
            break;
        default:
            // unsupported output format
            err = PLIST_ERR_FORMAT;
            break;
    }
    return err;
}

plist_err_t plist_write_to_stream(plist_t plist, FILE *stream, plist_format_t format, plist_write_options_t options)
{
    if (!plist || !stream) {
        return PLIST_ERR_INVALID_ARG;
    }
    plist_err_t err = PLIST_ERR_UNKNOWN;
    char *output = NULL;
    uint32_t length = 0;
    switch (format) {
        case PLIST_FORMAT_BINARY:
            err = plist_to_bin(plist, &output, &length);
            break;
        case PLIST_FORMAT_XML:
            err = plist_to_xml(plist, &output, &length);
            break;
        case PLIST_FORMAT_JSON:
            err = plist_to_json_with_options(plist, &output, &length, options);
            break;
        case PLIST_FORMAT_OSTEP:
            err = plist_to_openstep_with_options(plist, &output, &length, options);
            break;
        case PLIST_FORMAT_PRINT:
            err = plist_write_to_stream_default(plist, stream, options);
            break;
        case PLIST_FORMAT_LIMD:
            err = plist_write_to_stream_limd(plist, stream, options);
            break;
        case PLIST_FORMAT_PLUTIL:
            err = plist_write_to_stream_plutil(plist, stream, options);
            break;
        default:
            // unsupported output format
            err = PLIST_ERR_FORMAT;
            break;
    }
    if (output && err == PLIST_ERR_SUCCESS) {
        if (fwrite(output, 1, length, stream) < length) {
            err = PLIST_ERR_IO;
        }
        free(output);
    }
    return err;
}

plist_err_t plist_write_to_file(plist_t plist, const char* filename, plist_format_t format, plist_write_options_t options)
{
    if (!plist || !filename) {
        return PLIST_ERR_INVALID_ARG;
    }
    FILE* f = fopen(filename, "wb");
    if (!f) {
        return PLIST_ERR_IO;
    }
    plist_err_t err = plist_write_to_stream(plist, f, format, options);
    fclose(f);
    return err;
}

void plist_print(plist_t plist)
{
     plist_write_to_stream(plist, stdout, PLIST_FORMAT_PRINT, PLIST_OPT_PARTIAL_DATA);
}

const char* libplist_version()
{
#ifndef PACKAGE_VERSION
#error PACKAGE_VERSION is not defined!
#endif
	return PACKAGE_VERSION;
}
