From 84d6af8f82b30b6519bb401d467febe4ea981dad Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Mon, 21 Jan 2019 02:09:44 +0100 Subject: 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. --- include/plist/plist.h | 46 +++++++++++++++++++++++++++++++++++++--------- src/Array.cpp | 38 ++++++++++++++++---------------------- src/plist.c | 38 ++++++++++++++++++++++++++++++++++---- 3 files changed, 87 insertions(+), 35 deletions(-) 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 @@ 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); 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::Array(Node* parent) : Structure(PLIST_ARRAY, parent) _array.clear(); } +static void array_fill(Array *_this, std::vector 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; } 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 @@ 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); -- cgit v1.1-32-gdbae