]> git.saurik.com Git - wxWidgets.git/blob - src/common/fs_mem.cpp
6e8ba3b6fdcb008893f5a3e14ed0f8f43e03433e
[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/hashmap.h"
24 #include "wx/wxcrtvararg.h"
25 #if wxUSE_GUI
26 #include "wx/image.h"
27 #endif // wxUSE_GUI
28 #endif
29
30 #include "wx/mstream.h"
31
32 class MemFSHashObj
33 {
34 public:
35 MemFSHashObj(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 MemFSHashObj(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 ~MemFSHashObj()
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 DECLARE_NO_COPY_CLASS(MemFSHashObj)
66
67 private:
68 void InitTime()
69 {
70 #if wxUSE_DATETIME
71 m_Time = wxDateTime::Now();
72 #endif // wxUSE_DATETIME
73 }
74 };
75
76 WX_DECLARE_STRING_HASH_MAP(MemFSHashObj *, wxMemoryFSHash);
77
78 #if wxUSE_BASE
79
80
81 //--------------------------------------------------------------------------------
82 // wxMemoryFSHandler
83 //--------------------------------------------------------------------------------
84
85
86 wxMemoryFSHash *wxMemoryFSHandlerBase::m_Hash = NULL;
87
88
89 wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
90 {
91 }
92
93 wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
94 {
95 // as only one copy of FS handler is supposed to exist, we may silently
96 // delete static data here. (There is no way how to remove FS handler from
97 // wxFileSystem other than releasing _all_ handlers.)
98
99 if (m_Hash)
100 {
101 WX_CLEAR_HASH_MAP(wxMemoryFSHash, *m_Hash);
102 delete m_Hash;
103 m_Hash = NULL;
104 }
105 }
106
107 bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
108 {
109 return GetProtocol(location) == "memory";
110 }
111
112 wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs),
113 const wxString& location)
114 {
115 if ( !m_Hash )
116 return NULL;
117
118 wxMemoryFSHash::const_iterator i = m_Hash->find(GetRightLocation(location));
119 if ( i == m_Hash->end() )
120 return NULL;
121
122 const MemFSHashObj * const obj = i->second;
123
124 return new wxFSFile
125 (
126 new wxMemoryInputStream(obj->m_Data, obj->m_Len),
127 location,
128 obj->m_MimeType,
129 GetAnchor(location)
130 #if wxUSE_DATETIME
131 , obj->m_Time
132 #endif // wxUSE_DATETIME
133 );
134 }
135
136 wxString wxMemoryFSHandlerBase::FindFirst(const wxString& WXUNUSED(spec),
137 int WXUNUSED(flags))
138 {
139 wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindFirst not implemented"));
140
141 return wxEmptyString;
142 }
143
144 wxString wxMemoryFSHandlerBase::FindNext()
145 {
146 wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindNext not implemented"));
147
148 return wxEmptyString;
149 }
150
151 bool wxMemoryFSHandlerBase::CheckHash(const wxString& filename)
152 {
153 if ( !m_Hash )
154 m_Hash = new wxMemoryFSHash;
155
156 if ( m_Hash->count(filename) )
157 {
158 wxLogError(_("Memory VFS already contains file '%s'!"), filename);
159 return false;
160 }
161
162 return true;
163 }
164
165
166 /*static*/
167 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
168 const wxString& textdata,
169 const wxString& mimetype)
170 {
171 AddFileWithMimeType(filename,
172 (const void*) textdata.mb_str(), textdata.length(),
173 mimetype);
174 }
175
176
177 /*static*/
178 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
179 const void *binarydata, size_t size,
180 const wxString& mimetype)
181 {
182 if ( !CheckHash(filename) )
183 return;
184
185 (*m_Hash)[filename] = new MemFSHashObj(binarydata, size, mimetype);
186 }
187
188 /*static*/
189 void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
190 const wxString& textdata)
191 {
192 AddFileWithMimeType(filename, textdata, wxEmptyString);
193 }
194
195
196 /*static*/
197 void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
198 const void *binarydata, size_t size)
199 {
200 AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
201 }
202
203
204
205 /*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
206 {
207 if ( m_Hash )
208 {
209 wxMemoryFSHash::iterator i = m_Hash->find(filename);
210 if ( i != m_Hash->end() )
211 {
212 delete i->second;
213 m_Hash->erase(i);
214 }
215 }
216
217 wxLogError(_("Trying to remove file '%s' from memory VFS, "
218 "but it is not loaded!"),
219 filename);
220 }
221
222 #endif // wxUSE_BASE
223
224 #if wxUSE_GUI
225
226 #if wxUSE_IMAGE
227 /*static*/ void
228 wxMemoryFSHandler::AddFile(const wxString& filename,
229 const wxImage& image,
230 wxBitmapType type)
231 {
232 if ( !CheckHash(filename) )
233 return;
234
235 wxMemoryOutputStream mems;
236 if ( image.Ok() && image.SaveFile(mems, type) )
237 {
238 (*m_Hash)[filename] = new MemFSHashObj
239 (
240 mems,
241 wxImage::FindHandler(type)->GetMimeType()
242 );
243 }
244 else
245 {
246 wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
247 }
248 }
249
250 /*static*/ void
251 wxMemoryFSHandler::AddFile(const wxString& filename,
252 const wxBitmap& bitmap,
253 wxBitmapType type)
254 {
255 wxImage img = bitmap.ConvertToImage();
256 AddFile(filename, img, type);
257 }
258
259 #endif // wxUSE_IMAGE
260
261 #endif // wxUSE_GUI
262
263
264 #endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP