plist: Add iterator for #PLIST_ARRAY nodes

Similar to #PLIST_DICT, an iterator can now be used for #PLIST_ARRAY
nodes. Get an iterator with plist_array_new_iter() and use
plist_array_next_item() to iterate over the elements.
diff --git a/include/plist/plist.h b/include/plist/plist.h
index e817b4b..707460e 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -3,7 +3,8 @@
  * @brief Main include of libplist
  * \internal
  *
- * Copyright (c) 2008 Jonathan Beck All Rights Reserved.
+ * Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved.
+ * Copyright (c) 2008-2009 Jonathan Beck, 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
@@ -90,7 +91,12 @@
     /**
      * The plist dictionary iterator.
      */
-    typedef void *plist_dict_iter;
+    typedef void* plist_dict_iter;
+
+    /**
+     * The plist array iterator.
+     */
+    typedef void* plist_array_iter;
 
     /**
      * The enumeration of plist node types.
@@ -281,6 +287,27 @@
      */
     void plist_array_remove_item(plist_t node, uint32_t n);
 
+    /**
+     * Create an iterator of a #PLIST_ARRAY node.
+     * The allocated iterator should be freed with the standard free function.
+     *
+     * @param node The node of type #PLIST_ARRAY
+     * @param iter Location to store the iterator for the array.
+     */
+    void plist_array_new_iter(plist_t node, plist_array_iter *iter);
+
+    /**
+     * Increment iterator of a #PLIST_ARRAY node.
+     *
+     * @param node The node of type #PLIST_ARRAY.
+     * @param iter Iterator of the array
+     * @param item Location to store the item. The caller must *not* free the
+     *          returned item. Will be set to NULL when no more items are left
+     *          to iterate.
+     */
+    void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item);
+
+
     /********************************************
      *                                          *
      *         Dictionary functions             *
@@ -299,20 +326,21 @@
      * Create an iterator of a #PLIST_DICT node.
      * The allocated iterator should be freed with the standard free function.
      *
-     * @param node the node of type #PLIST_DICT
-     * @param iter iterator of the #PLIST_DICT node
+     * @param node The node of type #PLIST_DICT.
+     * @param iter Location to store the iterator for the dictionary.
      */
     void plist_dict_new_iter(plist_t node, plist_dict_iter *iter);
 
     /**
      * Increment iterator of a #PLIST_DICT node.
      *
-     * @param node the node of type #PLIST_DICT
-     * @param iter iterator of the dictionary
-     * @param key a location to store the key, or NULL. The caller is responsible
+     * @param node The node of type #PLIST_DICT
+     * @param iter Iterator of the dictionary
+     * @param key Location to store the key, or NULL. The caller is responsible
      *		for freeing the the returned string.
-     * @param val a location to store the value, or NULL. The caller should *not*
-     *		free the returned value.
+     * @param val Location to store the value, or NULL. The caller must *not*
+     *		free the returned value. Will be set to NULL when no more
+     *		key/value pairs are left to iterate.
      */
     void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val);
 
diff --git a/src/Array.cpp b/src/Array.cpp
index 7c38a69..a511841 100644
--- a/src/Array.cpp
+++ b/src/Array.cpp
@@ -31,29 +31,30 @@
     _array.clear();
 }
 
+static void array_fill(Array *_this, std::vector<Node*> array, plist_t node)
+{
+    plist_array_iter iter = NULL;
+    plist_array_new_iter(node, &iter);
+    plist_t subnode;
+    do {
+        subnode = NULL;
+        plist_array_next_item(node, iter, &subnode);
+        array.push_back( Node::FromPlist(subnode, _this) );
+    } while (subnode);
+    free(iter);
+}
+
 Array::Array(plist_t node, Node* parent) : Structure(parent)
 {
     _node = node;
-    uint32_t size = plist_array_get_size(_node);
-
-    for (uint32_t i = 0; i < size; i++)
-    {
-        plist_t subnode = plist_array_get_item(_node, i);
-        _array.push_back(  Node::FromPlist(subnode, this) );
-    }
+    array_fill(this, _array, _node);
 }
 
 Array::Array(const PList::Array& a) : Structure()
 {
     _array.clear();
     _node = plist_copy(a.GetPlist());
-    uint32_t size = plist_array_get_size(_node);
-
-    for (uint32_t i = 0; i < size; i++)
-    {
-        plist_t subnode = plist_array_get_item(_node, i);
-        _array.push_back(  Node::FromPlist(subnode, this) );
-    }
+    array_fill(this, _array, _node);
 }
 
 Array& Array::operator=(PList::Array& a)
@@ -64,15 +65,8 @@
         delete _array.at(it);
     }
     _array.clear();
-
     _node = plist_copy(a.GetPlist());
-    uint32_t size = plist_array_get_size(_node);
-
-    for (uint32_t i = 0; i < size; i++)
-    {
-        plist_t subnode = plist_array_get_item(_node, i);
-        _array.push_back(  Node::FromPlist(subnode, this) );
-    }
+    array_fill(this, _array, _node);
     return *this;
 }
 
diff --git a/src/plist.c b/src/plist.c
index 6b604d6..1b33ec3 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -2,9 +2,9 @@
  * plist.c
  * Builds plist XML structures
  *
- * Copyright (c) 2009-2016 Nikias Bassen All Rights Reserved.
- * Copyright (c) 2010-2015 Martin Szulecki All Rights Reserved.
- * Copyright (c) 2008 Zach C. All Rights Reserved.
+ * Copyright (c) 2009-2019 Nikias Bassen, All Rights Reserved.
+ * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved.
+ * Copyright (c) 2008 Zach C., All Rights Reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -457,6 +457,36 @@
     return;
 }
 
+PLIST_API void plist_array_new_iter(plist_t node, plist_array_iter *iter)
+{
+    if (iter)
+    {
+        *iter = malloc(sizeof(node_t*));
+        *((node_t**)(*iter)) = node_first_child(node);
+    }
+    return;
+}
+
+PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item)
+{
+    node_t** iter_node = (node_t**)iter;
+
+    if (item)
+    {
+        *item = NULL;
+    }
+
+    if (node && PLIST_ARRAY == plist_get_node_type(node) && *iter_node)
+    {
+        if (item)
+        {
+            *item = (plist_t)(*iter_node);
+        }
+        *iter_node = node_next_sibling(*iter_node);
+    }
+    return;
+}
+
 PLIST_API uint32_t plist_dict_get_size(plist_t node)
 {
     uint32_t ret = 0;
@@ -469,7 +499,7 @@
 
 PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
 {
-    if (iter && *iter == NULL)
+    if (iter)
     {
         *iter = malloc(sizeof(node_t*));
         *((node_t**)(*iter)) = node_first_child(node);