Implement plist_from_memory()

Rather than having everyone reimplement binary/XML plist detection by
looking at the first bytes of the plist content, it's better to do this
detection in libplist and hide that internal detail from library users.
diff --git a/include/plist/plist.h b/include/plist/plist.h
index 2b7e1a1..7e59acb 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -617,6 +617,17 @@
     void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist);
 
     /**
+     * Import the #plist_t structure from memory data.
+     * This method will look at the first bytes of plist_data
+     * to determine if plist_data contains a binary or XML plist.
+     *
+     * @param plist_data a pointer to the memory buffer containing plist data.
+     * @param length length of the buffer to read.
+     * @param plist a pointer to the imported plist.
+     */
+    void plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist);
+
+    /**
      * Test if in-memory plist data is binary or XML
      * This method will look at the first bytes of plist_data
      * to determine if plist_data contains a binary or XML plist.
diff --git a/src/plist.c b/src/plist.c
index 3e69e2a..1ff17fc 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -58,6 +58,21 @@
     return (memcmp(plist_data, "bplist00", 8) == 0);
 }
 
+
+PLIST_API void plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist)
+{
+    if (length < 8) {
+        *plist = NULL;
+        return;
+    }
+
+    if (plist_is_binary(plist_data, length)) {
+        plist_from_bin(plist_data, length, plist);
+    } else {
+        plist_from_xml(plist_data, length, plist);
+    }
+}
+
 plist_t plist_new_node(plist_data_t data)
 {
     return (plist_t) node_create(NULL, data);