Beispiel #1
0
int ListRemove(List *list, void *payload)
{
    if (!list || !payload)
        return -1;
    ListNode *node = NULL;
    /*
     * This is a complicated matter. We could detach the list before
     * we know that we have a new node, but that will mean that we
     * might have copied the whole list without real reasons. On the
     * other hand, it saves us a whole traversal of the list if we
     * just do it.
     */
    int found = ListFindNode(list, payload);
    if (!found)
        return -1;
    ListDetach(list);
    node = NULL;
    /*
     * We need to find the node again since we have a new list.
     * In theory we don't have to worry about the existence of the node,
     * since the list has not changed, it might have been copied but
     * it is still the same as before.
     */
    for (node = list->list; node; node = node->next) 
	{
        if (list->compare) 
		{
            if (!list->compare(node->payload, payload)) 
			{
                found = 1;
                break;
            }
        } 
		else 
		{
            if (node->payload == payload) 
			{
                found = 1;
                break;
            }
        }
    }
    /*
     * Before deleting the node we have to update the mutable iterator.
     * We might need to advance it!
     */
    ListUpdateMutableIterator(list, node);
    ListRemoveNode(list, node);
    if (list->destroy && node->payload) 
    {
        list->destroy(node->payload);
	}
    free(node);
    ListUpdateListState(list);
    return 0;
}
Beispiel #2
0
int ListMutableIteratorRemove(ListMutableIterator *iterator)
{
    if (!iterator)
        return -1;
    if (IsMutableIteratorValid(iterator))
        return -1;
    ListDetach(iterator->origin);
    /*
     * Removing an element is not as simple as it sounds. We need to inform the list
     * and make sure we move out of the way.
     */
    ListNode *node = NULL;
    if (iterator->current->next) {
        /*
         * We are not the last element, therefore we proceed as normal.
         */
        node = iterator->current->next;
    } else {
        /*
         * We might be the last element or the only element on the list.
         * If we are the only element we do not destroy the element otherwise the iterator
         * would become invalid.
         */
        if (iterator->current->previous) {
            /*
             * last element
             */
            node = iterator->current->previous;
        } else
            return -1;
    }
    ListRemoveNode(iterator->origin, iterator->current);
    if (iterator->origin->destroy)
        iterator->origin->destroy(iterator->current->payload);
    free (iterator->current);
    iterator->current = node;
    ListUpdateListState(iterator->origin);
    return 0;
}
Beispiel #3
0
int ListRemove(List *list, void *payload)
{
    if (!list || !payload)
        return -1;
    ListNode *node = NULL;
    /*
     * This is a complicated matter. We could detach the list before
     * we know that we have a new node, but that will mean that we
     * might have copied the whole list without real reasons. On the
     * other hand, it saves us a whole traversal of the list if we
     * just do it.
     */
    int found = ListFindNode(list, payload);
    if (!found)
        return -1;
    found = 0;
    ListDetach(list);
    node = NULL;
    /*
     * We need to find the node again since we have a new list.
     * In theory we don't have to worry about the existence of the node,
     * since the list has not changed, it might have been copied but
     * it is still the same as before.
     */
    for (node = list->list; node; node = node->next) 
	{
        if (list->compare) 
		{
            if (!list->compare(node->payload, payload)) 
			{
                found = 1;
                break;
            }
        } 
		else 
		{
            if (node->payload == payload) 
			{
                found = 1;
                break;
            }
        }
    }
    /*
     * This is nearly impossible, so we will only assert it.
     */
    assert(found == 1);
    /*
     * Before deleting the node we have to update the mutable iterator.
     * We might need to advance it!
     */
    if (list->iterator)
    {
        if (list->iterator->current == node) 
        {
            /*
             * So lucky, it is the same node!
             * Move the iterator so it is not dangling.
             * Rules for moving:
             * 1. Move forward.
             * 2. if not possible, move backward.
             * 3. If not possible, then invalidate the iterator.
             */
            if (list->iterator->current->next)
            {
                list->iterator->current = list->iterator->current->next;
            }
            else if (list->iterator->current->previous)
            {
                list->iterator->current = list->iterator->current->previous;
            }
            else
            {
                list->iterator->valid = 0;
            }
        }
    }
    /*
     * Now, remove the node from the list and delete it.
     */
    if (node->next && node->previous) 
    {
        // Middle of the list
        node->next->previous = node->previous;
        node->previous->next = node->next;
    }
    else if (node->next)
    {
        // First element of the list
        list->list = node->next;
        list->first = node->next;
        node->next->previous = NULL;
    }
    else if (node->previous)
    {
        // Last element
        node->previous->next = NULL;
        list->last = node->previous;
    }
    else
    {
        // Single element
        list->list = NULL;
        list->first = NULL;
        list->last = NULL;
    }
    if (list->destroy && node->payload) 
    {
        list->destroy(node->payload);
    }
    else
    {
        free (node->payload);
    }
    free(node);
    ListUpdateListState(list);
    return 0;
}