From: Tobias Brunner Date: Thu, 14 Feb 2008 12:29:29 +0000 (-0000) Subject: find methods for linked lists X-Git-Tag: 4.1.11~5 X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=commitdiff_plain;h=e3311a40f0bec7594b513029ca2118d3d234d90f find methods for linked lists --- diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 5cd8ffd..63e1bcf 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -677,6 +677,52 @@ static status_t get_last(private_linked_list_t *this, void **item) } /** + * Implementation of linked_list_t.find_first. + */ +static status_t find_first(private_linked_list_t *this, linked_list_match_t match, + void **item, void *d1, void *d2, void *d3, void *d4, void *d5) +{ + element_t *current = this->first; + + while (current) + { + if (match(current->value, d1, d2, d3, d4, d5)) + { + if (item != NULL) + { + *item = current->value; + } + return SUCCESS; + } + current = current->next; + } + return NOT_FOUND; +} + +/** + * Implementation of linked_list_t.find_last. + */ +static status_t find_last(private_linked_list_t *this, linked_list_match_t match, + void **item, void *d1, void *d2, void *d3, void *d4, void *d5) +{ + element_t *current = this->last; + + while (current) + { + if (match(current->value, d1, d2, d3, d4, d5)) + { + if (item != NULL) + { + *item = current->value; + } + return SUCCESS; + } + current = current->previous; + } + return NOT_FOUND; +} + +/** * Implementation of linked_list_t.invoke_offset. */ static void invoke_offset(private_linked_list_t *this, size_t offset) @@ -843,6 +889,8 @@ linked_list_t *linked_list_create() this->public.create_enumerator = (enumerator_t*(*)(linked_list_t*))create_enumerator; this->public.get_first = (status_t (*) (linked_list_t *, void **item))get_first; this->public.get_last = (status_t (*) (linked_list_t *, void **item))get_last; + this->public.find_first = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_first; + this->public.find_last = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_last; this->public.insert_first = (void (*) (linked_list_t *, void *item))insert_first; this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last; this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first; diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h index ebe5c18..ac36ef4 100644 --- a/src/libstrongswan/utils/linked_list.h +++ b/src/libstrongswan/utils/linked_list.h @@ -33,6 +33,19 @@ typedef struct linked_list_t linked_list_t; #include #include + +/** + * Method to match elements in a linked list (used in find_* functions) + * + * @param item current list item + * @param ... user supplied data (only pointers, at most 5) + * @return + * - TRUE, if the item matched + * - FALSE, otherwise + * @ingroup utils + */ +typedef bool (*linked_list_match_t)(void *item, ...); + /** * @brief Class implementing a double linked list. * @@ -187,6 +200,50 @@ struct linked_list_t { */ status_t (*get_last) (linked_list_t *this, void **item); + /** @brief Find the first matching element in the list. + * + * 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, + * the next item is checked. + * + * @warning Only use pointers as user supplied data. + * + * @param this calling object + * @param match comparison function to call on each object + * @param[out] item + * - the list item, if found + * - NULL, otherwise + * @param ... user data to supply to match function (limited to 5 arguments) + * @return + * - SUCCESS, if found + * - NOT_FOUND, otherwise + */ + status_t (*find_first) (linked_list_t *this, linked_list_match_t match, void **item, ...); + + /** @brief Find the last matching element in the list. + * + * 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, + * the next item is checked. + * + * @warning Only use pointers as user supplied data. + * + * @param this calling object + * @param match comparison function to call on each object + * @param[out] item + * - the list item, if found + * - NULL, otherwise + * @param ... user data to supply to match function (limited to 5 arguments) + * @return + * - SUCCESS, if found + * - NOT_FOUND, otherwise + */ + status_t (*find_last) (linked_list_t *this, linked_list_match_t match, void **item, ...); + /** * @brief Invoke a method on all of the contained objects. *