From c60024e393ea601cf0543c501e59edf892092655 Mon Sep 17 00:00:00 2001 From: cedric Date: Tue, 12 Aug 2008 15:58:41 +0000 Subject: [PATCH] Add Inlist Iterator. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/e17/proto/eina@35445 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/eina_inlist.c | 148 ++++++++++++++++++++++++++++++++++++++++- src/tests/eina_test_accessor.c | 90 ++++++++++++++++++++++++- src/tests/eina_test_iterator.c | 79 +++++++++++++++++++++- 3 files changed, 314 insertions(+), 3 deletions(-) diff --git a/src/lib/eina_inlist.c b/src/lib/eina_inlist.c index 03bc30d..d3af896 100644 --- a/src/lib/eina_inlist.c +++ b/src/lib/eina_inlist.c @@ -22,7 +22,108 @@ /* FIXME: TODO please, refactor this :) */ /*============================================================================* - * API * + * Local * + *============================================================================*/ +typedef struct _Eina_Iterator_Inlist Eina_Iterator_Inlist; +typedef struct _Eina_Accessor_Inlist Eina_Accessor_Inlist; + +struct _Eina_Iterator_Inlist +{ + Eina_Iterator iterator; + const Eina_Inlist *head; + const Eina_Inlist *current; +}; + +struct _Eina_Accessor_Inlist +{ + Eina_Accessor accessor; + + const Eina_Inlist *head; + const Eina_Inlist *current; + + unsigned int index; +}; + +static Eina_Bool +eina_inlist_iterator_next(Eina_Iterator_Inlist *it, void **data) { + if (it->current == NULL) return EINA_FALSE; + if (data) *data = (void*) it->current; + + it->current = it->current->next; + + return EINA_TRUE; +} + +static Eina_Inlist * +eina_inlist_iterator_get_container(Eina_Iterator_Inlist *it) { + return (Eina_Inlist*) it->head; +} + +static void +eina_inlist_iterator_free(Eina_Iterator_Inlist *it) { + free(it); +} + +static Eina_Bool +eina_inlist_accessor_get_at(Eina_Accessor_Inlist *it, unsigned int index, void **data) { + const Eina_Inlist *over; + unsigned int middle; + unsigned int i; + + if (it->index == index) { + over = it->current; + } else if (index > it->index) { + /* Looking after current. */ + for (i = it->index, over = it->current; + i < index && over != NULL; + ++i, over = over->next) + ; + + if (over == NULL) return EINA_FALSE; + } else { + middle = it->index >> 1; + + if (index > middle) { + /* Looking backward from current. */ + for (i = it->index, over = it->current; + i > index && over != NULL; + --i, over = over->prev) + ; + + if (over == NULL) return EINA_FALSE; + } else { + /* Looking from the start. */ + for (i = 0, over = it->head; + i < index && over != NULL; + ++i, over = over->next) + ; + + if (over == NULL) return EINA_FALSE; + } + } + + it->current = over; + it->index = index; + + if (data) *data = (void*) over; + return EINA_TRUE; +} + +static Eina_Inlist * +eina_inlist_accessor_get_container(Eina_Accessor_Inlist *it) { + return (Eina_Inlist *) it->head; +} + +static void +eina_inlist_accessor_free(Eina_Accessor_Inlist *it) { + free(it); +} + +/*============================================================================* + * Global * + *============================================================================*/ +/*============================================================================* + * API * *============================================================================*/ /** * To be documented @@ -176,3 +277,48 @@ EAPI void * eina_inlist_find(void *in_list, void *in_item) { } return NULL; } + +EAPI Eina_Iterator *eina_inlist_iterator_new(const void *in_list) { + Eina_Iterator_Inlist *it; + + if (!in_list) return NULL; + + eina_error_set(0); + it = calloc(1, sizeof (Eina_Iterator_Inlist)); + if (!it) { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + it->head = in_list; + it->current = in_list; + + it->iterator.next = FUNC_ITERATOR_NEXT(eina_inlist_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(eina_inlist_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(eina_inlist_iterator_free); + + return &it->iterator; +} + +EAPI Eina_Accessor *eina_inlist_accessor_new(const void *in_list) { + Eina_Accessor_Inlist *it; + + if (!in_list) return NULL; + + eina_error_set(0); + it = calloc(1, sizeof (Eina_Accessor_Inlist)); + if (!it) { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + it->head = in_list; + it->current = in_list; + it->index = 0; + + it->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_inlist_accessor_get_at); + it->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(eina_inlist_accessor_get_container); + it->accessor.free = FUNC_ACCESSOR_FREE(eina_inlist_accessor_free); + + return &it->accessor; +} diff --git a/src/tests/eina_test_accessor.c b/src/tests/eina_test_accessor.c index a5fd8d2..1df3aa5 100644 --- a/src/tests/eina_test_accessor.c +++ b/src/tests/eina_test_accessor.c @@ -24,6 +24,7 @@ #include "eina_suite.h" #include "eina_array.h" +#include "eina_inlist.h" #include "eina_private.h" static Eina_Bool @@ -60,7 +61,7 @@ START_TEST(eina_accessor_array_simple) it = eina_array_accessor_new(ea); fail_if(!it); - fail_if(eina_accessor_data_get(it, 100, &tmp) != EINA_TRUE); + fail_if(eina_accessor_data_get(it, 100, (void**) &tmp) != EINA_TRUE); fail_if(!tmp); fail_if(*tmp != 100); @@ -78,8 +79,95 @@ START_TEST(eina_accessor_array_simple) } END_TEST +typedef struct _Eina_Test_Inlist Eina_Test_Inlist; +struct _Eina_Test_Inlist +{ + Eina_Inlist list; + int i; +}; + +static Eina_Test_Inlist* +_eina_test_inlist_build(int i) +{ + Eina_Test_Inlist *tmp; + + tmp = malloc(sizeof(Eina_Test_Inlist)); + fail_if(!tmp); + tmp->i = i; + + return tmp; +} + +static Eina_Bool +eina_accessor_inlist_data_check(__UNUSED__ const Eina_Inlist *in_list, Eina_Test_Inlist *data, int *fdata) +{ + switch (*fdata) + { + case 0: fail_if(data->i != 3227); break; + case 1: fail_if(data->i != 1664); break; + } + + (*fdata)++; + + return EINA_TRUE; +} + +START_TEST(eina_accessor_inlist_simple) +{ + Eina_Test_Inlist *lst = NULL; + Eina_Test_Inlist *tmp; + Eina_Test_Inlist *prev; + Eina_Accessor *it; + int i = 0; + + tmp = _eina_test_inlist_build(42); + lst = eina_inlist_append(lst, tmp); + fail_if(!lst); + + tmp = _eina_test_inlist_build(1664); + lst = eina_inlist_append_relative(lst, tmp, lst); + fail_if(!lst); + fail_if(lst->i != 42); + + prev = tmp; + tmp = _eina_test_inlist_build(3227); + lst = eina_inlist_prepend_relative(lst, tmp, prev); + fail_if(!lst); + fail_if(lst->i != 42); + + tmp = _eina_test_inlist_build(27); + lst = eina_inlist_prepend_relative(lst, tmp, NULL); + + tmp = _eina_test_inlist_build(81); + lst = eina_inlist_append_relative(lst, tmp, NULL); + + tmp = _eina_test_inlist_build(7); + lst = eina_inlist_append(lst, tmp); + + it = eina_inlist_accessor_new(lst); + fail_if(!it); + fail_if(eina_accessor_container_get(it) != lst); + + eina_accessor_over(it, EINA_EACH(eina_accessor_inlist_data_check), 2, 4, &i); + + fail_if(eina_accessor_data_get(it, 5, (void**) &tmp) != EINA_TRUE); + fail_if(eina_accessor_data_get(it, 3, (void**) &tmp) != EINA_TRUE); + fail_if(tmp->i != 1664); + fail_if(eina_accessor_data_get(it, 3, (void**) &tmp) != EINA_TRUE); + fail_if(tmp->i != 1664); + fail_if(eina_accessor_data_get(it, 1, (void**) &tmp) != EINA_TRUE); + fail_if(tmp->i != 42); + + eina_accessor_free(it); + + fail_if(i != 2); +} +END_TEST + + void eina_test_accessor(TCase *tc) { tcase_add_test(tc, eina_accessor_array_simple); + tcase_add_test(tc, eina_accessor_inlist_simple); } diff --git a/src/tests/eina_test_iterator.c b/src/tests/eina_test_iterator.c index 1b5be77..4315969 100644 --- a/src/tests/eina_test_iterator.c +++ b/src/tests/eina_test_iterator.c @@ -25,6 +25,7 @@ #include "eina_suite.h" #include "eina_array.h" #include "eina_hash.h" +#include "eina_inlist.h" #include "eina_private.h" static Eina_Bool @@ -66,7 +67,7 @@ START_TEST(eina_iterator_array_simple) fail_if(i != 199); fail_if(eina_iterator_container_get(it) != ea); - fail_if(eina_iterator_next(it, &tmp) != EINA_FALSE); + fail_if(eina_iterator_next(it, (void**) &tmp) != EINA_FALSE); eina_iterator_free(it); @@ -136,9 +137,85 @@ START_TEST(eina_iterator_hash_simple) } END_TEST +typedef struct _Eina_Test_Inlist Eina_Test_Inlist; +struct _Eina_Test_Inlist +{ + Eina_Inlist list; + int i; +}; + +static Eina_Test_Inlist* +_eina_test_inlist_build(int i) +{ + Eina_Test_Inlist *tmp; + + tmp = malloc(sizeof(Eina_Test_Inlist)); + fail_if(!tmp); + tmp->i = i; + + return tmp; +} + +static Eina_Bool +eina_iterator_inlist_data_check(__UNUSED__ const Eina_Inlist *in_list, Eina_Test_Inlist *data, int *fdata) +{ + switch (*fdata) + { + case 0: fail_if(data->i != 27); break; + case 1: fail_if(data->i != 42); break; + case 2: fail_if(data->i != 3227); break; + case 3: fail_if(data->i != 1664); break; + case 4: fail_if(data->i != 81); break; + } + + (*fdata)++; + + return EINA_TRUE; +} + +START_TEST(eina_iterator_inlist_simple) +{ + Eina_Test_Inlist *lst = NULL; + Eina_Test_Inlist *tmp; + Eina_Test_Inlist *prev; + Eina_Iterator *it; + int i = 0; + + tmp = _eina_test_inlist_build(42); + lst = eina_inlist_append(lst, tmp); + fail_if(!lst); + + tmp = _eina_test_inlist_build(1664); + lst = eina_inlist_append_relative(lst, tmp, lst); + fail_if(!lst); + fail_if(lst->i != 42); + + prev = tmp; + tmp = _eina_test_inlist_build(3227); + lst = eina_inlist_prepend_relative(lst, tmp, prev); + fail_if(!lst); + fail_if(lst->i != 42); + + tmp = _eina_test_inlist_build(27); + lst = eina_inlist_prepend_relative(lst, tmp, NULL); + + tmp = _eina_test_inlist_build(81); + lst = eina_inlist_append_relative(lst, tmp, NULL); + + it = eina_inlist_iterator_new(lst); + fail_if(!it); + + eina_iterator_foreach(it, EINA_EACH(eina_iterator_inlist_data_check), &i); + eina_iterator_free(it); + + fail_if(i != 5); +} +END_TEST + void eina_test_iterator(TCase *tc) { tcase_add_test(tc, eina_iterator_array_simple); tcase_add_test(tc, eina_iterator_hash_simple); + tcase_add_test(tc, eina_iterator_inlist_simple); } -- 2.7.4