]> git.saurik.com Git - wxWidgets.git/blame - 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
dcb86da0 1/////////////////////////////////////////////////////////////////////////////
0bca0373 2// Name: src/common/fs_mem.cpp
dcb86da0
VS
3// Purpose: in-memory file system
4// Author: Vaclav Slavik
5// Copyright: (c) 2000 Vaclav Slavik
65571936 6// Licence: wxWindows licence
dcb86da0
VS
7/////////////////////////////////////////////////////////////////////////////
8
dcb86da0
VS
9#include "wx/wxprec.h"
10
2b5f62a0 11#ifdef __BORLANDC__
0bca0373 12 #pragma hdrstop
dcb86da0
VS
13#endif
14
24528b0c 15#if wxUSE_FILESYSTEM && wxUSE_STREAMS
dcb86da0 16
e2478fde
VZ
17#include "wx/fs_mem.h"
18
b4f4d3dd 19#ifndef WX_PRECOMP
04dbb646
VZ
20 #include "wx/intl.h"
21 #include "wx/log.h"
6b24b421 22 #include "wx/wxcrtvararg.h"
0bca0373 23 #if wxUSE_GUI
155ecd4c 24 #include "wx/image.h"
0bca0373 25 #endif // wxUSE_GUI
dcb86da0
VS
26#endif
27
dcb86da0
VS
28#include "wx/mstream.h"
29
8c9d7602
VZ
30// represents a file entry in wxMemoryFS
31class wxMemoryFSFile
dcb86da0 32{
cb564879 33public:
8c9d7602 34 wxMemoryFSFile(const void *data, size_t len, const wxString& mime)
cb564879
VZ
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
8c9d7602 43 wxMemoryFSFile(const wxMemoryOutputStream& stream, const wxString& mime)
cb564879
VZ
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
8c9d7602 52 virtual ~wxMemoryFSFile()
cb564879
VZ
53 {
54 delete[] m_Data;
55 }
56
57 char *m_Data;
58 size_t m_Len;
59 wxString m_MimeType;
e2b87f38 60#if wxUSE_DATETIME
cb564879 61 wxDateTime m_Time;
e2b87f38 62#endif // wxUSE_DATETIME
22f3361e 63
cb564879
VZ
64private:
65 void InitTime()
66 {
e2b87f38 67#if wxUSE_DATETIME
cb564879 68 m_Time = wxDateTime::Now();
a62848fd 69#endif // wxUSE_DATETIME
cb564879 70 }
dcb86da0 71
c0c133e1 72 wxDECLARE_NO_COPY_CLASS(wxMemoryFSFile);
8c9d7602 73};
0eb2e510 74
ec67cff1 75#if wxUSE_BASE
60c0a8db 76
dcb86da0
VS
77
78//--------------------------------------------------------------------------------
79// wxMemoryFSHandler
80//--------------------------------------------------------------------------------
81
82
8c9d7602 83wxMemoryFSHash wxMemoryFSHandlerBase::m_Hash;
dcb86da0
VS
84
85
e2478fde 86wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
dcb86da0 87{
dcb86da0
VS
88}
89
e2478fde 90wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
dcb86da0
VS
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.)
8c9d7602 95 WX_CLEAR_HASH_MAP(wxMemoryFSHash, m_Hash);
dcb86da0
VS
96}
97
e2478fde 98bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
dcb86da0 99{
cb564879 100 return GetProtocol(location) == "memory";
dcb86da0
VS
101}
102
cb564879
VZ
103wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs),
104 const wxString& location)
105{
8c9d7602
VZ
106 wxMemoryFSHash::const_iterator i = m_Hash.find(GetRightLocation(location));
107 if ( i == m_Hash.end() )
cb564879 108 return NULL;
dcb86da0 109
8c9d7602 110 const wxMemoryFSFile * const obj = i->second;
0eb2e510
VZ
111
112 return new wxFSFile
113 (
114 new wxMemoryInputStream(obj->m_Data, obj->m_Len),
115 location,
116 obj->m_MimeType,
117 GetAnchor(location)
e2b87f38 118#if wxUSE_DATETIME
0eb2e510 119 , obj->m_Time
a62848fd 120#endif // wxUSE_DATETIME
0eb2e510 121 );
dcb86da0
VS
122}
123
c8c86bd0 124wxString wxMemoryFSHandlerBase::FindFirst(const wxString& url, int flags)
dcb86da0 125{
fcc65883
VZ
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
c8c86bd0 133 const wxString spec = GetRightLocation(url);
fcc65883
VZ
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
c8c86bd0 138 return m_Hash.count(spec) ? url : wxString();
fcc65883
VZ
139 }
140 //else: deal with wildcards in FindNext()
bc1dcfc1 141
fcc65883
VZ
142 m_findArgument = spec;
143 m_findIter = m_Hash.begin();
144
145 return FindNext();
dcb86da0
VS
146}
147
e2478fde 148wxString wxMemoryFSHandlerBase::FindNext()
dcb86da0 149{
fcc65883
VZ
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 {
c8c86bd0
VZ
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
fcc65883
VZ
159 const wxMemoryFSHash::const_iterator current = m_findIter;
160
161 if ( ++m_findIter == m_Hash.end() )
162 m_findArgument.clear();
163
c8c86bd0
VZ
164 if ( found )
165 return "memory:" + current->first;
fcc65883 166 }
bc1dcfc1 167
fcc65883 168 return wxString();
dcb86da0
VS
169}
170
8c9d7602 171bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename)
dcb86da0 172{
8c9d7602 173 if ( m_Hash.count(filename) )
dcb86da0 174 {
cb564879 175 wxLogError(_("Memory VFS already contains file '%s'!"), filename);
a62848fd 176 return false;
dcb86da0 177 }
cb564879
VZ
178
179 return true;
dcb86da0
VS
180}
181
182
c5d7b81e
VS
183/*static*/
184void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
185 const wxString& textdata,
186 const wxString& mimetype)
dcb86da0 187{
e1db4c12
VZ
188 const wxCharBuffer buf(textdata.To8BitData());
189
190 AddFileWithMimeType(filename, buf.data(), buf.length(), mimetype);
dcb86da0
VS
191}
192
193
c5d7b81e
VS
194/*static*/
195void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
196 const void *binarydata, size_t size,
197 const wxString& mimetype)
dcb86da0 198{
8c9d7602 199 if ( !CheckDoesntExist(filename) )
cb564879
VZ
200 return;
201
8c9d7602 202 m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype);
c5d7b81e
VS
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);
dcb86da0
VS
218}
219
220
221
e2478fde 222/*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
dcb86da0 223{
8c9d7602
VZ
224 wxMemoryFSHash::iterator i = m_Hash.find(filename);
225 if ( i == m_Hash.end() )
dcb86da0 226 {
8c9d7602
VZ
227 wxLogError(_("Trying to remove file '%s' from memory VFS, "
228 "but it is not loaded!"),
229 filename);
230 return;
cb564879 231 }
0eb2e510 232
8c9d7602
VZ
233 delete i->second;
234 m_Hash.erase(i);
dcb86da0
VS
235}
236
ec67cff1 237#endif // wxUSE_BASE
e2478fde
VZ
238
239#if wxUSE_GUI
240
2de5a6ee
VS
241#if wxUSE_IMAGE
242/*static*/ void
989a2421
VZ
243wxMemoryFSHandler::AddFile(const wxString& filename,
244 const wxImage& image,
d75a69e8 245 wxBitmapType type)
2de5a6ee 246{
8c9d7602 247 if ( !CheckDoesntExist(filename) )
cb564879 248 return;
2de5a6ee 249
2de5a6ee 250 wxMemoryOutputStream mems;
a1b806b9 251 if ( image.IsOk() && image.SaveFile(mems, type) )
c5d7b81e 252 {
8c9d7602
VZ
253 m_Hash[filename] = new wxMemoryFSFile
254 (
0eb2e510
VZ
255 mems,
256 wxImage::FindHandler(type)->GetMimeType()
8c9d7602 257 );
c5d7b81e 258 }
2de5a6ee
VS
259 else
260 {
cb564879 261 wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
2de5a6ee
VS
262 }
263}
2de5a6ee 264
989a2421
VZ
265/*static*/ void
266wxMemoryFSHandler::AddFile(const wxString& filename,
267 const wxBitmap& bitmap,
d75a69e8 268 wxBitmapType type)
e2478fde
VZ
269{
270 wxImage img = bitmap.ConvertToImage();
271 AddFile(filename, img, type);
272}
273
1904aa72
DS
274#endif // wxUSE_IMAGE
275
276#endif // wxUSE_GUI
dcb86da0
VS
277
278
24528b0c 279#endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP