Added an insert_after and insert_before function to linked_list_t.
authorTobias Brunner <tobias@strongswan.org>
Fri, 13 May 2011 09:51:58 +0000 (11:51 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 6 Jul 2011 07:43:45 +0000 (09:43 +0200)
src/libstrongswan/utils/linked_list.c
src/libstrongswan/utils/linked_list.h

index 5647222..cc5590e 100644 (file)
@@ -145,20 +145,16 @@ METHOD(enumerator_t, enumerate, bool,
 {
        if (!this->current)
        {
-               if (!this->list->first)
-               {
-                       return FALSE;
-               }
                this->current = this->list->first;
        }
        else
        {
-               if (!this->current->next)
-               {
-                       return FALSE;
-               }
                this->current = this->current->next;
        }
+       if (!this->current)
+       {
+               return FALSE;
+       }
        *item = this->current->value;
        return TRUE;
 }
@@ -270,30 +266,60 @@ METHOD(iterator_t, iterator_remove, status_t,
        return SUCCESS;
 }
 
-METHOD(iterator_t, iterator_insert_before, void,
-          private_iterator_t * iterator, void *item)
+static void insert_item_before(private_linked_list_t *this, element_t *current,
+                                                          void *item)
 {
-       if (iterator->current == NULL)
+       if (!current)
        {
-               iterator->list->public.insert_first(&(iterator->list->public), item);
+               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 (iterator->current->previous == NULL)
+       if (current->next)
        {
-               iterator->current->previous = element;
-               element->next = iterator->current;
-               iterator->list->first = element;
+               current->next->previous = element;
+               element->next = current->next;
+               current->next = element;
+               element->previous = current;
        }
        else
        {
-               iterator->current->previous->next = element;
-               element->previous = iterator->current->previous;
-               iterator->current->previous = element;
-               element->next = iterator->current;
+               current->next = element;
+               element->previous = current;
+               this->last = element;
        }
-       iterator->list->count++;
+       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,
@@ -315,27 +341,7 @@ METHOD(iterator_t, iterator_replace, status_t,
 METHOD(iterator_t, iterator_insert_after, void,
           private_iterator_t *iterator, void *item)
 {
-       if (iterator->current == NULL)
-       {
-               iterator->list->public.insert_first(&(iterator->list->public),item);
-               return;
-       }
-
-       element_t *element = element_create(item);
-       if (iterator->current->next == NULL)
-       {
-               iterator->current->next = element;
-               element->previous = iterator->current;
-               iterator->list->last = element;
-       }
-       else
-       {
-               iterator->current->next->previous = element;
-               element->next = iterator->current->next;
-               iterator->current->next = element;
-               element->previous = iterator->current;
-       }
-       iterator->list->count++;
+       insert_item_after(iterator->list, iterator->current, item);
 }
 
 METHOD(iterator_t, iterator_destroy, void,
@@ -456,6 +462,20 @@ METHOD(linked_list_t, insert_last, void,
        this->count++;
 }
 
+METHOD(linked_list_t, insert_before, void,
+          private_linked_list_t *this, private_enumerator_t *enumerator,
+          void *item)
+{
+       insert_item_before(this, enumerator->current, item);
+}
+
+METHOD(linked_list_t, insert_after, void,
+          private_linked_list_t *this, private_enumerator_t *enumerator,
+          void *item)
+{
+       insert_item_after(this, enumerator->current, item);
+}
+
 METHOD(linked_list_t, get_last, status_t,
           private_linked_list_t *this, void **item)
 {
@@ -700,6 +720,8 @@ linked_list_t *linked_list_create()
                        .find_last = (void*)_find_last,
                        .insert_first = _insert_first,
                        .insert_last = _insert_last,
+                       .insert_after = (void*)_insert_after,
+                       .insert_before = (void*)_insert_before,
                        .remove_first = _remove_first,
                        .remove_last = _remove_last,
                        .remove = _remove_,
index 1444c93..25daaab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Tobias Brunner
+ * Copyright (C) 2007-2011 Tobias Brunner
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -100,6 +100,32 @@ struct linked_list_t {
        status_t (*remove_first) (linked_list_t *this, void **item);
 
        /**
+        * Inserts a new item before the item the enumerator currently points to.
+        *
+        * @note The position of the enumerator is not changed.
+        * @note If the enumerator's position is invalid, the item is inserted last.
+        *
+        * @param enumerator    enumerator with position
+        * @param item                  item value to insert in list
+        */
+       void (*insert_before)(linked_list_t *this, enumerator_t *enumerator,
+                                                 void *item);
+
+       /**
+        * Inserts a new item after the item the enumerator currently points to.
+        *
+        * @note The position of the enumerator is not changed (thus the next item
+        * the enumerator returns will be the inserted item).
+        *
+        * @note If the enumerator's position is invalid, the item is inserted last.
+        *
+        * @param enumerator    enumerator with position
+        * @param item                  item value to insert in list
+        */
+       void (*insert_after)(linked_list_t *this, enumerator_t *enumerator,
+                                                void *item);
+
+       /**
         * Remove an item from the list where the enumerator points to.
         *
         * @param enumerator enumerator with position