From 87b85132ddf369e207e6e592099fa455719abbbf Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 2 Jul 2010 15:25:22 +0000 Subject: [PATCH] * ecore: add ecore_file_ls_iterator. SVN revision: 49997 --- legacy/ecore/src/lib/ecore_file/Ecore_File.h | 1 + legacy/ecore/src/lib/ecore_file/ecore_file.c | 84 ++++++++++++++++++- .../src/lib/ecore_file/ecore_file_private.h | 15 ++++ 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/legacy/ecore/src/lib/ecore_file/Ecore_File.h b/legacy/ecore/src/lib/ecore_file/Ecore_File.h index acfa66ad7a..d466969dbe 100644 --- a/legacy/ecore/src/lib/ecore_file/Ecore_File.h +++ b/legacy/ecore/src/lib/ecore_file/Ecore_File.h @@ -90,6 +90,7 @@ extern "C" { EAPI Eina_Bool ecore_file_can_exec (const char *file); EAPI char *ecore_file_readlink (const char *link); EAPI Eina_List *ecore_file_ls (const char *dir); + EAPI Eina_Iterator *ecore_file_ls_iterator(const char *dir); EAPI char *ecore_file_app_exe_get (const char *app); EAPI char *ecore_file_escape_name (const char *filename); EAPI char *ecore_file_strip_ext (const char *file); diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file.c b/legacy/ecore/src/lib/ecore_file/ecore_file.c index 8435c45ccc..fd4faa9e27 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file.c @@ -8,9 +8,6 @@ #include #include -#include -#include -#include #ifndef _MSC_VER # include @@ -32,6 +29,47 @@ int _ecore_file_log_dom = -1; static int _ecore_file_init_count = 0; +static Eina_Bool +_ecore_file_ls_iterator_next(Ecore_File_Iterator *it, void **data) +{ + struct dirent *dp; + char *name; + size_t length; + + do + { + dp = readdir(it->dirp); + if (!dp) return EINA_FALSE; + } + while (!strcmp(dp->d_name, ".") + || !strcmp(dp->d_name, "..")); + + length = strlen(dp->d_name); + name = alloca(length + 2 + it->length); + + memcpy(name, it->dir, it->length); + memcpy(name + it->length, "/", 1); + memcpy(name + it->length + 1, dp->d_name, length + 1); + + *data = (char*) eina_stringshare_add(name); + return EINA_TRUE; +} + +static char * +_ecore_file_ls_iterator_container(Ecore_File_Iterator *it) +{ + return it->dir; +} + +static void +_ecore_file_ls_iterator_free(Ecore_File_Iterator *it) +{ + closedir(it->dirp); + + EINA_MAGIC_SET(&it->iterator, 0); + free(it); +} + /* externally accessible functions */ /** * Initialize Ecore_File and the services it will use. Call this function @@ -702,6 +740,46 @@ ecore_file_ls(const char *dir) return list; } +/** + * Get an iterator to list the content of a directory. Give a chance to interrupt it + * and make it completly asynchrone. + * The iterator will walk over '.' and '..' without returning them. + * @param dir The name of the directory to list + * @return Return an Eina_Iterator that will walk over the files and directory in the pointed + * directory. On failure it will return NULL. + */ +EAPI Eina_Iterator * +ecore_file_ls_iterator(const char *dir) +{ + Ecore_File_Iterator *it; + size_t length; + + if (!dir) return NULL; + + length = strlen(dir); + + it = malloc(sizeof (Ecore_File_Iterator) + length); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->dirp = opendir(dir); + if (!it->dirp) + { + free(it); + return NULL; + } + + memcpy(it->dir, dir, length + 1); + it->length = length; + + it->iterator.next = FUNC_ITERATOR_NEXT(_ecore_file_ls_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_ecore_file_ls_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_ecore_file_ls_iterator_free); + + return &it->iterator; +} + /** * FIXME: To be documented. */ diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_private.h b/legacy/ecore/src/lib/ecore_file/ecore_file_private.h index 072987299a..95cc1c7e09 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_private.h +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_private.h @@ -13,6 +13,10 @@ # include #endif +#include +#include +#include + #include "Ecore.h" #include "ecore_private.h" @@ -78,6 +82,17 @@ struct _Ecore_File_Monitor Ecore_File *files; }; +typedef struct _Ecore_File_Iterator Ecore_File_Iterator; +struct _Ecore_File_Iterator +{ + Eina_Iterator iterator; + + DIR *dirp; + int length; + + char dir[1]; +}; + #ifdef HAVE_INOTIFY int ecore_file_monitor_inotify_init(void); int ecore_file_monitor_inotify_shutdown(void);