* eina: rename ecore_file_ls_iterator to eina_file_ls.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 2 Jul 2010 17:23:05 +0000 (17:23 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 2 Jul 2010 17:23:05 +0000 (17:23 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@50002 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/include/eina_file.h
src/lib/eina_file.c

index 7011781..432881d 100644 (file)
@@ -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);
 
 /**
  * @}
index f826c8b..0b805ec 100644 (file)
@@ -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;
+}
+
+/**
  * @}
  */