2007-04-27 Jonathan Chambers <joncham@gmail.com>
[mono.git] / eglib / src / gdir.c
index 69f8bc1f89abb2fe09d4fe49bb7075bb9bc3bf74..e8de00212074b1697d76ecee929a32dcad990145 100644 (file)
 #ifndef _MSC_VER
 #include <unistd.h>
 #include <dirent.h>
+#else
+#include <io.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <winsock2.h>
 #endif
 
 struct _GDir {
 #ifdef G_OS_WIN32
-       /* FIXME */
-       int dir;
+       HANDLE handle;
+       gchar* current;
+       gchar* next;
 #else
        DIR *dir;
 #endif
@@ -49,7 +56,54 @@ GDir *
 g_dir_open (const gchar *path, guint flags, GError **error)
 {
 #ifdef G_OS_WIN32
-       return NULL;
+       GDir *dir;
+       gunichar2* path_utf16;
+       gunichar2* path_utf16_search;
+       WIN32_FIND_DATA find_data;
+
+       g_return_val_if_fail (path != NULL, NULL);
+       g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+       dir = g_new0 (GDir, 1);
+
+       path_utf16 = u8to16 (path);
+
+       dir->handle = FindFirstFile (path_utf16, &find_data);
+       if (dir->handle == INVALID_HANDLE_VALUE) {
+               if (error) {
+                       gint err = errno;
+                       *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), strerror (err));
+               }
+               g_free (dir);
+               g_free (path_utf16);
+               return NULL;
+       }
+
+       /* now get files */
+       FindClose (dir->handle);
+       path_utf16_search = g_malloc ((wcslen(path_utf16) + 3)*sizeof(gunichar2));
+       wcscpy (path_utf16_search, path_utf16);
+       wcscat (path_utf16_search, L"\\*");
+
+       dir->handle = FindFirstFile (path_utf16_search, &find_data);
+       g_free (path_utf16_search);
+
+       while ((wcscmp (find_data.cFileName, L".") == 0) || (wcscmp (find_data.cFileName, L"..") == 0)) {
+               if (!FindNextFile (dir->handle, &find_data)) {
+                       if (error) {
+                               gint err = errno;
+                               *error = g_error_new (G_LOG_DOMAIN, g_file_error_from_errno (err), strerror (err));
+                       }
+                       g_free (dir);
+                       g_free (path_utf16);
+                       return NULL;
+               }
+       }
+
+       dir->current = NULL;
+       dir->next = u16to8 (find_data.cFileName);
+
+       g_free (path_utf16);
+       return dir;
 #else
        GDir *dir;
 
@@ -75,7 +129,30 @@ const gchar *
 g_dir_read_name (GDir *dir)
 {
 #ifdef G_OS_WIN32
-       return NULL;
+       WIN32_FIND_DATA find_data;
+
+       g_return_val_if_fail (dir != NULL && dir->handle != 0, NULL);
+
+       if (dir->current)
+               g_free (dir->current);
+       dir->current = NULL;
+
+       dir->current = dir->next;
+
+       if (!dir->current)
+               return NULL;
+
+       dir->next = NULL;
+
+       do {
+               if (!FindNextFile (dir->handle, &find_data)) {
+                       dir->next = NULL;
+                       return dir->current;
+               }
+       } while ((wcscmp (find_data.cFileName, L".") == 0) || (wcscmp (find_data.cFileName, L"..") == 0));
+
+       dir->next = u16to8 (find_data.cFileName);
+       return dir->current;
 #else
        struct dirent *entry;
 
@@ -104,11 +181,23 @@ void
 g_dir_close (GDir *dir)
 {
 #ifdef G_OS_WIN32
+       g_return_if_fail (dir != NULL && dir->handle != 0);
+       
+       if (dir->current)
+               g_free (dir->current);
+       dir->current = NULL;
+       if (dir->next)
+               g_free (dir->next);
+       dir->next = NULL;
+       FindClose (dir->handle);
+       dir->handle = 0;
+       g_free (dir);
 #else
-       g_return_if_fail (dir != NULL && dir->dir != NULL);
+       g_return_if_fail (dir != NULL && dir->dir != 0);
        closedir (dir->dir);
        dir->dir = NULL;
        g_free (dir);
 #endif
 }
 
+