diff options
author | Tobias Brunner <tobias@strongswan.org> | 2015-10-16 12:12:43 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2016-03-08 10:21:57 +0100 |
commit | 348b0ffbc67aab6c7e386418d14ed85aeac748a9 (patch) | |
tree | cce4cc6bb9de97cdee446a7892d14ccf9834aa1b | |
parent | 229cdf6bc8f24f9ce445943117c518dc6bb876a4 (diff) | |
download | strongswan-348b0ffbc67aab6c7e386418d14ed85aeac748a9.tar.bz2 strongswan-348b0ffbc67aab6c7e386418d14ed85aeac748a9.tar.xz |
linked-list: Add method to compare two lists of objects for equality
-rw-r--r-- | src/libstrongswan/collections/linked_list.c | 54 | ||||
-rw-r--r-- | src/libstrongswan/collections/linked_list.h | 23 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_linked_list.c | 91 |
3 files changed, 166 insertions, 2 deletions
diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index a176e5a54..b8fe81578 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Tobias Brunner + * Copyright (C) 2007-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -433,6 +433,56 @@ METHOD(linked_list_t, clone_offset, linked_list_t*, return clone; } +METHOD(linked_list_t, equals_offset, bool, + private_linked_list_t *this, linked_list_t *other_pub, size_t offset) +{ + private_linked_list_t *other = (private_linked_list_t*)other_pub; + element_t *cur_t, *cur_o; + + if (this->count != other->count) + { + return FALSE; + } + cur_t = this->first; + cur_o = other->first; + while (cur_t && cur_o) + { + bool (**method)(void*,void*) = cur_t->value + offset; + if (!(*method)(cur_t->value, cur_o->value)) + { + return FALSE; + } + cur_t = cur_t->next; + cur_o = cur_o->next; + } + return TRUE; +} + +METHOD(linked_list_t, equals_function, bool, + private_linked_list_t *this, linked_list_t *other_pub, + bool (*fn)(void*,void*)) +{ + private_linked_list_t *other = (private_linked_list_t*)other_pub; + element_t *cur_t, *cur_o; + + if (this->count != other->count) + { + return FALSE; + } + cur_t = this->first; + cur_o = other->first; + while (cur_t && cur_o) + { + if (!fn(cur_t->value, cur_o->value)) + { + return FALSE; + } + cur_t = cur_t->next; + cur_o = cur_o->next; + } + return TRUE; +} + METHOD(linked_list_t, destroy, void, private_linked_list_t *this) { @@ -503,6 +553,8 @@ linked_list_t *linked_list_create() .invoke_offset = (void*)_invoke_offset, .invoke_function = (void*)_invoke_function, .clone_offset = _clone_offset, + .equals_offset = _equals_offset, + .equals_function = _equals_function, .destroy = _destroy, .destroy_offset = _destroy_offset, .destroy_function = _destroy_function, diff --git a/src/libstrongswan/collections/linked_list.h b/src/libstrongswan/collections/linked_list.h index abc33c12a..5edaa07aa 100644 --- a/src/libstrongswan/collections/linked_list.h +++ b/src/libstrongswan/collections/linked_list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Tobias Brunner + * Copyright (C) 2007-2015 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -218,6 +218,27 @@ struct linked_list_t { linked_list_t *(*clone_offset) (linked_list_t *this, size_t offset); /** + * Compare two lists and their objects for equality using the given equals + * method. + * + * @param other list to compare + * @param offset offset of the objects equals method + * @return TRUE if lists and objects are equal, FALSE otherwise + */ + bool (*equals_offset) (linked_list_t *this, linked_list_t *other, + size_t offset); + + /** + * Compare two lists and their objects for equality using the given function. + * + * @param other list to compare + * @param function function to compare the objects + * @return TRUE if lists and objects are equal, FALSE otherwise + */ + bool (*equals_function) (linked_list_t *this, linked_list_t *other, + bool (*)(void*,void*)); + + /** * Destroys a linked_list object. */ void (*destroy) (linked_list_t *this); diff --git a/src/libstrongswan/tests/suites/test_linked_list.c b/src/libstrongswan/tests/suites/test_linked_list.c index 922f954e3..7a161817c 100644 --- a/src/libstrongswan/tests/suites/test_linked_list.c +++ b/src/libstrongswan/tests/suites/test_linked_list.c @@ -348,6 +348,91 @@ START_TEST(test_clone_offset) } END_TEST + +/******************************************************************************* + * equals + */ + +typedef struct equals_t equals_t; + +struct equals_t { + int val; + bool (*equals)(equals_t *a, equals_t *b); +}; + +static bool equalsfn(equals_t *a, equals_t *b) +{ + return a->val == b->val; +} + +START_TEST(test_equals_offset) +{ + linked_list_t *other; + equals_t *x, items[] = { + { .val = 1, .equals = equalsfn, }, + { .val = 2, .equals = equalsfn, }, + { .val = 3, .equals = equalsfn, }, + { .val = 4, .equals = equalsfn, }, + { .val = 5, .equals = equalsfn, }, + }; + int i; + + for (i = 0; i < countof(items); i++) + { + list->insert_last(list, &items[i]); + } + ck_assert(list->equals_offset(list, list, offsetof(equals_t, equals))); + other = linked_list_create_from_enumerator(list->create_enumerator(list)); + ck_assert(list->equals_offset(list, other, offsetof(equals_t, equals))); + other->remove_last(other, (void**)&x); + ck_assert(!list->equals_offset(list, other, offsetof(equals_t, equals))); + list->remove_last(list, (void**)&x); + ck_assert(list->equals_offset(list, other, offsetof(equals_t, equals))); + other->remove_first(other, (void**)&x); + ck_assert(!list->equals_offset(list, other, offsetof(equals_t, equals))); + list->remove_first(list, (void**)&x); + ck_assert(list->equals_offset(list, other, offsetof(equals_t, equals))); + while (list->remove_first(list, (void**)&x) == SUCCESS); + while (other->remove_first(other, (void**)&x) == SUCCESS); + ck_assert(list->equals_offset(list, other, offsetof(equals_t, equals))); + other->destroy(other); +} +END_TEST + +START_TEST(test_equals_function) +{ + linked_list_t *other; + equals_t *x, items[] = { + { .val = 1, }, + { .val = 2, }, + { .val = 3, }, + { .val = 4, }, + { .val = 5, }, + }; + int i; + + for (i = 0; i < countof(items); i++) + { + list->insert_last(list, &items[i]); + } + ck_assert(list->equals_function(list, list, (void*)equalsfn)); + other = linked_list_create_from_enumerator(list->create_enumerator(list)); + ck_assert(list->equals_function(list, other, (void*)equalsfn)); + other->remove_last(other, (void**)&x); + ck_assert(!list->equals_function(list, other, (void*)equalsfn)); + list->remove_last(list, (void**)&x); + ck_assert(list->equals_function(list, other, (void*)equalsfn)); + other->remove_first(other, (void**)&x); + ck_assert(!list->equals_function(list, other, (void*)equalsfn)); + list->remove_first(list, (void**)&x); + ck_assert(list->equals_function(list, other, (void*)equalsfn)); + while (list->remove_first(list, (void**)&x) == SUCCESS); + while (other->remove_first(other, (void**)&x) == SUCCESS); + ck_assert(list->equals_function(list, other, (void*)equalsfn)); + other->destroy(other); +} +END_TEST + Suite *linked_list_suite_create() { Suite *s; @@ -386,5 +471,11 @@ Suite *linked_list_suite_create() tcase_add_test(tc, test_clone_offset); suite_add_tcase(s, tc); + tc = tcase_create("equals"); + tcase_add_checked_fixture(tc, setup_list, teardown_list); + tcase_add_test(tc, test_equals_offset); + tcase_add_test(tc, test_equals_function); + suite_add_tcase(s, tc); + return s; } |