#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"
//--------------------------------------------------------------------------------
// 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;
wxList wxFileSystem::m_Handlers;
+wxFileSystem::~wxFileSystem()
+{
+ WX_CLEAR_HASH_MAP(wxFSHandlerHash, m_LocalHandlers)
+}
+
+
static wxString MakeCorrectPath(const wxString& path)
{
wxString p(path);
-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;
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();
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);
}
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();
}
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();
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)