diff options
| author | 2019-01-21 02:09:44 +0100 | |
|---|---|---|
| committer | 2019-01-21 02:22:28 +0100 | |
| commit | 84d6af8f82b30b6519bb401d467febe4ea981dad (patch) | |
| tree | cfd1f1f34e60cfb87696a8cb480e5af00b8c89a3 | |
| parent | 5f8ca6e30334b81bd39a67f87a011cee8f282c3c (diff) | |
| download | libplist-84d6af8f82b30b6519bb401d467febe4ea981dad.tar.gz libplist-84d6af8f82b30b6519bb401d467febe4ea981dad.tar.bz2 | |
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.
| -rw-r--r-- | include/plist/plist.h | 46 | ||||
| -rw-r--r-- | src/Array.cpp | 38 | ||||
| -rw-r--r-- | 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 @@ | |||
| 3 | * @brief Main include of libplist | 3 | * @brief Main include of libplist |
| 4 | * \internal | 4 | * \internal |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. | 6 | * Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved. |
| 7 | * Copyright (c) 2008-2009 Jonathan Beck, All Rights Reserved. | ||
| 7 | * | 8 | * |
| 8 | * This library is free software; you can redistribute it and/or | 9 | * This library is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU Lesser General Public | 10 | * modify it under the terms of the GNU Lesser General Public |
| @@ -90,7 +91,12 @@ extern "C" | |||
| 90 | /** | 91 | /** |
| 91 | * The plist dictionary iterator. | 92 | * The plist dictionary iterator. |
| 92 | */ | 93 | */ |
| 93 | typedef void *plist_dict_iter; | 94 | typedef void* plist_dict_iter; |
| 95 | |||
| 96 | /** | ||
| 97 | * The plist array iterator. | ||
| 98 | */ | ||
| 99 | typedef void* plist_array_iter; | ||
| 94 | 100 | ||
| 95 | /** | 101 | /** |
| 96 | * The enumeration of plist node types. | 102 | * The enumeration of plist node types. |
| @@ -281,6 +287,27 @@ extern "C" | |||
| 281 | */ | 287 | */ |
| 282 | void plist_array_remove_item(plist_t node, uint32_t n); | 288 | void plist_array_remove_item(plist_t node, uint32_t n); |
| 283 | 289 | ||
| 290 | /** | ||
| 291 | * Create an iterator of a #PLIST_ARRAY node. | ||
| 292 | * The allocated iterator should be freed with the standard free function. | ||
| 293 | * | ||
| 294 | * @param node The node of type #PLIST_ARRAY | ||
| 295 | * @param iter Location to store the iterator for the array. | ||
| 296 | */ | ||
| 297 | void plist_array_new_iter(plist_t node, plist_array_iter *iter); | ||
| 298 | |||
| 299 | /** | ||
| 300 | * Increment iterator of a #PLIST_ARRAY node. | ||
| 301 | * | ||
| 302 | * @param node The node of type #PLIST_ARRAY. | ||
| 303 | * @param iter Iterator of the array | ||
| 304 | * @param item Location to store the item. The caller must *not* free the | ||
| 305 | * returned item. Will be set to NULL when no more items are left | ||
| 306 | * to iterate. | ||
| 307 | */ | ||
| 308 | void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item); | ||
| 309 | |||
| 310 | |||
| 284 | /******************************************** | 311 | /******************************************** |
| 285 | * * | 312 | * * |
| 286 | * Dictionary functions * | 313 | * Dictionary functions * |
| @@ -299,20 +326,21 @@ extern "C" | |||
| 299 | * Create an iterator of a #PLIST_DICT node. | 326 | * Create an iterator of a #PLIST_DICT node. |
| 300 | * The allocated iterator should be freed with the standard free function. | 327 | * The allocated iterator should be freed with the standard free function. |
| 301 | * | 328 | * |
| 302 | * @param node the node of type #PLIST_DICT | 329 | * @param node The node of type #PLIST_DICT. |
| 303 | * @param iter iterator of the #PLIST_DICT node | 330 | * @param iter Location to store the iterator for the dictionary. |
| 304 | */ | 331 | */ |
| 305 | void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); | 332 | void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); |
| 306 | 333 | ||
| 307 | /** | 334 | /** |
| 308 | * Increment iterator of a #PLIST_DICT node. | 335 | * Increment iterator of a #PLIST_DICT node. |
| 309 | * | 336 | * |
| 310 | * @param node the node of type #PLIST_DICT | 337 | * @param node The node of type #PLIST_DICT |
| 311 | * @param iter iterator of the dictionary | 338 | * @param iter Iterator of the dictionary |
| 312 | * @param key a location to store the key, or NULL. The caller is responsible | 339 | * @param key Location to store the key, or NULL. The caller is responsible |
| 313 | * for freeing the the returned string. | 340 | * for freeing the the returned string. |
| 314 | * @param val a location to store the value, or NULL. The caller should *not* | 341 | * @param val Location to store the value, or NULL. The caller must *not* |
| 315 | * free the returned value. | 342 | * free the returned value. Will be set to NULL when no more |
| 343 | * key/value pairs are left to iterate. | ||
| 316 | */ | 344 | */ |
| 317 | void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); | 345 | void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); |
| 318 | 346 | ||
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) | |||
| 31 | _array.clear(); | 31 | _array.clear(); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | static void array_fill(Array *_this, std::vector<Node*> array, plist_t node) | ||
| 35 | { | ||
| 36 | plist_array_iter iter = NULL; | ||
| 37 | plist_array_new_iter(node, &iter); | ||
| 38 | plist_t subnode; | ||
| 39 | do { | ||
| 40 | subnode = NULL; | ||
| 41 | plist_array_next_item(node, iter, &subnode); | ||
| 42 | array.push_back( Node::FromPlist(subnode, _this) ); | ||
| 43 | } while (subnode); | ||
| 44 | free(iter); | ||
| 45 | } | ||
| 46 | |||
| 34 | Array::Array(plist_t node, Node* parent) : Structure(parent) | 47 | Array::Array(plist_t node, Node* parent) : Structure(parent) |
| 35 | { | 48 | { |
| 36 | _node = node; | 49 | _node = node; |
| 37 | uint32_t size = plist_array_get_size(_node); | 50 | array_fill(this, _array, _node); |
| 38 | |||
| 39 | for (uint32_t i = 0; i < size; i++) | ||
| 40 | { | ||
| 41 | plist_t subnode = plist_array_get_item(_node, i); | ||
| 42 | _array.push_back( Node::FromPlist(subnode, this) ); | ||
| 43 | } | ||
| 44 | } | 51 | } |
| 45 | 52 | ||
| 46 | Array::Array(const PList::Array& a) : Structure() | 53 | Array::Array(const PList::Array& a) : Structure() |
| 47 | { | 54 | { |
| 48 | _array.clear(); | 55 | _array.clear(); |
| 49 | _node = plist_copy(a.GetPlist()); | 56 | _node = plist_copy(a.GetPlist()); |
| 50 | uint32_t size = plist_array_get_size(_node); | 57 | array_fill(this, _array, _node); |
| 51 | |||
| 52 | for (uint32_t i = 0; i < size; i++) | ||
| 53 | { | ||
| 54 | plist_t subnode = plist_array_get_item(_node, i); | ||
| 55 | _array.push_back( Node::FromPlist(subnode, this) ); | ||
| 56 | } | ||
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | Array& Array::operator=(PList::Array& a) | 60 | Array& Array::operator=(PList::Array& a) |
| @@ -64,15 +65,8 @@ Array& Array::operator=(PList::Array& a) | |||
| 64 | delete _array.at(it); | 65 | delete _array.at(it); |
| 65 | } | 66 | } |
| 66 | _array.clear(); | 67 | _array.clear(); |
| 67 | |||
| 68 | _node = plist_copy(a.GetPlist()); | 68 | _node = plist_copy(a.GetPlist()); |
| 69 | uint32_t size = plist_array_get_size(_node); | 69 | array_fill(this, _array, _node); |
| 70 | |||
| 71 | for (uint32_t i = 0; i < size; i++) | ||
| 72 | { | ||
| 73 | plist_t subnode = plist_array_get_item(_node, i); | ||
| 74 | _array.push_back( Node::FromPlist(subnode, this) ); | ||
| 75 | } | ||
| 76 | return *this; | 70 | return *this; |
| 77 | } | 71 | } |
| 78 | 72 | ||
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 @@ | |||
| 2 | * plist.c | 2 | * plist.c |
| 3 | * Builds plist XML structures | 3 | * Builds plist XML structures |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2009-2016 Nikias Bassen All Rights Reserved. | 5 | * Copyright (c) 2009-2019 Nikias Bassen, All Rights Reserved. |
| 6 | * Copyright (c) 2010-2015 Martin Szulecki All Rights Reserved. | 6 | * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved. |
| 7 | * Copyright (c) 2008 Zach C. All Rights Reserved. | 7 | * Copyright (c) 2008 Zach C., All Rights Reserved. |
| 8 | * | 8 | * |
| 9 | * This library is free software; you can redistribute it and/or | 9 | * This library is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU Lesser General Public | 10 | * 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) | |||
| 457 | return; | 457 | return; |
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | PLIST_API void plist_array_new_iter(plist_t node, plist_array_iter *iter) | ||
| 461 | { | ||
| 462 | if (iter) | ||
| 463 | { | ||
| 464 | *iter = malloc(sizeof(node_t*)); | ||
| 465 | *((node_t**)(*iter)) = node_first_child(node); | ||
| 466 | } | ||
| 467 | return; | ||
| 468 | } | ||
| 469 | |||
| 470 | PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item) | ||
| 471 | { | ||
| 472 | node_t** iter_node = (node_t**)iter; | ||
| 473 | |||
| 474 | if (item) | ||
| 475 | { | ||
| 476 | *item = NULL; | ||
| 477 | } | ||
| 478 | |||
| 479 | if (node && PLIST_ARRAY == plist_get_node_type(node) && *iter_node) | ||
| 480 | { | ||
| 481 | if (item) | ||
| 482 | { | ||
| 483 | *item = (plist_t)(*iter_node); | ||
| 484 | } | ||
| 485 | *iter_node = node_next_sibling(*iter_node); | ||
| 486 | } | ||
| 487 | return; | ||
| 488 | } | ||
| 489 | |||
| 460 | PLIST_API uint32_t plist_dict_get_size(plist_t node) | 490 | PLIST_API uint32_t plist_dict_get_size(plist_t node) |
| 461 | { | 491 | { |
| 462 | uint32_t ret = 0; | 492 | uint32_t ret = 0; |
| @@ -469,7 +499,7 @@ PLIST_API uint32_t plist_dict_get_size(plist_t node) | |||
| 469 | 499 | ||
| 470 | PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) | 500 | PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) |
| 471 | { | 501 | { |
| 472 | if (iter && *iter == NULL) | 502 | if (iter) |
| 473 | { | 503 | { |
| 474 | *iter = malloc(sizeof(node_t*)); | 504 | *iter = malloc(sizeof(node_t*)); |
| 475 | *((node_t**)(*iter)) = node_first_child(node); | 505 | *((node_t**)(*iter)) = node_first_child(node); |
