]> git.sesse.net Git - vlc/blobdiff - src/extras/dirent.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / src / extras / dirent.c
index ad3803d394d44185185cd9dca869a76c96a0f1c8..d19b762890a5f4ee7dae03631116e4be719bab7d 100644 (file)
@@ -1,32 +1,73 @@
 /*
  * dirent.c
  *
- * Derived from DIRLIB.C by Matt J. Weinstein 
+ * Derived from DIRLIB.C by Matt J. Weinstein
  * This note appears in the DIRLIB.H
  * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
  *
  * Updated by Jeremy Bettis <jeremy@hksys.com>
  * Significantly revised and rewinddir, seekdir and telldir added by Colin
  * Peters <colin@fu.is.saga-u.ac.jp>
- *     
- * $Revision: 1.1 $
+ *
+ * $Revision: 1.6 $
  * $Author: sam $
- * $Date: 2002/11/09 16:34:52 $
+ * $Date: 2002/11/13 20:51:04 $
  *
  */
 
+#include "config.h"
+
 #include <stdlib.h>
+#include <stdio.h>
+
 #include <errno.h>
 #include <string.h>
-#include <io.h>
-#include <direct.h>
-#include <dirent.h>
+#ifndef UNDER_CE
+#   include <io.h>
+#   include <direct.h>
+#else
+#   define FILENAME_MAX (260)
+#endif
 
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h> /* for GetFileAttributes */
 
-#define SUFFIX "*"
-#define        SLASH   "\\"
+#include <tchar.h>
+#define SUFFIX  "*"
+#define SLASH   "\\"
+
+struct dirent
+{
+    long        d_ino;        /* Always zero. */
+    unsigned short    d_reclen;    /* Always zero. */
+    unsigned short    d_namlen;    /* Length of name in d_name. */
+    char            d_name[FILENAME_MAX]; /* File name. */
+};
+
+typedef struct
+{
+    /* disk transfer area for this dir */
+    WIN32_FIND_DATA        dd_dta;
+
+    /* dirent struct to return from dir (NOTE: this makes this thread
+     * safe as long as only one thread uses a particular DIR struct at
+     * a time) */
+    struct dirent        dd_dir;
+
+    /* findnext handle */
+    HANDLE            dd_handle;
+
+    /*
+         * Status of search:
+     *   0 = not started yet (next entry to read is first entry)
+     *  -1 = off the end
+     *   positive = 0 based index of next entry
+     */
+    int            dd_stat;
+
+    /* given path for dir with search pattern (struct is extended) */
+    char            dd_name[1];
+} DIR;
 
 /*
  * opendir
  * Returns a pointer to a DIR structure appropriately filled in to begin
  * searching a directory.
  */
-DIR * 
-opendir (const CHAR *szPath)
+DIR *
+vlc_opendir (const CHAR *szPath)
 {
   DIR *nd;
   unsigned int rc;
   CHAR szFullPath[MAX_PATH];
-       
+
   errno = 0;
 
   if (!szPath)
@@ -56,8 +97,17 @@ opendir (const CHAR *szPath)
     }
 
   /* Attempt to determine if the given path really is a directory. */
+#ifdef UNICODE
+  {
+    wchar_t szPathTmp[MAX_PATH];
+    mbstowcs( szPathTmp, szPath, MAX_PATH );
+    szPathTmp[MAX_PATH-1] = 0;
+    rc = GetFileAttributes (szPathTmp);
+  }
+#else
   rc = GetFileAttributes (szPath);
-  if (rc == -1)
+#endif
+  if (rc == (unsigned int)-1)
     {
       /* call GetLastError for more error info */
       errno = ENOENT;
@@ -71,12 +121,34 @@ opendir (const CHAR *szPath)
     }
 
   /* Make an absolute pathname.  */
+#if defined( UNDER_CE )
+  if (szPath[0] == '\\' || szPath[0] == '/')
+    {
+      sprintf (szFullPath, "%s", szPath);
+      szFullPath[0] = '\\';
+    }
+  else
+    {
+      wchar_t szFullPathTmp[MAX_PATH];
+      if (GetModuleFileName( NULL, szFullPathTmp, MAX_PATH ) )
+        {
+          wcstombs( szFullPath, szFullPathTmp, MAX_PATH );
+          szFullPath[MAX_PATH-1] = 0;
+        }
+      else
+        {
+          /* FIXME: if I wasn't lazy, I'd check for overflows here. */
+          sprintf (szFullPath, "\\%s", szPath );
+        }
+    }
+#else
   _fullpath (szFullPath, szPath, MAX_PATH);
+#endif
 
   /* Allocate enough space to store DIR structure and the complete
    * directory path given. */
-  nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + strlen (SLASH) +
-                      strlen (SUFFIX));
+  nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + sizeof (SLASH) +
+                       sizeof (SUFFIX));
 
   if (!nd)
     {
@@ -99,9 +171,9 @@ opendir (const CHAR *szPath)
   /* Add on the search pattern */
   strcat (nd->dd_name, SUFFIX);
 
-  /* Initialize handle to -1 so that a premature closedir doesn't try
-   * to call _findclose on it. */
-  nd->dd_handle = -1;
+  /* Initialize handle so that a premature closedir doesn't try
+   * to call FindClose on it. */
+  nd->dd_handle = INVALID_HANDLE_VALUE;
 
   /* Initialize the status. */
   nd->dd_stat = 0;
@@ -112,7 +184,7 @@ opendir (const CHAR *szPath)
   nd->dd_dir.d_ino = 0;
   nd->dd_dir.d_reclen = 0;
   nd->dd_dir.d_namlen = 0;
-  nd->dd_dir.d_name = nd->dd_dta.name;
+  memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
 
   return nd;
 }
@@ -125,7 +197,7 @@ opendir (const CHAR *szPath)
  * next entry in the directory.
  */
 struct dirent *
-readdir (DIR * dirp)
+vlc_readdir (DIR * dirp)
 {
   errno = 0;
 
@@ -136,13 +208,6 @@ readdir (DIR * dirp)
       return (struct dirent *) 0;
     }
 
-  if (dirp->dd_dir.d_name != dirp->dd_dta.name)
-    {
-      /* The structure does not seem to be set up correctly. */
-      errno = EINVAL;
-      return (struct dirent *) 0;
-    }
-
   if (dirp->dd_stat < 0)
     {
       /* We have already returned all files in the directory
@@ -151,44 +216,59 @@ readdir (DIR * dirp)
     }
   else if (dirp->dd_stat == 0)
     {
+#ifdef UNICODE
+        wchar_t dd_name[MAX_PATH];
+        mbstowcs( dd_name, dirp->dd_name, MAX_PATH );
+        dd_name[MAX_PATH-1] = 0;
+#else
+        char *dd_name = dirp->dd_name;
+#endif
       /* We haven't started the search yet. */
       /* Start the search */
-      dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
-
-         if (dirp->dd_handle == -1)
-       {
-         /* Whoops! Seems there are no files in that
-          * directory. */
-         dirp->dd_stat = -1;
-       }
+      dirp->dd_handle = FindFirstFile (dd_name, &(dirp->dd_dta));
+
+          if (dirp->dd_handle == INVALID_HANDLE_VALUE)
+        {
+          /* Whoops! Seems there are no files in that
+           * directory. */
+          dirp->dd_stat = -1;
+        }
       else
-       {
-         dirp->dd_stat = 1;
-       }
+        {
+          dirp->dd_stat = 1;
+        }
     }
   else
     {
       /* Get the next search entry. */
-      if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
-       {
-         /* We are off the end or otherwise error. */
-         _findclose (dirp->dd_handle);
-         dirp->dd_handle = -1;
-         dirp->dd_stat = -1;
-       }
+      if (!FindNextFile ((HANDLE)dirp->dd_handle, &(dirp->dd_dta)))
+        {
+          /* We are off the end or otherwise error. */
+          FindClose ((HANDLE)dirp->dd_handle);
+          dirp->dd_handle = INVALID_HANDLE_VALUE;
+          dirp->dd_stat = -1;
+        }
       else
-       {
-         /* Update the status to indicate the correct
-          * number. */
-         dirp->dd_stat++;
-       }
+        {
+          /* Update the status to indicate the correct
+           * number. */
+          dirp->dd_stat++;
+        }
     }
 
   if (dirp->dd_stat > 0)
     {
-      /* Successfully got an entry. Everything about the file is
-       * already appropriately filled in except the length of the
-       * file name. */
+      /* Successfully got an entry */
+
+#ifdef UNICODE
+      char d_name[MAX_PATH];
+      wcstombs( d_name, dirp->dd_dta.cFileName, MAX_PATH );
+      d_name[MAX_PATH-1] = 0;
+#else
+      char *d_name = dirp->dd_dta.cFileName;
+#endif
+
+      strcpy (dirp->dd_dir.d_name, d_name);
       dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
       return &dirp->dd_dir;
     }
@@ -203,7 +283,7 @@ readdir (DIR * dirp)
  * Frees up resources allocated by opendir.
  */
 int
-closedir (DIR * dirp)
+vlc_closedir (DIR * dirp)
 {
   int rc;
 
@@ -216,9 +296,9 @@ closedir (DIR * dirp)
       return -1;
     }
 
-  if (dirp->dd_handle != -1)
+  if (dirp->dd_handle != INVALID_HANDLE_VALUE)
     {
-      rc = _findclose (dirp->dd_handle);
+      rc = FindClose ((HANDLE)dirp->dd_handle);
     }
 
   /* Delete the dir structure. */
@@ -234,7 +314,7 @@ closedir (DIR * dirp)
  * and then reset things like an opendir.
  */
 void
-rewinddir (DIR * dirp)
+vlc_rewinddir (DIR * dirp)
 {
   errno = 0;
 
@@ -244,76 +324,11 @@ rewinddir (DIR * dirp)
       return;
     }
 
-  if (dirp->dd_handle != -1)
+  if (dirp->dd_handle != INVALID_HANDLE_VALUE)
     {
-      _findclose (dirp->dd_handle);
+      FindClose ((HANDLE)dirp->dd_handle);
     }
 
-  dirp->dd_handle = -1;
+  dirp->dd_handle = INVALID_HANDLE_VALUE;
   dirp->dd_stat = 0;
 }
-
-/*
- * telldir
- *
- * Returns the "position" in the "directory stream" which can be used with
- * seekdir to go back to an old entry. We simply return the value in stat.
- */
-long
-telldir (DIR * dirp)
-{
-  errno = 0;
-
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return -1;
-    }
-  return dirp->dd_stat;
-}
-
-/*
- * seekdir
- *
- * Seek to an entry previously returned by telldir. We rewind the directory
- * and call readdir repeatedly until either dd_stat is the position number
- * or -1 (off the end). This is not perfect, in that the directory may
- * have changed while we weren't looking. But that is probably the case with
- * any such system.
- */
-void
-seekdir (DIR * dirp, long lPos)
-{
-  errno = 0;
-
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return;
-    }
-
-  if (lPos < -1)
-    {
-      /* Seeking to an invalid position. */
-      errno = EINVAL;
-      return;
-    }
-  else if (lPos == -1)
-    {
-      /* Seek past end. */
-      if (dirp->dd_handle != -1)
-       {
-         _findclose (dirp->dd_handle);
-       }
-      dirp->dd_handle = -1;
-      dirp->dd_stat = -1;
-    }
-  else
-    {
-      /* Rewind and read forward to the appropriate index. */
-      rewinddir (dirp);
-
-      while ((dirp->dd_stat < lPos) && readdir (dirp))
-       ;
-    }
-}