]> git.saurik.com Git - wxWidgets.git/blob - src/common/filesys.cpp
assert in GetNextItem() fixed (?)
[wxWidgets.git] / src / common / filesys.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: filesys.cpp
3 // Purpose: wxFileSystem class - interface for opening files
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #ifdef __GNUG__
10 #pragma implementation
11 #endif
12
13 #include "wx/wxprec.h"
14
15 #ifdef __BORDLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if !wxUSE_SOCKETS
20 #undef wxUSE_FS_INET
21 #define wxUSE_FS_INET 0
22 #endif
23
24 #if (wxUSE_HTML || wxUSE_FS_INET || wxUSE_FS_ZIP) && wxUSE_STREAMS
25
26 #include "wx/wfstream.h"
27 #include "wx/module.h"
28 #include "wx/filesys.h"
29 #include "wx/mimetype.h"
30
31
32
33
34 //--------------------------------------------------------------------------------
35 // wxFileSystemHandler
36 //--------------------------------------------------------------------------------
37
38 IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler, wxObject)
39
40
41 wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
42 {
43 wxString ext = wxEmptyString, mime = wxEmptyString;
44 wxString loc = GetRightLocation(location);
45 char c;
46 int l = loc.Length(), l2;
47 wxFileType *ft;
48
49 l2 = l;
50 for (int i = l-1; i >= 0; i--) {
51 c = loc[(unsigned int) i];
52 if (c == wxT('#')) l2 = i + 1;
53 if (c == wxT('.')) {ext = loc.Right(l2-i-1); break;}
54 if ((c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':'))) {return wxEmptyString;}
55 }
56
57 static bool s_MinimalMimeEnsured = FALSE;
58 if (!s_MinimalMimeEnsured) {
59 static const wxFileTypeInfo fallbacks[] =
60 {
61 wxFileTypeInfo("image/jpeg",
62 "",
63 "",
64 "JPEG image (from fallback)",
65 "jpg", "jpeg", NULL),
66 wxFileTypeInfo("image/gif",
67 "",
68 "",
69 "GIF image (from fallback)",
70 "gif", NULL),
71 wxFileTypeInfo("image/png",
72 "",
73 "",
74 "PNG image (from fallback)",
75 "png", NULL),
76 wxFileTypeInfo("image/bmp",
77 "",
78 "",
79 "windows bitmap image (from fallback)",
80 "bmp", NULL),
81 wxFileTypeInfo("text/html",
82 "",
83 "",
84 "HTML document (from fallback)",
85 "htm", "html", NULL),
86
87 // must terminate the table with this!
88 wxFileTypeInfo()
89 };
90
91 wxTheMimeTypesManager -> AddFallbacks(fallbacks);
92 }
93
94 ft = wxTheMimeTypesManager -> GetFileTypeFromExtension(ext);
95 if (ft && (ft -> GetMimeType(&mime))) {
96 delete ft;
97 return mime;
98 }
99 else {
100 delete ft;
101 return wxEmptyString;
102 }
103 }
104
105
106
107 wxString wxFileSystemHandler::GetProtocol(const wxString& location) const
108 {
109 wxString s = wxEmptyString;
110 int i, l = location.Length();
111 bool fnd;
112
113 fnd = FALSE;
114 for (i = l-1; (i >= 0) && ((location[i] != wxT('#')) || (!fnd)); i--) {
115 if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
116 }
117 if (!fnd) return wxT("file");
118 for (++i; (i < l) && (location[i] != wxT(':')); i++) s << location[i];
119 return s;
120 }
121
122
123 wxString wxFileSystemHandler::GetLeftLocation(const wxString& location) const
124 {
125 int i;
126 bool fnd;
127
128 fnd = FALSE;
129 for (i = location.Length()-1; i >= 0; i--) {
130 if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
131 else if (fnd && (location[i] == wxT('#'))) return location.Left(i);
132 }
133 return wxEmptyString;
134 }
135
136 wxString wxFileSystemHandler::GetRightLocation(const wxString& location) const
137 {
138 int i, l = location.Length();
139 int l2 = l + 1;
140 for (i = l-1; (i >= 0) && ((location[i] != wxT(':')) || (i == 1) || (location[i-2] == wxT(':'))); i--) {if (location[i] == wxT('#')) l2 = i + 1;}
141 if (i == 0) return wxEmptyString;
142 else return location.Mid(i + 1, l2 - i - 2);
143 }
144
145 wxString wxFileSystemHandler::GetAnchor(const wxString& location) const
146 {
147 char c;
148 int l = location.Length();
149
150 for (int i = l-1; i >= 0; i--) {
151 c = location[i];
152 if (c == wxT('#')) return location.Right(l-i-1);
153 else if ((c == wxT('.')) || (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':'))) return wxEmptyString;
154 }
155 return wxEmptyString;
156 }
157
158
159 wxString wxFileSystemHandler::FindFirst(const wxString& WXUNUSED(spec),
160 int WXUNUSED(flags))
161 {
162 return wxEmptyString;
163 }
164
165 wxString wxFileSystemHandler::FindNext()
166 {
167 return wxEmptyString;
168 }
169
170 //--------------------------------------------------------------------------------
171 // wxLocalFSHandler
172 //--------------------------------------------------------------------------------
173
174 class wxLocalFSHandler : public wxFileSystemHandler
175 {
176 public:
177 virtual bool CanOpen(const wxString& location);
178 virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
179 virtual wxString FindFirst(const wxString& spec, int flags = 0);
180 virtual wxString FindNext();
181 };
182
183
184 bool wxLocalFSHandler::CanOpen(const wxString& location)
185 {
186 return GetProtocol(location) == wxT("file");
187 }
188
189 wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
190 {
191 wxString right = GetRightLocation(location);
192 if (wxFileExists(right))
193 return new wxFSFile(new wxFileInputStream(right),
194 right,
195 GetMimeTypeFromExt(location),
196 GetAnchor(location),
197 wxDateTime(wxFileModificationTime(right)));
198 else return (wxFSFile*) NULL;
199 }
200
201 wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags)
202 {
203 wxString right = GetRightLocation(spec);
204 return wxFindFirstFile(right, flags);
205 }
206
207 wxString wxLocalFSHandler::FindNext()
208 {
209 return wxFindNextFile();
210 }
211
212
213
214 //-----------------------------------------------------------------------------
215 // wxFileSystem
216 //-----------------------------------------------------------------------------
217
218 IMPLEMENT_DYNAMIC_CLASS(wxFileSystem, wxObject)
219
220
221 wxList wxFileSystem::m_Handlers;
222
223
224
225 void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
226 {
227 int i, pathpos = -1;
228 m_Path = location;
229
230 for (i = m_Path.Length()-1; i >= 0; i--)
231 if (m_Path[(unsigned int) i] == wxT('\\')) m_Path.GetWritableChar(i) = wxT('/'); // wanna be windows-safe
232
233 if (is_dir)
234 {
235 if (m_Path.Length() > 0 && m_Path.Last() != wxT('/') && m_Path.Last() != wxT(':'))
236 m_Path << wxT('/');
237 }
238
239 else
240 {
241 for (i = m_Path.Length()-1; i >= 0; i--)
242 {
243 if (m_Path[(unsigned int) i] == wxT('/'))
244 {
245 if ((i > 1) && (m_Path[(unsigned int) (i-1)] == wxT('/')) && (m_Path[(unsigned int) (i-2)] == wxT(':')))
246 {
247 i -= 2;
248 continue;
249 }
250 else
251 {
252 pathpos = i;
253 break;
254 }
255 }
256 else if (m_Path[(unsigned int) i] == wxT(':')) {
257 pathpos = i;
258 break;
259 }
260 }
261 if (pathpos == -1)
262 {
263 for (i = 0; i < (int) m_Path.Length(); i++)
264 {
265 if (m_Path[(unsigned int) i] == wxT(':'))
266 {
267 m_Path.Remove(i+1);
268 break;
269 }
270 }
271 if (i == (int) m_Path.Length())
272 m_Path = wxEmptyString;
273 }
274 else
275 {
276 m_Path.Remove(pathpos+1);
277 }
278 }
279 }
280
281
282
283 wxFSFile* wxFileSystem::OpenFile(const wxString& location)
284 {
285 wxString loc = location;
286 int i, ln;
287 char meta;
288 wxFSFile *s = NULL;
289 wxNode *node;
290
291 ln = loc.Length();
292 meta = 0;
293 for (i = 0; i < ln; i++)
294 {
295 if (loc[(unsigned int) i] == wxT('\\')) loc.GetWritableChar(i) = wxT('/'); // wanna be windows-safe
296 if (!meta)
297 switch (loc[(unsigned int) i])
298 {
299 case wxT('/') : case wxT(':') : case wxT('#') : meta = loc[(unsigned int) i];
300 }
301 }
302 m_LastName = wxEmptyString;
303
304 // try relative paths first :
305 if (meta != wxT(':'))
306 {
307 node = m_Handlers.GetFirst();
308 while (node)
309 {
310 wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
311 if (h->CanOpen(m_Path + loc))
312 {
313 s = h->OpenFile(*this, m_Path + loc);
314 if (s) { m_LastName = m_Path + loc; break; }
315 }
316 node = node->GetNext();
317 }
318 }
319
320 // if failed, try absolute paths :
321 if (s == NULL)
322 {
323 node = m_Handlers.GetFirst();
324 while (node)
325 {
326 wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
327 if (h->CanOpen(loc))
328 {
329 s = h->OpenFile(*this, loc);
330 if (s) { m_LastName = loc; break; }
331 }
332 node = node->GetNext();
333 }
334 }
335 return (s);
336 }
337
338
339
340 wxString wxFileSystem::FindFirst(const wxString& spec, int flags)
341 {
342 wxNode *node;
343 wxString spec2(spec);
344
345 m_FindFileHandler = NULL;
346
347 for (int i = spec2.Length()-1; i >= 0; i--)
348 if (spec2[(unsigned int) i] == wxT('\\')) spec2.GetWritableChar(i) = wxT('/'); // wanna be windows-safe
349
350 node = m_Handlers.GetFirst();
351 while (node)
352 {
353 m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
354 if (m_FindFileHandler -> CanOpen(m_Path + spec2))
355 return m_FindFileHandler -> FindFirst(m_Path + spec2, flags);
356 node = node->GetNext();
357 }
358
359 node = m_Handlers.GetFirst();
360 while (node)
361 {
362 m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
363 if (m_FindFileHandler -> CanOpen(spec2))
364 return m_FindFileHandler -> FindFirst(spec2, flags);
365 node = node->GetNext();
366 }
367
368 return wxEmptyString;
369 }
370
371
372
373 wxString wxFileSystem::FindNext()
374 {
375 if (m_FindFileHandler == NULL) return wxEmptyString;
376 else return m_FindFileHandler -> FindNext();
377 }
378
379
380
381 void wxFileSystem::AddHandler(wxFileSystemHandler *handler)
382 {
383 m_Handlers.Append(handler);
384 }
385
386
387 void wxFileSystem::CleanUpHandlers()
388 {
389 m_Handlers.DeleteContents(TRUE);
390 m_Handlers.Clear();
391 }
392
393
394
395
396 ///// Module:
397
398 class wxFileSystemModule : public wxModule
399 {
400 DECLARE_DYNAMIC_CLASS(wxFileSystemModule)
401
402 public:
403 virtual bool OnInit()
404 {
405 wxFileSystem::AddHandler(new wxLocalFSHandler);
406 return TRUE;
407 }
408 virtual void OnExit()
409 {
410 wxFileSystem::CleanUpHandlers();
411 }
412 };
413
414 IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule, wxModule)
415
416 #endif
417 // (wxUSE_FS_INET || wxUSE_FS_ZIP) && wxUSE_STREAMS
418
419
420