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