]> git.saurik.com Git - wxWidgets.git/blob - src/common/fs_mem.cpp
fix the menu item bitmaps for wxMSW;
[wxWidgets.git] / src / common / fs_mem.cpp
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
32 class wxMemoryFSFile
33 {
34 public:
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
65 private:
66 void InitTime()
67 {
68 #if wxUSE_DATETIME
69 m_Time = wxDateTime::Now();
70 #endif // wxUSE_DATETIME
71 }
72
73 DECLARE_NO_COPY_CLASS(wxMemoryFSFile)
74 };
75
76 #if wxUSE_BASE
77
78
79 //--------------------------------------------------------------------------------
80 // wxMemoryFSHandler
81 //--------------------------------------------------------------------------------
82
83
84 wxMemoryFSHash wxMemoryFSHandlerBase::m_Hash;
85
86
87 wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
88 {
89 }
90
91 wxMemoryFSHandlerBase::~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
99 bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
100 {
101 return GetProtocol(location) == "memory";
102 }
103
104 wxFSFile * 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
125 wxString wxMemoryFSHandlerBase::FindFirst(const wxString& spec, 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 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) ? spec : 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
148 wxString 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 // advance m_findIter before checking the value at the current position
155 // as we need to do it anyhow, whether it matches or not
156 const wxMemoryFSHash::const_iterator current = m_findIter;
157
158 if ( ++m_findIter == m_Hash.end() )
159 m_findArgument.clear();
160
161 if ( current->first.Matches(m_findArgument) )
162 return current->first;
163 }
164
165 return wxString();
166 }
167
168 bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename)
169 {
170 if ( m_Hash.count(filename) )
171 {
172 wxLogError(_("Memory VFS already contains file '%s'!"), filename);
173 return false;
174 }
175
176 return true;
177 }
178
179
180 /*static*/
181 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
182 const wxString& textdata,
183 const wxString& mimetype)
184 {
185 AddFileWithMimeType(filename,
186 (const void*) textdata.mb_str(), textdata.length(),
187 mimetype);
188 }
189
190
191 /*static*/
192 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
193 const void *binarydata, size_t size,
194 const wxString& mimetype)
195 {
196 if ( !CheckDoesntExist(filename) )
197 return;
198
199 m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype);
200 }
201
202 /*static*/
203 void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
204 const wxString& textdata)
205 {
206 AddFileWithMimeType(filename, textdata, wxEmptyString);
207 }
208
209
210 /*static*/
211 void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
212 const void *binarydata, size_t size)
213 {
214 AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
215 }
216
217
218
219 /*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
220 {
221 wxMemoryFSHash::iterator i = m_Hash.find(filename);
222 if ( i == m_Hash.end() )
223 {
224 wxLogError(_("Trying to remove file '%s' from memory VFS, "
225 "but it is not loaded!"),
226 filename);
227 return;
228 }
229
230 delete i->second;
231 m_Hash.erase(i);
232 }
233
234 #endif // wxUSE_BASE
235
236 #if wxUSE_GUI
237
238 #if wxUSE_IMAGE
239 /*static*/ void
240 wxMemoryFSHandler::AddFile(const wxString& filename,
241 const wxImage& image,
242 wxBitmapType type)
243 {
244 if ( !CheckDoesntExist(filename) )
245 return;
246
247 wxMemoryOutputStream mems;
248 if ( image.Ok() && image.SaveFile(mems, type) )
249 {
250 m_Hash[filename] = new wxMemoryFSFile
251 (
252 mems,
253 wxImage::FindHandler(type)->GetMimeType()
254 );
255 }
256 else
257 {
258 wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
259 }
260 }
261
262 /*static*/ void
263 wxMemoryFSHandler::AddFile(const wxString& filename,
264 const wxBitmap& bitmap,
265 wxBitmapType type)
266 {
267 wxImage img = bitmap.ConvertToImage();
268 AddFile(filename, img, type);
269 }
270
271 #endif // wxUSE_IMAGE
272
273 #endif // wxUSE_GUI
274
275
276 #endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP