* ecore: add ecore_file_ls_iterator.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 2 Jul 2010 15:25:22 +0000 (15:25 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 2 Jul 2010 15:25:22 +0000 (15:25 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@49997 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_file/Ecore_File.h
src/lib/ecore_file/ecore_file.c
src/lib/ecore_file/ecore_file_private.h

index acfa66a..d466969 100644 (file)
@@ -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);
index 8435c45..fd4faa9 100644 (file)
@@ -8,9 +8,6 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
 
 #ifndef _MSC_VER
 # include <unistd.h>
 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
@@ -703,6 +741,46 @@ ecore_file_ls(const char *dir)
 }
 
 /**
+ * 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.
  */
 EAPI char *
index 0729872..95cc1c7 100644 (file)
 # include <Evil.h>
 #endif
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
 #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);