]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/filesys.cpp
added explanatory comment
[wxWidgets.git] / src / common / filesys.cpp
index 61ec083da446e7c3728772e64bf26b7faca0f6bb..94a229f49c5d280494719a6459c3b710e94d5534 100644 (file)
 
 #ifndef WX_PRECOMP
     #include "wx/log.h"
+    #include "wx/module.h"
 #endif
 
 #include "wx/wfstream.h"
-#include "wx/module.h"
 #include "wx/mimetype.h"
 #include "wx/filename.h"
 #include "wx/tokenzr.h"
+#include "wx/private/fileback.h"
 
 
 //--------------------------------------------------------------------------------
@@ -68,27 +69,27 @@ wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
                            wxEmptyString,
                            wxEmptyString,
                            _T("JPEG image (from fallback)"),
-                           _T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), NULL),
+                           _T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), 0),
             wxFileTypeInfo(_T("image/gif"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("GIF image (from fallback)"),
-                           _T("gif"), _T("GIF"), NULL),
+                           _T("gif"), _T("GIF"), 0),
             wxFileTypeInfo(_T("image/png"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("PNG image (from fallback)"),
-                           _T("png"), _T("PNG"), NULL),
+                           _T("png"), _T("PNG"), 0),
             wxFileTypeInfo(_T("image/bmp"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("windows bitmap image (from fallback)"),
-                           _T("bmp"), _T("BMP"), NULL),
+                           _T("bmp"), _T("BMP"), 0),
             wxFileTypeInfo(_T("text/html"),
                            wxEmptyString,
                            wxEmptyString,
                            _T("HTML document (from fallback)"),
-                           _T("htm"), _T("html"), _T("HTM"), _T("HTML"), NULL),
+                           _T("htm"), _T("html"), _T("HTM"), _T("HTML"), 0),
             // must terminate the table with this!
             wxFileTypeInfo()
         };
@@ -214,7 +215,13 @@ wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString&
 
     // we need to check whether we can really read from this file, otherwise
     // wxFSFile is not going to work
+#if wxUSE_FILE
+    wxFileInputStream *is = new wxFileInputStream(fullpath);
+#elif wxUSE_FFILE
     wxFFileInputStream *is = new wxFFileInputStream(fullpath);
+#else
+#error One of wxUSE_FILE or wxUSE_FFILE must be set to 1 for wxFSHandler to work
+#endif
     if ( !is->Ok() )
     {
         delete is;
@@ -255,6 +262,12 @@ IMPLEMENT_ABSTRACT_CLASS(wxFSFile, wxObject)
 wxList wxFileSystem::m_Handlers;
 
 
+wxFileSystem::~wxFileSystem()
+{
+    WX_CLEAR_HASH_MAP(wxFSHandlerHash, m_LocalHandlers)
+}
+
+
 static wxString MakeCorrectPath(const wxString& path)
 {
     wxString p(path);
@@ -351,8 +364,30 @@ void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
 
 
 
-wxFSFile* wxFileSystem::OpenFile(const wxString& location)
+wxFileSystemHandler *wxFileSystem::MakeLocal(wxFileSystemHandler *h)
+{
+    wxClassInfo *classinfo = h->GetClassInfo();
+
+    if (classinfo->IsDynamic())
+    {
+        wxFileSystemHandler*& local = m_LocalHandlers[classinfo];
+        if (!local)
+            local = (wxFileSystemHandler*)classinfo->CreateObject();
+        return local;
+    }
+    else
+    {
+        return h;
+    }
+}
+
+
+
+wxFSFile* wxFileSystem::OpenFile(const wxString& location, int flags)
 {
+    if ((flags & wxFS_READ) == 0)
+        return NULL;
+
     wxString loc = MakeCorrectPath(location);
     unsigned i, ln;
     wxChar meta;
@@ -363,7 +398,7 @@ wxFSFile* wxFileSystem::OpenFile(const wxString& location)
     meta = 0;
     for (i = 0; i < ln; i++)
     {
-        switch (loc[i])
+        switch ( loc[i].GetValue() )
         {
             case wxT('/') : case wxT(':') : case wxT('#') :
                 meta = loc[i];
@@ -382,7 +417,7 @@ wxFSFile* wxFileSystem::OpenFile(const wxString& location)
             wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
             if (h->CanOpen(m_Path + loc))
             {
-                s = h->OpenFile(*this, m_Path + loc);
+                s = MakeLocal(h)->OpenFile(*this, m_Path + loc);
                 if (s) { m_LastName = m_Path + loc; break; }
             }
             node = node->GetNext();
@@ -398,12 +433,21 @@ wxFSFile* wxFileSystem::OpenFile(const wxString& location)
             wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
             if (h->CanOpen(loc))
             {
-                s = h->OpenFile(*this, loc);
+                s = MakeLocal(h)->OpenFile(*this, loc);
                 if (s) { m_LastName = loc; break; }
             }
             node = node->GetNext();
         }
     }
+
+    if (s && (flags & wxFS_SEEKABLE) != 0 && !s->GetStream()->IsSeekable())
+    {
+        wxBackedInputStream *stream;
+        stream = new wxBackedInputStream(s->DetachStream());
+        stream->FindLength();
+        s->SetStream(stream);
+    }
+
     return (s);
 }
 
@@ -422,18 +466,24 @@ wxString wxFileSystem::FindFirst(const wxString& spec, int flags)
     node = m_Handlers.GetFirst();
     while (node)
     {
-        m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
-        if (m_FindFileHandler -> CanOpen(m_Path + spec2))
+        wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
+        if (h -> CanOpen(m_Path + spec2))
+        {
+            m_FindFileHandler = MakeLocal(h);
             return m_FindFileHandler -> FindFirst(m_Path + spec2, flags);
+        }
         node = node->GetNext();
     }
 
     node = m_Handlers.GetFirst();
     while (node)
     {
-        m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
-        if (m_FindFileHandler -> CanOpen(spec2))
+        wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
+        if (h -> CanOpen(spec2))
+        {
+            m_FindFileHandler = MakeLocal(h);
             return m_FindFileHandler -> FindFirst(spec2, flags);
+        }
         node = node->GetNext();
     }
 
@@ -482,9 +532,37 @@ bool wxFileSystem::FindFileInPath(wxString *pStr,
 
 void wxFileSystem::AddHandler(wxFileSystemHandler *handler)
 {
-    m_Handlers.Append(handler);
+    // prepend the handler to the beginning of the list because handlers added
+    // last should have the highest priority to allow overriding them
+    m_Handlers.Insert((size_t)0, handler);
 }
 
+wxFileSystemHandler* wxFileSystem::RemoveHandler(wxFileSystemHandler *handler)
+{
+    // if handler has already been removed (or deleted)
+    // we return NULL. This is by design in case
+    // CleanUpHandlers() is called before RemoveHandler
+    // is called, as we cannot control the order
+    // which modules are unloaded
+    if (!m_Handlers.DeleteObject(handler))
+        return NULL;
+
+    return handler;
+}
+
+
+bool wxFileSystem::HasHandlerForPath(const wxString &location)
+{
+    for ( wxList::compatibility_iterator node = m_Handlers.GetFirst();
+           node; node = node->GetNext() )
+    {
+        wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
+        if (h->CanOpen(location))
+            return true;
+    }
+
+    return false;
+}
 
 void wxFileSystem::CleanUpHandlers()
 {
@@ -575,15 +653,28 @@ class wxFileSystemModule : public wxModule
     DECLARE_DYNAMIC_CLASS(wxFileSystemModule)
 
     public:
+        wxFileSystemModule() :
+            wxModule(),
+            m_handler(NULL)
+        {
+        }
+
         virtual bool OnInit()
         {
-            wxFileSystem::AddHandler(new wxLocalFSHandler);
+            m_handler = new wxLocalFSHandler;
+            wxFileSystem::AddHandler(m_handler);
             return true;
         }
         virtual void OnExit()
         {
+            delete wxFileSystem::RemoveHandler(m_handler);
+
             wxFileSystem::CleanUpHandlers();
         }
+
+    private:
+        wxFileSystemHandler* m_handler;
+
 };
 
 IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule, wxModule)