botan: Add support for Ed25519 keys
[strongswan.git] / src / libstrongswan / collections / linked_list.c
index 4feb66f..c7342c6 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 2007-2011 Tobias Brunner
+ * Copyright (C) 2007-2018 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -47,6 +47,17 @@ struct element_t {
        element_t *next;
 };
 
+/*
+ * Described in header
+ */
+bool linked_list_match_str(void *item, va_list args)
+{
+       char *a = item, *b;
+
+       VA_ARGS_VGET(args, b);
+       return streq(a, b);
+}
+
 /**
  * Creates an empty linked list object.
  */
@@ -100,7 +111,7 @@ struct private_enumerator_t {
        /**
         * implements enumerator interface
         */
-       enumerator_t enumerator;
+       enumerator_t public;
 
        /**
         * associated linked list
@@ -111,35 +122,43 @@ struct private_enumerator_t {
         * current item
         */
        element_t *current;
-
-       /**
-        * enumerator has enumerated all items
-        */
-       bool finished;
 };
 
-METHOD(enumerator_t, enumerate, bool,
-       private_enumerator_t *this, void **item)
+/**
+ * Enumerate the current item
+ */
+static bool do_enumerate(private_enumerator_t *this, va_list args)
 {
-       if (this->finished)
+       void **item;
+
+       VA_ARGS_VGET(args, item);
+
+       if (!this->current)
        {
                return FALSE;
        }
-       if (!this->current)
+       if (item)
        {
-               this->current = this->list->first;
+               *item = this->current->value;
        }
-       else
+       return TRUE;
+}
+
+METHOD(enumerator_t, enumerate_next, bool,
+       private_enumerator_t *this, va_list args)
+{
+       if (this->current)
        {
                this->current = this->current->next;
        }
-       if (!this->current)
-       {
-               this->finished = TRUE;
-               return FALSE;
-       }
-       *item = this->current->value;
-       return TRUE;
+       return do_enumerate(this, args);
+}
+
+METHOD(enumerator_t, enumerate_current, bool,
+       private_enumerator_t *this, va_list args)
+{
+       this->public.venumerate = _enumerate_next;
+       return do_enumerate(this, args);
 }
 
 METHOD(linked_list_t, create_enumerator, enumerator_t*,
@@ -148,31 +167,23 @@ METHOD(linked_list_t, create_enumerator, enumerator_t*,
        private_enumerator_t *enumerator;
 
        INIT(enumerator,
-               .enumerator = {
-                       .enumerate = (void*)_enumerate,
+               .public = {
+                       .enumerate = enumerator_enumerate_default,
+                       .venumerate = _enumerate_current,
                        .destroy = (void*)free,
                },
                .list = this,
+               .current = this->first,
        );
 
-       return &enumerator->enumerator;
+       return &enumerator->public;
 }
 
 METHOD(linked_list_t, reset_enumerator, void,
        private_linked_list_t *this, private_enumerator_t *enumerator)
 {
-       enumerator->current = NULL;
-       enumerator->finished = FALSE;
-}
-
-METHOD(linked_list_t, has_more, bool,
-       private_linked_list_t *this, private_enumerator_t *enumerator)
-{
-       if (enumerator->current)
-       {
-               return enumerator->current->next != NULL;
-       }
-       return !enumerator->finished && this->first != NULL;
+       enumerator->current = this->first;
+       enumerator->public.venumerate = _enumerate_current;
 }
 
 METHOD(linked_list_t, get_count, int,
@@ -289,14 +300,7 @@ METHOD(linked_list_t, insert_before, void,
        current = enumerator->current;
        if (!current)
        {
-               if (enumerator->finished)
-               {
-                       this->public.insert_last(&this->public, item);
-               }
-               else
-               {
-                       this->public.insert_first(&this->public, item);
-               }
+               insert_last(this, item);
                return;
        }
        element = element_create(item);
@@ -368,57 +372,75 @@ METHOD(linked_list_t, remove_at, void,
        if (enumerator->current)
        {
                current = enumerator->current;
-               enumerator->current = current->previous;
+               enumerator->current = current->next;
+               /* the enumerator already points to the next item */
+               enumerator->public.venumerate = _enumerate_current;
                remove_element(this, current);
        }
 }
 
-METHOD(linked_list_t, find_first, status_t,
-       private_linked_list_t *this, linked_list_match_t match,
-       void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
+METHOD(linked_list_t, find_first, bool,
+       private_linked_list_t *this, linked_list_match_t match, void **item, ...)
 {
        element_t *current = this->first;
+       va_list args;
+       bool matched = FALSE;
+
+       if (!match && !item)
+       {
+               return FALSE;
+       }
 
        while (current)
        {
-               if ((match && match(current->value, d1, d2, d3, d4, d5)) ||
-                       (!match && item && current->value == *item))
+               if (match)
+               {
+                       va_start(args, item);
+                       matched = match(current->value, args);
+                       va_end(args);
+               }
+               else
+               {
+                       matched = current->value == *item;
+               }
+               if (matched)
                {
                        if (item != NULL)
                        {
                                *item = current->value;
                        }
-                       return SUCCESS;
+                       return TRUE;
                }
                current = current->next;
        }
-       return NOT_FOUND;
+       return FALSE;
 }
 
 METHOD(linked_list_t, invoke_offset, void,
-       private_linked_list_t *this, size_t offset,
-       void *d1, void *d2, void *d3, void *d4, void *d5)
+       private_linked_list_t *this, size_t offset)
 {
        element_t *current = this->first;
-       linked_list_invoke_t *method;
+       void (**method)(void*);
 
        while (current)
        {
                method = current->value + offset;
-               (*method)(current->value, d1, d2, d3, d4, d5);
+               (*method)(current->value);
                current = current->next;
        }
 }
 
 METHOD(linked_list_t, invoke_function, void,
-       private_linked_list_t *this, linked_list_invoke_t fn,
-       void *d1, void *d2, void *d3, void *d4, void *d5)
+       private_linked_list_t *this, linked_list_invoke_t fn, ...)
 {
        element_t *current = this->first;
+       va_list args;
 
        while (current)
        {
-               fn(current->value, d1, d2, d3, d4, d5);
+               va_start(args, fn);
+               fn(current->value, args);
+               va_end(args);
                current = current->next;
        }
 }
@@ -440,19 +462,54 @@ METHOD(linked_list_t, clone_offset, linked_list_t*,
        return clone;
 }
 
-METHOD(linked_list_t, clone_function, linked_list_t*,
-       private_linked_list_t *this, void* (*fn)(void*))
+METHOD(linked_list_t, equals_offset, bool,
+       private_linked_list_t *this, linked_list_t *other_pub, size_t offset)
 {
-       element_t *current = this->first;
-       linked_list_t *clone;
+       private_linked_list_t *other = (private_linked_list_t*)other_pub;
+       element_t *cur_t, *cur_o;
 
-       clone = linked_list_create();
-       while (current)
+       if (this->count != other->count)
        {
-               clone->insert_last(clone, fn(current->value));
-               current = current->next;
+               return FALSE;
        }
-       return clone;
+       cur_t = this->first;
+       cur_o = other->first;
+       while (cur_t && cur_o)
+       {
+               bool (**method)(void*,void*) = cur_t->value + offset;
+               if (!(*method)(cur_t->value, cur_o->value))
+               {
+                       return FALSE;
+               }
+               cur_t = cur_t->next;
+               cur_o = cur_o->next;
+       }
+       return TRUE;
+}
+
+METHOD(linked_list_t, equals_function, bool,
+       private_linked_list_t *this, linked_list_t *other_pub,
+       bool (*fn)(void*,void*))
+{
+       private_linked_list_t *other = (private_linked_list_t*)other_pub;
+       element_t *cur_t, *cur_o;
+
+       if (this->count != other->count)
+       {
+               return FALSE;
+       }
+       cur_t = this->first;
+       cur_o = other->first;
+       while (cur_t && cur_o)
+       {
+               if (!fn(cur_t->value, cur_o->value))
+               {
+                       return FALSE;
+               }
+               cur_t = cur_t->next;
+               cur_o = cur_o->next;
+       }
+       return TRUE;
 }
 
 METHOD(linked_list_t, destroy, void,
@@ -512,10 +569,9 @@ linked_list_t *linked_list_create()
                        .get_count = _get_count,
                        .create_enumerator = _create_enumerator,
                        .reset_enumerator = (void*)_reset_enumerator,
-                       .has_more = (void*)_has_more,
                        .get_first = _get_first,
                        .get_last = _get_last,
-                       .find_first = (void*)_find_first,
+                       .find_first = _find_first,
                        .insert_first = _insert_first,
                        .insert_last = _insert_last,
                        .insert_before = (void*)_insert_before,
@@ -523,10 +579,11 @@ linked_list_t *linked_list_create()
                        .remove_last = _remove_last,
                        .remove = _remove_,
                        .remove_at = (void*)_remove_at,
-                       .invoke_offset = (void*)_invoke_offset,
-                       .invoke_function = (void*)_invoke_function,
+                       .invoke_offset = _invoke_offset,
+                       .invoke_function = _invoke_function,
                        .clone_offset = _clone_offset,
-                       .clone_function = _clone_function,
+                       .equals_offset = _equals_offset,
+                       .equals_function = _equals_function,
                        .destroy = _destroy,
                        .destroy_offset = _destroy_offset,
                        .destroy_function = _destroy_function,