diff options
author | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
commit | b34738ed08c2227300d554b139e2495ca5da97d6 (patch) | |
tree | 62f33b52820f2e49f0e53c0f8c636312037c8054 /src/libstrongswan/utils/linked_list.c | |
parent | 0a9d51a49042a68daa15b0c74a2b7f152f52606b (diff) | |
download | vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.tar.gz vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.zip |
Imported Upstream version 4.6.4
Diffstat (limited to 'src/libstrongswan/utils/linked_list.c')
-rw-r--r-- | src/libstrongswan/utils/linked_list.c | 547 |
1 files changed, 174 insertions, 373 deletions
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 9b37359dc..59d416f2f 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2008 Tobias Brunner + * Copyright (C) 2007-2011 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -51,13 +51,11 @@ struct element_t { */ element_t *element_create(void *value) { - element_t *this = malloc_thing(element_t); - - this->previous = NULL; - this->next = NULL; - this->value = value; - - return (this); + element_t *this; + INIT(this, + .value = value, + ); + return this; } @@ -91,34 +89,6 @@ struct private_linked_list_t { 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; /** @@ -140,241 +110,78 @@ struct private_enumerator_t { * current item */ element_t *current; + + /** + * enumerator has enumerated all items + */ + bool finished; }; -/** - * Implementation of private_enumerator_t.enumerator.enumerate. - */ -static bool enumerate(private_enumerator_t *this, void **item) +METHOD(enumerator_t, enumerate, bool, + private_enumerator_t *this, void **item) { + if (this->finished) + { + return FALSE; + } 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; } - *item = this->current->value; - 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->list = this; - enumerator->current = NULL; - - return &enumerator->enumerator; -} - -/** - * Implementation of iterator_t.get_count. - */ -static int get_list_count(private_iterator_t *this) -{ - return this->list->count; -} - -/** - * Implementation of iterator_t.iterate. - */ -static bool iterate(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) + if (!this->current) { + this->finished = TRUE; return FALSE; } - *value = this->current->value; + *item = this->current->value; return TRUE; } -/** - * Implementation of iterator_t.reset. - */ -static void iterator_reset(private_iterator_t *this) +METHOD(linked_list_t, create_enumerator, enumerator_t*, + private_linked_list_t *this) { - this->current = NULL; -} + private_enumerator_t *enumerator; -/** - * Implementation of iterator_t.remove. - */ -static status_t iterator_remove(private_iterator_t *this) -{ - element_t *new_current; + INIT(enumerator, + .enumerator = { + .enumerate = (void*)_enumerate, + .destroy = (void*)free, + }, + .list = this, + ); - 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; -} - -/** - * Implementation of iterator_t.insert_before. - */ -static void insert_before(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->previous == NULL) - { - iterator->current->previous = element; - element->next = iterator->current; - iterator->list->first = element; - } - else - { - iterator->current->previous->next = element; - element->previous = iterator->current->previous; - iterator->current->previous = element; - element->next = iterator->current; - } - iterator->list->count++; + return &enumerator->enumerator; } -/** - * Implementation of iterator_t.replace. - */ -static status_t replace(private_iterator_t *this, void **old_item, void *new_item) +METHOD(linked_list_t, reset_enumerator, void, + private_linked_list_t *this, private_enumerator_t *enumerator) { - if (this->current == NULL) - { - return NOT_FOUND; - } - if (old_item != NULL) - { - *old_item = this->current->value; - } - this->current->value = new_item; - - return SUCCESS; + enumerator->current = NULL; + enumerator->finished = FALSE; } -/** - * Implementation of iterator_t.insert_after. - */ -static void insert_after(private_iterator_t *iterator, void *item) +METHOD(linked_list_t, has_more, bool, + private_linked_list_t *this, private_enumerator_t *enumerator) { - 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 + if (enumerator->current) { - iterator->current->next->previous = element; - element->next = iterator->current->next; - iterator->current->next = element; - element->previous = iterator->current; + return enumerator->current->next != NULL; } - iterator->list->count++; + return !enumerator->finished && this->first != NULL; } -/** - * Implementation of iterator_t.destroy. - */ -static void iterator_destroy(private_iterator_t *this) -{ - free(this); -} - -/** - * Implementation of linked_list_t.get_count. - */ -static int get_count(private_linked_list_t *this) +METHOD(linked_list_t, get_count, int, + private_linked_list_t *this) { return this->count; } -/** - * Implementation of linked_list_t.insert_first. - */ -static void insert_first(private_linked_list_t *this, void *item) +METHOD(linked_list_t, insert_first, void, + private_linked_list_t *this, void *item) { element_t *element; @@ -384,15 +191,11 @@ static void insert_first(private_linked_list_t *this, void *item) /* first entry in list */ this->first = element; this->last = element; - element->previous = NULL; - element->next = NULL; } else { - element_t *old_first_element = this->first; - element->next = old_first_element; - element->previous = NULL; - old_first_element->previous = element; + element->next = this->first; + this->first->previous = element; this->first = element; } this->count++; @@ -401,7 +204,8 @@ static void insert_first(private_linked_list_t *this, void *item) /** * unlink an element form the list, returns following element */ -static element_t* remove_element(private_linked_list_t *this, element_t *element) +static element_t* remove_element(private_linked_list_t *this, + element_t *element) { element_t *next, *previous; @@ -432,10 +236,8 @@ static element_t* remove_element(private_linked_list_t *this, element_t *element return next; } -/** - * Implementation of linked_list_t.get_first. - */ -static status_t get_first(private_linked_list_t *this, void **item) +METHOD(linked_list_t, get_first, status_t, + private_linked_list_t *this, void **item) { if (this->count == 0) { @@ -445,10 +247,8 @@ static status_t get_first(private_linked_list_t *this, void **item) return SUCCESS; } -/** - * Implementation of linked_list_t.remove_first. - */ -static status_t remove_first(private_linked_list_t *this, void **item) +METHOD(linked_list_t, remove_first, status_t, + private_linked_list_t *this, void **item) { if (get_first(this, item) == SUCCESS) { @@ -458,36 +258,79 @@ static status_t remove_first(private_linked_list_t *this, void **item) return NOT_FOUND; } -/** - * Implementation of linked_list_t.insert_last. - */ -static void insert_last(private_linked_list_t *this, void *item) +METHOD(linked_list_t, insert_last, void, + private_linked_list_t *this, void *item) { - element_t *element = element_create(item); + element_t *element; + element = element_create(item); if (this->count == 0) { /* first entry in list */ this->first = element; this->last = element; - element->previous = NULL; - element->next = NULL; } else { - element_t *old_last_element = this->last; - element->previous = old_last_element; - element->next = NULL; - old_last_element->next = element; + element->previous = this->last; + this->last->next = element; this->last = element; } this->count++; } -/** - * Implementation of linked_list_t.get_last. - */ -static status_t get_last(private_linked_list_t *this, void **item) +METHOD(linked_list_t, insert_before, void, + private_linked_list_t *this, private_enumerator_t *enumerator, + void *item) +{ + element_t *current, *element; + + current = enumerator->current; + if (!current) + { + if (enumerator->finished) + { + this->public.insert_last(&this->public, item); + } + else + { + this->public.insert_first(&this->public, item); + } + return; + } + 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*, + private_linked_list_t *this, private_enumerator_t *enumerator, + void *item) +{ + void *old = NULL; + + if (enumerator->current) + { + old = enumerator->current->value; + enumerator->current->value = item; + } + return old; +} + +METHOD(linked_list_t, get_last, status_t, + private_linked_list_t *this, void **item) { if (this->count == 0) { @@ -497,10 +340,8 @@ static status_t get_last(private_linked_list_t *this, void **item) return SUCCESS; } -/** - * Implementation of linked_list_t.remove_last. - */ -static status_t remove_last(private_linked_list_t *this, void **item) +METHOD(linked_list_t, remove_last, status_t, + private_linked_list_t *this, void **item) { if (get_last(this, item) == SUCCESS) { @@ -510,11 +351,8 @@ static status_t remove_last(private_linked_list_t *this, void **item) return NOT_FOUND; } -/** - * Implementation of linked_list_t.remove. - */ -static int remove_(private_linked_list_t *this, void *item, - bool (*compare)(void *,void*)) +METHOD(linked_list_t, remove_, int, + private_linked_list_t *this, void *item, bool (*compare)(void*,void*)) { element_t *current = this->first; int removed = 0; @@ -535,10 +373,8 @@ static int remove_(private_linked_list_t *this, void *item, return removed; } -/** - * Implementation of linked_list_t.remove_at. - */ -static void remove_at(private_linked_list_t *this, private_enumerator_t *enumerator) +METHOD(linked_list_t, remove_at, void, + private_linked_list_t *this, private_enumerator_t *enumerator) { element_t *current; @@ -550,11 +386,9 @@ static void remove_at(private_linked_list_t *this, private_enumerator_t *enumera } } -/** - * Implementation of linked_list_t.find_first. - */ -static status_t find_first(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, status_t, + private_linked_list_t *this, linked_list_match_t match, + void **item, void *d1, void *d2, void *d3, void *d4, void *d5) { element_t *current = this->first; @@ -574,11 +408,9 @@ static status_t find_first(private_linked_list_t *this, linked_list_match_t matc return NOT_FOUND; } -/** - * Implementation of linked_list_t.find_last. - */ -static status_t find_last(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_last, status_t, + private_linked_list_t *this, linked_list_match_t match, + void **item, void *d1, void *d2, void *d3, void *d4, void *d5) { element_t *current = this->last; @@ -598,27 +430,24 @@ static status_t find_last(private_linked_list_t *this, linked_list_match_t match return NOT_FOUND; } -/** - * Implementation of linked_list_t.invoke_offset. - */ -static void invoke_offset(private_linked_list_t *this, size_t offset, - void *d1, void *d2, void *d3, void *d4, void *d5) +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) { element_t *current = this->first; + linked_list_invoke_t *method; while (current) { - linked_list_invoke_t *method = current->value + offset; + method = current->value + offset; (*method)(current->value, d1, d2, d3, d4, d5); current = current->next; } } -/** - * Implementation of linked_list_t.invoke_function. - */ -static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn, - void *d1, void *d2, void *d3, void *d4, void *d5) +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) { element_t *current = this->first; @@ -629,14 +458,13 @@ static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn } } -/** - * Implementation of linked_list_t.clone_offset - */ -static linked_list_t *clone_offset(private_linked_list_t *this, size_t offset) +METHOD(linked_list_t, clone_offset, linked_list_t*, + private_linked_list_t *this, size_t offset) { - linked_list_t *clone = linked_list_create(); element_t *current = this->first; + linked_list_t *clone; + clone = linked_list_create(); while (current) { void* (**method)(void*) = current->value + offset; @@ -647,29 +475,26 @@ static linked_list_t *clone_offset(private_linked_list_t *this, size_t offset) return clone; } -/** - * Implementation of linked_list_t.clone_function - */ -static linked_list_t *clone_function(private_linked_list_t *this, void* (*fn)(void*)) +METHOD(linked_list_t, clone_function, linked_list_t*, + private_linked_list_t *this, void* (*fn)(void*)) { - linked_list_t *clone = linked_list_create(); element_t *current = this->first; + linked_list_t *clone; + clone = linked_list_create(); 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) +METHOD(linked_list_t, destroy, void, + private_linked_list_t *this) { void *value; + /* Remove all list items before destroying list */ while (remove_first(this, &value) == SUCCESS) { @@ -679,10 +504,8 @@ static void destroy(private_linked_list_t *this) free(this); } -/** - * Implementation of linked_list_t.destroy_offset. - */ -static void destroy_offset(private_linked_list_t *this, size_t offset) +METHOD(linked_list_t, destroy_offset, void, + private_linked_list_t *this, size_t offset) { element_t *current = this->first, *next; @@ -697,10 +520,8 @@ static void destroy_offset(private_linked_list_t *this, size_t offset) free(this); } -/** - * Implementation of linked_list_t.destroy_function. - */ -static void destroy_function(private_linked_list_t *this, void (*fn)(void*)) +METHOD(linked_list_t, destroy_function, void, + private_linked_list_t *this, void (*fn)(void*)) { element_t *current = this->first, *next; @@ -714,60 +535,40 @@ static void destroy_function(private_linked_list_t *this, void (*fn)(void*)) free(this); } -/** - * Implementation of linked_list_t.create_iterator. - */ -static iterator_t *create_iterator(private_linked_list_t *linked_list, bool forward) -{ - private_iterator_t *this = malloc_thing(private_iterator_t); - - this->public.get_count = (int (*) (iterator_t*)) get_list_count; - this->public.iterate = (bool (*) (iterator_t*, void **value)) iterate; - this->public.insert_before = (void (*) (iterator_t*, void *item)) insert_before; - this->public.insert_after = (void (*) (iterator_t*, void *item)) insert_after; - this->public.replace = (status_t (*) (iterator_t*, void **, void *)) replace; - this->public.remove = (status_t (*) (iterator_t*)) iterator_remove; - this->public.reset = (void (*) (iterator_t*)) iterator_reset; - this->public.destroy = (void (*) (iterator_t*)) iterator_destroy; - - this->forward = forward; - this->current = NULL; - this->list = linked_list; - - return &this->public; -} - /* * Described in header. */ linked_list_t *linked_list_create() { - private_linked_list_t *this = malloc_thing(private_linked_list_t); - - 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_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.find_first = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_first; - this->public.find_last = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_last; - this->public.insert_first = (void (*) (linked_list_t *, void *item))insert_first; - this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last; - this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first; - this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last; - this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove_; - this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at; - this->public.invoke_offset = (void (*)(linked_list_t*,size_t,...))invoke_offset; - this->public.invoke_function = (void (*)(linked_list_t*,linked_list_invoke_t,...))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; - - this->count = 0; - this->first = NULL; - this->last = NULL; + private_linked_list_t *this; + + INIT(this, + .public = { + .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_last = (void*)_find_last, + .insert_first = _insert_first, + .insert_last = _insert_last, + .insert_before = (void*)_insert_before, + .replace = (void*)_replace, + .remove_first = _remove_first, + .remove_last = _remove_last, + .remove = _remove_, + .remove_at = (void*)_remove_at, + .invoke_offset = (void*)_invoke_offset, + .invoke_function = (void*)_invoke_function, + .clone_offset = _clone_offset, + .clone_function = _clone_function, + .destroy = _destroy, + .destroy_offset = _destroy_offset, + .destroy_function = _destroy_function, + }, + ); return &this->public; } |