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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs