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