]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/fs_mem.cpp
fixing modal dialog quit after nested message box problem
[wxWidgets.git] / src / common / fs_mem.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/fs_mem.cpp
3// Purpose: in-memory file system
4// Author: Vaclav Slavik
5// RCS-ID: $Id$
6// Copyright: (c) 2000 Vaclav Slavik
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#include "wx/wxprec.h"
11
12#ifdef __BORLANDC__
13 #pragma hdrstop
14#endif
15
16#if wxUSE_FILESYSTEM && wxUSE_STREAMS
17
18#include "wx/fs_mem.h"
19
20#ifndef WX_PRECOMP
21 #include "wx/intl.h"
22 #include "wx/log.h"
23 #include "wx/wxcrtvararg.h"
24 #if wxUSE_GUI
25 #include "wx/image.h"
26 #endif // wxUSE_GUI
27#endif
28
29#include "wx/mstream.h"
30
31// represents a file entry in wxMemoryFS
32class wxMemoryFSFile
33{
34public:
35 wxMemoryFSFile(const void *data, size_t len, const wxString& mime)
36 {
37 m_Data = new char[len];
38 memcpy(m_Data, data, len);
39 m_Len = len;
40 m_MimeType = mime;
41 InitTime();
42 }
43
44 wxMemoryFSFile(const wxMemoryOutputStream& stream, const wxString& mime)
45 {
46 m_Len = stream.GetSize();
47 m_Data = new char[m_Len];
48 stream.CopyTo(m_Data, m_Len);
49 m_MimeType = mime;
50 InitTime();
51 }
52
53 virtual ~wxMemoryFSFile()
54 {
55 delete[] m_Data;
56 }
57
58 char *m_Data;
59 size_t m_Len;
60 wxString m_MimeType;
61#if wxUSE_DATETIME
62 wxDateTime m_Time;
63#endif // wxUSE_DATETIME
64
65private:
66 void InitTime()
67 {
68#if wxUSE_DATETIME
69 m_Time = wxDateTime::Now();
70#endif // wxUSE_DATETIME
71 }
72
73 wxDECLARE_NO_COPY_CLASS(wxMemoryFSFile);
74};
75
76#if wxUSE_BASE
77
78
79//--------------------------------------------------------------------------------
80// wxMemoryFSHandler
81//--------------------------------------------------------------------------------
82
83
84wxMemoryFSHash wxMemoryFSHandlerBase::m_Hash;
85
86
87wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
88{
89}
90
91wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
92{
93 // as only one copy of FS handler is supposed to exist, we may silently
94 // delete static data here. (There is no way how to remove FS handler from
95 // wxFileSystem other than releasing _all_ handlers.)
96 WX_CLEAR_HASH_MAP(wxMemoryFSHash, m_Hash);
97}
98
99bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
100{
101 return GetProtocol(location) == "memory";
102}
103
104wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs),
105 const wxString& location)
106{
107 wxMemoryFSHash::const_iterator i = m_Hash.find(GetRightLocation(location));
108 if ( i == m_Hash.end() )
109 return NULL;
110
111 const wxMemoryFSFile * const obj = i->second;
112
113 return new wxFSFile
114 (
115 new wxMemoryInputStream(obj->m_Data, obj->m_Len),
116 location,
117 obj->m_MimeType,
118 GetAnchor(location)
119#if wxUSE_DATETIME
120 , obj->m_Time
121#endif // wxUSE_DATETIME
122 );
123}
124
125wxString wxMemoryFSHandlerBase::FindFirst(const wxString& url, int flags)
126{
127 if ( (flags & wxDIR) && !(flags & wxFILE) )
128 {
129 // we only store files, not directories, so we don't risk finding
130 // anything
131 return wxString();
132 }
133
134 const wxString spec = GetRightLocation(url);
135 if ( spec.find_first_of("?*") == wxString::npos )
136 {
137 // simple case: there are no wildcard characters so we can return
138 // either 0 or 1 results and we can find the potential match quickly
139 return m_Hash.count(spec) ? url : wxString();
140 }
141 //else: deal with wildcards in FindNext()
142
143 m_findArgument = spec;
144 m_findIter = m_Hash.begin();
145
146 return FindNext();
147}
148
149wxString wxMemoryFSHandlerBase::FindNext()
150{
151 // m_findArgument is used to indicate that search is in progress, we reset
152 // it to empty string after iterating over all elements
153 while ( !m_findArgument.empty() )
154 {
155 // test for the match before (possibly) clearing m_findArgument below
156 const bool found = m_findIter->first.Matches(m_findArgument);
157
158 // advance m_findIter first as we need to do it anyhow, whether it
159 // matches or not
160 const wxMemoryFSHash::const_iterator current = m_findIter;
161
162 if ( ++m_findIter == m_Hash.end() )
163 m_findArgument.clear();
164
165 if ( found )
166 return "memory:" + current->first;
167 }
168
169 return wxString();
170}
171
172bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename)
173{
174 if ( m_Hash.count(filename) )
175 {
176 wxLogError(_("Memory VFS already contains file '%s'!"), filename);
177 return false;
178 }
179
180 return true;
181}
182
183
184/*static*/
185void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
186 const wxString& textdata,
187 const wxString& mimetype)
188{
189 AddFileWithMimeType
190 (
191 filename,
192 static_cast<const char *>(textdata.To8BitData()),
193 wxStrlen(static_cast<const char *>(textdata.To8BitData())),
194 mimetype
195 );
196}
197
198
199/*static*/
200void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
201 const void *binarydata, size_t size,
202 const wxString& mimetype)
203{
204 if ( !CheckDoesntExist(filename) )
205 return;
206
207 m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype);
208}
209
210/*static*/
211void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
212 const wxString& textdata)
213{
214 AddFileWithMimeType(filename, textdata, wxEmptyString);
215}
216
217
218/*static*/
219void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
220 const void *binarydata, size_t size)
221{
222 AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
223}
224
225
226
227/*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
228{
229 wxMemoryFSHash::iterator i = m_Hash.find(filename);
230 if ( i == m_Hash.end() )
231 {
232 wxLogError(_("Trying to remove file '%s' from memory VFS, "
233 "but it is not loaded!"),
234 filename);
235 return;
236 }
237
238 delete i->second;
239 m_Hash.erase(i);
240}
241
242#endif // wxUSE_BASE
243
244#if wxUSE_GUI
245
246#if wxUSE_IMAGE
247/*static*/ void
248wxMemoryFSHandler::AddFile(const wxString& filename,
249 const wxImage& image,
250 wxBitmapType type)
251{
252 if ( !CheckDoesntExist(filename) )
253 return;
254
255 wxMemoryOutputStream mems;
256 if ( image.Ok() && image.SaveFile(mems, type) )
257 {
258 m_Hash[filename] = new wxMemoryFSFile
259 (
260 mems,
261 wxImage::FindHandler(type)->GetMimeType()
262 );
263 }
264 else
265 {
266 wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
267 }
268}
269
270/*static*/ void
271wxMemoryFSHandler::AddFile(const wxString& filename,
272 const wxBitmap& bitmap,
273 wxBitmapType type)
274{
275 wxImage img = bitmap.ConvertToImage();
276 AddFile(filename, img, type);
277}
278
279#endif // wxUSE_IMAGE
280
281#endif // wxUSE_GUI
282
283
284#endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP