summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils/linked_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils/linked_list.c')
-rw-r--r--src/libstrongswan/utils/linked_list.c108
1 files changed, 104 insertions, 4 deletions
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index de52ea46a..5cd8ffd7a 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -140,6 +141,52 @@ struct private_iterator_t {
void *hook_param;
};
+typedef struct private_enumerator_t private_enumerator_t;
+
+/**
+ * linked lists enumerator implementation
+ */
+struct private_enumerator_t {
+
+ /**
+ * implements enumerator interface
+ */
+ enumerator_t enumerator;
+
+ /**
+ * next item to enumerate
+ */
+ element_t *next;
+};
+
+/**
+ * Implementation of private_enumerator_t.enumerator.enumerate.
+ */
+static bool enumerate(private_enumerator_t *this, void **item)
+{
+ if (this->next == NULL)
+ {
+ return FALSE;
+ }
+ *item = this->next->value;
+ this->next = this->next->next;
+ return TRUE;
+}
+
+/**
+ * Implementation of linked_list_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_linked_list_t *this)
+{
+ private_enumerator_t *enumerator = malloc_thing(private_enumerator_t);
+
+ enumerator->enumerator.enumerate = (void*)enumerate;
+ enumerator->enumerator.destroy = (void*)free;
+ enumerator->next = this->first;
+
+ return &enumerator->enumerator;
+}
+
/**
* Implementation of iterator_t.get_count.
*/
@@ -630,9 +677,9 @@ static status_t get_last(private_linked_list_t *this, void **item)
}
/**
- * Implementation of linked_list_t.invoke.
+ * Implementation of linked_list_t.invoke_offset.
*/
-static void invoke(private_linked_list_t *this, size_t offset)
+static void invoke_offset(private_linked_list_t *this, size_t offset)
{
element_t *current = this->first;
@@ -645,13 +692,62 @@ static void invoke(private_linked_list_t *this, size_t offset)
}
/**
+ * Implementation of linked_list_t.invoke_function.
+ */
+static void invoke_function(private_linked_list_t *this, void(*fn)(void*))
+{
+ element_t *current = this->first;
+
+ while (current)
+ {
+ fn(current->value);
+ current = current->next;
+ }
+}
+
+/**
+ * Implementation of linked_list_t.clone_offset
+ */
+static linked_list_t *clone_offset(private_linked_list_t *this, size_t offset)
+{
+ linked_list_t *clone = linked_list_create();
+ element_t *current = this->first;
+
+ while (current)
+ {
+ void* (**method)(void*) = current->value + offset;
+ clone->insert_last(clone, (*method)(current->value));
+ current = current->next;
+ }
+
+ return clone;
+}
+
+/**
+ * Implementation of linked_list_t.clone_function
+ */
+static linked_list_t *clone_function(private_linked_list_t *this, void* (*fn)(void*))
+{
+ linked_list_t *clone = linked_list_create();
+ element_t *current = this->first;
+
+ while (current)
+ {
+ clone->insert_last(clone, fn(current->value));
+ current = current->next;
+ }
+
+ return clone;
+}
+
+/**
* Implementation of linked_list_t.destroy.
*/
static void destroy(private_linked_list_t *this)
{
void *value;
/* Remove all list items before destroying list */
- while (this->public.remove_first(&(this->public), &value) == SUCCESS)
+ while (remove_first(this, &value) == SUCCESS)
{
/* values are not destroyed so memory leaks are possible
* if list is not empty when deleting */
@@ -744,6 +840,7 @@ linked_list_t *linked_list_create()
this->public.get_count = (int (*) (linked_list_t *)) get_count;
this->public.create_iterator = (iterator_t * (*) (linked_list_t *,bool))create_iterator;
this->public.create_iterator_locked = (iterator_t * (*) (linked_list_t *,pthread_mutex_t*))create_iterator_locked;
+ this->public.create_enumerator = (enumerator_t*(*)(linked_list_t*))create_enumerator;
this->public.get_first = (status_t (*) (linked_list_t *, void **item))get_first;
this->public.get_last = (status_t (*) (linked_list_t *, void **item))get_last;
this->public.insert_first = (void (*) (linked_list_t *, void *item))insert_first;
@@ -753,7 +850,10 @@ linked_list_t *linked_list_create()
this->public.insert_at_position = (status_t (*) (linked_list_t *,size_t, void *))insert_at_position;
this->public.remove_at_position = (status_t (*) (linked_list_t *,size_t, void **))remove_at_position;
this->public.get_at_position = (status_t (*) (linked_list_t *,size_t, void **))get_at_position;
- this->public.invoke = (void (*)(linked_list_t*,size_t))invoke;
+ this->public.invoke_offset = (void (*)(linked_list_t*,size_t))invoke_offset;
+ this->public.invoke_function = (void (*)(linked_list_t*,void(*)(void*)))invoke_function;
+ this->public.clone_offset = (linked_list_t * (*)(linked_list_t*,size_t))clone_offset;
+ this->public.clone_function = (linked_list_t * (*)(linked_list_t*,void*(*)(void*)))clone_function;
this->public.destroy = (void (*) (linked_list_t *))destroy;
this->public.destroy_offset = (void (*) (linked_list_t *,size_t))destroy_offset;
this->public.destroy_function = (void (*)(linked_list_t*,void(*)(void*)))destroy_function;