]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/filefn.cpp
don't write the strings to the stream one char at a time, it's *horribly* slow
[wxWidgets.git] / src / common / filefn.cpp
index 583c0711b330a6e8f5ace3aa7d4efa67f944a04f..a45a871c00f002253472f82020f19853d6d5646c 100644 (file)
 
 #ifdef __WINDOWS__
     #include <windows.h>
 
 #ifdef __WINDOWS__
     #include <windows.h>
+    #include "wx/msw/mslu.h"
 
     // sys/cygwin.h is needed for cygwin_conv_to_full_win32_path()
     //
 
     // sys/cygwin.h is needed for cygwin_conv_to_full_win32_path()
     //
     #define _MAXPATHLEN 1024
 #endif
 
     #define _MAXPATHLEN 1024
 #endif
 
-extern wxChar *wxBuffer;
-
 #ifdef __WXMAC__
 #    include "MoreFiles.h"
 #    include "MoreFilesExtras.h"
 #ifdef __WXMAC__
 #    include "MoreFiles.h"
 #    include "MoreFilesExtras.h"
@@ -157,6 +156,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxStringList)
 // private globals
 // ----------------------------------------------------------------------------
 
 // private globals
 // ----------------------------------------------------------------------------
 
+// MT-FIXME: get rid of this horror and all code using it
 static wxChar wxFileFunctionsBuffer[4*_MAXPATHLEN];
 
 #if defined(__VISAGECPP__) && __IBMCPP__ >= 400
 static wxChar wxFileFunctionsBuffer[4*_MAXPATHLEN];
 
 #if defined(__VISAGECPP__) && __IBMCPP__ >= 400
@@ -670,11 +670,6 @@ wxContractPath (const wxString& filename, const wxString& envname, const wxStrin
       wxStrcpy(wxFileFunctionsBuffer, wxT("~"));
       if (user != wxT(""))
              wxStrcat(wxFileFunctionsBuffer, (const wxChar*) user);
       wxStrcpy(wxFileFunctionsBuffer, wxT("~"));
       if (user != wxT(""))
              wxStrcat(wxFileFunctionsBuffer, (const wxChar*) user);
-#ifdef __WXMSW__
-//      strcat(wxFileFunctionsBuffer, "\\");
-#else
-//      strcat(wxFileFunctionsBuffer, "/");
-#endif
       wxStrcat(wxFileFunctionsBuffer, dest + len);
       wxStrcpy (dest, wxFileFunctionsBuffer);
     }
       wxStrcat(wxFileFunctionsBuffer, dest + len);
       wxStrcpy (dest, wxFileFunctionsBuffer);
     }
@@ -682,75 +677,27 @@ wxContractPath (const wxString& filename, const wxString& envname, const wxStrin
   return dest;
 }
 
   return dest;
 }
 
-// Return just the filename, not the path
-// (basename)
+// Return just the filename, not the path (basename)
 wxChar *wxFileNameFromPath (wxChar *path)
 {
 wxChar *wxFileNameFromPath (wxChar *path)
 {
-    if (path)
-    {
-        register wxChar *tcp;
+    wxString p = path;
+    wxString n = wxFileNameFromPath(p);
 
 
-        tcp = path + wxStrlen (path);
-        while (--tcp >= path)
-        {
-#if defined(__WXMAC__) && !defined(__DARWIN__)
-            // Classic or Carbon CodeWarrior like
-            // Carbon with Apple DevTools is Unix like
-            if (*tcp == wxT(':'))
-                return tcp + 1;
-#else
-            // Unix like or Windows
-            if (*tcp == wxT('/') || *tcp == wxT('\\'))
-                return tcp + 1;
-#endif
-#ifdef __VMS__
-            if (*tcp == wxT(':') || *tcp == wxT(']'))
-                return tcp + 1;
-#endif
-        } /* while */
-#if defined(__WXMSW__) || defined(__WXPM__)
-        // MSDOS like
-        if (wxIsalpha (*path) && *(path + 1) == wxT(':'))
-            return path + 2;
-#endif
-    }
-    return path;
+    return path + p.length() - n.length();
 }
 
 }
 
-wxString wxFileNameFromPath (const wxString& path1)
+wxString wxFileNameFromPath (const wxString& path)
 {
 {
-    if (path1 != wxT(""))
-    {
-        wxChar *path = WXSTRINGCAST path1 ;
-        register wxChar *tcp;
+    wxString name, ext;
+    wxFileName::SplitPath(path, NULL, &name, &ext);
 
 
-        tcp = path + wxStrlen (path);
-        while (--tcp >= path)
-        {
-#if defined(__WXMAC__) && !defined(__DARWIN__)
-            // Classic or Carbon CodeWarrior like
-            // Carbon with Apple DevTools is Unix like
-            if (*tcp == wxT(':') )
-                return wxString(tcp + 1);
-#else
-            // Unix like or Windows
-            if (*tcp == wxT('/') || *tcp == wxT('\\'))
-                return wxString(tcp + 1);
-#endif
-#ifdef __VMS__
-            if (*tcp == wxT(':') || *tcp == wxT(']'))
-                return wxString(tcp + 1);
-#endif
-        } /* while */
-#if defined(__WXMSW__) || defined(__WXPM__)
-        // MSDOS like
-        if (wxIsalpha (*path) && *(path + 1) == wxT(':'))
-            return wxString(path + 2);
-#endif
+    wxString fullname = name;
+    if ( !ext.empty() )
+    {
+        fullname << wxFILE_SEP_EXT << ext;
     }
     }
-    // Yes, this should return the path, not an empty string, otherwise
-    // we get "thing.txt" -> "".
-    return path1;
+
+    return fullname;
 }
 
 // Return just the directory, or NULL if no directory
 }
 
 // Return just the directory, or NULL if no directory
@@ -874,13 +821,55 @@ wxString wxPathOnly (const wxString& path)
 wxString wxMacFSSpec2MacFilename( const FSSpec *spec )
 {
 #ifdef __DARWIN__
 wxString wxMacFSSpec2MacFilename( const FSSpec *spec )
 {
 #ifdef __DARWIN__
-    FSRef theRef;
-    char  thePath[FILENAME_MAX];
-
-    // convert the FSSpec to an FSRef
-    (void) FSpMakeFSRef( spec, &theRef );
-    // get the POSIX path associated with the FSRef
-    (void) FSRefMakePath( &theRef, (UInt8 *)thePath, sizeof(thePath) );
+    int         i;
+    int         j;
+    OSErr       theErr;
+    OSStatus    theStatus;
+    Boolean    isDirectory = false;
+    Str255     theParentPath = "\p";
+    FSSpec      theParentSpec;
+    FSRef       theParentRef;
+    char        theFileName[FILENAME_MAX];
+    char        thePath[FILENAME_MAX];
+
+    strcpy(thePath, "");
+
+    // GD: Separate file name from path and make a FSRef to the parent
+    //     directory. This is necessary since FSRefs cannot reference files
+    //     that have not yet been created.
+    //     Based on example code from Apple Technical Note TN2022
+    //       http://developer.apple.com/technotes/tn/tn2022.html
+
+    // check whether we are converting a directory
+    isDirectory = ((spec->name)[spec->name[0]] == ':');
+    // count length of file name
+    for (i = spec->name[0] - (isDirectory ? 1 : 0); ((spec->name[i] != ':') && (i > 0)); i--);
+    // copy file name
+    //   prepend path separator since it will later be appended to the path
+    theFileName[0] = wxFILE_SEP_PATH;
+    for (j = i + 1; j <= spec->name[0] - (isDirectory ? 1 : 0); j++) {
+        theFileName[j - i] = spec->name[j];
+    }
+    theFileName[j - i] = '\0';
+    // copy path if any
+    for (j = 1; j <= i; j++) {
+        theParentPath[++theParentPath[0]] = spec->name[j];
+    }
+    theErr = FSMakeFSSpec(spec->vRefNum, spec->parID, theParentPath, &theParentSpec);
+    if (theErr == noErr) {
+        // convert the FSSpec to an FSRef
+        theErr = FSpMakeFSRef(&theParentSpec, &theParentRef);
+    }
+    if (theErr == noErr) {
+        // get the POSIX path associated with the FSRef
+        theStatus = FSRefMakePath(&theParentRef,
+                                  (UInt8 *)thePath, sizeof(thePath));
+    }
+    if (theStatus == noErr) {
+        // append file name to path
+        //   includes previously prepended path separator
+        strcat(thePath, theFileName);
+    }
 
     // create path string for return value
     wxString result( thePath ) ;
 
     // create path string for return value
     wxString result( thePath ) ;
@@ -1087,11 +1076,15 @@ wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite)
     // instead of our code if available
     //
     // NB: 3rd parameter is bFailIfExists i.e. the inverse of overwrite
     // instead of our code if available
     //
     // NB: 3rd parameter is bFailIfExists i.e. the inverse of overwrite
-    return ::CopyFile(file1, file2, !overwrite) != 0;
+    if ( !::CopyFile(file1, file2, !overwrite) )
+    {
+        wxLogSysError(_("Failed to copy the file '%s' to '%s'"),
+                      file1.c_str(), file2.c_str());
+
+        return FALSE;
+    }
 #elif defined(__WXPM__)
 #elif defined(__WXPM__)
-    if (::DosCopy(file2, file2, overwrite ? DCPY_EXISTING : 0) == 0)
-        return TRUE;
-    else
+    if ( ::DosCopy(file2, file2, overwrite ? DCPY_EXISTING : 0) != 0 )
         return FALSE;
 #else // !Win32
     wxStructStat fbuf;
         return FALSE;
 #else // !Win32
     wxStructStat fbuf;
@@ -1170,9 +1163,9 @@ wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite)
         return FALSE;
     }
 #endif // OS/2 || Mac
         return FALSE;
     }
 #endif // OS/2 || Mac
+#endif // __WXMSW__ && __WIN32__
 
     return TRUE;
 
     return TRUE;
-#endif // __WXMSW__ && __WIN32__
 }
 
 bool
 }
 
 bool
@@ -1326,7 +1319,7 @@ static wxString gs_dirPath;
 
 wxString wxFindFirstFile(const wxChar *spec, int flags)
 {
 
 wxString wxFindFirstFile(const wxChar *spec, int flags)
 {
-    gs_dirPath = wxPathOnly(spec);
+    wxSplitPath(spec, &gs_dirPath, NULL, NULL);
     if ( gs_dirPath.IsEmpty() )
         gs_dirPath = wxT(".");
     if ( gs_dirPath.Last() != wxFILE_SEP_PATH )
     if ( gs_dirPath.IsEmpty() )
         gs_dirPath = wxT(".");
     if ( gs_dirPath.Last() != wxFILE_SEP_PATH )
@@ -1351,7 +1344,7 @@ wxString wxFindFirstFile(const wxChar *spec, int flags)
     }
 
     wxString result;
     }
 
     wxString result;
-    gs_dir->GetFirst(&result, wxFileNameFromPath(spec), dirFlags);
+    gs_dir->GetFirst(&result, wxFileNameFromPath(wxString(spec)), dirFlags);
     if ( result.IsEmpty() )
     {
         wxDELETE(gs_dir);
     if ( result.IsEmpty() )
     {
         wxDELETE(gs_dir);
@@ -1388,21 +1381,37 @@ wxChar *wxGetWorkingDirectory(wxChar *buf, int sz)
         buf = new wxChar[sz + 1];
     }
 
         buf = new wxChar[sz + 1];
     }
 
-    bool ok;
+    bool ok = FALSE;
 
     // for the compilers which have Unicode version of _getcwd(), call it
     // directly, for the others call the ANSI version and do the translation
 
     // for the compilers which have Unicode version of _getcwd(), call it
     // directly, for the others call the ANSI version and do the translation
-#if wxUSE_UNICODE
+#if !wxUSE_UNICODE
+    #define cbuf buf
+#else // wxUSE_UNICODE
+    bool needsANSI = TRUE;
+
+    #if !defined(HAVE_WGETCWD) || wxUSE_UNICODE_MSLU
+        wxCharBuffer c_buffer(sz);
+        char *cbuf = (char*)(const char*)c_buffer;
+    #endif
+
     #ifdef HAVE_WGETCWD
     #ifdef HAVE_WGETCWD
-        ok = _wgetcwd(buf, sz) != NULL;
-    #else // !HAVE_WGETCWD
-        wxCharBuffer cbuf(sz);
+        #if wxUSE_UNICODE_MSLU
+            if ( wxGetOsVersion() != wxWIN95 )
+        #else
+            char *cbuf = NULL; // never really used because needsANSI will always be FALSE
+        #endif
+            {
+                ok = _wgetcwd(buf, sz) != NULL;
+                needsANSI = FALSE;
+            }
     #endif
     #endif
-#endif //
 
 
-#if !wxUSE_UNICODE || !defined(HAVE_WGETCWD)
+    if ( needsANSI )
+#endif // wxUSE_UNICODE
+    {
     #ifdef _MSC_VER
     #ifdef _MSC_VER
-        ok = _getcwd(buf, sz) != NULL;
+        ok = _getcwd(cbuf, sz) != NULL;
     #elif defined(__WXMAC__) && !defined(__DARWIN__)
         FSSpec cwdSpec ;
         FCBPBRec pb;
     #elif defined(__WXMAC__) && !defined(__DARWIN__)
         FSSpec cwdSpec ;
         FCBPBRec pb;
@@ -1420,8 +1429,8 @@ wxChar *wxGetWorkingDirectory(wxChar *buf, int sz)
             cwdSpec.name[0] = 0 ;
             wxString res = wxMacFSSpec2MacFilename( &cwdSpec ) ;
 
             cwdSpec.name[0] = 0 ;
             wxString res = wxMacFSSpec2MacFilename( &cwdSpec ) ;
 
-            strcpy( buf , res ) ;
-            buf[res.length()]=0 ;
+            strcpy( cbuf , res ) ;
+            cbuf[res.length()]=0 ;
 
             ok = TRUE;
         }
 
             ok = TRUE;
         }
@@ -1432,14 +1441,19 @@ wxChar *wxGetWorkingDirectory(wxChar *buf, int sz)
     #elif defined(__VISAGECPP__) || (defined (__OS2__) && defined (__WATCOMC__))
         APIRET rc;
         rc = ::DosQueryCurrentDir( 0 // current drive
     #elif defined(__VISAGECPP__) || (defined (__OS2__) && defined (__WATCOMC__))
         APIRET rc;
         rc = ::DosQueryCurrentDir( 0 // current drive
-                                  ,buf
+                                  ,cbuf
                                   ,(PULONG)&sz
                                  );
         ok = rc != 0;
     #else // !Win32/VC++ !Mac !OS2
                                   ,(PULONG)&sz
                                  );
         ok = rc != 0;
     #else // !Win32/VC++ !Mac !OS2
-        ok = getcwd(buf, sz) != NULL;
+        ok = getcwd(cbuf, sz) != NULL;
     #endif // platform
     #endif // platform
-#endif // !wxUSE_UNICODE || !HAVE_WGETCWD
+
+    #if wxUSE_UNICODE
+        // finally convert the result to Unicode if needed
+        wxConvFile.MB2WC(buf, cbuf, sz);
+    #endif // wxUSE_UNICODE
+    }
 
     if ( !ok )
     {
 
     if ( !ok )
     {
@@ -1468,14 +1482,13 @@ wxChar *wxGetWorkingDirectory(wxChar *buf, int sz)
         wxString pathUnix = buf;
         cygwin_conv_to_full_win32_path(pathUnix, buf);
 #endif // __CYGWIN__
         wxString pathUnix = buf;
         cygwin_conv_to_full_win32_path(pathUnix, buf);
 #endif // __CYGWIN__
-
-        // finally convert the result to Unicode if needed
-#if wxUSE_UNICODE && !defined(HAVE_WGETCWD)
-        wxConvFile.MB2WC(buf, cbuf, sz);
-#endif // wxUSE_UNICODE
     }
 
     return buf;
     }
 
     return buf;
+
+#if !wxUSE_UNICODE
+    #undef cbuf
+#endif
 }
 
 wxString wxGetCwd()
 }
 
 wxString wxGetCwd()
@@ -1633,7 +1646,7 @@ bool wxIsWild( const wxString& pattern )
 
 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
 
 
 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
 
-#if defined(HAVE_FNMATCH_H)
+#ifdef HAVE_FNMATCH
 {
 // this probably won't work well for multibyte chars in Unicode mode?
    if(dot_special)
 {
 // this probably won't work well for multibyte chars in Unicode mode?
    if(dot_special)
@@ -1641,7 +1654,7 @@ bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
    else
       return fnmatch(pat.fn_str(), text.fn_str(), 0) == 0;
 }
    else
       return fnmatch(pat.fn_str(), text.fn_str(), 0) == 0;
 }
-#else
+#else // !HAVE_FNMATCH
 
 // #pragma error Broken implementation of wxMatchWild() -- needs fixing!
 
 
 // #pragma error Broken implementation of wxMatchWild() -- needs fixing!
 
@@ -1782,33 +1795,8 @@ bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
     return ((*str == wxT('\0')) && (*pattern == wxT('\0')));
 };
 
     return ((*str == wxT('\0')) && (*pattern == wxT('\0')));
 };
 
-#endif
+#endif // HAVE_FNMATCH/!HAVE_FNMATCH
 
 #ifdef __VISUALC__
     #pragma warning(default:4706)   // assignment within conditional expression
 #endif // VC++
 
 #ifdef __VISUALC__
     #pragma warning(default:4706)   // assignment within conditional expression
 #endif // VC++
-
-//------------------------------------------------------------------------
-// Missing functions in Unicode for Win9x
-//------------------------------------------------------------------------
-
-// NB: MSLU only covers Win32 API, it doesn't provide Unicode implementation of
-//     libc functions. Unfortunately, some of MSVCRT wchar_t functions
-//     (e.g. _wopen) don't work on Windows 9x, so we have to workaround it
-//     by calling the char version. We still want to use wchar_t version on
-//     NT/2000/XP, though, because they allow for Unicode file names.
-#if wxUSE_UNICODE_MSLU
-
-    #if defined( __VISUALC__ ) \
-        || ( defined(__MINGW32__) && wxCHECK_W32API_VERSION( 0, 5 ) ) \
-        || ( defined(__MWERKS__) && defined(__WXMSW__) )
-    WXDLLEXPORT int wxOpen(const wxChar *name, int flags, int mode)
-    {
-        if ( wxGetOsVersion() == wxWINDOWS_NT )
-            return _wopen(name, flags, mode);
-        else
-            return _open(wxConvFile.cWX2MB(name), flags, mode);
-    }
-    #endif
-
-#endif // wxUSE_UNICODE_MSLU