X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cb564879c1f9550ecc88be97dc8f534cfa370e0e..f239a20092359e3c914adb79bd39f3f5d2b2e06f:/src/common/fs_mem.cpp diff --git a/src/common/fs_mem.cpp b/src/common/fs_mem.cpp index 33cc18dcd0..e306437de4 100644 --- a/src/common/fs_mem.cpp +++ b/src/common/fs_mem.cpp @@ -20,7 +20,6 @@ #ifndef WX_PRECOMP #include "wx/intl.h" #include "wx/log.h" - #include "wx/hash.h" #include "wx/wxcrtvararg.h" #if wxUSE_GUI #include "wx/image.h" @@ -29,10 +28,11 @@ #include "wx/mstream.h" -class MemFSHashObj : public wxObject +// represents a file entry in wxMemoryFS +class wxMemoryFSFile { public: - MemFSHashObj(const void *data, size_t len, const wxString& mime) + wxMemoryFSFile(const void *data, size_t len, const wxString& mime) { m_Data = new char[len]; memcpy(m_Data, data, len); @@ -41,7 +41,7 @@ public: InitTime(); } - MemFSHashObj(const wxMemoryOutputStream& stream, const wxString& mime) + wxMemoryFSFile(const wxMemoryOutputStream& stream, const wxString& mime) { m_Len = stream.GetSize(); m_Data = new char[m_Len]; @@ -50,7 +50,7 @@ public: InitTime(); } - virtual ~MemFSHashObj() + virtual ~wxMemoryFSFile() { delete[] m_Data; } @@ -62,8 +62,6 @@ public: wxDateTime m_Time; #endif // wxUSE_DATETIME -DECLARE_NO_COPY_CLASS(MemFSHashObj) - private: void InitTime() { @@ -71,6 +69,8 @@ private: m_Time = wxDateTime::Now(); #endif // wxUSE_DATETIME } + + wxDECLARE_NO_COPY_CLASS(wxMemoryFSFile); }; #if wxUSE_BASE @@ -81,7 +81,7 @@ private: //-------------------------------------------------------------------------------- -wxHashTable *wxMemoryFSHandlerBase::m_Hash = NULL; +wxMemoryFSHash wxMemoryFSHandlerBase::m_Hash; wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler() @@ -93,13 +93,7 @@ wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase() // as only one copy of FS handler is supposed to exist, we may silently // delete static data here. (There is no way how to remove FS handler from // wxFileSystem other than releasing _all_ handlers.) - - if (m_Hash) - { - WX_CLEAR_HASH_TABLE(*m_Hash); - delete m_Hash; - m_Hash = NULL; - } + WX_CLEAR_HASH_MAP(wxMemoryFSHash, m_Hash); } bool wxMemoryFSHandlerBase::CanOpen(const wxString& location) @@ -110,46 +104,74 @@ bool wxMemoryFSHandlerBase::CanOpen(const wxString& location) wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { - if ( !m_Hash ) + wxMemoryFSHash::const_iterator i = m_Hash.find(GetRightLocation(location)); + if ( i == m_Hash.end() ) return NULL; - MemFSHashObj *obj = (MemFSHashObj*) m_Hash->Get(GetRightLocation(location)); - if ( !obj ) - return NULL; + const wxMemoryFSFile * const obj = i->second; - else return new wxFSFile(new wxMemoryInputStream(obj->m_Data, obj->m_Len), - location, - obj->m_MimeType, - GetAnchor(location) + return new wxFSFile + ( + new wxMemoryInputStream(obj->m_Data, obj->m_Len), + location, + obj->m_MimeType, + GetAnchor(location) #if wxUSE_DATETIME - , obj->m_Time + , obj->m_Time #endif // wxUSE_DATETIME - ); + ); } -wxString wxMemoryFSHandlerBase::FindFirst(const wxString& WXUNUSED(spec), - int WXUNUSED(flags)) +wxString wxMemoryFSHandlerBase::FindFirst(const wxString& url, int flags) { - wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindFirst not implemented")); + if ( (flags & wxDIR) && !(flags & wxFILE) ) + { + // we only store files, not directories, so we don't risk finding + // anything + return wxString(); + } - return wxEmptyString; -} + const wxString spec = GetRightLocation(url); + if ( spec.find_first_of("?*") == wxString::npos ) + { + // simple case: there are no wildcard characters so we can return + // either 0 or 1 results and we can find the potential match quickly + return m_Hash.count(spec) ? url : wxString(); + } + //else: deal with wildcards in FindNext() -wxString wxMemoryFSHandlerBase::FindNext() -{ - wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindNext not implemented")); + m_findArgument = spec; + m_findIter = m_Hash.begin(); - return wxEmptyString; + return FindNext(); } -bool wxMemoryFSHandlerBase::CheckHash(const wxString& filename) +wxString wxMemoryFSHandlerBase::FindNext() { - if ( !m_Hash ) + // m_findArgument is used to indicate that search is in progress, we reset + // it to empty string after iterating over all elements + while ( !m_findArgument.empty() ) { - m_Hash = new wxHashTable(wxKEY_STRING); + // test for the match before (possibly) clearing m_findArgument below + const bool found = m_findIter->first.Matches(m_findArgument); + + // advance m_findIter first as we need to do it anyhow, whether it + // matches or not + const wxMemoryFSHash::const_iterator current = m_findIter; + + if ( ++m_findIter == m_Hash.end() ) + m_findArgument.clear(); + + if ( found ) + return "memory:" + current->first; } - if ( m_Hash->Get(filename) ) + return wxString(); +} + +bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename) +{ + if ( m_Hash.count(filename) ) { wxLogError(_("Memory VFS already contains file '%s'!"), filename); return false; @@ -164,9 +186,13 @@ void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename, const wxString& textdata, const wxString& mimetype) { - AddFileWithMimeType(filename, - (const void*) textdata.mb_str(), textdata.length(), - mimetype); + AddFileWithMimeType + ( + filename, + static_cast(textdata.To8BitData()), + wxStrlen(static_cast(textdata.To8BitData())), + mimetype + ); } @@ -175,10 +201,10 @@ void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename, const void *binarydata, size_t size, const wxString& mimetype) { - if ( !CheckHash(filename) ) + if ( !CheckDoesntExist(filename) ) return; - m_Hash->Put(filename, new MemFSHashObj(binarydata, size, mimetype)); + m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype); } /*static*/ @@ -200,16 +226,17 @@ void wxMemoryFSHandlerBase::AddFile(const wxString& filename, /*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename) { - if ( !m_Hash || !m_Hash->Get(filename) ) + wxMemoryFSHash::iterator i = m_Hash.find(filename); + if ( i == m_Hash.end() ) { wxLogError(_("Trying to remove file '%s' from memory VFS, " "but it is not loaded!"), filename); + return; } - else - { - delete m_Hash->Delete(filename); - } + + delete i->second; + m_Hash.erase(i); } #endif // wxUSE_BASE @@ -222,21 +249,17 @@ wxMemoryFSHandler::AddFile(const wxString& filename, const wxImage& image, wxBitmapType type) { - if ( !CheckHash(filename) ) + if ( !CheckDoesntExist(filename) ) return; wxMemoryOutputStream mems; - if (image.Ok() && image.SaveFile(mems, type)) + if ( image.IsOk() && image.SaveFile(mems, type) ) { - m_Hash->Put - ( - filename, - new MemFSHashObj - ( - mems, - wxImage::FindHandler(type)->GetMimeType() - ) - ); + m_Hash[filename] = new wxMemoryFSFile + ( + mems, + wxImage::FindHandler(type)->GetMimeType() + ); } else { @@ -249,10 +272,8 @@ wxMemoryFSHandler::AddFile(const wxString& filename, const wxBitmap& bitmap, wxBitmapType type) { -#if !defined(__WXMSW__) || wxUSE_WXDIB wxImage img = bitmap.ConvertToImage(); AddFile(filename, img, type); -#endif } #endif // wxUSE_IMAGE