Пример #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;
}
Пример #2
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;
}