libimobiledevice / libplist

A library to handle Apple Property List format in binary or XML
https://libimobiledevice.org
GNU Lesser General Public License v2.1
535 stars 304 forks source link

It is recommended to add a function of plist_array_remove_item2 #130

Closed xdeng closed 5 years ago

xdeng commented 5 years ago

I now need to find multiple items in the array and delete them.

list<int> del_list;
for(int i = 0, i < plist_array_get_size(arr), i++)
{
    if( x == y )
        del_list.push_front(i);
}
plist_array_remove_item(arr, del_list.pop_front);
plist_array_remove_item(arr, del_list.pop_front);

This will cause problems, Index position is not reliable

list<plist_t> del_list;
for(int i = 0, i < plist_array_get_size(arr), i++)
{
    if( x == y )
        del_list.push_front(plist_array_get_item(arr, i));
}
plist_array_remove_item(arr, plist_array_get_item_index(del_list.pop_front));
plist_array_remove_item(arr, plist_array_get_item_index(del_list.pop_front));

This will be very troublesome

xdeng commented 5 years ago
PLIST_API void plist_array_remove_item2(plist_t node)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_ARRAY == plist_get_node_type(father))
    {
        plist_free(node);
    }
}

Simple and fast reference: plist_array_get_item_index plist_array_remove_item

nikias commented 5 years ago

Your first example will work if you delete the nodes in reverse order. I will think about the other idea...

nikias commented 5 years ago

See commit 9555e71d9887d0d5caf87341dc47d9ad313bb609. I named it plist_array_item_remove. You can use it pretty easily like this:

plist_array_iter iter = NULL;
plist_array_new_iter(array, &iter);
if (iter) {
    plist_t n = NULL;
    do {
        plist_array_next_item(array, iter, &n);
        if (n) {
            // check the node, e.g. plist_get_uint_val() or whatever
            if (CONDITION) {
                plist_array_item_remove(n);
            }
        }
    } while (n);
    free(iter);
}