Win32: expand, simplify and (hopefully) fix vlc_w*dir() functions
authorRémi Denis-Courmont <remi@remlab.net>
Wed, 3 Nov 2010 16:12:35 +0000 (18:12 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Wed, 3 Nov 2010 16:12:35 +0000 (18:12 +0200)
src/extras/libc.c
src/libvlc.h
src/win32/filesystem.c

index 9912d4f..4d56540 100644 (file)
 #if defined(WIN32) || defined(UNDER_CE)
 #   define WIN32_LEAN_AND_MEAN
 #   include <windows.h>
-#   include <dirent.h>
 #endif
 
-/*****************************************************************************
- * vlc_*dir_wrapper: wrapper under Windows to return the list of drive letters
- * when called with an empty argument or just '\'
- *****************************************************************************/
-#if defined(WIN32)
-#   include <assert.h>
-
-typedef struct vlc_DIR
-{
-    _WDIR *p_real_dir;
-    int i_drives;
-    struct _wdirent dd_dir;
-    bool b_insert_back;
-} vlc_DIR;
-
-void *vlc_wopendir( const wchar_t *wpath )
-{
-    vlc_DIR *p_dir = NULL;
-    _WDIR *p_real_dir = NULL;
-
-    if ( wpath == NULL || wpath[0] == '\0'
-          || (wcscmp (wpath, L"\\") == 0) )
-    {
-        /* Special mode to list drive letters */
-        p_dir = malloc( sizeof(vlc_DIR) );
-        if( !p_dir )
-            return NULL;
-        p_dir->p_real_dir = NULL;
-#if defined(UNDER_CE)
-        p_dir->i_drives = NULL;
-#else
-        p_dir->i_drives = GetLogicalDrives();
-#endif
-        return (void *)p_dir;
-    }
-
-    p_real_dir = _wopendir( wpath );
-    if ( p_real_dir == NULL )
-        return NULL;
-
-    p_dir = malloc( sizeof(vlc_DIR) );
-    if( !p_dir )
-    {
-        _wclosedir( p_real_dir );
-        return NULL;
-    }
-    p_dir->p_real_dir = p_real_dir;
-
-    assert (wpath[0]); // wpath[1] is defined
-    p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
-    return (void *)p_dir;
-}
-
-struct _wdirent *vlc_wreaddir( void *_p_dir )
-{
-    vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
-    DWORD i_drives;
-
-    if ( p_dir->p_real_dir != NULL )
-    {
-        if ( p_dir->b_insert_back )
-        {
-            /* Adds "..", gruik! */
-            p_dir->dd_dir.d_ino = 0;
-            p_dir->dd_dir.d_reclen = 0;
-            p_dir->dd_dir.d_namlen = 2;
-            wcscpy( p_dir->dd_dir.d_name, L".." );
-            p_dir->b_insert_back = false;
-            return &p_dir->dd_dir;
-        }
-
-        return _wreaddir( p_dir->p_real_dir );
-    }
-
-    /* Drive letters mode */
-    i_drives = p_dir->i_drives;
-#ifdef UNDER_CE
-    swprintf( p_dir->dd_dir.d_name, L"\\");
-    p_dir->dd_dir.d_namlen = wcslen(p_dir->dd_dir.d_name);
-#else
-    unsigned int i;
-    if ( !i_drives )
-        return NULL; /* end */
-
-    for ( i = 0; i < sizeof(DWORD)*8; i++, i_drives >>= 1 )
-        if ( i_drives & 1 ) break;
-
-    if ( i >= 26 )
-        return NULL; /* this should not happen */
-
-    swprintf( p_dir->dd_dir.d_name, L"%c:\\", 'A' + i );
-    p_dir->dd_dir.d_namlen = wcslen(p_dir->dd_dir.d_name);
-    p_dir->i_drives &= ~(1UL << i);
-#endif
-    return &p_dir->dd_dir;
-}
-
-void vlc_rewinddir( void *_p_dir )
-{
-    vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
-
-    if ( p_dir->p_real_dir != NULL )
-        _wrewinddir( p_dir->p_real_dir );
-}
-
-/* This one is in the libvlccore exported symbol list */
-int vlc_wclosedir( void *_p_dir )
-{
-    vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
-    int i_ret = 0;
-
-    if ( p_dir->p_real_dir != NULL )
-        i_ret = _wclosedir( p_dir->p_real_dir );
-
-    free( p_dir );
-    return i_ret;
-}
-#endif
 
 
 #ifdef ENABLE_NLS
index 793e67a..ff52467 100644 (file)
@@ -319,19 +319,4 @@ VLC_EXPORT( void, stats_ComputeInputStats, (input_thread_t*, input_stats_t*) );
 VLC_EXPORT( void, stats_ReinitInputStats, (input_stats_t *) );
 VLC_EXPORT( void, stats_DumpInputStats, (input_stats_t *) );
 
-/*
- * Replacement functions
- */
-#if defined (WIN32)
-#   include <dirent.h>
-void *vlc_wopendir (const wchar_t *);
-void *vlc_wclosedir (void *);
-struct _wdirent *vlc_wreaddir (void *);
-void vlc_rewinddir (void *);
-#   define _wopendir vlc_wopendir
-#   define _wreaddir vlc_wreaddir
-#   define _wclosedir vlc_wclosedir
-#   define rewinddir vlc_rewinddir
-#endif
-
 #endif
index d6a84c4..fde025b 100644 (file)
@@ -108,21 +108,120 @@ int vlc_mkdir( const char *dirname, mode_t mode )
 #endif
 }
 
-DIR *vlc_opendir( const char *dirname )
+/* Under Windows, these wrappers return the list of drive letters
+ * when called with an empty argument or just '\'. */
+typedef struct vlc_DIR
+{
+    _WDIR *p_real_dir;
+    int i_drives;
+    bool b_insert_back;
+} vlc_DIR;
+
+
+DIR *vlc_opendir (const char *dirname)
 {
     CONVERT_PATH (dirname, wpath, NULL);
-    return (DIR *)vlc_wopendir (wpath);
+
+    vlc_DIR *p_dir = malloc (sizeof (*p_dir));
+    if (unlikely(p_dir == NULL))
+        return NULL;
+
+    if (wpath == NULL || wpath[0] == '\0'
+     || (wcscmp (wpath, L"\\") == 0))
+    {
+        /* Special mode to list drive letters */
+        p_dir->p_real_dir = NULL;
+#ifdef UNDER_CE
+        p_dir->i_drives = 1;
+#else
+        p_dir->i_drives = GetLogicalDrives ();
+#endif
+        return (void *)p_dir;
+    }
+
+    _WDIR *p_real_dir = _wopendir (wpath);
+    if (p_real_dir == NULL)
+    {
+        free (p_dir);
+        return NULL;
+    }
+
+    p_dir->p_real_dir = p_real_dir;
+
+    assert (wpath[0]); // wpath[1] is defined
+    p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
+    return (void *)p_dir;
 }
 
-char *vlc_readdir( DIR *dir )
+char *vlc_readdir (DIR *dir)
 {
-    struct _wdirent *ent = vlc_wreaddir (dir);
+    vlc_DIR *p_dir = (vlc_DIR *)dir;
+
+    if (p_dir->p_real_dir == NULL)
+    {
+        /* Drive letters mode */
+        DWORD drives = p_dir->i_drives;
+        if (drives == 0)
+            return NULL; /* end */
+#ifdef UNDER_CE
+        p_dir->i_drives = 0;
+        return strdup ("\\");
+#else
+        unsigned int i;
+        for (i = 0; !(drives & 1); i++)
+            drives >>= 1;
+        p_dir->i_drives &= ~(1UL << i);
+        assert (i < 26);
+
+        char *ret;
+        if (asprintf (&ret, "%c:\\", 'A' + i) == -1)
+            return NULL;
+        return ret;
+#endif
+    }
+
+    if (p_dir->b_insert_back)
+    {
+        /* Adds "..", gruik! */
+        p_dir->b_insert_back = false;
+        return strdup ("..");
+    }
+
+    struct _wdirent *ent = _wreaddir (p_dir->p_real_dir);
     if (ent == NULL)
         return NULL;
-
     return FromWide (ent->d_name);
 }
 
+#if 0
+void vlc_rewinddir (DIR *dir)
+{
+    vlc_DIR *p_dir = (DIR *)dir;
+
+    if (p_dir->p_real_dir == NULL)
+        p_dir->i_drives = GetLogicalDrives ();
+    else
+        _wrewinddir (p_dir->p_real_dir);
+}
+#endif
+
+/* FIXME XXX TODO: needs to replace closedir() with this!!! */
+#warning THIS REALLY NEEDS FIXING!!!
+int vlc_wclosedir (DIR *dir)
+{
+    vlc_DIR *p_dir = (vlc_DIR *)dir;
+    int ret;
+
+    if (p_dir->p_real_dir == NULL)
+        ret = 0;
+    else
+        ret = _wclosedir (p_dir->p_real_dir);
+    free (p_dir);
+
+    return ret;
+}
+
+
 int vlc_stat (const char *filename, struct stat *buf)
 {
 #ifdef UNDER_CE