]> git.saurik.com Git - wxWidgets.git/blob - src/common/fs_mem.cpp
41cc0944343b84228d0151a20c0e8d0fbcd66bf0
[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& WXUNUSED(spec),
126 int WXUNUSED(flags))
127 {
128 wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindFirst not implemented"));
129
130 return wxEmptyString;
131 }
132
133 wxString wxMemoryFSHandlerBase::FindNext()
134 {
135 wxFAIL_MSG(wxT("wxMemoryFSHandlerBase::FindNext not implemented"));
136
137 return wxEmptyString;
138 }
139
140 bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename)
141 {
142 if ( m_Hash.count(filename) )
143 {
144 wxLogError(_("Memory VFS already contains file '%s'!"), filename);
145 return false;
146 }
147
148 return true;
149 }
150
151
152 /*static*/
153 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
154 const wxString& textdata,
155 const wxString& mimetype)
156 {
157 AddFileWithMimeType(filename,
158 (const void*) textdata.mb_str(), textdata.length(),
159 mimetype);
160 }
161
162
163 /*static*/
164 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
165 const void *binarydata, size_t size,
166 const wxString& mimetype)
167 {
168 if ( !CheckDoesntExist(filename) )
169 return;
170
171 m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype);
172 }
173
174 /*static*/
175 void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
176 const wxString& textdata)
177 {
178 AddFileWithMimeType(filename, textdata, wxEmptyString);
179 }
180
181
182 /*static*/
183 void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
184 const void *binarydata, size_t size)
185 {
186 AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
187 }
188
189
190
191 /*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
192 {
193 wxMemoryFSHash::iterator i = m_Hash.find(filename);
194 if ( i == m_Hash.end() )
195 {
196 wxLogError(_("Trying to remove file '%s' from memory VFS, "
197 "but it is not loaded!"),
198 filename);
199 return;
200 }
201
202 delete i->second;
203 m_Hash.erase(i);
204 }
205
206 #endif // wxUSE_BASE
207
208 #if wxUSE_GUI
209
210 #if wxUSE_IMAGE
211 /*static*/ void
212 wxMemoryFSHandler::AddFile(const wxString& filename,
213 const wxImage& image,
214 wxBitmapType type)
215 {
216 if ( !CheckDoesntExist(filename) )
217 return;
218
219 wxMemoryOutputStream mems;
220 if ( image.Ok() && image.SaveFile(mems, type) )
221 {
222 m_Hash[filename] = new wxMemoryFSFile
223 (
224 mems,
225 wxImage::FindHandler(type)->GetMimeType()
226 );
227 }
228 else
229 {
230 wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
231 }
232 }
233
234 /*static*/ void
235 wxMemoryFSHandler::AddFile(const wxString& filename,
236 const wxBitmap& bitmap,
237 wxBitmapType type)
238 {
239 wxImage img = bitmap.ConvertToImage();
240 AddFile(filename, img, type);
241 }
242
243 #endif // wxUSE_IMAGE
244
245 #endif // wxUSE_GUI
246
247
248 #endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP