]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/filesys.cpp
Move the wxWebFileProtocolHandler from the IE backend to the common source, add the...
[wxWidgets.git] / src / common / filesys.cpp
index fc12af7d55762f6c4504186faf937d23fce932bc..f94b3f5d91fe60b628ad29b8ac778ff7b9fce8e2 100644 (file)
@@ -23,6 +23,7 @@
     #include "wx/module.h"
 #endif
 
+#include "wx/sysopt.h"
 #include "wx/wfstream.h"
 #include "wx/mimetype.h"
 #include "wx/filename.h"
@@ -77,64 +78,74 @@ wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
 
 #if wxUSE_MIMETYPE
     static bool s_MinimalMimeEnsured = false;
-    if (!s_MinimalMimeEnsured)
+
+    // Don't use mime types manager if the application doesn't need it and it would be
+    // cause an unacceptable delay, especially on startup.
+#if wxUSE_SYSTEM_OPTIONS
+    if ( !wxSystemOptions::GetOptionInt(wxT("filesys.no-mimetypesmanager")) )
+#endif
     {
-        static const wxFileTypeInfo fallbacks[] =
+        if (!s_MinimalMimeEnsured)
         {
-            wxFileTypeInfo(_T("image/jpeg"),
-                           wxEmptyString,
-                           wxEmptyString,
-                           _T("JPEG image (from fallback)"),
-                           _T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), wxNullPtr),
-            wxFileTypeInfo(_T("image/gif"),
-                           wxEmptyString,
-                           wxEmptyString,
-                           _T("GIF image (from fallback)"),
-                           _T("gif"), _T("GIF"), wxNullPtr),
-            wxFileTypeInfo(_T("image/png"),
-                           wxEmptyString,
-                           wxEmptyString,
-                           _T("PNG image (from fallback)"),
-                           _T("png"), _T("PNG"), wxNullPtr),
-            wxFileTypeInfo(_T("image/bmp"),
-                           wxEmptyString,
-                           wxEmptyString,
-                           _T("windows bitmap image (from fallback)"),
-                           _T("bmp"), _T("BMP"), wxNullPtr),
-            wxFileTypeInfo(_T("text/html"),
-                           wxEmptyString,
-                           wxEmptyString,
-                           _T("HTML document (from fallback)"),
-                           _T("htm"), _T("html"), _T("HTM"), _T("HTML"), wxNullPtr),
-            // must terminate the table with this!
-            wxFileTypeInfo()
-        };
-        wxTheMimeTypesManager->AddFallbacks(fallbacks);
-        s_MinimalMimeEnsured = true;
-    }
+            static const wxFileTypeInfo fallbacks[] =
+            {
+                wxFileTypeInfo(wxT("image/jpeg"),
+                    wxEmptyString,
+                    wxEmptyString,
+                    wxT("JPEG image (from fallback)"),
+                    wxT("jpg"), wxT("jpeg"), wxT("JPG"), wxT("JPEG"), wxNullPtr),
+                wxFileTypeInfo(wxT("image/gif"),
+                    wxEmptyString,
+                    wxEmptyString,
+                    wxT("GIF image (from fallback)"),
+                    wxT("gif"), wxT("GIF"), wxNullPtr),
+                wxFileTypeInfo(wxT("image/png"),
+                    wxEmptyString,
+                    wxEmptyString,
+                    wxT("PNG image (from fallback)"),
+                    wxT("png"), wxT("PNG"), wxNullPtr),
+                wxFileTypeInfo(wxT("image/bmp"),
+                    wxEmptyString,
+                    wxEmptyString,
+                    wxT("windows bitmap image (from fallback)"),
+                    wxT("bmp"), wxT("BMP"), wxNullPtr),
+                wxFileTypeInfo(wxT("text/html"),
+                    wxEmptyString,
+                    wxEmptyString,
+                    wxT("HTML document (from fallback)"),
+                    wxT("htm"), wxT("html"), wxT("HTM"), wxT("HTML"), wxNullPtr),
+                // must terminate the table with this!
+                wxFileTypeInfo()
+            };
+            wxTheMimeTypesManager->AddFallbacks(fallbacks);
+            s_MinimalMimeEnsured = true;
+        }
 
-    wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
-    if ( !ft || !ft -> GetMimeType(&mime) )
-    {
-        mime = wxEmptyString;
-    }
+        wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
+        if ( !ft || !ft -> GetMimeType(&mime) )
+        {
+            mime = wxEmptyString;
+        }
 
-    delete ft;
+        delete ft;
 
-    return mime;
-#else
-    if ( ext.IsSameAs(wxT("htm"), false) || ext.IsSameAs(_T("html"), false) )
-        return wxT("text/html");
-    if ( ext.IsSameAs(wxT("jpg"), false) || ext.IsSameAs(_T("jpeg"), false) )
-        return wxT("image/jpeg");
-    if ( ext.IsSameAs(wxT("gif"), false) )
-        return wxT("image/gif");
-    if ( ext.IsSameAs(wxT("png"), false) )
-        return wxT("image/png");
-    if ( ext.IsSameAs(wxT("bmp"), false) )
-        return wxT("image/bmp");
-    return wxEmptyString;
+        return mime;
+    }
+    else
 #endif
+    {
+        if ( ext.IsSameAs(wxT("htm"), false) || ext.IsSameAs(wxT("html"), false) )
+            return wxT("text/html");
+        if ( ext.IsSameAs(wxT("jpg"), false) || ext.IsSameAs(wxT("jpeg"), false) )
+            return wxT("image/jpeg");
+        if ( ext.IsSameAs(wxT("gif"), false) )
+            return wxT("image/gif");
+        if ( ext.IsSameAs(wxT("png"), false) )
+            return wxT("image/png");
+        if ( ext.IsSameAs(wxT("bmp"), false) )
+            return wxT("image/bmp");
+        return wxEmptyString;
+    }
 }
 
 
@@ -233,7 +244,7 @@ wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString&
     wxString fullpath = ms_root + fn.GetFullPath();
 
     if (!wxFileExists(fullpath))
-        return (wxFSFile*) NULL;
+        return NULL;
 
     // we need to check whether we can really read from this file, otherwise
     // wxFSFile is not going to work
@@ -244,10 +255,10 @@ wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString&
 #else
 #error One of wxUSE_FILE or wxUSE_FFILE must be set to 1 for wxFSHandler to work
 #endif
-    if ( !is->Ok() )
+    if ( !is->IsOk() )
     {
         delete is;
-        return (wxFSFile*) NULL;
+        return NULL;
     }
 
     return new wxFSFile(is,
@@ -263,12 +274,18 @@ wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString&
 wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags)
 {
     wxFileName fn = wxFileSystem::URLToFileName(GetRightLocation(spec));
-    return wxFindFirstFile(ms_root + fn.GetFullPath(), flags);
+    const wxString found = wxFindFirstFile(ms_root + fn.GetFullPath(), flags);
+    if ( found.empty() )
+        return found;
+    return wxFileSystem::FileNameToURL(found);
 }
 
 wxString wxLocalFSHandler::FindNext()
 {
-    return wxFindNextFile();
+    const wxString found = wxFindNextFile();
+    if ( found.empty() )
+        return found;
+    return wxFileSystem::FileNameToURL(found);
 }
 
 
@@ -338,7 +355,7 @@ void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
 
     if (is_dir)
     {
-        if (m_Path.length() > 0 && m_Path.Last() != wxT('/') && m_Path.Last() != wxT(':'))
+        if (!m_Path.empty() && m_Path.Last() != wxT('/') && m_Path.Last() != wxT(':'))
             m_Path << wxT('/');
     }
 
@@ -526,7 +543,7 @@ bool wxFileSystem::FindFileInPath(wxString *pStr,
 {
     // we assume that it's not empty
     wxCHECK_MSG( !basename.empty(), false,
-                _T("empty file name in wxFileSystem::FindFileInPath"));
+                wxT("empty file name in wxFileSystem::FindFileInPath"));
 
     wxString name;
     // skip path separator in the beginning of the file name if present
@@ -639,6 +656,42 @@ wxFileName wxFileSystem::URLToFileName(const wxString& url)
     return wxFileName(path, wxPATH_NATIVE);
 }
 
+// Escapes non-ASCII and others characters in file: URL to be valid URLs
+static wxString EscapeFileNameCharsInURL(const char *in)
+{
+    wxString s;
+
+    for ( const unsigned char *p = (const unsigned char*)in; *p; ++p )
+    {
+        const unsigned char c = *p;
+
+        // notice that all colons *must* be encoded in the paths used by
+        // wxFileSystem even though this makes URLs produced by this method
+        // unusable with IE under Windows as it requires "file:///c:/foo.bar"
+        // and doesn't accept "file:///c%3a/foo.bar" -- but then we never made
+        // any guarantees about general suitability of the strings returned by
+        // this method, they must work with wxFileSystem only and not encoding
+        // the colon breaks handling of
+        // "http://wherever/whatever.zip#zip:filename.ext" URLs so we really
+        // can't do this without heavy changes to the parsing code here, in
+        // particular in GetRightLocation()
+
+        if ( c == '/' || c == '-' || c == '.' || c == '_' || c == '~' ||
+             (c >= '0' && c <= '9') ||
+             (c >= 'a' && c <= 'z') ||
+             (c >= 'A' && c <= 'Z') )
+        {
+            s << c;
+        }
+        else
+        {
+            s << wxString::Format("%%%02x", c);
+        }
+    }
+
+    return s;
+}
+
 // Returns the file URL for a native path
 wxString wxFileSystem::FileNameToURL(const wxFileName& filename)
 {
@@ -663,21 +716,10 @@ wxString wxFileSystem::FileNameToURL(const wxFileName& filename)
 #endif
 
     url.Replace(g_nativePathString, g_unixPathString);
-    url.Replace(wxT("%"), wxT("%25")); // '%'s must be replaced first!
-    url.Replace(wxT("#"), wxT("%23"));
-
-    // notice that all colons *must* be encoded in the paths used by
-    // wxFileSystem even though this makes URLs produced by this method
-    // unusable with IE under Windows as it requires "file:///c:/foo.bar" and
-    // doesn't accept "file:///c%3a/foo.bar" -- but then we never made any
-    // guarantees about general suitability of the strings returned by this
-    // method, they must work with wxFileSystem only and not encoding the colon
-    // breaks handling of "http://wherever/whatever.zip#zip:filename.ext" URLs
-    // so we really can't do this without heavy changes to the parsing code
-    // here, in particular in GetRightLocation()
-    url.Replace(wxT(":"), wxT("%3A"));
-    url = wxT("file:") + url;
-    return url;
+
+    // Do wxURI- and common practice-compatible escaping: encode the string
+    // into UTF-8, then escape anything non-ASCII:
+    return wxT("file:") + EscapeFileNameCharsInURL(url.utf8_str());
 }