Change interface for enumerator_create_filter() callback
This avoids the unportable 5 pointer hack, but requires enumerating in the callback.
This commit is contained in:
@@ -518,9 +518,9 @@ enumerator_t *enumerator_create_nested(enumerator_t *outer,
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -531,35 +531,28 @@ METHOD(enumerator_t, destroy_filter, void,
|
||||
{
|
||||
this->destructor(this->data);
|
||||
}
|
||||
this->unfiltered->destroy(this->unfiltered);
|
||||
this->orig->destroy(this->orig);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(enumerator_t, enumerate_filter, bool,
|
||||
filter_enumerator_t *this, va_list args)
|
||||
{
|
||||
void *i1, *i2, *i3, *i4, *i5;
|
||||
void *o1, *o2, *o3, *o4, *o5;
|
||||
bool result = FALSE;
|
||||
|
||||
/* FIXME: what happens if there are less than five arguments is not defined */
|
||||
VA_ARGS_VGET(args, o1, o2, o3, o4, o5);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@@ -569,7 +562,7 @@ enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
|
||||
.venumerate = _enumerate_filter,
|
||||
.destroy = _destroy_filter,
|
||||
},
|
||||
.unfiltered = unfiltered,
|
||||
.orig = orig,
|
||||
.filter = filter,
|
||||
.data = data,
|
||||
.destructor = destructor,
|
||||
|
||||
@@ -189,25 +189,24 @@ enumerator_t *enumerator_create_nested(enumerator_t *outer,
|
||||
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.
|
||||
|
||||
@@ -163,17 +163,23 @@ METHOD(credential_factory_t, create, void*,
|
||||
return construct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function for builder enumerator
|
||||
*/
|
||||
static bool builder_filter(void *null, entry_t **entry, credential_type_t *type,
|
||||
void *dummy1, int *subtype)
|
||||
CALLBACK(builder_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if ((*entry)->final)
|
||||
entry_t *entry;
|
||||
credential_type_t *type;
|
||||
int *subtype;
|
||||
|
||||
VA_ARGS_VGET(args, type, subtype);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*type = (*entry)->type;
|
||||
*subtype = (*entry)->subtype;
|
||||
return TRUE;
|
||||
if (entry->final)
|
||||
{
|
||||
*type = entry->type;
|
||||
*subtype = entry->subtype;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -184,7 +190,7 @@ METHOD(credential_factory_t, create_builder_enumerator, enumerator_t*,
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->constructors->create_enumerator(this->constructors),
|
||||
(void*)builder_filter, this->lock, (void*)this->lock->unlock);
|
||||
builder_filter, this->lock, (void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
METHOD(credential_factory_t, destroy, void,
|
||||
|
||||
@@ -74,25 +74,27 @@ typedef struct {
|
||||
identification_t *id;
|
||||
} cert_data_t;
|
||||
|
||||
/**
|
||||
* destroy cert_data
|
||||
*/
|
||||
static void cert_data_destroy(cert_data_t *data)
|
||||
CALLBACK(cert_data_destroy, void,
|
||||
cert_data_t *data)
|
||||
{
|
||||
data->lock->unlock(data->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter function for certs enumerator
|
||||
*/
|
||||
static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **out)
|
||||
CALLBACK(certs_filter, bool,
|
||||
cert_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
public_key_t *public;
|
||||
certificate_t *cert = *in;
|
||||
certificate_t *cert, **out;
|
||||
|
||||
if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &cert))
|
||||
{
|
||||
if (data->cert != CERT_ANY && data->cert != cert->get_type(cert))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
public = cert->get_public_key(cert);
|
||||
if (public)
|
||||
{
|
||||
@@ -102,7 +104,7 @@ static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **
|
||||
data->id->get_encoding(data->id)))
|
||||
{
|
||||
public->destroy(public);
|
||||
*out = *in;
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -110,11 +112,11 @@ static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **
|
||||
}
|
||||
else if (data->key != KEY_ANY)
|
||||
{
|
||||
return FALSE;
|
||||
continue;
|
||||
}
|
||||
if (data->id == NULL || cert->has_subject(cert, data->id))
|
||||
if (!data->id || cert->has_subject(cert, data->id))
|
||||
{
|
||||
*out = *in;
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -143,8 +145,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
||||
{
|
||||
enumerator = this->untrusted->create_enumerator(this->untrusted);
|
||||
}
|
||||
return enumerator_create_filter(enumerator, (void*)certs_filter, data,
|
||||
(void*)cert_data_destroy);
|
||||
return enumerator_create_filter(enumerator, certs_filter, data,
|
||||
cert_data_destroy);
|
||||
}
|
||||
|
||||
static bool certificate_equals(certificate_t *item, certificate_t *cert)
|
||||
@@ -301,30 +303,30 @@ typedef struct {
|
||||
identification_t *id;
|
||||
} key_data_t;
|
||||
|
||||
/**
|
||||
* Destroy key enumerator data
|
||||
*/
|
||||
static void key_data_destroy(key_data_t *data)
|
||||
CALLBACK(key_data_destroy, void,
|
||||
key_data_t *data)
|
||||
{
|
||||
data->lock->unlock(data->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter function for private key enumerator
|
||||
*/
|
||||
static bool key_filter(key_data_t *data, private_key_t **in, private_key_t **out)
|
||||
CALLBACK(key_filter, bool,
|
||||
key_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
private_key_t *key;
|
||||
private_key_t *key, **out;
|
||||
|
||||
key = *in;
|
||||
if (data->type == KEY_ANY || data->type == key->get_type(key))
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &key))
|
||||
{
|
||||
if (data->id == NULL ||
|
||||
key->has_fingerprint(key, data->id->get_encoding(data->id)))
|
||||
if (data->type == KEY_ANY || data->type == key->get_type(key))
|
||||
{
|
||||
*out = key;
|
||||
return TRUE;
|
||||
if (data->id == NULL ||
|
||||
key->has_fingerprint(key, data->id->get_encoding(data->id)))
|
||||
{
|
||||
*out = key;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
@@ -342,7 +344,7 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
|
||||
);
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->keys->create_enumerator(this->keys),
|
||||
(void*)key_filter, data, (void*)key_data_destroy);
|
||||
key_filter, data, key_data_destroy);
|
||||
}
|
||||
|
||||
METHOD(mem_cred_t, add_key, void,
|
||||
@@ -468,10 +470,8 @@ typedef struct {
|
||||
shared_key_type_t type;
|
||||
} shared_data_t;
|
||||
|
||||
/**
|
||||
* free shared key enumerator data and unlock list
|
||||
*/
|
||||
static void shared_data_destroy(shared_data_t *data)
|
||||
CALLBACK(shared_data_destroy, void,
|
||||
shared_data_t *data)
|
||||
{
|
||||
data->lock->unlock(data->lock);
|
||||
free(data);
|
||||
@@ -499,44 +499,47 @@ static id_match_t has_owner(shared_entry_t *entry, identification_t *owner)
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator filter function for shared entries
|
||||
*/
|
||||
static bool shared_filter(shared_data_t *data,
|
||||
shared_entry_t **in, shared_key_t **out,
|
||||
void **unused1, id_match_t *me,
|
||||
void **unused2, id_match_t *other)
|
||||
CALLBACK(shared_filter, bool,
|
||||
shared_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
id_match_t my_match = ID_MATCH_NONE, other_match = ID_MATCH_NONE;
|
||||
shared_entry_t *entry = *in;
|
||||
shared_entry_t *entry;
|
||||
shared_key_t **out;
|
||||
id_match_t *me, *other;
|
||||
|
||||
if (data->type != SHARED_ANY &&
|
||||
entry->shared->get_type(entry->shared) != data->type)
|
||||
VA_ARGS_VGET(args, out, me, other);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
return FALSE;
|
||||
if (data->type != SHARED_ANY &&
|
||||
entry->shared->get_type(entry->shared) != data->type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (data->me)
|
||||
{
|
||||
my_match = has_owner(entry, data->me);
|
||||
}
|
||||
if (data->other)
|
||||
{
|
||||
other_match = has_owner(entry, data->other);
|
||||
}
|
||||
if ((data->me || data->other) && (!my_match && !other_match))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*out = entry->shared;
|
||||
if (me)
|
||||
{
|
||||
*me = my_match;
|
||||
}
|
||||
if (other)
|
||||
{
|
||||
*other = other_match;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (data->me)
|
||||
{
|
||||
my_match = has_owner(entry, data->me);
|
||||
}
|
||||
if (data->other)
|
||||
{
|
||||
other_match = has_owner(entry, data->other);
|
||||
}
|
||||
if ((data->me || data->other) && (!my_match && !other_match))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*out = entry->shared;
|
||||
if (me)
|
||||
{
|
||||
*me = my_match;
|
||||
}
|
||||
if (other)
|
||||
{
|
||||
*other = other_match;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
||||
@@ -554,7 +557,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
||||
data->lock->read_lock(data->lock);
|
||||
return enumerator_create_filter(
|
||||
this->shared->create_enumerator(this->shared),
|
||||
(void*)shared_filter, data, (void*)shared_data_destroy);
|
||||
shared_filter, data, shared_data_destroy);
|
||||
}
|
||||
|
||||
METHOD(mem_cred_t, add_shared_unique, void,
|
||||
@@ -648,23 +651,27 @@ METHOD(mem_cred_t, remove_shared_unique, void,
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter unique ids of shared keys (ingore secrets without unique id)
|
||||
*/
|
||||
static bool unique_filter(void *unused,
|
||||
shared_entry_t **in, char **id)
|
||||
CALLBACK(unique_filter, bool,
|
||||
void *unused, enumerator_t *orig, va_list args)
|
||||
{
|
||||
shared_entry_t *entry = *in;
|
||||
shared_entry_t *entry;
|
||||
char **id;
|
||||
|
||||
if (!entry->id)
|
||||
VA_ARGS_VGET(args, id);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
return FALSE;
|
||||
if (!entry->id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (id)
|
||||
{
|
||||
*id = entry->id;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (id)
|
||||
{
|
||||
*id = entry->id;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*,
|
||||
@@ -673,7 +680,7 @@ METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*,
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->shared->create_enumerator(this->shared),
|
||||
(void*)unique_filter, this->lock,
|
||||
unique_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
@@ -721,30 +728,35 @@ typedef struct {
|
||||
rwlock_t *lock;
|
||||
} cdp_data_t;
|
||||
|
||||
/**
|
||||
* Clean up CDP enumerator data
|
||||
*/
|
||||
static void cdp_data_destroy(cdp_data_t *data)
|
||||
CALLBACK(cdp_data_destroy, void,
|
||||
cdp_data_t *data)
|
||||
{
|
||||
data->lock->unlock(data->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* CDP enumerator filter
|
||||
*/
|
||||
static bool cdp_filter(cdp_data_t *data, cdp_t **cdp, char **uri)
|
||||
CALLBACK(cdp_filter, bool,
|
||||
cdp_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (data->type != CERT_ANY && data->type != (*cdp)->type)
|
||||
cdp_t *cdp;
|
||||
char **uri;
|
||||
|
||||
VA_ARGS_VGET(args, uri);
|
||||
|
||||
while (orig->enumerate(orig, &cdp))
|
||||
{
|
||||
return FALSE;
|
||||
if (data->type != CERT_ANY && data->type != cdp->type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (data->id && !cdp->id->matches(cdp->id, data->id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*uri = cdp->uri;
|
||||
return TRUE;
|
||||
}
|
||||
if (data->id && !(*cdp)->id->matches((*cdp)->id, data->id))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*uri = (*cdp)->uri;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
|
||||
@@ -759,7 +771,7 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
|
||||
);
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->cdps->create_enumerator(this->cdps),
|
||||
(void*)cdp_filter, data, (void*)cdp_data_destroy);
|
||||
cdp_filter, data, cdp_data_destroy);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -819,43 +819,57 @@ static bool entry_match(entry_t *a, entry_t *b)
|
||||
return a->algo == b->algo;
|
||||
}
|
||||
|
||||
/**
|
||||
* check for uniqueness of an entry
|
||||
*/
|
||||
static bool unique_check(linked_list_t *list, entry_t **in, entry_t **out)
|
||||
CALLBACK(unique_check, bool,
|
||||
linked_list_t *list, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (list->find_first(list, (void*)entry_match, NULL, *in) == SUCCESS)
|
||||
entry_t *entry, **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &entry))
|
||||
{
|
||||
return FALSE;
|
||||
if (list->find_first(list, (void*)entry_match, NULL, entry) == SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*out = entry;
|
||||
list->insert_last(list, entry);
|
||||
return TRUE;
|
||||
}
|
||||
*out = *in;
|
||||
list->insert_last(list, *in);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* create an enumerator over entry->algo in list with locking and unique check
|
||||
*/
|
||||
static enumerator_t *create_enumerator(private_crypto_factory_t *this,
|
||||
linked_list_t *list, void *filter)
|
||||
linked_list_t *list,
|
||||
bool (*filter)(void*,enumerator_t*,va_list))
|
||||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
enumerator_create_filter(
|
||||
list->create_enumerator(list), (void*)unique_check,
|
||||
list->create_enumerator(list), unique_check,
|
||||
linked_list_create(), (void*)list->destroy),
|
||||
filter, this->lock, (void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate algorithm, not entry
|
||||
*/
|
||||
static bool crypter_filter(void *n, entry_t **entry, encryption_algorithm_t *algo,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(crypter_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*algo = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
encryption_algorithm_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*,
|
||||
@@ -870,15 +884,22 @@ METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->aeads, crypter_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate algorithm, not entry
|
||||
*/
|
||||
static bool signer_filter(void *n, entry_t **entry, integrity_algorithm_t *algo,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(signer_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*algo = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
integrity_algorithm_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*,
|
||||
@@ -887,15 +908,22 @@ METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->signers, signer_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate algorithm, not entry
|
||||
*/
|
||||
static bool hasher_filter(void *n, entry_t **entry, hash_algorithm_t *algo,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(hasher_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*algo = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
hash_algorithm_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*,
|
||||
@@ -904,15 +932,22 @@ METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->hashers, hasher_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate algorithm, not entry
|
||||
*/
|
||||
static bool prf_filter(void *n, entry_t **entry, pseudo_random_function_t *algo,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(prf_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*algo = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
pseudo_random_function_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
|
||||
@@ -921,15 +956,22 @@ METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->prfs, prf_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate algorithm, not entry
|
||||
*/
|
||||
static bool xof_filter(void *n, entry_t **entry, ext_out_function_t *algo,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(xof_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*algo = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
ext_out_function_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
|
||||
@@ -938,15 +980,22 @@ METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->xofs, xof_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate group, not entry
|
||||
*/
|
||||
static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(dh_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*group = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
diffie_hellman_group_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*,
|
||||
@@ -955,15 +1004,22 @@ METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->dhs, dh_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate strength, not entry
|
||||
*/
|
||||
static bool rng_filter(void *n, entry_t **entry, rng_quality_t *quality,
|
||||
void *i2, const char **plugin_name)
|
||||
CALLBACK(rng_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*quality = (*entry)->algo;
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
rng_quality_t *algo;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, algo, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*algo = entry->algo;
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*,
|
||||
@@ -972,13 +1028,20 @@ METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*,
|
||||
return create_enumerator(this, this->rngs, rng_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to enumerate plugin name, not entry
|
||||
*/
|
||||
static bool nonce_gen_filter(void *n, entry_t **entry, const char **plugin_name)
|
||||
CALLBACK(nonce_gen_filter, bool,
|
||||
void *n, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*plugin_name = (*entry)->plugin_name;
|
||||
return TRUE;
|
||||
entry_t *entry;
|
||||
const char **plugin_name;
|
||||
|
||||
VA_ARGS_VGET(args, plugin_name);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
*plugin_name = entry->plugin_name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crypto_factory_t, create_nonce_gen_enumerator, enumerator_t*,
|
||||
|
||||
@@ -71,17 +71,26 @@ METHOD(hash_algorithm_set_t, count, int,
|
||||
return array_count(this->algorithms);
|
||||
}
|
||||
|
||||
static bool hash_filter(void *data, void **in, hash_algorithm_t *out)
|
||||
CALLBACK(hash_filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = **(hash_algorithm_t**)in;
|
||||
return TRUE;
|
||||
hash_algorithm_t *algo, *out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
if (orig->enumerate(orig, &algo))
|
||||
{
|
||||
*out = *algo;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*,
|
||||
private_hash_algorithm_set_t *this)
|
||||
{
|
||||
return enumerator_create_filter(array_create_enumerator(this->algorithms),
|
||||
(void*)hash_filter, NULL, NULL);
|
||||
hash_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(hash_algorithm_set_t, destroy, void,
|
||||
|
||||
@@ -153,30 +153,32 @@ static bool load_certificates(private_pkcs11_creds_t *this)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* filter function for certs enumerator
|
||||
*/
|
||||
static bool certs_filter(identification_t *id,
|
||||
certificate_t **in, certificate_t **out)
|
||||
CALLBACK(certs_filter, bool,
|
||||
identification_t *id, enumerator_t *orig, va_list args)
|
||||
{
|
||||
public_key_t *public;
|
||||
certificate_t *cert = *in;
|
||||
certificate_t *cert, **out;
|
||||
|
||||
if (id == NULL || cert->has_subject(cert, id))
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &cert))
|
||||
{
|
||||
*out = *in;
|
||||
return TRUE;
|
||||
}
|
||||
public = cert->get_public_key(cert);
|
||||
if (public)
|
||||
{
|
||||
if (public->has_fingerprint(public, id->get_encoding(id)))
|
||||
if (id == NULL || cert->has_subject(cert, id))
|
||||
{
|
||||
public->destroy(public);
|
||||
*out = *in;
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
public->destroy(public);
|
||||
public = cert->get_public_key(cert);
|
||||
if (public)
|
||||
{
|
||||
if (public->has_fingerprint(public, id->get_encoding(id)))
|
||||
{
|
||||
public->destroy(public);
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
public->destroy(public);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -199,7 +201,7 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
||||
{
|
||||
inner = this->untrusted->create_enumerator(this->untrusted);
|
||||
}
|
||||
return enumerator_create_filter(inner, (void*)certs_filter, id, NULL);
|
||||
return enumerator_create_filter(inner, certs_filter, id, NULL);
|
||||
}
|
||||
|
||||
METHOD(pkcs11_creds_t, get_library, pkcs11_library_t*,
|
||||
|
||||
@@ -465,34 +465,48 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert enumerated provided_feature_t to plugin_feature_t
|
||||
*/
|
||||
static bool feature_filter(void *null, provided_feature_t **provided,
|
||||
plugin_feature_t **feature)
|
||||
CALLBACK(feature_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*feature = (*provided)->feature;
|
||||
return (*provided)->loaded;
|
||||
provided_feature_t *provided;
|
||||
plugin_feature_t **feature;
|
||||
|
||||
VA_ARGS_VGET(args, feature);
|
||||
|
||||
while (orig->enumerate(orig, &provided))
|
||||
{
|
||||
if (provided->loaded)
|
||||
{
|
||||
*feature = provided->feature;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert enumerated entries to plugin_t
|
||||
*/
|
||||
static bool plugin_filter(void *null, plugin_entry_t **entry, plugin_t **plugin,
|
||||
void *in, linked_list_t **list)
|
||||
CALLBACK(plugin_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
plugin_entry_t *this = *entry;
|
||||
plugin_entry_t *entry;
|
||||
linked_list_t **list;
|
||||
plugin_t **plugin;
|
||||
|
||||
*plugin = this->plugin;
|
||||
if (list)
|
||||
VA_ARGS_VGET(args, plugin, list);
|
||||
|
||||
if (orig->enumerate(orig, &entry))
|
||||
{
|
||||
enumerator_t *features;
|
||||
features = enumerator_create_filter(
|
||||
this->features->create_enumerator(this->features),
|
||||
(void*)feature_filter, NULL, NULL);
|
||||
*list = linked_list_create_from_enumerator(features);
|
||||
*plugin = entry->plugin;
|
||||
if (list)
|
||||
{
|
||||
enumerator_t *features;
|
||||
features = enumerator_create_filter(
|
||||
entry->features->create_enumerator(entry->features),
|
||||
feature_filter, NULL, NULL);
|
||||
*list = linked_list_create_from_enumerator(features);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*,
|
||||
@@ -500,7 +514,7 @@ METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*,
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
this->plugins->create_enumerator(this->plugins),
|
||||
(void*)plugin_filter, NULL, NULL);
|
||||
plugin_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(plugin_loader_t, has_feature, bool,
|
||||
@@ -1095,14 +1109,20 @@ static int plugin_priority_cmp(const plugin_priority_t *a,
|
||||
return diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert enumerated plugin_priority_t to a plugin name
|
||||
*/
|
||||
static bool plugin_priority_filter(void *null, plugin_priority_t **prio,
|
||||
char **name)
|
||||
CALLBACK(plugin_priority_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*name = (*prio)->name;
|
||||
return TRUE;
|
||||
plugin_priority_t *prio;
|
||||
char **name;
|
||||
|
||||
VA_ARGS_VGET(args, name);
|
||||
|
||||
if (orig->enumerate(orig, &prio))
|
||||
{
|
||||
*name = prio->name;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,7 +1162,7 @@ static char *modular_pluginlist(char *list)
|
||||
else
|
||||
{
|
||||
enumerator = enumerator_create_filter(array_create_enumerator(given),
|
||||
(void*)plugin_priority_filter, NULL, NULL);
|
||||
plugin_priority_filter, NULL, NULL);
|
||||
load_def = TRUE;
|
||||
}
|
||||
while (enumerator->enumerate(enumerator, &plugin))
|
||||
|
||||
@@ -804,20 +804,27 @@ METHOD(ac_t, get_authKeyIdentifier, chunk_t,
|
||||
return this->authKeyIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function for attribute enumeration
|
||||
*/
|
||||
static bool attr_filter(void *null, group_t **in, ac_group_type_t *type,
|
||||
void *in2, chunk_t *out)
|
||||
CALLBACK(attr_filter, bool,
|
||||
void *null, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if ((*in)->type == AC_GROUP_TYPE_STRING &&
|
||||
!chunk_printable((*in)->value, NULL, 0))
|
||||
{ /* skip non-printable strings */
|
||||
return FALSE;
|
||||
group_t *group;
|
||||
ac_group_type_t *type;
|
||||
chunk_t *out;
|
||||
|
||||
VA_ARGS_VGET(args, type, out);
|
||||
|
||||
while (orig->enumerate(orig, &group))
|
||||
{
|
||||
if (group->type == AC_GROUP_TYPE_STRING &&
|
||||
!chunk_printable(group->value, NULL, 0))
|
||||
{ /* skip non-printable strings */
|
||||
continue;
|
||||
}
|
||||
*type = group->type;
|
||||
*out = group->value;
|
||||
return TRUE;
|
||||
}
|
||||
*type = (*in)->type;
|
||||
*out = (*in)->value;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ac_t, create_group_enumerator, enumerator_t*,
|
||||
@@ -825,7 +832,7 @@ METHOD(ac_t, create_group_enumerator, enumerator_t*,
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
this->groups->create_enumerator(this->groups),
|
||||
(void*)attr_filter, NULL, NULL);
|
||||
attr_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(certificate_t, get_type, certificate_type_t,
|
||||
|
||||
@@ -364,25 +364,33 @@ end:
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator filter callback for create_enumerator
|
||||
*/
|
||||
static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2,
|
||||
time_t *date, void *p3, crl_reason_t *reason)
|
||||
CALLBACK(filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (serial)
|
||||
revoked_t *revoked;
|
||||
crl_reason_t *reason;
|
||||
chunk_t *serial;
|
||||
time_t *date;
|
||||
|
||||
VA_ARGS_VGET(args, serial, date, reason);
|
||||
|
||||
if (orig->enumerate(orig, &revoked))
|
||||
{
|
||||
*serial = (*revoked)->serial;
|
||||
if (serial)
|
||||
{
|
||||
*serial = revoked->serial;
|
||||
}
|
||||
if (date)
|
||||
{
|
||||
*date = revoked->date;
|
||||
}
|
||||
if (reason)
|
||||
{
|
||||
*reason = revoked->reason;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (date)
|
||||
{
|
||||
*date = (*revoked)->date;
|
||||
}
|
||||
if (reason)
|
||||
{
|
||||
*reason = (*revoked)->reason;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(crl_t, get_serial, chunk_t,
|
||||
@@ -422,7 +430,7 @@ METHOD(crl_t, create_enumerator, enumerator_t*,
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
this->revoked->create_enumerator(this->revoked),
|
||||
(void*)filter, NULL, NULL);
|
||||
filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(certificate_t, get_type, certificate_type_t,
|
||||
|
||||
@@ -228,32 +228,38 @@ METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*,
|
||||
return this->certs->create_enumerator(this->certs);
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerator filter callback for create_response_enumerator
|
||||
*/
|
||||
static bool filter(void *data, single_response_t **response,
|
||||
chunk_t *serialNumber,
|
||||
void *p2, cert_validation_t *status,
|
||||
void *p3, time_t *revocationTime,
|
||||
void *p4, crl_reason_t *revocationReason)
|
||||
CALLBACK(filter, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
if (serialNumber)
|
||||
single_response_t *response;
|
||||
cert_validation_t *status;
|
||||
crl_reason_t *revocationReason;
|
||||
chunk_t *serialNumber;
|
||||
time_t *revocationTime;
|
||||
|
||||
VA_ARGS_VGET(args, serialNumber, status, revocationTime, revocationReason);
|
||||
|
||||
if (orig->enumerate(orig, &response))
|
||||
{
|
||||
*serialNumber = (*response)->serialNumber;
|
||||
if (serialNumber)
|
||||
{
|
||||
*serialNumber = response->serialNumber;
|
||||
}
|
||||
if (status)
|
||||
{
|
||||
*status = response->status;
|
||||
}
|
||||
if (revocationTime)
|
||||
{
|
||||
*revocationTime = response->revocationTime;
|
||||
}
|
||||
if (revocationReason)
|
||||
{
|
||||
*revocationReason = response->revocationReason;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (status)
|
||||
{
|
||||
*status = (*response)->status;
|
||||
}
|
||||
if (revocationTime)
|
||||
{
|
||||
*revocationTime = (*response)->revocationTime;
|
||||
}
|
||||
if (revocationReason)
|
||||
{
|
||||
*revocationReason = (*response)->revocationReason;
|
||||
}
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
|
||||
@@ -261,7 +267,7 @@ METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
this->responses->create_enumerator(this->responses),
|
||||
(void*)filter, NULL, NULL);
|
||||
filter, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -753,18 +753,25 @@ CALLBACK(enumerator_destroy, void,
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate section names, not sections
|
||||
*/
|
||||
static bool section_filter(hashtable_t *seen, section_t **in, char **out)
|
||||
CALLBACK(section_filter, bool,
|
||||
hashtable_t *seen, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*out = (*in)->name;
|
||||
if (seen->get(seen, *out))
|
||||
section_t *section;
|
||||
char **out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, §ion))
|
||||
{
|
||||
return FALSE;
|
||||
if (seen->get(seen, section->name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*out = section->name;
|
||||
seen->put(seen, section->name, section->name);
|
||||
return TRUE;
|
||||
}
|
||||
seen->put(seen, *out, *out);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -774,8 +781,8 @@ static enumerator_t *section_enumerator(section_t *section,
|
||||
enumerator_data_t *data)
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
array_create_enumerator(section->sections_order),
|
||||
(void*)section_filter, data->seen, NULL);
|
||||
array_create_enumerator(section->sections_order),
|
||||
section_filter, data->seen, NULL);
|
||||
}
|
||||
|
||||
METHOD(settings_t, create_section_enumerator, enumerator_t*,
|
||||
@@ -801,23 +808,29 @@ METHOD(settings_t, create_section_enumerator, enumerator_t*,
|
||||
.seen = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8),
|
||||
);
|
||||
return enumerator_create_nested(array_create_enumerator(sections),
|
||||
(void*)section_enumerator, data, (void*)enumerator_destroy);
|
||||
(void*)section_enumerator, data, enumerator_destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate key and values, not kv_t entries
|
||||
*/
|
||||
static bool kv_filter(hashtable_t *seen, kv_t **in, char **key,
|
||||
void *none, char **value)
|
||||
CALLBACK(kv_filter, bool,
|
||||
hashtable_t *seen, enumerator_t *orig, va_list args)
|
||||
{
|
||||
*key = (*in)->key;
|
||||
if (seen->get(seen, *key) || !(*in)->value)
|
||||
kv_t *kv;
|
||||
char **key, **value;
|
||||
|
||||
VA_ARGS_VGET(args, key, value);
|
||||
|
||||
while (orig->enumerate(orig, &kv))
|
||||
{
|
||||
return FALSE;
|
||||
if (seen->get(seen, kv->key) || !kv->value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*key = kv->key;
|
||||
*value = kv->value;
|
||||
seen->put(seen, kv->key, kv->key);
|
||||
return TRUE;
|
||||
}
|
||||
*value = (*in)->value;
|
||||
seen->put(seen, *key, *key);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -826,7 +839,7 @@ static bool kv_filter(hashtable_t *seen, kv_t **in, char **key,
|
||||
static enumerator_t *kv_enumerator(section_t *section, enumerator_data_t *data)
|
||||
{
|
||||
return enumerator_create_filter(array_create_enumerator(section->kv_order),
|
||||
(void*)kv_filter, data->seen, NULL);
|
||||
kv_filter, data->seen, NULL);
|
||||
}
|
||||
|
||||
METHOD(settings_t, create_key_value_enumerator, enumerator_t*,
|
||||
|
||||
@@ -104,25 +104,45 @@ static void destroy_data(void *data)
|
||||
* filtered test
|
||||
*/
|
||||
|
||||
static bool filter(int *data, int **v, int *vo, int **w, int *wo,
|
||||
int **x, int *xo, int **y, int *yo, int **z, int *zo)
|
||||
CALLBACK(filter, bool,
|
||||
int *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
int val = **v;
|
||||
int *item, *vo, *wo, *xo, *yo, *zo;
|
||||
|
||||
*vo = val++;
|
||||
*wo = val++;
|
||||
*xo = val++;
|
||||
*yo = val++;
|
||||
*zo = val++;
|
||||
fail_if(data != (void*)101, "data does not match '101' in filter function");
|
||||
return TRUE;
|
||||
VA_ARGS_VGET(args, vo, wo, xo, yo, zo);
|
||||
|
||||
if (orig->enumerate(orig, &item))
|
||||
{
|
||||
int val = *item;
|
||||
*vo = val++;
|
||||
*wo = val++;
|
||||
*xo = val++;
|
||||
*yo = val++;
|
||||
*zo = val++;
|
||||
fail_if(data != (void*)101, "data does not match '101' in filter function");
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool filter_odd(void *data, int **item, int *out)
|
||||
CALLBACK(filter_odd, bool,
|
||||
void *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
int *item, *out;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
fail_if(data != (void*)101, "data does not match '101' in filter function");
|
||||
*out = **item;
|
||||
return **item % 2 == 0;
|
||||
|
||||
while (orig->enumerate(orig, &item))
|
||||
{
|
||||
if (*item % 2 == 0)
|
||||
{
|
||||
*out = *item;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
START_TEST(test_filtered)
|
||||
@@ -136,7 +156,7 @@ START_TEST(test_filtered)
|
||||
|
||||
round = 1;
|
||||
enumerator = enumerator_create_filter(list->create_enumerator(list),
|
||||
(void*)filter, (void*)101, destroy_data);
|
||||
filter, (void*)101, destroy_data);
|
||||
while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z))
|
||||
{
|
||||
ck_assert_int_eq(v, round);
|
||||
@@ -166,7 +186,7 @@ START_TEST(test_filtered_filter)
|
||||
/* should also work without destructor, so set this manually */
|
||||
destroy_data_called = 1;
|
||||
enumerator = enumerator_create_filter(list->create_enumerator(list),
|
||||
(void*)filter_odd, (void*)101, NULL);
|
||||
filter_odd, (void*)101, NULL);
|
||||
while (enumerator->enumerate(enumerator, &x))
|
||||
{
|
||||
ck_assert(x % 2 == 0);
|
||||
|
||||
Reference in New Issue
Block a user