cimport cpython
cimport libc.stdlib
from libc.stdint cimport *

# https://groups.google.com/forum/#!topic/cython-users/xoKNFTRagvk
cdef _from_string_and_size(char *s, size_t length):
    return s[:length].encode('utf-8')

cdef extern from *:
    ctypedef enum plist_type:
        PLIST_BOOLEAN,
        PLIST_UINT,
        PLIST_REAL,
        PLIST_STRING,
        PLIST_ARRAY,
        PLIST_DICT,
        PLIST_DATE,
        PLIST_DATA,
        PLIST_KEY,
        PLIST_UID,
        PLIST_NONE

    plist_t plist_new_bool(uint8_t val)
    void plist_get_bool_val(plist_t node, uint8_t *val)
    void plist_set_bool_val(plist_t node, uint8_t val)

    plist_t plist_new_uint(uint64_t val)
    void plist_get_uint_val(plist_t node, uint64_t *val)
    void plist_set_uint_val(plist_t node, uint64_t val)

    plist_t plist_new_real(double val)
    void plist_get_real_val(plist_t node, double *val)
    void plist_set_real_val(plist_t node, double val)

    plist_t plist_new_date(int32_t sec, int32_t usec)
    void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
    void plist_set_date_val(plist_t node, int32_t sec, int32_t usec)

    void plist_get_key_val(plist_t node, char **val)
    void plist_set_key_val(plist_t node, char *val)

    plist_t plist_new_uid(uint64_t val)
    void plist_get_uid_val(plist_t node, uint64_t *val)
    void plist_set_uid_val(plist_t node, uint64_t val)

    plist_t plist_new_string(char *val)
    void plist_get_string_val(plist_t node, char **val)
    void plist_set_string_val(plist_t node, char *val)

    plist_t plist_new_data(char *val, uint64_t length)
    void plist_get_data_val(plist_t node, char **val, uint64_t * length)
    void plist_set_data_val(plist_t node, char *val, uint64_t length)

    plist_t plist_new_dict()
    int plist_dict_get_size(plist_t node)
    plist_t plist_dict_get_item(plist_t node, char* key)
    void plist_dict_set_item(plist_t node, char* key, plist_t item)
    void plist_dict_insert_item(plist_t node, char* key, plist_t item)
    void plist_dict_remove_item(plist_t node, char* key)

    void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
    void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)

    plist_t plist_new_array()
    uint32_t plist_array_get_size(plist_t node)
    plist_t plist_array_get_item(plist_t node, uint32_t n)
    uint32_t plist_array_get_item_index(plist_t node)
    void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
    void plist_array_append_item(plist_t node, plist_t item)
    void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
    void plist_array_remove_item(plist_t node, uint32_t n)

    void plist_free(plist_t plist)
    plist_t plist_copy(plist_t plist)
    void plist_to_xml(plist_t plist, char **plist_xml, uint32_t *length)
    void plist_to_bin(plist_t plist, char **plist_bin, uint32_t *length)

    plist_t plist_get_parent(plist_t node)
    plist_type plist_get_node_type(plist_t node)

    void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist)
    void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist)

cdef class Node:
    def __init__(self, *args, **kwargs):
        self._c_managed = True

    def __dealloc__(self):
        if self._c_node is not NULL and self._c_managed:
            plist_free(self._c_node)

    cpdef object __deepcopy__(self, memo={}):
        return plist_t_to_node(plist_copy(self._c_node))

    cpdef object copy(self):
        cdef plist_t c_node = NULL
        c_node = plist_copy(self._c_node)
        return plist_t_to_node(c_node)

    cpdef unicode to_xml(self):
        cdef:
            char* out = NULL
            uint32_t length
        plist_to_xml(self._c_node, &out, &length)

        try:
            return cpython.PyUnicode_DecodeUTF8(out, length, 'strict')
        finally:
            if out != NULL:
                libc.stdlib.free(out)

    cpdef bytes to_bin(self):
        cdef:
            char* out = NULL
            uint32_t length
        plist_to_bin(self._c_node, &out, &length)

        try:
            return bytes(out[:length])
        finally:
            if out != NULL:
                libc.stdlib.free(out)

    property parent:
        def __get__(self):
            cdef plist_t c_parent = NULL
            cdef Node node

            c_parent = plist_get_parent(self._c_node)
            if c_parent == NULL:
                return None

            return plist_t_to_node(c_parent)

    def __str__(self):
        return str(self.get_value())

cdef class Bool(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        if value is None:
            self._c_node = plist_new_bool(0)
        else:
            self._c_node = plist_new_bool(bool(value))

    def __nonzero__(self):
        return self.get_value()

    def __richcmp__(self, other, op):
        cdef bint b = self.get_value()
        if op == 0:
            return b < other
        if op == 1:
            return b <= other
        if op == 2:
            return b == other
        if op == 3:
            return b != other
        if op == 4:
            return b > other
        if op == 5:
            return b >= other

    def __repr__(self):
        b = self.get_value()
        return '<Bool: %s>' % b

    cpdef set_value(self, object value):
        plist_set_bool_val(self._c_node, bool(value))

    cpdef bint get_value(self):
        cdef uint8_t value
        plist_get_bool_val(self._c_node, &value)
        return bool(value)

cdef Bool Bool_factory(plist_t c_node, bint managed=True):
    cdef Bool instance = Bool.__new__(Bool)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef class Integer(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        if value is None:
            self._c_node = plist_new_uint(0)
        else:
            self._c_node = plist_new_uint(int(value))

    def __repr__(self):
        cdef uint64_t i = self.get_value()
        return '<Integer: %s>' % i

    def __int__(self):
        return self.get_value()

    def __float__(self):
        return float(self.get_value())

    def __richcmp__(self, other, op):
        cdef int i = self.get_value()
        if op == 0:
            return i < other
        if op == 1:
            return i <= other
        if op == 2:
            return i == other
        if op == 3:
            return i != other
        if op == 4:
            return i > other
        if op == 5:
            return i >= other

    cpdef set_value(self, object value):
        plist_set_uint_val(self._c_node, int(value))

    cpdef uint64_t get_value(self):
        cdef uint64_t value
        plist_get_uint_val(self._c_node, &value)
        return value

cdef Integer Integer_factory(plist_t c_node, bint managed=True):
    cdef Integer instance = Integer.__new__(Integer)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef class Real(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        if value is None:
            self._c_node = plist_new_real(0.0)
        else:
            self._c_node = plist_new_real(float(value))

    def __repr__(self):
        r = self.get_value()
        return '<Real: %s>' % r

    def __float__(self):
        return self.get_value()

    def __int__(self):
        return int(self.get_value())

    def __richcmp__(self, other, op):
        cdef float f = self.get_value()
        if op == 0:
            return f < other
        if op == 1:
            return f <= other
        if op == 2:
            return f == other
        if op == 3:
            return f != other
        if op == 4:
            return f > other
        if op == 5:
            return f >= other

    cpdef set_value(self, object value):
        plist_set_real_val(self._c_node, float(value))

    cpdef float get_value(self):
        cdef double value
        plist_get_real_val(self._c_node, &value)
        return value

cdef Real Real_factory(plist_t c_node, bint managed=True):
    cdef Real instance = Real.__new__(Real)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef class Uid(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        if value is None:
            self._c_node = plist_new_uid(0)
        else:
            self._c_node = plist_new_uid(int(value))

    def __repr__(self):
        cdef uint64_t i = self.get_value()
        return '<Uid: %s>' % i

    def __int__(self):
        return self.get_value()

    def __float__(self):
        return float(self.get_value())

    def __richcmp__(self, other, op):
        cdef int i = self.get_value()
        if op == 0:
            return i < other
        if op == 1:
            return i <= other
        if op == 2:
            return i == other
        if op == 3:
            return i != other
        if op == 4:
            return i > other
        if op == 5:
            return i >= other

    cpdef set_value(self, object value):
        plist_set_uid_val(self._c_node, int(value))

    cpdef uint64_t get_value(self):
        cdef uint64_t value
        plist_get_uid_val(self._c_node, &value)
        return value

cdef Uid Uid_factory(plist_t c_node, bint managed=True):
    cdef Uid instance = Uid.__new__(Uid)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

from cpython cimport PY_MAJOR_VERSION

cdef class Key(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        cdef:
            char* c_utf8_data = NULL
            bytes utf8_data
        if value is None:
            raise ValueError("Requires a value")
        else:
            if isinstance(value, unicode):
                utf8_data = value.encode('utf-8')
            elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
                value.encode('ascii') # trial decode
                utf8_data = value.encode('ascii')
            else:
                raise ValueError("Requires unicode input, got %s" % type(value))
            c_utf8_data = utf8_data
            self._c_node = plist_new_string("")
            plist_set_key_val(self._c_node, c_utf8_data)

    def __repr__(self):
        s = self.get_value()
        return '<Key: %s>' % s.encode('utf-8')

    def __richcmp__(self, other, op):
        cdef unicode s = self.get_value()
        if op == 0:
            return s < other
        if op == 1:
            return s <= other
        if op == 2:
            return s == other
        if op == 3:
            return s != other
        if op == 4:
            return s > other
        if op == 5:
            return s >= other

    cpdef set_value(self, object value):
        cdef:
            char* c_utf8_data = NULL
            bytes utf8_data
        if value is None:
            plist_set_key_val(self._c_node, c_utf8_data)
        else:
            if isinstance(value, unicode):
                utf8_data = value.encode('utf-8')
            elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
                value.encode('ascii') # trial decode
                utf8_data = value.encode('ascii')
            else:
                raise ValueError("Requires unicode input, got %s" % type(value))
            c_utf8_data = utf8_data
            plist_set_key_val(self._c_node, c_utf8_data)

    cpdef unicode get_value(self):
        cdef:
            char* c_value = NULL
        plist_get_key_val(self._c_node, &c_value)
        try:
            return cpython.PyUnicode_DecodeUTF8(c_value, len(c_value), 'strict')
        finally:
            libc.stdlib.free(c_value)

cdef Key Key_factory(plist_t c_node, bint managed=True):
    cdef Key instance = Key.__new__(Key)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef class String(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        cdef:
            char* c_utf8_data = NULL
            bytes utf8_data
        if value is None:
            self._c_node = plist_new_string("")
        else:
            if isinstance(value, unicode):
                utf8_data = value.encode('utf-8')
            elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
                value.encode('ascii') # trial decode
                utf8_data = value.encode('ascii')
            else:
                raise ValueError("Requires unicode input, got %s" % type(value))
            c_utf8_data = utf8_data
            self._c_node = plist_new_string(c_utf8_data)

    def __repr__(self):
        s = self.get_value()
        return '<String: %s>' % s.encode('utf-8')

    def __richcmp__(self, other, op):
        cdef unicode s = self.get_value()
        if op == 0:
            return s < other
        if op == 1:
            return s <= other
        if op == 2:
            return s == other
        if op == 3:
            return s != other
        if op == 4:
            return s > other
        if op == 5:
            return s >= other

    cpdef set_value(self, object value):
        cdef:
            char* c_utf8_data = NULL
            bytes utf8_data
        if value is None:
            plist_set_string_val(self._c_node, c_utf8_data)
        else:
            if isinstance(value, unicode):
                utf8_data = value.encode('utf-8')
            elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
                value.encode('ascii') # trial decode
                utf8_data = value.encode('ascii')
            else:
                raise ValueError("Requires unicode input, got %s" % type(value))
            c_utf8_data = utf8_data
            plist_set_string_val(self._c_node, c_utf8_data)

    cpdef unicode get_value(self):
        cdef:
            char* c_value = NULL
        plist_get_string_val(self._c_node, &c_value)
        try:
            return cpython.PyUnicode_DecodeUTF8(c_value, len(c_value), 'strict')
        finally:
            libc.stdlib.free(c_value)

cdef String String_factory(plist_t c_node, bint managed=True):
    cdef String instance = String.__new__(String)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef extern from "plist_util.h":
    void datetime_to_ints(object obj, int32_t* sec, int32_t* usec)
    object ints_to_datetime(int32_t sec, int32_t usec)
    int check_datetime(object obj)

cdef plist_t create_date_plist(value=None):
    cdef plist_t node = NULL
    cdef int32_t secs
    cdef int32_t usecs
    if value is None:
        node = plist_new_date(0, 0)
    elif check_datetime(value):
        datetime_to_ints(value, &secs, &usecs)
        node = plist_new_date(secs, usecs)
    return node

cdef class Date(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        self._c_node = create_date_plist(value)

    def __repr__(self):
        d = self.get_value()
        return '<Date: %s>' % d.ctime()

    def __richcmp__(self, other, op):
        d = self.get_value()
        if op == 0:
            return d < other
        if op == 1:
            return d <= other
        if op == 2:
            return d == other
        if op == 3:
            return d != other
        if op == 4:
            return d > other
        if op == 5:
            return d >= other

    cpdef object get_value(self):
        cdef int32_t secs = 0
        cdef int32_t usecs = 0
        plist_get_date_val(self._c_node, &secs, &usecs)
        return ints_to_datetime(secs, usecs)

    cpdef set_value(self, object value):
        cdef int32_t secs
        cdef int32_t usecs
        if not check_datetime(value):
            raise ValueError("Expected a datetime")
        datetime_to_ints(value, &secs, &usecs)
        plist_set_date_val(self._c_node, secs, usecs)

cdef Date Date_factory(plist_t c_node, bint managed=True):
    cdef Date instance = Date.__new__(Date)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef class Data(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        if value is None:
            self._c_node = plist_new_data(NULL, 0)
        else:
            self._c_node = plist_new_data(value, len(value))

    def __repr__(self):
        d = self.get_value()
        return '<Data: %s>' % d

    def __richcmp__(self, other, op):
        cdef bytes d = self.get_value()
        if op == 0:
            return d < other
        if op == 1:
            return d <= other
        if op == 2:
            return d == other
        if op == 3:
            return d != other
        if op == 4:
            return d > other
        if op == 5:
            return d >= other

    cpdef bytes get_value(self):
        cdef:
            char* val = NULL
            uint64_t length = 0
        plist_get_data_val(self._c_node, &val, &length)

        try:
            return _from_string_and_size(val, length)
        finally:
            libc.stdlib.free(val)

    cpdef set_value(self, object value):
        cdef:
            bytes py_val = value
        plist_set_data_val(self._c_node, py_val, len(value))

cdef Data Data_factory(plist_t c_node, bint managed=True):
    cdef Data instance = Data.__new__(Data)
    instance._c_managed = managed
    instance._c_node = c_node
    return instance

cdef plist_t create_dict_plist(object value=None):
    cdef plist_t node = NULL
    cdef plist_t c_node = NULL
    node = plist_new_dict()
    if value is not None and isinstance(value, dict):
        for key, item in value.items():
            c_node = native_to_plist_t(item)
            plist_dict_set_item(node, key, c_node)
            c_node = NULL
    return node

cimport cpython

cdef class Dict(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        self._c_node = create_dict_plist(value)

    def __init__(self, value=None, *args, **kwargs):
        self._init()

    cdef void _init(self):
        cdef plist_dict_iter it = NULL
        cdef char* key = NULL
        cdef plist_t subnode = NULL

        self._map = cpython.PyDict_New()

        plist_dict_new_iter(self._c_node, &it);
        plist_dict_next_item(self._c_node, it, &key, &subnode);

        while subnode is not NULL:
            py_key = key

            if PY_MAJOR_VERSION >= 3:
                py_key = py_key.decode('utf-8')

            cpython.PyDict_SetItem(self._map, py_key, plist_t_to_node(subnode, False))
            subnode = NULL
            libc.stdlib.free(key)
            key = NULL
            plist_dict_next_item(self._c_node, it, &key, &subnode);
        libc.stdlib.free(it)

    def __dealloc__(self):
        self._map = None

    def __richcmp__(self, other, op):
        cdef dict d = self.get_value()
        if op == 0:
            return d < other
        if op == 1:
            return d <= other
        if op == 2:
            return d == other
        if op == 3:
            return d != other
        if op == 4:
            return d > other
        if op == 5:
            return d >= other

    def __len__(self):
        return cpython.PyDict_Size(self._map)

    def __repr__(self):
        return '<Dict: %s>' % self._map

    cpdef dict get_value(self):
        return dict([(key, value.get_value()) for key, value in self.items()])

    cpdef set_value(self, dict value):
        plist_free(self._c_node)
        self._map = {}
        self._c_node = NULL
        self._c_node = create_dict_plist(value)
        self._init()

    def __iter__(self):
        return self._map.__iter__()

    cpdef bint has_key(self, key):
        return self._map.has_key(key)

    cpdef object get(self, key, default=None):
        return self._map.get(key, default)

    cpdef list keys(self):
        return cpython.PyDict_Keys(self._map)

    cpdef object iterkeys(self):
        return self._map.iterkeys()

    cpdef list items(self):
        return cpython.PyDict_Items(self._map)

    cpdef object iteritems(self):
        return self._map.iteritems()

    cpdef list values(self):
        return cpython.PyDict_Values(self._map)

    cpdef object itervalues(self):
        return self._map.itervalues()

    def __getitem__(self, key):
        return self._map[key]

    def __setitem__(self, key, value):
        cdef Node n
        if isinstance(value, Node):
            n = value.copy()
        else:
            n = plist_t_to_node(native_to_plist_t(value), False)

        plist_dict_set_item(self._c_node, key, n._c_node)
        self._map[key] = n

    def __delitem__(self, key):
        cpython.PyDict_DelItem(self._map, key)
        plist_dict_remove_item(self._c_node, key)

cdef Dict Dict_factory(plist_t c_node, bint managed=True):
    cdef Dict instance = Dict.__new__(Dict)
    instance._c_managed = managed
    instance._c_node = c_node
    instance._init()
    return instance

cdef plist_t create_array_plist(object value=None):
    cdef plist_t node = NULL
    cdef plist_t c_node = NULL
    node = plist_new_array()
    if value is not None and (isinstance(value, list) or isinstance(value, tuple)):
        for item in value:
            c_node = native_to_plist_t(item)
            plist_array_append_item(node, c_node)
            c_node = NULL
    return node

cdef class Array(Node):
    def __cinit__(self, object value=None, *args, **kwargs):
        self._c_node = create_array_plist(value)

    def __init__(self, value=None, *args, **kwargs):
        self._init()

    cdef void _init(self):
        self._array = []
        cdef uint32_t size = plist_array_get_size(self._c_node)
        cdef plist_t subnode = NULL

        for i in range(size):
            subnode = plist_array_get_item(self._c_node, i)
            self._array.append(plist_t_to_node(subnode, False))

    def __richcmp__(self, other, op):
        cdef list l = self.get_value()
        if op == 0:
            return l < other
        if op == 1:
            return l <= other
        if op == 2:
            return l == other
        if op == 3:
            return l != other
        if op == 4:
            return l > other
        if op == 5:
            return l >= other

    def __len__(self):
        return len(self._array)

    def __repr__(self):
        return '<Array: %s>' % self._array

    cpdef list get_value(self):
        return [i.get_value() for i in self]

    cpdef set_value(self, object value):
        self._array = []
        plist_free(self._c_node)
        self._c_node = NULL
        self._c_node = create_array_plist(value)
        self._init()

    def __iter__(self):
        return self._array.__iter__()

    def __getitem__(self, index):
        return self._array[index]

    def __setitem__(self, index, value):
        cdef Node n
        if isinstance(value, Node):
            n = value.copy()
        else:
            n = plist_t_to_node(native_to_plist_t(value), False)

        if index < 0:
            index = len(self) + index

        plist_array_set_item(self._c_node, n._c_node, index)
        self._array[index] = n

    def __delitem__(self, index):
        if index < 0:
            index = len(self) + index
        del self._array[index]
        plist_array_remove_item(self._c_node, index)

    cpdef append(self, object item):
        cdef Node n

        if isinstance(item, Node):
            n = item.copy()
        else:
            n = plist_t_to_node(native_to_plist_t(item), False)

        plist_array_append_item(self._c_node, n._c_node)
        self._array.append(n)

cdef Array Array_factory(plist_t c_node, bint managed=True):
    cdef Array instance = Array.__new__(Array)
    instance._c_managed = managed
    instance._c_node = c_node
    instance._init()
    return instance

cpdef object from_xml(xml):
    cdef plist_t c_node = NULL
    plist_from_xml(xml, len(xml), &c_node)
    return plist_t_to_node(c_node)

cpdef object from_bin(bytes bin):
    cdef plist_t c_node = NULL
    plist_from_bin(bin, len(bin), &c_node)
    return plist_t_to_node(c_node)

cdef plist_t native_to_plist_t(object native):
    cdef plist_t c_node
    cdef plist_t child_c_node
    cdef int32_t secs = 0
    cdef int32_t usecs = 0
    cdef Node node
    if isinstance(native, Node):
        node = native
        return plist_copy(node._c_node)
    if isinstance(native, basestring):
        return plist_new_string(native)
    if isinstance(native, bool):
        return plist_new_bool(<bint>native)
    if isinstance(native, int) or isinstance(native, long):
        return plist_new_uint(native)
    if isinstance(native, float):
        return plist_new_real(native)
    if isinstance(native, dict):
        return create_dict_plist(native)
    if isinstance(native, list) or isinstance(native, tuple):
        return create_array_plist(native)
    if check_datetime(native):
        return create_date_plist(native)

cdef object plist_t_to_node(plist_t c_plist, bint managed=True):
    cdef plist_type t = plist_get_node_type(c_plist)
    if t == PLIST_BOOLEAN:
        return Bool_factory(c_plist, managed)
    if t == PLIST_UINT:
        return Integer_factory(c_plist, managed)
    if t == PLIST_KEY:
        return Key_factory(c_plist, managed)
    if t == PLIST_REAL:
        return Real_factory(c_plist, managed)
    if t == PLIST_STRING:
        return String_factory(c_plist, managed)
    if t == PLIST_ARRAY:
        return Array_factory(c_plist, managed)
    if t == PLIST_DICT:
        return Dict_factory(c_plist, managed)
    if t == PLIST_DATE:
        return Date_factory(c_plist, managed)
    if t == PLIST_DATA:
        return Data_factory(c_plist, managed)
    if t == PLIST_UID:
        return Uid_factory(c_plist, managed)
    if t == PLIST_NONE:
        return None

# This is to match up with the new plistlib API
# http://docs.python.org/dev/library/plistlib.html
# dump() and dumps() are not yet implemented
FMT_XML = 1
FMT_BINARY = 2

cpdef object load(fp, fmt=None, use_builtin_types=True, dict_type=dict):
    is_binary = fp.read(6) == 'bplist'
    fp.seek(0)

    cdef object cb = None

    if not fmt:
        if is_binary:
            if 'b' not in fp.mode:
                raise IOError('File handle must be opened in binary (b) mode to read binary property lists')
            cb = from_bin
        else:
            cb = from_xml
    else:
        if fmt not in (FMT_XML, FMT_BINARY):
            raise ValueError('Format must be constant FMT_XML or FMT_BINARY')
        if fmt == FMT_BINARY:
            cb = from_bin
        elif fmt == FMT_XML:
            cb = from_xml

    if is_binary and fmt == FMT_XML:
        raise ValueError('Cannot parse binary property list as XML')
    elif not is_binary and fmt == FMT_BINARY:
        raise ValueError('Cannot parse XML property list as binary')

    return cb(fp.read())

cpdef object loads(data, fmt=None, use_builtin_types=True, dict_type=dict):
    is_binary = data[0:6] == 'bplist'

    cdef object cb = None

    if fmt is not None:
        if fmt not in (FMT_XML, FMT_BINARY):
            raise ValueError('Format must be constant FMT_XML or FMT_BINARY')
        if fmt == FMT_BINARY:
            cb = from_bin
        else:
            cb = from_xml
    else:
        if is_binary:
            cb = from_bin
        else:
            cb = from_xml

    if is_binary and fmt == FMT_XML:
        raise ValueError('Cannot parse binary property list as XML')
    elif not is_binary and fmt == FMT_BINARY:
        raise ValueError('Cannot parse XML property list as binary')

    return cb(data)

cpdef object dump(value, fp, fmt=FMT_XML, sort_keys=True, skipkeys=False):
    fp.write(dumps(value, fmt=fmt))

cpdef object dumps(value, fmt=FMT_XML, sort_keys=True, skipkeys=False):
    if fmt not in (FMT_XML, FMT_BINARY):
        raise ValueError('Format must be constant FMT_XML or FMT_BINARY')

    if check_datetime(value):
        node = Date(value)
    elif isinstance(value, unicode):
        node = String(value)
    elif PY_MAJOR_VERSION >= 3 and isinstance(value, bytes):
        node = Data(value)
    elif isinstance(value, str):
        # See if this is binary
        try:
            node = String(value)
        except ValueError:
            node = Data(value)
    elif isinstance(value, bool):
        node = Bool(value)
    elif isinstance(value, int):
        node = Integer(value)
    elif isinstance(value, float):
        node = Real(value)
    elif isinstance(value, dict):
        node = Dict(value)
    elif type(value) in (list, set, tuple):
        node = Array(value)

    if fmt == FMT_XML:
        return node.to_xml()

    return node.to_bin()
