/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/filesys.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/filesys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File size: 18878 byte(s)
committing r3113 initial commit again...
1 william 31 /////////////////////////////////////////////////////////////////////////////
2     // Name: src/common/filesys.cpp
3     // Purpose: wxFileSystem class - interface for opening files
4     // Author: Vaclav Slavik
5     // Copyright: (c) 1999 Vaclav Slavik
6     // CVS-ID: $Id: filesys.cpp 55271 2008-08-26 00:03:04Z VZ $
7     // Licence: wxWindows licence
8     /////////////////////////////////////////////////////////////////////////////
9    
10     #include "wx/wxprec.h"
11    
12     #ifdef __BORLANDC__
13     #pragma hdrstop
14     #endif
15    
16    
17     #if wxUSE_FILESYSTEM
18    
19     #include "wx/filesys.h"
20    
21     #ifndef WX_PRECOMP
22     #include "wx/log.h"
23     #include "wx/module.h"
24     #endif
25    
26     #include "wx/sysopt.h"
27     #include "wx/wfstream.h"
28     #include "wx/mimetype.h"
29     #include "wx/filename.h"
30     #include "wx/tokenzr.h"
31     #include "wx/uri.h"
32     #include "wx/private/fileback.h"
33    
34    
35     //--------------------------------------------------------------------------------
36     // wxFileSystemHandler
37     //--------------------------------------------------------------------------------
38    
39     IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler, wxObject)
40    
41    
42     wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
43     {
44     wxString ext, mime;
45     wxString loc = GetRightLocation(location);
46     wxChar c;
47     int l = loc.length(), l2;
48    
49     l2 = l;
50     for (int i = l-1; i >= 0; i--)
51     {
52     c = loc[(unsigned int) i];
53     if ( c == wxT('#') )
54     l2 = i + 1;
55     if ( c == wxT('.') )
56     {
57     ext = loc.Right(l2-i-1);
58     break;
59     }
60     if ( (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':')) )
61     return wxEmptyString;
62     }
63    
64     #if wxUSE_MIMETYPE
65     static bool s_MinimalMimeEnsured = false;
66    
67     // Don't use mime types manager if the application doesn't need it and it would be
68     // cause an unacceptable delay, especially on startup.
69     bool useMimeTypesManager = true;
70     #if wxUSE_SYSTEM_OPTIONS
71     useMimeTypesManager = (wxSystemOptions::GetOptionInt(wxT("filesys.no-mimetypesmanager")) == 0);
72     #endif
73    
74     if (useMimeTypesManager)
75     {
76     if (!s_MinimalMimeEnsured)
77     {
78     static const wxFileTypeInfo fallbacks[] =
79     {
80     wxFileTypeInfo(_T("image/jpeg"),
81     wxEmptyString,
82     wxEmptyString,
83     _T("JPEG image (from fallback)"),
84     _T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), NULL),
85     wxFileTypeInfo(_T("image/gif"),
86     wxEmptyString,
87     wxEmptyString,
88     _T("GIF image (from fallback)"),
89     _T("gif"), _T("GIF"), NULL),
90     wxFileTypeInfo(_T("image/png"),
91     wxEmptyString,
92     wxEmptyString,
93     _T("PNG image (from fallback)"),
94     _T("png"), _T("PNG"), NULL),
95     wxFileTypeInfo(_T("image/bmp"),
96     wxEmptyString,
97     wxEmptyString,
98     _T("windows bitmap image (from fallback)"),
99     _T("bmp"), _T("BMP"), NULL),
100     wxFileTypeInfo(_T("text/html"),
101     wxEmptyString,
102     wxEmptyString,
103     _T("HTML document (from fallback)"),
104     _T("htm"), _T("html"), _T("HTM"), _T("HTML"), NULL),
105     // must terminate the table with this!
106     wxFileTypeInfo()
107     };
108     wxTheMimeTypesManager->AddFallbacks(fallbacks);
109     s_MinimalMimeEnsured = true;
110     }
111    
112     wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
113     if ( !ft || !ft -> GetMimeType(&mime) )
114     {
115     mime = wxEmptyString;
116     }
117    
118     delete ft;
119    
120     return mime;
121     }
122     else
123     #endif
124     {
125     if ( ext.IsSameAs(wxT("htm"), false) || ext.IsSameAs(_T("html"), false) )
126     return wxT("text/html");
127     if ( ext.IsSameAs(wxT("jpg"), false) || ext.IsSameAs(_T("jpeg"), false) )
128     return wxT("image/jpeg");
129     if ( ext.IsSameAs(wxT("gif"), false) )
130     return wxT("image/gif");
131     if ( ext.IsSameAs(wxT("png"), false) )
132     return wxT("image/png");
133     if ( ext.IsSameAs(wxT("bmp"), false) )
134     return wxT("image/bmp");
135     return wxEmptyString;
136     }
137     }
138    
139    
140    
141     wxString wxFileSystemHandler::GetProtocol(const wxString& location) const
142     {
143     wxString s = wxEmptyString;
144     int i, l = location.length();
145     bool fnd = false;
146    
147     for (i = l-1; (i >= 0) && ((location[i] != wxT('#')) || (!fnd)); i--) {
148     if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = true;
149     }
150     if (!fnd) return wxT("file");
151     for (++i; (i < l) && (location[i] != wxT(':')); i++) s << location[i];
152     return s;
153     }
154    
155    
156     wxString wxFileSystemHandler::GetLeftLocation(const wxString& location) const
157     {
158     int i;
159     bool fnd = false;
160    
161     for (i = location.length()-1; i >= 0; i--) {
162     if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = true;
163     else if (fnd && (location[i] == wxT('#'))) return location.Left(i);
164     }
165     return wxEmptyString;
166     }
167    
168     wxString wxFileSystemHandler::GetRightLocation(const wxString& location) const
169     {
170     int i, l = location.length();
171     int l2 = l + 1;
172    
173     for (i = l-1;
174     (i >= 0) &&
175     ((location[i] != wxT(':')) || (i == 1) || (location[i-2] == wxT(':')));
176     i--)
177     {
178     if (location[i] == wxT('#')) l2 = i + 1;
179     }
180     if (i == 0) return wxEmptyString;
181     else return location.Mid(i + 1, l2 - i - 2);
182     }
183    
184     wxString wxFileSystemHandler::GetAnchor(const wxString& location) const
185     {
186     wxChar c;
187     int l = location.length();
188    
189     for (int i = l-1; i >= 0; i--) {
190     c = location[i];
191     if (c == wxT('#'))
192     return location.Right(l-i-1);
193     else if ((c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':')))
194     return wxEmptyString;
195     }
196     return wxEmptyString;
197     }
198    
199    
200     wxString wxFileSystemHandler::FindFirst(const wxString& WXUNUSED(spec),
201     int WXUNUSED(flags))
202     {
203     return wxEmptyString;
204     }
205    
206     wxString wxFileSystemHandler::FindNext()
207     {
208     return wxEmptyString;
209     }
210    
211     //--------------------------------------------------------------------------------
212     // wxLocalFSHandler
213     //--------------------------------------------------------------------------------
214    
215    
216     wxString wxLocalFSHandler::ms_root;
217    
218     bool wxLocalFSHandler::CanOpen(const wxString& location)
219     {
220     return GetProtocol(location) == wxT("file");
221     }
222    
223     wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
224     {
225     // location has Unix path separators
226     wxString right = GetRightLocation(location);
227     wxFileName fn = wxFileSystem::URLToFileName(right);
228     wxString fullpath = ms_root + fn.GetFullPath();
229    
230     if (!wxFileExists(fullpath))
231     return (wxFSFile*) NULL;
232    
233     // we need to check whether we can really read from this file, otherwise
234     // wxFSFile is not going to work
235     #if wxUSE_FFILE
236     wxFFileInputStream *is = new wxFFileInputStream(fullpath);
237     #elif wxUSE_FILE
238     wxFileInputStream *is = new wxFileInputStream(fullpath);
239     #else
240     #error One of wxUSE_FILE or wxUSE_FFILE must be set to 1 for wxFSHandler to work
241     #endif
242     if ( !is->Ok() )
243     {
244     delete is;
245     return (wxFSFile*) NULL;
246     }
247    
248     return new wxFSFile(is,
249     right,
250     GetMimeTypeFromExt(location),
251     GetAnchor(location)
252     #if wxUSE_DATETIME
253     ,wxDateTime(wxFileModificationTime(fullpath))
254     #endif // wxUSE_DATETIME
255     );
256     }
257    
258     wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags)
259     {
260     wxFileName fn = wxFileSystem::URLToFileName(GetRightLocation(spec));
261     return wxFindFirstFile(ms_root + fn.GetFullPath(), flags);
262     }
263    
264     wxString wxLocalFSHandler::FindNext()
265     {
266     return wxFindNextFile();
267     }
268    
269    
270    
271     //-----------------------------------------------------------------------------
272     // wxFileSystem
273     //-----------------------------------------------------------------------------
274    
275     IMPLEMENT_DYNAMIC_CLASS(wxFileSystem, wxObject)
276     IMPLEMENT_ABSTRACT_CLASS(wxFSFile, wxObject)
277    
278    
279     wxList wxFileSystem::m_Handlers;
280    
281    
282     wxFileSystem::~wxFileSystem()
283     {
284     WX_CLEAR_HASH_MAP(wxFSHandlerHash, m_LocalHandlers)
285     }
286    
287    
288     static wxString MakeCorrectPath(const wxString& path)
289     {
290     wxString p(path);
291     wxString r;
292     int i, j, cnt;
293    
294     cnt = p.length();
295     for (i = 0; i < cnt; i++)
296     if (p.GetChar(i) == wxT('\\')) p.GetWritableChar(i) = wxT('/'); // Want to be windows-safe
297    
298     if (p.Left(2) == wxT("./")) { p = p.Mid(2); cnt -= 2; }
299    
300     if (cnt < 3) return p;
301    
302     r << p.GetChar(0) << p.GetChar(1);
303    
304     // skip trailing ../.., if any
305     for (i = 2; i < cnt && (p.GetChar(i) == wxT('/') || p.GetChar(i) == wxT('.')); i++) r << p.GetChar(i);
306    
307     // remove back references: translate dir1/../dir2 to dir2
308     for (; i < cnt; i++)
309     {
310     r << p.GetChar(i);
311     if (p.GetChar(i) == wxT('/') && p.GetChar(i-1) == wxT('.') && p.GetChar(i-2) == wxT('.'))
312     {
313     for (j = r.length() - 2; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
314     if (j >= 0 && r.GetChar(j) != wxT(':'))
315     {
316     for (j = j - 1; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
317     r.Remove(j + 1);
318     }
319     }
320     }
321    
322     for (; i < cnt; i++) r << p.GetChar(i);
323    
324     return r;
325     }
326    
327    
328     void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
329     {
330     int i, pathpos = -1;
331    
332     m_Path = MakeCorrectPath(location);
333    
334     if (is_dir)
335     {
336     if (m_Path.length() > 0 && m_Path.Last() != wxT('/') && m_Path.Last() != wxT(':'))
337     m_Path << wxT('/');
338     }
339    
340     else
341     {
342     for (i = m_Path.length()-1; i >= 0; i--)
343     {
344     if (m_Path[(unsigned int) i] == wxT('/'))
345     {
346     if ((i > 1) && (m_Path[(unsigned int) (i-1)] == wxT('/')) && (m_Path[(unsigned int) (i-2)] == wxT(':')))
347     {
348     i -= 2;
349     continue;
350     }
351     else
352     {
353     pathpos = i;
354     break;
355     }
356     }
357     else if (m_Path[(unsigned int) i] == wxT(':')) {
358     pathpos = i;
359     break;
360     }
361     }
362     if (pathpos == -1)
363     {
364     for (i = 0; i < (int) m_Path.length(); i++)
365     {
366     if (m_Path[(unsigned int) i] == wxT(':'))
367     {
368     m_Path.Remove(i+1);
369     break;
370     }
371     }
372     if (i == (int) m_Path.length())
373     m_Path = wxEmptyString;
374     }
375     else
376     {
377     m_Path.Remove(pathpos+1);
378     }
379     }
380     }
381    
382    
383    
384     wxFileSystemHandler *wxFileSystem::MakeLocal(wxFileSystemHandler *h)
385     {
386     wxClassInfo *classinfo = h->GetClassInfo();
387    
388     if (classinfo->IsDynamic())
389     {
390     wxFileSystemHandler*& local = m_LocalHandlers[classinfo];
391     if (!local)
392     local = (wxFileSystemHandler*)classinfo->CreateObject();
393     return local;
394     }
395     else
396     {
397     return h;
398     }
399     }
400    
401    
402    
403     wxFSFile* wxFileSystem::OpenFile(const wxString& location, int flags)
404     {
405     if ((flags & wxFS_READ) == 0)
406     return NULL;
407    
408     wxString loc = MakeCorrectPath(location);
409     unsigned i, ln;
410     wxChar meta;
411     wxFSFile *s = NULL;
412     wxList::compatibility_iterator node;
413    
414     ln = loc.length();
415     meta = 0;
416     for (i = 0; i < ln; i++)
417     {
418     switch (loc[i])
419     {
420     case wxT('/') : case wxT(':') : case wxT('#') :
421     meta = loc[i];
422     break;
423     }
424     if (meta != 0) break;
425     }
426     m_LastName = wxEmptyString;
427    
428     // try relative paths first :
429     if (meta != wxT(':'))
430     {
431     node = m_Handlers.GetFirst();
432     while (node)
433     {
434     wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
435     if (h->CanOpen(m_Path + loc))
436     {
437     s = MakeLocal(h)->OpenFile(*this, m_Path + loc);
438     if (s) { m_LastName = m_Path + loc; break; }
439     }
440     node = node->GetNext();
441     }
442     }
443    
444     // if failed, try absolute paths :
445     if (s == NULL)
446     {
447     node = m_Handlers.GetFirst();
448     while (node)
449     {
450     wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
451     if (h->CanOpen(loc))
452     {
453     s = MakeLocal(h)->OpenFile(*this, loc);
454     if (s) { m_LastName = loc; break; }
455     }
456     node = node->GetNext();
457     }
458     }
459    
460     if (s && (flags & wxFS_SEEKABLE) != 0 && !s->GetStream()->IsSeekable())
461     {
462     wxBackedInputStream *stream;
463     stream = new wxBackedInputStream(s->DetachStream());
464     stream->FindLength();
465     s->SetStream(stream);
466     }
467    
468     return (s);
469     }
470    
471    
472    
473     wxString wxFileSystem::FindFirst(const wxString& spec, int flags)
474     {
475     wxList::compatibility_iterator node;
476     wxString spec2(spec);
477    
478     m_FindFileHandler = NULL;
479    
480     for (int i = spec2.length()-1; i >= 0; i--)
481     if (spec2[(unsigned int) i] == wxT('\\')) spec2.GetWritableChar(i) = wxT('/'); // Want to be windows-safe
482    
483     node = m_Handlers.GetFirst();
484     while (node)
485     {
486     wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
487     if (h -> CanOpen(m_Path + spec2))
488     {
489     m_FindFileHandler = MakeLocal(h);
490     return m_FindFileHandler -> FindFirst(m_Path + spec2, flags);
491     }
492     node = node->GetNext();
493     }
494    
495     node = m_Handlers.GetFirst();
496     while (node)
497     {
498     wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
499     if (h -> CanOpen(spec2))
500     {
501     m_FindFileHandler = MakeLocal(h);
502     return m_FindFileHandler -> FindFirst(spec2, flags);
503     }
504     node = node->GetNext();
505     }
506    
507     return wxEmptyString;
508     }
509    
510    
511    
512     wxString wxFileSystem::FindNext()
513     {
514     if (m_FindFileHandler == NULL) return wxEmptyString;
515     else return m_FindFileHandler -> FindNext();
516     }
517    
518     bool wxFileSystem::FindFileInPath(wxString *pStr,
519     const wxChar *path,
520     const wxChar *basename)
521     {
522     // we assume that it's not empty
523     wxCHECK_MSG( !wxIsEmpty(basename), false,
524     _T("empty file name in wxFileSystem::FindFileInPath"));
525    
526     // skip path separator in the beginning of the file name if present
527     if ( wxIsPathSeparator(*basename) )
528     basename++;
529    
530     wxStringTokenizer tokenizer(path, wxPATH_SEP);
531     while ( tokenizer.HasMoreTokens() )
532     {
533     wxString strFile = tokenizer.GetNextToken();
534     if ( !wxEndsWithPathSeparator(strFile) )
535     strFile += wxFILE_SEP_PATH;
536     strFile += basename;
537    
538     wxFSFile *file = OpenFile(strFile);
539     if ( file )
540     {
541     delete file;
542     *pStr = strFile;
543     return true;
544     }
545     }
546    
547     return false;
548     }
549    
550     void wxFileSystem::AddHandler(wxFileSystemHandler *handler)
551     {
552     // prepend the handler to the beginning of the list because handlers added
553     // last should have the highest priority to allow overriding them
554     m_Handlers.Insert((size_t)0, handler);
555     }
556    
557     wxFileSystemHandler* wxFileSystem::RemoveHandler(wxFileSystemHandler *handler)
558     {
559     // if handler has already been removed (or deleted)
560     // we return NULL. This is by design in case
561     // CleanUpHandlers() is called before RemoveHandler
562     // is called, as we cannot control the order
563     // which modules are unloaded
564     if (!m_Handlers.DeleteObject(handler))
565     return NULL;
566    
567     return handler;
568     }
569    
570    
571     bool wxFileSystem::HasHandlerForPath(const wxString &location)
572     {
573     for ( wxList::compatibility_iterator node = m_Handlers.GetFirst();
574     node; node = node->GetNext() )
575     {
576     wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
577     if (h->CanOpen(location))
578     return true;
579     }
580    
581     return false;
582     }
583    
584     void wxFileSystem::CleanUpHandlers()
585     {
586     WX_CLEAR_LIST(wxList, m_Handlers);
587     }
588    
589     static const wxString g_unixPathString(wxT("/"));
590     static const wxString g_nativePathString(wxFILE_SEP_PATH);
591    
592     // Returns the native path for a file URL
593     wxFileName wxFileSystem::URLToFileName(const wxString& url)
594     {
595     wxString path = url;
596    
597     if ( path.Find(wxT("file://")) == 0 )
598     {
599     path = path.Mid(7);
600     }
601     else if ( path.Find(wxT("file:")) == 0 )
602     {
603     path = path.Mid(5);
604     }
605     // Remove preceding double slash on Mac Classic
606     #if defined(__WXMAC__) && !defined(__UNIX__)
607     else if ( path.Find(wxT("//")) == 0 )
608     path = path.Mid(2);
609     #endif
610    
611     path = wxURI::Unescape(path);
612    
613     #ifdef __WXMSW__
614     // file urls either start with a forward slash (local harddisk),
615     // otherwise they have a servername/sharename notation,
616     // which only exists on msw and corresponds to a unc
617     if ( path[0u] == wxT('/') && path [1u] != wxT('/'))
618     {
619     path = path.Mid(1);
620     }
621     else if ( (url.Find(wxT("file://")) == 0) &&
622     (path.Find(wxT('/')) != wxNOT_FOUND) &&
623     (path.length() > 1) && (path[1u] != wxT(':')) )
624     {
625     path = wxT("//") + path;
626     }
627     #endif
628    
629     path.Replace(g_unixPathString, g_nativePathString);
630    
631     return wxFileName(path, wxPATH_NATIVE);
632     }
633    
634     // Returns the file URL for a native path
635     wxString wxFileSystem::FileNameToURL(const wxFileName& filename)
636     {
637     wxFileName fn = filename;
638     fn.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE);
639     wxString url = fn.GetFullPath(wxPATH_NATIVE);
640    
641     #ifndef __UNIX__
642     // unc notation, wxMSW
643     if ( url.Find(wxT("\\\\")) == 0 )
644     {
645     url = wxT("//") + url.Mid(2);
646     }
647     else
648     {
649     url = wxT("/") + url;
650     #ifdef __WXMAC__
651     url = wxT("/") + url;
652     #endif
653    
654     }
655     #endif
656    
657     url.Replace(g_nativePathString, g_unixPathString);
658     url.Replace(wxT("%"), wxT("%25")); // '%'s must be replaced first!
659     url.Replace(wxT("#"), wxT("%23"));
660     url.Replace(wxT(":"), wxT("%3A"));
661     url = wxT("file:") + url;
662     return url;
663     }
664    
665    
666     ///// Module:
667    
668     class wxFileSystemModule : public wxModule
669     {
670     DECLARE_DYNAMIC_CLASS(wxFileSystemModule)
671    
672     public:
673     wxFileSystemModule() :
674     wxModule(),
675     m_handler(NULL)
676     {
677     }
678    
679     virtual bool OnInit()
680     {
681     m_handler = new wxLocalFSHandler;
682     wxFileSystem::AddHandler(m_handler);
683     return true;
684     }
685     virtual void OnExit()
686     {
687     delete wxFileSystem::RemoveHandler(m_handler);
688    
689     wxFileSystem::CleanUpHandlers();
690     }
691    
692     private:
693     wxFileSystemHandler* m_handler;
694    
695     };
696    
697     IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule, wxModule)
698    
699     #endif
700     // wxUSE_FILESYSTEM

  ViewVC Help
Powered by ViewVC 1.1.22