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