diff options
author | Yves-Alexis Perez <corsac@corsac.net> | 2017-05-30 20:59:31 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@corsac.net> | 2017-05-30 20:59:31 +0200 |
commit | bba25e2ff6c4a193acb54560ea4417537bd2954e (patch) | |
tree | 9e074fe343f9ab6f5ce1e9c5142d9a6cf180fcda /src/libstrongswan/collections | |
parent | 05ddd767992d68bb38c7f16ece142e8c2e9ae016 (diff) | |
download | vyos-strongswan-bba25e2ff6c4a193acb54560ea4417537bd2954e.tar.gz vyos-strongswan-bba25e2ff6c4a193acb54560ea4417537bd2954e.zip |
New upstream version 5.5.3
Diffstat (limited to 'src/libstrongswan/collections')
-rw-r--r-- | src/libstrongswan/collections/array.c | 9 | ||||
-rw-r--r-- | src/libstrongswan/collections/enumerator.c | 368 | ||||
-rw-r--r-- | src/libstrongswan/collections/enumerator.h | 70 | ||||
-rw-r--r-- | src/libstrongswan/collections/hashtable.c | 10 | ||||
-rw-r--r-- | src/libstrongswan/collections/linked_list.c | 70 | ||||
-rw-r--r-- | src/libstrongswan/collections/linked_list.h | 56 |
6 files changed, 340 insertions, 243 deletions
diff --git a/src/libstrongswan/collections/array.c b/src/libstrongswan/collections/array.c index 69e7df99e..c3dd6e0e9 100644 --- a/src/libstrongswan/collections/array.c +++ b/src/libstrongswan/collections/array.c @@ -214,9 +214,11 @@ typedef struct { } array_enumerator_t; METHOD(enumerator_t, enumerate, bool, - array_enumerator_t *this, void **out) + array_enumerator_t *this, va_list args) { - void *pos; + void *pos, **out; + + VA_ARGS_VGET(args, out); if (this->idx >= this->array->count) { @@ -250,7 +252,8 @@ enumerator_t* array_create_enumerator(array_t *array) INIT(enumerator, .public = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .array = array, diff --git a/src/libstrongswan/collections/enumerator.c b/src/libstrongswan/collections/enumerator.c index fa277e7c8..52c9e1cd5 100644 --- a/src/libstrongswan/collections/enumerator.c +++ b/src/libstrongswan/collections/enumerator.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2013 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * 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 @@ -31,22 +31,43 @@ #include <utils/debug.h> -/** - * Implementation of enumerator_create_empty().enumerate +/* + * Described in header. */ -static bool enumerate_empty(enumerator_t *enumerator, ...) +bool enumerator_enumerate_default(enumerator_t *enumerator, ...) +{ + va_list args; + bool result; + + if (!enumerator->venumerate) + { + DBG1(DBG_LIB, "!!! ENUMERATE DEFAULT: venumerate() missing !!!"); + return FALSE; + } + va_start(args, enumerator); + result = enumerator->venumerate(enumerator, args); + va_end(args); + return result; +} + +METHOD(enumerator_t, enumerate_empty, bool, + enumerator_t *enumerator, va_list args) { return FALSE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_empty() { - enumerator_t *this = malloc_thing(enumerator_t); - this->enumerate = enumerate_empty; - this->destroy = (void*)free; + enumerator_t *this; + + INIT(this, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_empty, + .destroy = (void*)free, + ); return this; } @@ -64,32 +85,31 @@ typedef struct { char *full_end; } dir_enum_t; -/** - * Implementation of enumerator_create_directory().destroy - */ -static void destroy_dir_enum(dir_enum_t *this) +METHOD(enumerator_t, destroy_dir_enum, void, + dir_enum_t *this) { closedir(this->dir); free(this); } -/** - * Implementation of enumerator_create_directory().enumerate - */ -static bool enumerate_dir_enum(dir_enum_t *this, char **relative, - char **absolute, struct stat *st) +METHOD(enumerator_t, enumerate_dir_enum, bool, + dir_enum_t *this, va_list args) { struct dirent *entry = readdir(this->dir); + struct stat *st; size_t remaining; + char **relative, **absolute; int len; + VA_ARGS_VGET(args, relative, absolute, st); + if (!entry) { return FALSE; } if (streq(entry->d_name, ".") || streq(entry->d_name, "..")) { - return enumerate_dir_enum(this, relative, absolute, st); + return this->public.enumerate(&this->public, relative, absolute, st); } if (relative) { @@ -122,15 +142,21 @@ static bool enumerate_dir_enum(dir_enum_t *this, char **relative, return TRUE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_directory(const char *path) { + dir_enum_t *this; int len; - dir_enum_t *this = malloc_thing(dir_enum_t); - this->public.enumerate = (void*)enumerate_dir_enum; - this->public.destroy = (void*)destroy_dir_enum; + + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dir_enum, + .destroy = _destroy_dir_enum, + }, + ); if (*path == '\0') { @@ -152,9 +178,10 @@ enumerator_t* enumerator_create_directory(const char *path) this->full_end = &this->full[len]; this->dir = opendir(path); - if (this->dir == NULL) + if (!this->dir) { - DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, strerror(errno)); + DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, + strerror(errno)); free(this); return NULL; } @@ -177,21 +204,21 @@ typedef struct { char full[PATH_MAX]; } glob_enum_t; -/** - * Implementation of enumerator_create_glob().destroy - */ -static void destroy_glob_enum(glob_enum_t *this) +METHOD(enumerator_t, destroy_glob_enum, void, + glob_enum_t *this) { globfree(&this->glob); free(this); } -/** - * Implementation of enumerator_create_glob().enumerate - */ -static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) +METHOD(enumerator_t, enumerate_glob_enum, bool, + glob_enum_t *this, va_list args) { + struct stat *st; char *match; + char **file; + + VA_ARGS_VGET(args, file, st); if (this->pos >= this->glob.gl_pathc) { @@ -202,20 +229,17 @@ static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) { *file = match; } - if (st) + if (st && stat(match, st)) { - if (stat(match, st)) - { - DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, - strerror(errno)); - return FALSE; - } + DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, + strerror(errno)); + return FALSE; } return TRUE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_glob(const char *pattern) { @@ -229,8 +253,9 @@ enumerator_t* enumerator_create_glob(const char *pattern) INIT(this, .public = { - .enumerate = (void*)enumerate_glob_enum, - .destroy = (void*)destroy_glob_enum, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_glob_enum, + .destroy = _destroy_glob_enum, }, ); @@ -272,24 +297,22 @@ typedef struct { const char *trim; } token_enum_t; -/** - * Implementation of enumerator_create_token().destroy - */ -static void destroy_token_enum(token_enum_t *this) +METHOD(enumerator_t, destroy_token_enum, void, + token_enum_t *this) { free(this->string); free(this); } -/** - * Implementation of enumerator_create_token().enumerate - */ -static bool enumerate_token_enum(token_enum_t *this, char **token) +METHOD(enumerator_t, enumerate_token_enum, bool, + token_enum_t *this, va_list args) { const char *sep, *trim; - char *pos = NULL, *tmp; + char *pos = NULL, *tmp, **token; bool last = FALSE; + VA_ARGS_VGET(args, token); + /* trim leading characters/separators */ while (*this->pos) { @@ -390,52 +413,48 @@ static bool enumerate_token_enum(token_enum_t *this, char **token) return FALSE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_token(const char *string, const char *sep, const char *trim) { - token_enum_t *enumerator = malloc_thing(token_enum_t); + token_enum_t *this; - enumerator->public.enumerate = (void*)enumerate_token_enum; - enumerator->public.destroy = (void*)destroy_token_enum; - enumerator->string = strdup(string); - enumerator->pos = enumerator->string; - enumerator->sep = sep; - enumerator->trim = trim; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_token_enum, + .destroy = _destroy_token_enum, + }, + .string = strdup(string), + .sep = sep, + .trim = trim, + ); + this->pos = this->string; - return &enumerator->public; + return &this->public; } /** - * enumerator for nested enumerations + * Enumerator for nested enumerations */ typedef struct { - /* implements enumerator_t */ enumerator_t public; - /* outer enumerator */ enumerator_t *outer; - /* inner enumerator */ enumerator_t *inner; - /* constructor for inner enumerator */ enumerator_t *(*create_inner)(void *outer, void *data); - /* data to pass to constructor above */ void *data; - /* destructor for data */ - void (*destroy_data)(void *data); + void (*destructor)(void *data); } nested_enumerator_t; -/** - * Implementation of enumerator_create_nested().enumerate() - */ -static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, - void *v3, void *v4, void *v5) +METHOD(enumerator_t, enumerate_nested, bool, + nested_enumerator_t *this, va_list args) { while (TRUE) { - while (this->inner == NULL) + while (!this->inner) { void *outer; @@ -444,8 +463,13 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, return FALSE; } this->inner = this->create_inner(outer, this->data); + if (this->inner && !this->inner->venumerate) + { + DBG1(DBG_LIB, "!!! ENUMERATE NESTED: venumerate() missing !!!"); + return FALSE; + } } - if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5)) + if (this->inner->venumerate(this->inner, args)) { return TRUE; } @@ -454,103 +478,100 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, } } -/** - * Implementation of enumerator_create_nested().destroy() - **/ -static void destroy_nested(nested_enumerator_t *this) +METHOD(enumerator_t, destroy_nested, void, + nested_enumerator_t *this) { - if (this->destroy_data) + if (this->destructor) { - this->destroy_data(this->data); + this->destructor(this->data); } DESTROY_IF(this->inner); this->outer->destroy(this->outer); free(this); } -/** - * See header +/* + * Described in header */ enumerator_t *enumerator_create_nested(enumerator_t *outer, enumerator_t *(inner_constructor)(void *outer, void *data), - void *data, void (*destroy_data)(void *data)) + void *data, void (*destructor)(void *data)) { - nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t); + nested_enumerator_t *this; - enumerator->public.enumerate = (void*)enumerate_nested; - enumerator->public.destroy = (void*)destroy_nested; - enumerator->outer = outer; - enumerator->inner = NULL; - enumerator->create_inner = (void*)inner_constructor; - enumerator->data = data; - enumerator->destroy_data = destroy_data; - - return &enumerator->public; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_nested, + .destroy = _destroy_nested, + }, + .outer = outer, + .create_inner = inner_constructor, + .data = data, + .destructor = destructor, + ); + return &this->public; } /** - * enumerator for filtered enumerator + * Enumerator for filtered enumerator */ typedef struct { enumerator_t public; - enumerator_t *unfiltered; + enumerator_t *orig; void *data; - bool (*filter)(void *data, ...); + bool (*filter)(void*,enumerator_t*,va_list); void (*destructor)(void *data); } filter_enumerator_t; -/** - * Implementation of enumerator_create_filter().destroy - */ -static void destroy_filter(filter_enumerator_t *this) +METHOD(enumerator_t, destroy_filter, void, + filter_enumerator_t *this) { if (this->destructor) { this->destructor(this->data); } - this->unfiltered->destroy(this->unfiltered); + this->orig->destroy(this->orig); free(this); } -/** - * Implementation of enumerator_create_filter().enumerate - */ -static bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2, - void *o3, void *o4, void *o5) +METHOD(enumerator_t, enumerate_filter, bool, + filter_enumerator_t *this, va_list args) { - void *i1, *i2, *i3, *i4, *i5; + bool result = FALSE; - while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5)) + if (this->filter(this->data, this->orig, args)) { - if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5)) - { - return TRUE; - } + result = TRUE; } - return FALSE; + return result; } -/** - * see header +/* + * Described in header */ -enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, - bool (*filter)(void *data, ...), - void *data, void (*destructor)(void *data)) +enumerator_t *enumerator_create_filter(enumerator_t *orig, + bool (*filter)(void *data, enumerator_t *orig, va_list args), + void *data, void (*destructor)(void *data)) { - filter_enumerator_t *this = malloc_thing(filter_enumerator_t); - - this->public.enumerate = (void*)enumerate_filter; - this->public.destroy = (void*)destroy_filter; - this->unfiltered = unfiltered; - this->filter = filter; - this->data = data; - this->destructor = destructor; + filter_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_filter, + .destroy = _destroy_filter, + }, + .orig = orig, + .filter = filter, + .data = data, + .destructor = destructor, + ); return &this->public; } /** - * enumerator for cleaner enumerator + * Enumerator for cleaner enumerator */ typedef struct { enumerator_t public; @@ -559,44 +580,48 @@ typedef struct { void *data; } cleaner_enumerator_t; -/** - * Implementation of enumerator_create_cleanup().destroy - */ -static void destroy_cleaner(cleaner_enumerator_t *this) +METHOD(enumerator_t, destroy_cleaner, void, + cleaner_enumerator_t *this) { this->cleanup(this->data); this->wrapped->destroy(this->wrapped); free(this); } -/** - * Implementation of enumerator_create_cleaner().enumerate - */ -static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2, - void *v3, void *v4, void *v5) +METHOD(enumerator_t, enumerate_cleaner, bool, + cleaner_enumerator_t *this, va_list args) { - return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5); + if (!this->wrapped->venumerate) + { + DBG1(DBG_LIB, "!!! CLEANER ENUMERATOR: venumerate() missing !!!"); + return FALSE; + } + return this->wrapped->venumerate(this->wrapped, args); } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped, void (*cleanup)(void *data), void *data) { - cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t); - - this->public.enumerate = (void*)enumerate_cleaner; - this->public.destroy = (void*)destroy_cleaner; - this->wrapped = wrapped; - this->cleanup = cleanup; - this->data = data; + cleaner_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_cleaner, + .destroy = _destroy_cleaner, + }, + .wrapped = wrapped, + .cleanup = cleanup, + .data = data, + ); return &this->public; } /** - * enumerator for single enumerator + * Enumerator for single enumerator */ typedef struct { enumerator_t public; @@ -605,10 +630,8 @@ typedef struct { bool done; } single_enumerator_t; -/** - * Implementation of enumerator_create_single().destroy - */ -static void destroy_single(single_enumerator_t *this) +METHOD(enumerator_t, destroy_single, void, + single_enumerator_t *this) { if (this->cleanup) { @@ -617,11 +640,12 @@ static void destroy_single(single_enumerator_t *this) free(this); } -/** - * Implementation of enumerator_create_single().enumerate - */ -static bool enumerate_single(single_enumerator_t *this, void **item) +METHOD(enumerator_t, enumerate_single, bool, + single_enumerator_t *this, va_list args) { + void **item; + + VA_ARGS_VGET(args, item); if (this->done) { return FALSE; @@ -631,19 +655,21 @@ static bool enumerate_single(single_enumerator_t *this, void **item) return TRUE; } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)) { - single_enumerator_t *this = malloc_thing(single_enumerator_t); - - this->public.enumerate = (void*)enumerate_single; - this->public.destroy = (void*)destroy_single; - this->item = item; - this->cleanup = cleanup; - this->done = FALSE; + single_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_single, + .destroy = _destroy_single, + }, + .item = item, + .cleanup = cleanup, + ); return &this->public; } - diff --git a/src/libstrongswan/collections/enumerator.h b/src/libstrongswan/collections/enumerator.h index 55f8d83e6..99f8847e4 100644 --- a/src/libstrongswan/collections/enumerator.h +++ b/src/libstrongswan/collections/enumerator.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * 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 @@ -34,8 +34,11 @@ struct enumerator_t { /** * Enumerate collection. * - * The enumerate function takes a variable argument list containing - * pointers where the enumerated values get written. + * The enumerate() method takes a variable number of pointer arguments + * where the enumerated values get written to. + * + * @note Just assigning the generic enumerator_enumerate_default() function + * that calls the enumerator's venumerate() method is usually enough. * * @param ... variable list of enumerated items, implementation dependent * @return TRUE if pointers returned @@ -43,12 +46,34 @@ struct enumerator_t { bool (*enumerate)(enumerator_t *this, ...); /** - * Destroy a enumerator instance. + * Enumerate collection. + * + * The venumerate() method takes a variable argument list containing + * pointers where the enumerated values get written to. + * + * To simplify the implementation the VA_ARGS_VGET() macro may be used. + * + * @param args variable list of enumerated items, implementation dependent + * @return TRUE if pointers returned + */ + bool (*venumerate)(enumerator_t *this, va_list args); + + /** + * Destroy an enumerator_t instance. */ void (*destroy)(enumerator_t *this); }; /** + * Generic implementation of enumerator_t::enumerate() that simply calls + * the enumerator's venumerate() method. + * + * @param enumerator the enumerator + * @param ... arguments passed to enumerate() + */ +bool enumerator_enumerate_default(enumerator_t *enumerator, ...); + +/** * Create an enumerator which enumerates over nothing * * @return an enumerator over no values @@ -147,38 +172,41 @@ enumerator_t* enumerator_create_token(const char *string, const char *sep, /** * Creates an enumerator which enumerates over enumerated enumerators :-). * - * The variable argument list of enumeration values is limit to 5. + * The outer enumerator is expected to return objects that, when passed to + * inner_contructor, will create a new enumerator that will be enumerated until + * completion (to this enumerator will the pointer arguments that are passed to + * this enumerator be forwarded) at which point a new element from the outer + * enumerator is requested to create a new inner enumerator. * * @param outer outer enumerator - * @param inner_constructor constructor to inner enumerator + * @param inner_constructor constructor to create inner enumerator * @param data data to pass to each inner_constructor call - * @param destroy_data destructor to pass to data + * @param destructor destructor function to clean up data after use * @return the nested enumerator */ enumerator_t *enumerator_create_nested(enumerator_t *outer, enumerator_t *(*inner_constructor)(void *outer, void *data), - void *data, void (*destroy_data)(void *data)); + void *data, void (*destructor)(void *data)); /** - * Creates an enumerator which filters output of another enumerator. + * Creates an enumerator which filters/maps output of another enumerator. * - * The filter function receives the user supplied "data" followed by a - * unfiltered enumeration item, followed by an output pointer where to write - * the filtered data. Then the next input/output pair follows. - * It returns TRUE to deliver the - * values to the caller of enumerate(), FALSE to filter this enumeration. + * The filter function receives the user supplied "data" followed by the + * original enumerator, followed by the arguments passed to the outer + * enumerator. It returns TRUE to deliver the values assigned to these + * arguments to the caller of enumerate() and FALSE to end the enumeration. + * Filtering items is simple as the filter function may just skip enumerated + * items from the original enumerator. * - * The variable argument list of enumeration values is limit to 5. - * - * @param unfiltered unfiltered enumerator to wrap, gets destroyed + * @param orig original enumerator to wrap, gets destroyed * @param filter filter function * @param data user data to supply to filter * @param destructor destructor function to clean up data after use * @return the filtered enumerator */ -enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, - bool (*filter)(void *data, ...), - void *data, void (*destructor)(void *data)); +enumerator_t *enumerator_create_filter(enumerator_t *orig, + bool (*filter)(void *data, enumerator_t *orig, va_list args), + void *data, void (*destructor)(void *data)); /** * Create an enumerator wrapper which does a cleanup on destroy. diff --git a/src/libstrongswan/collections/hashtable.c b/src/libstrongswan/collections/hashtable.c index 2b77a37cc..b0eda9e6a 100644 --- a/src/libstrongswan/collections/hashtable.c +++ b/src/libstrongswan/collections/hashtable.c @@ -379,8 +379,13 @@ METHOD(hashtable_t, get_count, u_int, } METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, const void **key, void **value) + private_enumerator_t *this, va_list args) { + const void **key; + void **value; + + VA_ARGS_VGET(args, key, value); + while (this->count && this->row < this->table->capacity) { this->prev = this->current; @@ -417,7 +422,8 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*, INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .table = this, diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index b8fe81578..f877be5a6 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -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. */ @@ -119,8 +130,12 @@ struct private_enumerator_t { }; METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, void **item) + private_enumerator_t *this, va_list args) { + void **item; + + VA_ARGS_VGET(args, item); + if (this->finished) { return FALSE; @@ -152,7 +167,8 @@ METHOD(linked_list_t, create_enumerator, enumerator_t*, INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .list = this, @@ -366,52 +382,68 @@ METHOD(linked_list_t, remove_at, void, } } -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; } } @@ -542,7 +574,7 @@ linked_list_t *linked_list_create() .reset_enumerator = (void*)_reset_enumerator, .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, @@ -550,8 +582,8 @@ 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, .equals_offset = _equals_offset, .equals_function = _equals_function, diff --git a/src/libstrongswan/collections/linked_list.h b/src/libstrongswan/collections/linked_list.h index 0b73079d3..246b9a5c5 100644 --- a/src/libstrongswan/collections/linked_list.h +++ b/src/libstrongswan/collections/linked_list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2015 Tobias Brunner + * Copyright (C) 2007-2017 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -28,23 +28,30 @@ typedef struct linked_list_t linked_list_t; #include <collections/enumerator.h> /** - * Method to match elements in a linked list (used in find_* functions) + * Function to match elements in a linked list * * @param item current list item - * @param ... user supplied data (only pointers, at most 5) + * @param args user supplied data + * @return TRUE, if the item matched, FALSE otherwise + */ +typedef bool (*linked_list_match_t)(void *item, va_list args); + +/** + * Helper function to match a string in a linked list of strings + * + * @param item list item (char*) + * @param args user supplied data (char*) * @return - * - TRUE, if the item matched - * - FALSE, otherwise */ -typedef bool (*linked_list_match_t)(void *item, ...); +bool linked_list_match_str(void *item, va_list args); /** - * Method to be invoked on elements in a linked list (used in invoke_* functions) + * Function to be invoked on elements in a linked list * * @param item current list item - * @param ... user supplied data (only pointers, at most 5) + * @param args user supplied data */ -typedef void (*linked_list_invoke_t)(void *item, ...); +typedef void (*linked_list_invoke_t)(void *item, va_list args); /** * Class implementing a double linked list. @@ -167,21 +174,20 @@ struct linked_list_t { * * The first object passed to the match function is the current list item, * followed by the user supplied data. - * If the supplied function returns TRUE this function returns SUCCESS, and - * the current object is returned in the third parameter, otherwise, + * If the supplied function returns TRUE so does this function, and the + * current object is returned in the third parameter (if given), otherwise, * the next item is checked. * * If match is NULL, *item and the current object are compared. * - * @warning Only use pointers as user supplied data. - * * @param match comparison function to call on each object, or NULL - * @param item the list item, if found - * @param ... user data to supply to match function (limited to 5 arguments) - * @return SUCCESS if found, NOT_FOUND otherwise + * @param item the list item, if found, or NULL + * @param ... user data to supply to match function + * @return TRUE if found, FALSE otherwise (or if neither match, + * nor item is supplied) */ - status_t (*find_first) (linked_list_t *this, linked_list_match_t match, - void **item, ...); + bool (*find_first)(linked_list_t *this, linked_list_match_t match, + void **item, ...); /** * Invoke a method on all of the contained objects. @@ -192,22 +198,18 @@ struct linked_list_t { * which can be evalutated at compile time using the offsetof * macro, e.g.: list->invoke(list, offsetof(object_t, method)); * - * @warning Only use pointers as user supplied data. - * * @param offset offset of the method to invoke on objects - * @param ... user data to supply to called function (limited to 5 arguments) */ - void (*invoke_offset) (linked_list_t *this, size_t offset, ...); + void (*invoke_offset)(linked_list_t *this, size_t offset); /** * Invoke a function on all of the contained objects. * - * @warning Only use pointers as user supplied data. - * - * @param function offset of the method to invoke on objects - * @param ... user data to supply to called function (limited to 5 arguments) + * @param function function to call for each object + * @param ... user data to supply to called function */ - void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...); + void (*invoke_function)(linked_list_t *this, linked_list_invoke_t function, + ...); /** * Clones a list and its objects using the objects' clone method. |