diff options
Diffstat (limited to 'Source/charon')
-rw-r--r-- | Source/charon/testcases/linked_list_test.c | 34 | ||||
-rw-r--r-- | Source/charon/utils/linked_list.c | 125 | ||||
-rw-r--r-- | Source/charon/utils/linked_list.h | 36 |
3 files changed, 184 insertions, 11 deletions
diff --git a/Source/charon/testcases/linked_list_test.c b/Source/charon/testcases/linked_list_test.c index 6dedb3184..add3658d9 100644 --- a/Source/charon/testcases/linked_list_test.c +++ b/Source/charon/testcases/linked_list_test.c @@ -69,9 +69,41 @@ void test_linked_list(tester_t *tester) tester->assert_true(tester,(linked_list->get_count(linked_list) == 4), "count check"); tester->assert_true(tester,(linked_list->get_last(linked_list,&test_value) == SUCCESS), "get_last call check"); - tester->assert_true(tester,(strcmp((char *) test_value,"one") == 0), "get_last value check"); + tester->assert_true(tester,(strcmp((char *) test_value,"one") == 0), "get_last value check"); tester->assert_true(tester,(linked_list->get_count(linked_list) == 4), "count check"); + tester->assert_true(tester,(linked_list->get_at_position(linked_list,0,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"four") == 0), "get_at_position value check"); + + tester->assert_true(tester,(linked_list->get_at_position(linked_list,1,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"three") == 0), "get_at_position value check"); + + tester->assert_true(tester,(linked_list->get_at_position(linked_list,2,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"two") == 0), "get_at_position value check"); + + tester->assert_true(tester,(linked_list->get_at_position(linked_list,3,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"one") == 0), "get_at_position value check"); + + tester->assert_false(tester,(linked_list->get_at_position(linked_list,4,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_false(tester,(linked_list->remove_at_position(linked_list,4,&test_value) == SUCCESS), "remove_at_position call check"); + tester->assert_false(tester,(linked_list->insert_at_position(linked_list,5,test_value) == SUCCESS), "insert_at_position call 1 check"); + + tester->assert_true(tester,(linked_list->insert_at_position(linked_list,3,"six") == SUCCESS), "insert_at_position call 2 check"); + tester->assert_true(tester,(linked_list->insert_at_position(linked_list,3,"seven") == SUCCESS), "insert_at_position call 3 check"); + + tester->assert_true(tester,(linked_list->get_at_position(linked_list,3,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"seven") == 0), "get_at_position value 1 check"); + + tester->assert_true(tester,(linked_list->get_at_position(linked_list,4,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"six") == 0), "get_at_position value 2 check"); + + tester->assert_true(tester,(linked_list->get_at_position(linked_list,5,&test_value) == SUCCESS), "get_at_position call check"); + tester->assert_true(tester,(strcmp((char *) test_value,"one") == 0), "get_at_position value 3 check"); + + tester->assert_true(tester,(linked_list->remove_at_position(linked_list,3,&test_value) == SUCCESS), "remove_at_position call check"); + tester->assert_true(tester,(linked_list->remove_at_position(linked_list,3,&test_value) == SUCCESS), "remove_at_position call check"); + + tester->assert_true(tester,(linked_list->remove_last(linked_list,&test_value) == SUCCESS), "remove_last call check"); tester->assert_true(tester,(strcmp((char *) test_value,"one") == 0), "remove_last value check"); tester->assert_true(tester,(linked_list->get_count(linked_list) == 3), "count check"); diff --git a/Source/charon/utils/linked_list.c b/Source/charon/utils/linked_list.c index a38720af9..b6d4c348c 100644 --- a/Source/charon/utils/linked_list.c +++ b/Source/charon/utils/linked_list.c @@ -218,7 +218,7 @@ static status_t remove(private_iterator_t *this) return NOT_FOUND; } /* find out the new iterator position */ - if (this ->current->previous != NULL) + if (this->current->previous != NULL) { new_current = this->current->previous; } @@ -483,6 +483,107 @@ static status_t remove_last(private_linked_list_t *this, void **item) } /** + * Implementation of linked_list_t.insert_at_position. + */ +static status_t insert_at_position (private_linked_list_t *this,size_t position, void *item) +{ + linked_list_element_t *current_element; + int i; + + if (this->count <= position) + { + return INVALID_ARG; + } + + current_element = this->first; + + for (i = 0; i < position;i++) + { + current_element = current_element->next; + } + + if (current_element == NULL) + { + this->public.insert_last(&(this->public),item); + return SUCCESS; + } + + linked_list_element_t *element =(linked_list_element_t *) linked_list_element_create(item); + + + if (current_element->previous == NULL) + { + current_element->previous = element; + element->next = current_element; + this->first = element; + } + else + { + current_element->previous->next = element; + element->previous = current_element->previous; + current_element->previous = element; + element->next = current_element; + } + + + this->count++; + return SUCCESS; +} + +/** + * Implementation of linked_list_t.remove_at_position. + */ +static status_t remove_at_position (private_linked_list_t *this,size_t position, void **item) +{ + iterator_t *iterator; + int i; + + if (this->count <= position) + { + return INVALID_ARG; + } + + iterator = this->public.create_iterator(&(this->public),TRUE); + + iterator->has_next(iterator); + for (i = 0; i < position;i++) + { + iterator->has_next(iterator); + } + iterator->current(iterator,item); + iterator->remove(iterator); + iterator->destroy(iterator); + + return SUCCESS; +} + +/** + * Implementation of linked_list_t.get_at_position. + */ +static status_t get_at_position (private_linked_list_t *this,size_t position, void **item) +{ + int i; + iterator_t *iterator; + status_t status; + if (this->count <= position) + { + return INVALID_ARG; + } + + iterator = this->public.create_iterator(&(this->public),TRUE); + + iterator->has_next(iterator); + for (i = 0; i < position;i++) + { + iterator->has_next(iterator); + } + status = iterator->current(iterator,item); + iterator->destroy(iterator); + return status; +} + + +/** * Implementation of linked_list_t.get_last. */ static status_t get_last(private_linked_list_t *this, void **item) @@ -543,15 +644,19 @@ linked_list_t *linked_list_create() { private_linked_list_t *this = allocator_alloc_thing(private_linked_list_t); - this->public.get_count = (int (*) (linked_list_t *linked_list)) get_count; - this->public.create_iterator = (iterator_t * (*) (linked_list_t *linked_list,bool forward)) create_iterator; - this->public.get_first = (status_t (*) (linked_list_t *linked_list, void **item)) get_first; - this->public.get_last = (status_t (*) (linked_list_t *linked_list, void **item)) get_last; - this->public.insert_first = (void (*) (linked_list_t *linked_list, void *item)) insert_first; - this->public.insert_last = (void (*) (linked_list_t *linked_list, void *item)) insert_last; - this->public.remove_first = (status_t (*) (linked_list_t *linked_list, void **item)) remove_first; - this->public.remove_last = (status_t (*) (linked_list_t *linked_list, void **item)) remove_last; - this->public.destroy = (void (*) (linked_list_t *linked_list)) linked_list_destroy; + this->public.get_count = (int (*) (linked_list_t *)) get_count; + this->public.create_iterator = (iterator_t * (*) (linked_list_t *,bool )) create_iterator; + 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.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; + this->public.remove_last = (status_t (*) (linked_list_t *, void **item)) remove_last; + this->public.insert_at_position =(status_t (*) (linked_list_t *,size_t, void *)) insert_at_position; + this->public.remove_at_position =(status_t (*) (linked_list_t *,size_t, void **)) remove_at_position; + this->public.get_at_position =(status_t (*) (linked_list_t *,size_t, void **)) get_at_position; + + this->public.destroy = (void (*) (linked_list_t *)) linked_list_destroy; this->count = 0; this->first = NULL; diff --git a/Source/charon/utils/linked_list.h b/Source/charon/utils/linked_list.h index ee07ce487..779252e0f 100644 --- a/Source/charon/utils/linked_list.h +++ b/Source/charon/utils/linked_list.h @@ -98,6 +98,42 @@ struct linked_list_t { void (*insert_last) (linked_list_t *linked_list, void *item); /** + * @brief Inserts a new item at a given position in the list. + * + * @param linked_list calling object + * @param position position starting at 0 to insert new entry + * @param[in] item value to insert into list + * @return + * - SUCCESS + * - INVALID_ARG if position not existing + */ + status_t (*insert_at_position) (linked_list_t *linked_list,size_t position, void *item); + + /** + * @brief Removes an item from a given position in the list. + * + * @param linked_list calling object + * @param position position starting at 0 to remove entry from + * @param[out] removed item will be stored at this location + * @return + * - SUCCESS + * - INVALID_ARG if position not existing + */ + status_t (*remove_at_position) (linked_list_t *linked_list,size_t position, void **item); + + /** + * @brief Get an item from a given position in the list. + * + * @param linked_list calling object + * @param position position starting at 0 to get entry from + * @param[out] item will be stored at this location + * @return + * - SUCCESS + * - INVALID_ARG if position not existing + */ + status_t (*get_at_position) (linked_list_t *linked_list,size_t position, void **item); + + /** * @brief Removes the last item in the list and returns its value. * * @param linked_list calling object |