Enlightenment CVS committal

Author  : cedric
Project : e17
Module  : proto/eina

Dir     : e17/proto/eina/src/lib


Modified Files:
        Makefile.am eina_array.c eina_hash.c eina_magic.c 
Added Files:
        eina_accessor.c eina_iterator.c 


Log Message:
Add first try for an accessor and iterator API, comment welcome (lack inlist 
and list currently).
Rewrite EINA_ARRAY_ITER_NEXT, still fast, need one more parameter, but no more 
EINA_ARRAY_ITER_END.


===================================================================
RCS file: /cvs/e/e17/proto/eina/src/lib/Makefile.am,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- Makefile.am 6 Aug 2008 15:53:03 -0000       1.6
+++ Makefile.am 11 Aug 2008 16:30:16 -0000      1.7
@@ -20,6 +20,8 @@
 eina_magic.c \
 eina_main.c \
 eina_counter.c \
+eina_iterator.c \
+eina_accessor.c \
 eina_stringshare.c
 
 libeina_la_LIBADD = -ldl -lrt @COVERAGE_LIBS@
===================================================================
RCS file: /cvs/e/e17/proto/eina/src/lib/eina_array.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- eina_array.c        8 Aug 2008 14:20:11 -0000       1.6
+++ eina_array.c        11 Aug 2008 16:30:16 -0000      1.7
@@ -30,6 +30,7 @@
 #include "eina_error.h"
 #include "eina_array.h"
 #include "eina_inline_array.x"
+#include "eina_private.h"
 
 EAPI int
 eina_array_init(void)
@@ -170,3 +171,129 @@
    array->data = tmp;
    array->count = total;
 }
+
+typedef struct _Eina_Iterator_Array Eina_Iterator_Array;
+struct _Eina_Iterator_Array
+{
+   Eina_Iterator iterator;
+
+   const Eina_Array *array;
+   unsigned int index;
+};
+
+static Eina_Bool
+eina_array_iterator_next(Eina_Iterator_Array *it)
+{
+   if (!(it->index + 1 < eina_array_count(it->array)))
+     return EINA_FALSE;
+   it->index++;
+   return EINA_TRUE;
+}
+
+static void *
+eina_array_iterator_get_content(Eina_Iterator_Array *it)
+{
+   if (!(it->index < eina_array_count(it->array)))
+     return NULL;
+   return eina_array_get(it->array, it->index);
+}
+
+static Eina_Array *
+eina_array_iterator_get_container(Eina_Iterator_Array *it)
+{
+   return (Eina_Array *) it->array;
+}
+
+static void
+eina_array_iterator_free(Eina_Iterator_Array *it)
+{
+   free(it);
+}
+
+EAPI Eina_Iterator *
+eina_array_iterator_new(const Eina_Array *array)
+{
+   Eina_Iterator_Array *it;
+
+   if (!array) return NULL;
+   if (eina_array_count(array) <= 0) return NULL;
+
+   eina_error_set(0);
+   it = calloc(1, sizeof (Eina_Iterator_Array));
+   if (!it) {
+      eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+      return NULL;
+   }
+
+   it->array = array;
+
+   it->iterator.next = FUNC_ITERATOR_NEXT(eina_array_iterator_next);
+   it->iterator.get_content = 
FUNC_ITERATOR_GET_CONTENT(eina_array_iterator_get_content);
+   it->iterator.get_container = 
FUNC_ITERATOR_GET_CONTAINER(eina_array_iterator_get_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(eina_array_iterator_free);
+
+   return &it->iterator;
+}
+
+typedef struct _Eina_Accessor_Array Eina_Accessor_Array;
+struct _Eina_Accessor_Array
+{
+   Eina_Accessor accessor;
+
+   const Eina_Array *array;
+   unsigned int index;
+};
+
+static Eina_Bool
+eina_array_accessor_jump_at(Eina_Accessor_Array *it, unsigned int index)
+{
+   if (!(index < eina_array_count(it->array)))
+     return EINA_FALSE;
+   it->index = index;
+   return EINA_TRUE;
+}
+
+static void *
+eina_array_accessor_get_content(Eina_Accessor_Array *it)
+{
+   if (!(it->index < eina_array_count(it->array)))
+     return NULL;
+   return eina_array_get(it->array, it->index);
+}
+
+static Eina_Array *
+eina_array_accessor_get_container(Eina_Accessor_Array *it)
+{
+   return (Eina_Array *) it->array;
+}
+
+static void
+eina_array_accessor_free(Eina_Accessor_Array *it)
+{
+   free(it);
+}
+
+EAPI Eina_Accessor *
+eina_array_accessor_new(const Eina_Array *array)
+{
+   Eina_Accessor_Array *it;
+
+   if (!array) return NULL;
+
+   eina_error_set(0);
+   it = calloc(1, sizeof (Eina_Accessor_Array));
+   if (!it) {
+      eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+      return NULL;
+   }
+
+   it->array = array;
+
+   it->accessor.jump_at = FUNC_ACCESSOR_JUMP_AT(eina_array_accessor_jump_at);
+   it->accessor.get_content = 
FUNC_ACCESSOR_GET_CONTENT(eina_array_accessor_get_content);
+   it->accessor.get_container = 
FUNC_ACCESSOR_GET_CONTAINER(eina_array_accessor_get_container);
+   it->accessor.free = FUNC_ACCESSOR_FREE(eina_array_accessor_free);
+
+   return &it->accessor;
+}
+
===================================================================
RCS file: /cvs/e/e17/proto/eina/src/lib/eina_hash.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- eina_hash.c 9 Aug 2008 05:47:15 -0000       1.6
+++ eina_hash.c 11 Aug 2008 16:30:16 -0000      1.7
@@ -32,6 +32,9 @@
  *                                  Local                                     
* 
  
*============================================================================*/
 typedef struct _Eina_Hash_El Eina_Hash_El;
+typedef struct _Eina_Hash_Foreach Eina_Hash_Foreach;
+typedef struct _Eina_Iterator_Hash Eina_Iterator_Hash;
+
 struct _Eina_Hash
 {
    Eina_Key_Length key_length_cb;
@@ -45,10 +48,25 @@
 struct _Eina_Hash_El
 {
    Eina_Inlist _list_data;
+   Eina_Hash_Tuple tuple;
+};
 
-   void *data;
-   const void *key;
-   unsigned int length;
+struct _Eina_Hash_Foreach
+{
+   Eina_Foreach cb;
+   const void *fdata;
+};
+
+struct _Eina_Iterator_Hash
+{
+   Eina_Iterator iterator;
+
+   const Eina_Hash *hash;
+
+   Eina_Inlist *current;
+   int bucket;
+
+   int index;
 };
 
 static int _eina_hash_init_count = 0;
@@ -61,7 +79,7 @@
    key_hash &= 0xFF;
 
    EINA_INLIST_ITER_NEXT(hash->buckets[key_hash], el)
-     if (!hash->key_cmp_cb(el->key, el->length, key, key_length)) return el;
+     if (!hash->key_cmp_cb(el->tuple.key, el->tuple.key_length, key, 
key_length)) return el;
 
    return NULL;
 }
@@ -75,7 +93,7 @@
    /* FIXME: Use an iterator for this stuff */
    for (hash_num = 0; hash_num < 256; hash_num++)
      EINA_INLIST_ITER_NEXT(hash->buckets[hash_num], el)
-       if (el->data == data)
+       if (el->tuple.data == data)
         {
            *key_hash = hash_num;
            return el;
@@ -110,6 +128,90 @@
    return strcmp(key1, key2);
 }
 
+static Eina_Bool
+_eina_foreach_cb(const Eina_Hash *hash, Eina_Hash_Tuple *data, 
Eina_Hash_Foreach *fdata)
+{
+   return fdata->cb((Eina_Hash *) hash, data->key, data->data, (void*) 
fdata->fdata);
+}
+
+static Eina_Bool
+_eina_hash_iterator_next(Eina_Iterator_Hash *it)
+{
+   Eina_Inlist *move;
+   int bucket;
+
+   if (!(it->index + 1 < it->hash->population)) return EINA_FALSE;
+   if (it->current == NULL)
+     {
+       move = NULL;
+       bucket = 0;
+       it->index = -1;
+     }
+   else
+     {
+       bucket = it->bucket;
+       move = it->current->next;
+     }
+
+   if (!move)
+     {
+       while (bucket < 256)
+         {
+            if (it->hash->buckets[bucket] != NULL)
+              {
+                 move = it->hash->buckets[bucket];
+                 break ;
+              }
+            ++bucket;
+         }
+     }
+
+   it->index++;
+   it->bucket = bucket;
+   it->current = move;
+
+   return EINA_TRUE;
+}
+
+static void *
+_eina_hash_iterator_data_get_content(Eina_Iterator_Hash *it)
+{
+   Eina_Hash_El *stuff = (Eina_Hash_El *) it->current;
+
+   if (!stuff) return NULL;
+   return stuff->tuple.data;
+}
+
+static void *
+_eina_hash_iterator_key_get_content(Eina_Iterator_Hash *it)
+{
+   Eina_Hash_El *stuff = (Eina_Hash_El *) it->current;
+
+   if (!stuff) return NULL;
+   return (void *) stuff->tuple.key;
+}
+
+static Eina_Hash_Tuple *
+_eina_hash_iterator_tuple_get_content(Eina_Iterator_Hash *it)
+{
+   Eina_Hash_El *stuff = (Eina_Hash_El *) it->current;
+
+   if (!stuff) return NULL;
+   return &stuff->tuple;
+}
+
+static void *
+_eina_hash_iterator_get_container(Eina_Iterator_Hash *it)
+{
+   return (void *) it->hash;
+}
+
+static void
+_eina_hash_iterator_free(Eina_Iterator_Hash *it)
+{
+   free(it);
+}
+
 /*============================================================================*
  *                                 Global                                     *
  
*============================================================================*/
@@ -225,10 +327,10 @@
    if (!el) goto on_error;
 
    /* Setup the element */
-   el->length = key_length;
-   el->data = (void *) data;
-   el->key = (char *) (el + 1);
-   memcpy((char *) el->key, key, key_length);
+   el->tuple.key_length = key_length;
+   el->tuple.data = (void *) data;
+   el->tuple.key = (char *) (el + 1);
+   memcpy((char *) el->tuple.key, key, key_length);
 
    /* eina hash have 256 buckets. */
    key_hash &= 0xFF;
@@ -284,9 +386,9 @@
    if (!el) goto on_error;
 
    /* Setup the element */
-   el->length = key_length;
-   el->data = (void *) data;
-   el->key = key;
+   el->tuple.key_length = key_length;
+   el->tuple.data = (void *) data;
+   el->tuple.key = key;
 
    /* eina hash have 256 buckets. */
    key_hash &= 0xFF;
@@ -459,7 +561,7 @@
    if (el)
      {
        _eina_hash_reorder((Eina_Hash *) hash, el, key_hash);
-       return el->data;
+       return el->tuple.data;
      }
    return NULL;
 }
@@ -510,8 +612,8 @@
    if (el)
      {
        _eina_hash_reorder((Eina_Hash *) hash, el, key_hash);
-       old_data = el->data;
-       el->data = (void *) data;
+       old_data = el->tuple.data;
+       el->tuple.data = (void *) data;
      }
 
    return old_data;
@@ -601,7 +703,9 @@
    free(hash);
 }
 
-/* FIXME: Create a generic foreach function in the iterator implementation. */
+/*============================================================================*
+ *                                Iterator                                    *
+ 
*============================================================================*/
 /**
  * Call a function on every member stored in the hash table
  * @param hash The hash table whose members will be walked
@@ -635,29 +739,89 @@
  * @endcode
  * @ingroup Eina_Hash_General_Group
  */
-EAPI void eina_hash_foreach(
-               const Eina_Hash *hash,
-               Eina_Foreach func,
-               const void *fdata)
+EAPI void
+eina_hash_foreach(const Eina_Hash *hash,
+                 Eina_Foreach func,
+                 const void *fdata)
 {
-   int i;
+   Eina_Iterator *it;
+   Eina_Hash_Foreach foreach;
 
-   if (!hash) return;
-   for (i = 0; i < 256; i++)
-     {
-       Eina_Inlist *l, *next_l;
+   foreach.cb = func;
+   foreach.fdata = fdata;
 
-       for (l = hash->buckets[i]; l;)
-         {
-            Eina_Hash_El *el;
+   it = eina_hash_iterator_tuple_new(hash);
+   eina_iterator_foreach(it, EINA_EACH(_eina_foreach_cb), &foreach);
+   eina_iterator_free(it);
+}
 
-            next_l = l->next;
-            el = (Eina_Hash_El *)l;
-            if (!func(hash, el->key, el->data, (void *)fdata))
-              return;
-            l = next_l;
-         }
-     }
+EAPI Eina_Iterator *
+eina_hash_iterator_data_new(const Eina_Hash *hash)
+{
+   Eina_Iterator_Hash *it;
+
+   if (!hash) return NULL;
+   if (hash->population <= 0) return NULL;
+
+   it = calloc(1, sizeof (Eina_Iterator_Hash));
+   if (!it) return NULL;
+
+   it->hash = hash;
+
+   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
+   it->iterator.get_content = 
FUNC_ITERATOR_GET_CONTENT(_eina_hash_iterator_data_get_content);
+   it->iterator.get_container = 
FUNC_ITERATOR_GET_CONTAINER(_eina_hash_iterator_get_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free);
+
+   _eina_hash_iterator_next(it);
+
+   return &it->iterator;
+}
+
+EAPI Eina_Iterator *
+eina_hash_iterator_key_new(const Eina_Hash *hash)
+{
+   Eina_Iterator_Hash *it;
+
+   if (!hash) return NULL;
+   if (hash->population <= 0) return NULL;
+
+   it = calloc(1, sizeof (Eina_Iterator_Hash));
+   if (!it) return NULL;
+
+   it->hash = hash;
+
+   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
+   it->iterator.get_content = 
FUNC_ITERATOR_GET_CONTENT(_eina_hash_iterator_key_get_content);
+   it->iterator.get_container = 
FUNC_ITERATOR_GET_CONTAINER(_eina_hash_iterator_get_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free);
+
+   _eina_hash_iterator_next(it);
+
+   return &it->iterator;
+}
+
+EAPI Eina_Iterator *
+eina_hash_iterator_tuple_new(const Eina_Hash *hash)
+{
+   Eina_Iterator_Hash *it;
+
+   if (!hash) return NULL;
+   if (hash->population <= 0) return NULL;
+
+   it = calloc(1, sizeof (Eina_Iterator_Hash));
+   if (!it) return NULL;
+
+   it->hash = hash;
+
+   it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
+   it->iterator.get_content = 
FUNC_ITERATOR_GET_CONTENT(_eina_hash_iterator_tuple_get_content);
+   it->iterator.get_container = 
FUNC_ITERATOR_GET_CONTAINER(_eina_hash_iterator_get_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free);
+
+   _eina_hash_iterator_next(it);
+
+   return &it->iterator;
 }
 
 /* Common hash functions */
===================================================================
RCS file: /cvs/e/e17/proto/eina/src/lib/eina_magic.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- eina_magic.c        8 Aug 2008 14:20:11 -0000       1.3
+++ eina_magic.c        11 Aug 2008 16:30:16 -0000      1.4
@@ -66,14 +66,14 @@
 eina_magic_string_get(Eina_Magic magic)
 {
    Eina_Magic_String *ems;
+   Eina_Array_Iterator it;
    unsigned int i;
 
    if (!strings) return NULL;
 
-   EINA_ARRAY_ITER_NEXT(strings, i, ems)
+   EINA_ARRAY_ITER_NEXT(strings, i, ems, it)
      if (ems->magic == magic)
        return ems->string;
-   EINA_ARRAY_ITER_END;
 
    return NULL;
 }
@@ -82,11 +82,12 @@
 eina_magic_string_set(Eina_Magic magic, const char *magic_name)
 {
    Eina_Magic_String *ems;
+   Eina_Array_Iterator it;
    unsigned int i;
 
    if (!strings) return ;
 
-   EINA_ARRAY_ITER_NEXT(strings, i, ems)
+   EINA_ARRAY_ITER_NEXT(strings, i, ems, it)
      if (ems->magic == magic)
        {
          free(ems->string);
@@ -96,7 +97,6 @@
            ems->string = NULL;
          return ;
        }
-   EINA_ARRAY_ITER_END;
 
    ems = malloc(sizeof (Eina_Magic_String));
    ems->magic = magic;



-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to