Add Inlist Iterator.
authorcedric <cedric>
Tue, 12 Aug 2008 15:58:41 +0000 (15:58 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 12 Aug 2008 15:58:41 +0000 (15:58 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/e17/proto/eina@35445 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/eina_inlist.c
src/tests/eina_test_accessor.c
src/tests/eina_test_iterator.c

index 03bc30d..d3af896 100644 (file)
 /* 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;
+}
index a5fd8d2..1df3aa5 100644 (file)
@@ -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);
 }
index 1b5be77..4315969 100644 (file)
@@ -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);
 }