1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/common/fs_mem.cpp
3
// Purpose: in-memory file system
4
// Author: Vaclav Slavik
5
// Copyright: (c) 2000 Vaclav Slavik
6
// Licence: wxWindows licence
7
/////////////////////////////////////////////////////////////////////////////
15
#if wxUSE_FILESYSTEM && wxUSE_STREAMS
17
#include "wx/fs_mem.h"
22
#include "wx/wxcrtvararg.h"
28
#include "wx/mstream.h"
30
// represents a file entry in wxMemoryFS
34
wxMemoryFSFile(const void *data, size_t len, const wxString& mime)
36
m_Data = new char[len];
37
memcpy(m_Data, data, len);
43
wxMemoryFSFile(const wxMemoryOutputStream& stream, const wxString& mime)
45
m_Len = stream.GetSize();
46
m_Data = new char[m_Len];
47
stream.CopyTo(m_Data, m_Len);
52
virtual ~wxMemoryFSFile()
62
#endif // wxUSE_DATETIME
68
m_Time = wxDateTime::Now();
69
#endif // wxUSE_DATETIME
72
wxDECLARE_NO_COPY_CLASS(wxMemoryFSFile);
78
//--------------------------------------------------------------------------------
80
//--------------------------------------------------------------------------------
83
wxMemoryFSHash wxMemoryFSHandlerBase::m_Hash;
86
wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
90
wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
92
// as only one copy of FS handler is supposed to exist, we may silently
93
// delete static data here. (There is no way how to remove FS handler from
94
// wxFileSystem other than releasing _all_ handlers.)
95
WX_CLEAR_HASH_MAP(wxMemoryFSHash, m_Hash);
98
bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
100
return GetProtocol(location) == "memory";
103
wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs),
104
const wxString& location)
106
wxMemoryFSHash::const_iterator i = m_Hash.find(GetRightLocation(location));
107
if ( i == m_Hash.end() )
110
const wxMemoryFSFile * const obj = i->second;
114
new wxMemoryInputStream(obj->m_Data, obj->m_Len),
120
#endif // wxUSE_DATETIME
124
wxString wxMemoryFSHandlerBase::FindFirst(const wxString& url, int flags)
126
if ( (flags & wxDIR) && !(flags & wxFILE) )
128
// we only store files, not directories, so we don't risk finding
133
const wxString spec = GetRightLocation(url);
134
if ( spec.find_first_of("?*") == wxString::npos )
136
// simple case: there are no wildcard characters so we can return
137
// either 0 or 1 results and we can find the potential match quickly
138
return m_Hash.count(spec) ? url : wxString();
140
//else: deal with wildcards in FindNext()
142
m_findArgument = spec;
143
m_findIter = m_Hash.begin();
148
wxString wxMemoryFSHandlerBase::FindNext()
150
// m_findArgument is used to indicate that search is in progress, we reset
151
// it to empty string after iterating over all elements
152
while ( !m_findArgument.empty() )
154
// test for the match before (possibly) clearing m_findArgument below
155
const bool found = m_findIter->first.Matches(m_findArgument);
157
// advance m_findIter first as we need to do it anyhow, whether it
159
const wxMemoryFSHash::const_iterator current = m_findIter;
161
if ( ++m_findIter == m_Hash.end() )
162
m_findArgument.clear();
165
return "memory:" + current->first;
171
bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename)
173
if ( m_Hash.count(filename) )
175
wxLogError(_("Memory VFS already contains file '%s'!"), filename);
184
void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
185
const wxString& textdata,
186
const wxString& mimetype)
188
const wxCharBuffer buf(textdata.To8BitData());
190
AddFileWithMimeType(filename, buf.data(), buf.length(), mimetype);
195
void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
196
const void *binarydata, size_t size,
197
const wxString& mimetype)
199
if ( !CheckDoesntExist(filename) )
202
m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype);
206
void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
207
const wxString& textdata)
209
AddFileWithMimeType(filename, textdata, wxEmptyString);
214
void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
215
const void *binarydata, size_t size)
217
AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
222
/*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
224
wxMemoryFSHash::iterator i = m_Hash.find(filename);
225
if ( i == m_Hash.end() )
227
wxLogError(_("Trying to remove file '%s' from memory VFS, "
228
"but it is not loaded!"),
243
wxMemoryFSHandler::AddFile(const wxString& filename,
244
const wxImage& image,
247
if ( !CheckDoesntExist(filename) )
250
wxMemoryOutputStream mems;
251
if ( image.IsOk() && image.SaveFile(mems, type) )
253
m_Hash[filename] = new wxMemoryFSFile
256
wxImage::FindHandler(type)->GetMimeType()
261
wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
266
wxMemoryFSHandler::AddFile(const wxString& filename,
267
const wxBitmap& bitmap,
270
wxImage img = bitmap.ConvertToImage();
271
AddFile(filename, img, type);
274
#endif // wxUSE_IMAGE
279
#endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP