+++ /dev/null
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup iterator iterator
- * @{ @ingroup utils
- */
-
-#ifndef ITERATOR_H_
-#define ITERATOR_H_
-
-#include <library.h>
-
-
-typedef struct iterator_t iterator_t;
-
-/**
- * Iterator interface, allows iteration over collections.
- *
- * iterator_t defines an interface for iterating over collections.
- * It allows searching, deleting, updating and inserting.
- *
- * @deprecated Use enumerator instead.
- */
-struct iterator_t {
-
- /**
- * Return number of list items.
- *
- * @return number of list items
- */
- int (*get_count) (iterator_t *this);
-
- /**
- * Iterate over all items.
- *
- * The easy way to iterate over items.
- *
- * @param value item
- * @return TRUE, if there was an element available, FALSE otherwise
- */
- bool (*iterate) (iterator_t *this, void** value);
-
- /**
- * Inserts a new item before the given iterator position.
- *
- * The iterator position is not changed after inserting
- *
- * @param item value to insert in list
- */
- void (*insert_before) (iterator_t *this, void *item);
-
- /**
- * Inserts a new item after the given iterator position.
- *
- * The iterator position is not changed after inserting.
- *
- * @param item value to insert in list
- */
- void (*insert_after) (iterator_t *this, void *item);
-
- /**
- * Replace the current item at current iterator position.
- *
- * The iterator position is not changed after replacing.
- *
- * @param old old value will be written here(can be NULL)
- * @param new new value
- * @return SUCCESS, FAILED if iterator is on an invalid position
- */
- status_t (*replace) (iterator_t *this, void **old, void *new);
-
- /**
- * Removes an element from list at the given iterator position.
- *
- * The iterator is set the the following position:
- * - to the item before, if available
- * - it gets reseted, otherwise
- *
- * @return SUCCESS, FAILED if iterator is on an invalid position
- */
- status_t (*remove) (iterator_t *this);
-
- /**
- * Resets the iterator position.
- *
- * After reset, the iterator_t objects doesn't point to an element.
- * A call to iterator_t.has_next is necessary to do any other operations
- * with the resetted iterator.
- */
- void (*reset) (iterator_t *this);
-
- /**
- * Destroys an iterator.
- */
- void (*destroy) (iterator_t *this);
-};
-
-#endif /** ITERATOR_H_ @}*/
element_t *last;
};
-
-typedef struct private_iterator_t private_iterator_t;
-
-/**
- * Private variables and functions of linked list iterator.
- */
-struct private_iterator_t {
- /**
- * Public part of linked list iterator.
- */
- iterator_t public;
-
- /**
- * Associated linked list.
- */
- private_linked_list_t * list;
-
- /**
- * Current element of the iterator.
- */
- element_t *current;
-
- /**
- * Direction of iterator.
- */
- bool forward;
-};
-
typedef struct private_enumerator_t private_enumerator_t;
/**
enumerator->current = NULL;
}
-METHOD(iterator_t, iterator_get_count, int,
- private_iterator_t *this)
-{
- return this->list->count;
-}
-
-METHOD(iterator_t, iterate, bool,
- private_iterator_t *this, void** value)
-{
- if (this->forward)
- {
- this->current = this->current ? this->current->next : this->list->first;
- }
- else
- {
- this->current = this->current ? this->current->previous : this->list->last;
- }
- if (this->current == NULL)
- {
- return FALSE;
- }
- *value = this->current->value;
- return TRUE;
-}
-
-METHOD(iterator_t, iterator_reset, void,
- private_iterator_t *this)
-{
- this->current = NULL;
-}
-
-METHOD(iterator_t, iterator_remove, status_t,
- private_iterator_t *this)
-{
- element_t *new_current;
-
- if (this->current == NULL)
- {
- return NOT_FOUND;
- }
-
- if (this->list->count == 0)
- {
- return NOT_FOUND;
- }
- /* find out the new iterator position, depending on iterator direction */
- if (this->forward && this->current->previous != NULL)
- {
- new_current = this->current->previous;
- }
- else if (!this->forward && this->current->next != NULL)
- {
- new_current = this->current->next;
- }
- else
- {
- new_current = NULL;
- }
-
- /* now delete the entry :-) */
- if (this->current->previous == NULL)
- {
- if (this->current->next == NULL)
- {
- this->list->first = NULL;
- this->list->last = NULL;
- }
- else
- {
- this->current->next->previous = NULL;
- this->list->first = this->current->next;
- }
- }
- else if (this->current->next == NULL)
- {
- this->current->previous->next = NULL;
- this->list->last = this->current->previous;
- }
- else
- {
- this->current->previous->next = this->current->next;
- this->current->next->previous = this->current->previous;
- }
-
- this->list->count--;
- free(this->current);
- /* set the new iterator position */
- this->current = new_current;
- return SUCCESS;
-}
-
-static void insert_item_before(private_linked_list_t *this, element_t *current,
- void *item)
-{
- if (!current)
- {
- this->public.insert_last(&this->public, item);
- return;
- }
- element_t *element = element_create(item);
- if (current->previous)
- {
- current->previous->next = element;
- element->previous = current->previous;
- current->previous = element;
- element->next = current;
- }
- else
- {
- current->previous = element;
- element->next = current;
- this->first = element;
- }
- this->count++;
-}
-
-static void insert_item_after(private_linked_list_t *this, element_t *current,
- void *item)
-{
- if (!current)
- {
- this->public.insert_last(&this->public, item);
- return;
- }
- element_t *element = element_create(item);
- if (current->next)
- {
- current->next->previous = element;
- element->next = current->next;
- current->next = element;
- element->previous = current;
- }
- else
- {
- current->next = element;
- element->previous = current;
- this->last = element;
- }
- this->count++;
-}
-
-METHOD(iterator_t, iterator_insert_before, void,
- private_iterator_t * iterator, void *item)
-{
- insert_item_before(iterator->list, iterator->current, item);
-}
-
-METHOD(iterator_t, iterator_replace, status_t,
- private_iterator_t *this, void **old_item, void *new_item)
-{
- if (this->current == NULL)
- {
- return NOT_FOUND;
- }
- if (old_item != NULL)
- {
- *old_item = this->current->value;
- }
- this->current->value = new_item;
-
- return SUCCESS;
-}
-
-METHOD(iterator_t, iterator_insert_after, void,
- private_iterator_t *iterator, void *item)
-{
- insert_item_after(iterator->list, iterator->current, item);
-}
-
-METHOD(iterator_t, iterator_destroy, void,
- private_iterator_t *this)
-{
- free(this);
-}
-
METHOD(linked_list_t, get_count, int,
private_linked_list_t *this)
{
private_linked_list_t *this, private_enumerator_t *enumerator,
void *item)
{
- insert_item_before(this, enumerator->current, item);
+ element_t *current = enumerator->current;
+ if (!current)
+ {
+ this->public.insert_last(&this->public, item);
+ return;
+ }
+ element_t *element = element_create(item);
+ if (current->previous)
+ {
+ current->previous->next = element;
+ element->previous = current->previous;
+ current->previous = element;
+ element->next = current;
+ }
+ else
+ {
+ current->previous = element;
+ element->next = current;
+ this->first = element;
+ }
+ this->count++;
}
METHOD(linked_list_t, replace, void*,
free(this);
}
-METHOD(linked_list_t, create_iterator, iterator_t*,
- private_linked_list_t *linked_list, bool forward)
-{
- private_iterator_t *this;
-
- INIT(this,
- .public = {
- .get_count = _iterator_get_count,
- .iterate = _iterate,
- .insert_before = _iterator_insert_before,
- .insert_after = _iterator_insert_after,
- .replace = _iterator_replace,
- .remove = _iterator_remove,
- .reset = _iterator_reset,
- .destroy = _iterator_destroy,
- },
- .forward = forward,
- .list = linked_list,
- );
-
- return &this->public;
-}
-
/*
* Described in header.
*/
INIT(this,
.public = {
.get_count = _get_count,
- .create_iterator = _create_iterator,
.create_enumerator = _create_enumerator,
.reset_enumerator = (void*)_reset_enumerator,
.get_first = _get_first,