summaryrefslogtreecommitdiff
path: root/src/libstrongswan/collections
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2017-05-30 20:59:31 +0200
committerYves-Alexis Perez <corsac@corsac.net>2017-05-30 20:59:31 +0200
commitbba25e2ff6c4a193acb54560ea4417537bd2954e (patch)
tree9e074fe343f9ab6f5ce1e9c5142d9a6cf180fcda /src/libstrongswan/collections
parent05ddd767992d68bb38c7f16ece142e8c2e9ae016 (diff)
downloadvyos-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.c9
-rw-r--r--src/libstrongswan/collections/enumerator.c368
-rw-r--r--src/libstrongswan/collections/enumerator.h70
-rw-r--r--src/libstrongswan/collections/hashtable.c10
-rw-r--r--src/libstrongswan/collections/linked_list.c70
-rw-r--r--src/libstrongswan/collections/linked_list.h56
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.