Commit 84d6af8f authored by Nikias Bassen's avatar Nikias Bassen

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.
parent 5f8ca6e3
......@@ -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 @@ extern "C"
/**
* 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 @@ extern "C"
*/
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 @@ extern "C"
* 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);
......
......@@ -31,29 +31,30 @@ Array::Array(Node* parent) : Structure(PLIST_ARRAY, parent)
_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 @@ Array& Array::operator=(PList::Array& a)
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;
}
......
......@@ -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 @@ PLIST_API void plist_array_remove_item(plist_t node, uint32_t n)
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 uint32_t plist_dict_get_size(plist_t node)
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment