cython: Implement load()/loads() to match up with plistlib (Python 3.4)
diff --git a/cython/plist.pxd b/cython/plist.pxd
index ee8a65e..99dcca5 100644
--- a/cython/plist.pxd
+++ b/cython/plist.pxd
@@ -69,5 +69,8 @@
 cpdef object from_xml(xml)
 cpdef object from_bin(bytes bin)
 
+cpdef object load(fp, fmt=*, use_builtin_types=*, dict_type=*)
+cpdef object loads(data, fmt=*, use_builtin_types=*, dict_type=*)
+
 cdef object plist_t_to_node(plist_t c_plist, bint managed=*)
 cdef plist_t native_to_plist_t(object native)
diff --git a/cython/plist.pyx b/cython/plist.pyx
index f6696d6..573f17f 100644
--- a/cython/plist.pyx
+++ b/cython/plist.pyx
@@ -852,3 +852,58 @@
         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)
+
+    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'
+
+    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)