From: cedric Date: Fri, 2 Jul 2010 17:23:05 +0000 (+0000) Subject: * eina: rename ecore_file_ls_iterator to eina_file_ls. X-Git-Tag: 2.0_alpha~70^2~513 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2cd65c4aec030d4274a2dfafea66b62b9052fd2c;p=framework%2Fuifw%2Feina.git * eina: rename ecore_file_ls_iterator to eina_file_ls. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@50002 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/include/eina_file.h b/src/include/eina_file.h index 7011781..432881d 100644 --- a/src/include/eina_file.h +++ b/src/include/eina_file.h @@ -21,6 +21,7 @@ #include "eina_types.h" #include "eina_array.h" +#include "eina_iterator.h" /** * @addtogroup Eina_Tools_Group Tools @@ -52,6 +53,7 @@ typedef void (*Eina_File_Dir_List_Cb)(const char *name, const char *path, void * EAPI Eina_Bool eina_file_dir_list(const char *dir, Eina_Bool recursive, Eina_File_Dir_List_Cb cb, void *data) EINA_ARG_NONNULL(1, 3); EAPI Eina_Array *eina_file_split(char *path) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); +EAPI Eina_Iterator *eina_file_ls(const char *dir); /** * @} diff --git a/src/lib/eina_file.c b/src/lib/eina_file.c index f826c8b..0b805ec 100644 --- a/src/lib/eina_file.c +++ b/src/lib/eina_file.c @@ -67,6 +67,59 @@ void *alloca (size_t); /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ #include "eina_safety_checks.h" #include "eina_file.h" +#include "eina_stringshare.h" + +typedef struct _Eina_File_Iterator Eina_File_Iterator; +struct _Eina_File_Iterator +{ + Eina_Iterator iterator; + + DIR *dirp; + int length; + + char dir[1]; +}; + +static Eina_Bool +_eina_file_ls_iterator_next(Eina_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 * +_eina_file_ls_iterator_container(Eina_File_Iterator *it) +{ + return it->dir; +} + +static void +_eina_file_ls_iterator_free(Eina_File_Iterator *it) +{ + closedir(it->dirp); + + EINA_MAGIC_SET(&it->iterator, 0); + free(it); +} /*============================================================================* * Global * @@ -269,5 +322,45 @@ eina_file_split(char *path) } /** + * 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 * +eina_file_ls(const char *dir) +{ + Eina_File_Iterator *it; + size_t length; + + if (!dir) return NULL; + + length = strlen(dir); + + it = malloc(sizeof (Eina_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(_eina_file_ls_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_ls_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free); + + return &it->iterator; +} + +/** * @} */