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