find methods for linked lists
authorTobias Brunner <tobias@strongswan.org>
Thu, 14 Feb 2008 12:29:29 +0000 (12:29 -0000)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Feb 2008 12:29:29 +0000 (12:29 -0000)
src/libstrongswan/utils/linked_list.c
src/libstrongswan/utils/linked_list.h

index 5cd8ffd..63e1bcf 100644 (file)
@@ -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;
index ebe5c18..ac36ef4 100644 (file)
@@ -33,6 +33,19 @@ typedef struct linked_list_t linked_list_t;
 #include <utils/iterator.h>
 #include <utils/enumerator.h>
 
+
+/**
+ * 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.
         *