]> git.saurik.com Git - wxWidgets.git/blame - src/common/fs_mem.cpp
fixing bug 1841377
[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
0bca0373 5// RCS-ID: $Id$
dcb86da0 6// Copyright: (c) 2000 Vaclav Slavik
65571936 7// Licence: wxWindows licence
dcb86da0
VS
8/////////////////////////////////////////////////////////////////////////////
9
dcb86da0
VS
10#include "wx/wxprec.h"
11
2b5f62a0 12#ifdef __BORLANDC__
0bca0373 13 #pragma hdrstop
dcb86da0
VS
14#endif
15
24528b0c 16#if wxUSE_FILESYSTEM && wxUSE_STREAMS
dcb86da0 17
e2478fde
VZ
18#include "wx/fs_mem.h"
19
b4f4d3dd 20#ifndef WX_PRECOMP
04dbb646
VZ
21 #include "wx/intl.h"
22 #include "wx/log.h"
8b70ca26 23 #include "wx/hash.h"
6b24b421 24 #include "wx/wxcrtvararg.h"
0bca0373
WS
25 #if wxUSE_GUI
26 #include "wx/bitmap.h"
155ecd4c 27 #include "wx/image.h"
0bca0373 28 #endif // wxUSE_GUI
dcb86da0
VS
29#endif
30
dcb86da0
VS
31#include "wx/mstream.h"
32
dcb86da0
VS
33class MemFSHashObj : public wxObject
34{
35 public:
04dbb646 36
c5d7b81e 37 MemFSHashObj(const void *data, size_t len, const wxString& mime)
dcb86da0
VS
38 {
39 m_Data = new char[len];
40 memcpy(m_Data, data, len);
41 m_Len = len;
c5d7b81e 42 m_MimeType = mime;
e2b87f38 43 InitTime();
dcb86da0 44 }
04dbb646 45
c5d7b81e 46 MemFSHashObj(const wxMemoryOutputStream& stream, const wxString& mime)
dcb86da0
VS
47 {
48 m_Len = stream.GetSize();
49 m_Data = new char[m_Len];
50 stream.CopyTo(m_Data, m_Len);
c5d7b81e 51 m_MimeType = mime;
e2b87f38 52 InitTime();
dcb86da0 53 }
04dbb646 54
d3c7fc99 55 virtual ~MemFSHashObj()
dcb86da0
VS
56 {
57 delete[] m_Data;
58 }
04dbb646 59
dcb86da0
VS
60 char *m_Data;
61 size_t m_Len;
c5d7b81e 62 wxString m_MimeType;
e2b87f38 63#if wxUSE_DATETIME
dcb86da0 64 wxDateTime m_Time;
e2b87f38 65#endif // wxUSE_DATETIME
22f3361e
VZ
66
67 DECLARE_NO_COPY_CLASS(MemFSHashObj)
e2b87f38
VZ
68
69 private:
70 void InitTime()
71 {
72#if wxUSE_DATETIME
73 m_Time = wxDateTime::Now();
a62848fd 74#endif // wxUSE_DATETIME
e2b87f38 75 }
dcb86da0
VS
76};
77
ec67cff1 78#if wxUSE_BASE
60c0a8db 79
dcb86da0
VS
80
81//--------------------------------------------------------------------------------
82// wxMemoryFSHandler
83//--------------------------------------------------------------------------------
84
85
e2478fde 86wxHashTable *wxMemoryFSHandlerBase::m_Hash = NULL;
dcb86da0
VS
87
88
e2478fde 89wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
dcb86da0 90{
dcb86da0
VS
91}
92
93
94
e2478fde 95wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
dcb86da0
VS
96{
97 // as only one copy of FS handler is supposed to exist, we may silently
98 // delete static data here. (There is no way how to remove FS handler from
99 // wxFileSystem other than releasing _all_ handlers.)
04dbb646 100
e2478fde
VZ
101 if (m_Hash)
102 {
df5168c4 103 WX_CLEAR_HASH_TABLE(*m_Hash);
e2478fde
VZ
104 delete m_Hash;
105 m_Hash = NULL;
106 }
dcb86da0
VS
107}
108
109
110
e2478fde 111bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
dcb86da0
VS
112{
113 wxString p = GetProtocol(location);
114 return (p == wxT("memory"));
115}
116
117
118
119
e2478fde 120wxFSFile* wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
dcb86da0
VS
121{
122 if (m_Hash)
123 {
124 MemFSHashObj *obj = (MemFSHashObj*) m_Hash -> Get(GetRightLocation(location));
125 if (obj == NULL) return NULL;
126 else return new wxFSFile(new wxMemoryInputStream(obj -> m_Data, obj -> m_Len),
127 location,
c5d7b81e 128 obj->m_MimeType,
e2b87f38
VZ
129 GetAnchor(location)
130#if wxUSE_DATETIME
131 , obj -> m_Time
a62848fd 132#endif // wxUSE_DATETIME
e2b87f38 133 );
dcb86da0
VS
134 }
135 else return NULL;
136}
137
138
139
e2478fde 140wxString wxMemoryFSHandlerBase::FindFirst(const wxString& WXUNUSED(spec),
bc1dcfc1 141 int WXUNUSED(flags))
dcb86da0 142{
e2478fde 143 wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindFirst not implemented"));
bc1dcfc1 144
dcb86da0
VS
145 return wxEmptyString;
146}
147
148
149
e2478fde 150wxString wxMemoryFSHandlerBase::FindNext()
dcb86da0 151{
e2478fde 152 wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindNext not implemented"));
bc1dcfc1 153
dcb86da0
VS
154 return wxEmptyString;
155}
156
157
e2478fde 158bool wxMemoryFSHandlerBase::CheckHash(const wxString& filename)
dcb86da0 159{
04dbb646 160 if (m_Hash == NULL)
dcb86da0
VS
161 {
162 m_Hash = new wxHashTable(wxKEY_STRING);
dcb86da0 163 }
04dbb646 164
dcb86da0
VS
165 if (m_Hash -> Get(filename) != NULL)
166 {
167 wxString s;
168 s.Printf(_("Memory VFS already contains file '%s'!"), filename.c_str());
169 wxLogError(s);
a62848fd 170 return false;
dcb86da0
VS
171 }
172 else
a62848fd 173 return true;
dcb86da0
VS
174}
175
176
c5d7b81e
VS
177/*static*/
178void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
179 const wxString& textdata,
180 const wxString& mimetype)
dcb86da0 181{
c5d7b81e
VS
182 AddFileWithMimeType(filename,
183 (const void*) textdata.mb_str(), textdata.length(),
184 mimetype);
dcb86da0
VS
185}
186
187
c5d7b81e
VS
188/*static*/
189void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
190 const void *binarydata, size_t size,
191 const wxString& mimetype)
dcb86da0
VS
192{
193 if (!CheckHash(filename)) return;
c5d7b81e
VS
194 m_Hash -> Put(filename, new MemFSHashObj(binarydata, size, mimetype));
195}
196
197/*static*/
198void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
199 const wxString& textdata)
200{
201 AddFileWithMimeType(filename, textdata, wxEmptyString);
202}
203
204
205/*static*/
206void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
207 const void *binarydata, size_t size)
208{
209 AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
dcb86da0
VS
210}
211
212
213
e2478fde 214/*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
dcb86da0
VS
215{
216 if (m_Hash == NULL ||
217 m_Hash -> Get(filename) == NULL)
218 {
219 wxString s;
220 s.Printf(_("Trying to remove file '%s' from memory VFS, but it is not loaded!"), filename.c_str());
221 wxLogError(s);
222 }
223
224 else
225 delete m_Hash -> Delete(filename);
226}
227
ec67cff1 228#endif // wxUSE_BASE
e2478fde
VZ
229
230#if wxUSE_GUI
231
2de5a6ee
VS
232#if wxUSE_IMAGE
233/*static*/ void
989a2421
VZ
234wxMemoryFSHandler::AddFile(const wxString& filename,
235 const wxImage& image,
236 long type)
2de5a6ee
VS
237{
238 if (!CheckHash(filename)) return;
239
2de5a6ee
VS
240 wxMemoryOutputStream mems;
241 if (image.Ok() && image.SaveFile(mems, (int)type))
c5d7b81e
VS
242 {
243 m_Hash->Put
244 (
245 filename,
246 new MemFSHashObj
247 (
248 mems,
249 wxImage::FindHandler(type)->GetMimeType()
250 )
251 );
252 }
2de5a6ee
VS
253 else
254 {
255 wxString s;
256 s.Printf(_("Failed to store image '%s' to memory VFS!"), filename.c_str());
257 wxPrintf(wxT("'%s'\n"), s.c_str());
258 wxLogError(s);
259 }
260}
2de5a6ee 261
989a2421
VZ
262/*static*/ void
263wxMemoryFSHandler::AddFile(const wxString& filename,
264 const wxBitmap& bitmap,
265 long type)
e2478fde 266{
64c288fa 267#if !defined(__WXMSW__) || wxUSE_WXDIB
e2478fde
VZ
268 wxImage img = bitmap.ConvertToImage();
269 AddFile(filename, img, type);
64c288fa 270#endif
e2478fde
VZ
271}
272
1904aa72
DS
273#endif // wxUSE_IMAGE
274
275#endif // wxUSE_GUI
dcb86da0
VS
276
277
24528b0c 278#endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP