]>
git.saurik.com Git - wxWidgets.git/blob - src/common/filesys.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFileSystem class - interface for opening files
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation
14 #include "wx/wxprec.h"
22 #define wxUSE_FS_INET 0
25 #if (wxUSE_HTML || wxUSE_FS_INET || wxUSE_FS_ZIP) && wxUSE_STREAMS
27 #include "wx/wfstream.h"
28 #include "wx/module.h"
29 #include "wx/filesys.h"
30 #include "wx/mimetype.h"
35 //--------------------------------------------------------------------------------
36 // wxFileSystemHandler
37 //--------------------------------------------------------------------------------
39 IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler
, wxObject
)
42 wxString
wxFileSystemHandler::GetMimeTypeFromExt(const wxString
& location
)
44 wxString ext
= wxEmptyString
, mime
= wxEmptyString
;
45 wxString loc
= GetRightLocation(location
);
47 int l
= loc
.Length(), l2
;
51 for (int i
= l
-1; i
>= 0; i
--) {
52 c
= loc
[(unsigned int) i
];
53 if (c
== wxT('#')) l2
= i
+ 1;
54 if (c
== wxT('.')) {ext
= loc
.Right(l2
-i
-1); break;}
55 if ((c
== wxT('/')) || (c
== wxT('\\')) || (c
== wxT(':'))) {return wxEmptyString
;}
58 static bool s_MinimalMimeEnsured
= FALSE
;
59 if (!s_MinimalMimeEnsured
) {
60 static const wxFileTypeInfo fallbacks
[] =
62 wxFileTypeInfo("image/jpeg",
65 "JPEG image (from fallback)",
67 wxFileTypeInfo("image/gif",
70 "GIF image (from fallback)",
72 wxFileTypeInfo("image/png",
75 "PNG image (from fallback)",
77 wxFileTypeInfo("image/bmp",
80 "windows bitmap image (from fallback)",
82 wxFileTypeInfo("text/html",
85 "HTML document (from fallback)",
88 // must terminate the table with this!
92 wxTheMimeTypesManager
-> AddFallbacks(fallbacks
);
95 ft
= wxTheMimeTypesManager
-> GetFileTypeFromExtension(ext
);
96 if (ft
&& (ft
-> GetMimeType(&mime
))) {
102 return wxEmptyString
;
108 wxString
wxFileSystemHandler::GetProtocol(const wxString
& location
) const
110 wxString s
= wxEmptyString
;
111 int i
, l
= location
.Length();
115 for (i
= l
-1; (i
>= 0) && ((location
[i
] != wxT('#')) || (!fnd
)); i
--) {
116 if ((location
[i
] == wxT(':')) && (i
!= 1 /*win: C:\path*/)) fnd
= TRUE
;
118 if (!fnd
) return wxT("file");
119 for (++i
; (i
< l
) && (location
[i
] != wxT(':')); i
++) s
<< location
[i
];
124 wxString
wxFileSystemHandler::GetLeftLocation(const wxString
& location
) const
130 for (i
= location
.Length()-1; i
>= 0; i
--) {
131 if ((location
[i
] == wxT(':')) && (i
!= 1 /*win: C:\path*/)) fnd
= TRUE
;
132 else if (fnd
&& (location
[i
] == wxT('#'))) return location
.Left(i
);
134 return wxEmptyString
;
137 wxString
wxFileSystemHandler::GetRightLocation(const wxString
& location
) const
139 int i
, l
= location
.Length();
141 for (i
= l
-1; (i
>= 0) && ((location
[i
] != wxT(':')) || (i
== 1) || (location
[i
-2] == wxT(':'))); i
--) {if (location
[i
] == wxT('#')) l2
= i
+ 1;}
142 if (i
== 0) return wxEmptyString
;
143 else return location
.Mid(i
+ 1, l2
- i
- 2);
146 wxString
wxFileSystemHandler::GetAnchor(const wxString
& location
) const
149 int l
= location
.Length();
151 for (int i
= l
-1; i
>= 0; i
--) {
153 if (c
== wxT('#')) return location
.Right(l
-i
-1);
154 else if ((c
== wxT('.')) || (c
== wxT('/')) || (c
== wxT('\\')) || (c
== wxT(':'))) return wxEmptyString
;
156 return wxEmptyString
;
160 wxString
wxFileSystemHandler::FindFirst(const wxString
& WXUNUSED(spec
),
163 return wxEmptyString
;
166 wxString
wxFileSystemHandler::FindNext()
168 return wxEmptyString
;
171 //--------------------------------------------------------------------------------
173 //--------------------------------------------------------------------------------
175 class wxLocalFSHandler
: public wxFileSystemHandler
178 virtual bool CanOpen(const wxString
& location
);
179 virtual wxFSFile
* OpenFile(wxFileSystem
& fs
, const wxString
& location
);
180 virtual wxString
FindFirst(const wxString
& spec
, int flags
= 0);
181 virtual wxString
FindNext();
185 bool wxLocalFSHandler::CanOpen(const wxString
& location
)
187 return GetProtocol(location
) == wxT("file");
190 wxFSFile
* wxLocalFSHandler::OpenFile(wxFileSystem
& WXUNUSED(fs
), const wxString
& location
)
192 wxString right
= GetRightLocation(location
);
193 if (wxFileExists(right
))
194 return new wxFSFile(new wxFileInputStream(right
),
196 GetMimeTypeFromExt(location
),
198 wxDateTime(wxFileModificationTime(right
)));
199 else return (wxFSFile
*) NULL
;
202 wxString
wxLocalFSHandler::FindFirst(const wxString
& spec
, int flags
)
204 wxString right
= GetRightLocation(spec
);
205 return wxFindFirstFile(right
, flags
);
208 wxString
wxLocalFSHandler::FindNext()
210 return wxFindNextFile();
215 //-----------------------------------------------------------------------------
217 //-----------------------------------------------------------------------------
219 IMPLEMENT_DYNAMIC_CLASS(wxFileSystem
, wxObject
)
222 wxList
wxFileSystem::m_Handlers
;
225 static wxString
MakeCorrectPath(const wxString
& path
)
232 for (i
= 0; i
< cnt
; i
++)
233 if (p
.GetChar(i
) == wxT('\\')); p
.GetWritableChar(i
) = wxT('/'); // wanna be windows-safe
235 if (p
.Left(2) == wxT("./")) { p
= p
.Mid(2); cnt
-= 2; }
237 if (cnt
< 3) return p
;
239 r
<< p
.GetChar(0) << p
.GetChar(1);
241 // skip trailing ../.., if any
242 for (i
= 2; i
< cnt
&& (p
.GetChar(i
) == wxT('/') || p
.GetChar(i
) == wxT('.')); i
++) r
<< p
.GetChar(i
);
244 // remove back references: translate dir1/../dir2 to dir2
248 if (p
.GetChar(i
) == wxT('/') && p
.GetChar(i
-1) == wxT('.') && p
.GetChar(i
-2) == wxT('.'))
250 for (j
= r
.Length() - 2; j
>= 0 && r
.GetChar(j
) != wxT('/') && r
.GetChar(j
) != wxT(':'); j
--) {}
251 if (j
>= 0 && r
.GetChar(j
) != wxT(':'))
253 for (j
= j
- 1; j
>= 0 && r
.GetChar(j
) != wxT('/') && r
.GetChar(j
) != wxT(':'); j
--) {}
259 for (; i
< cnt
; i
++) r
<< p
.GetChar(i
);
265 void wxFileSystem::ChangePathTo(const wxString
& location
, bool is_dir
)
269 m_Path
= MakeCorrectPath(location
);
273 if (m_Path
.Length() > 0 && m_Path
.Last() != wxT('/') && m_Path
.Last() != wxT(':'))
279 for (i
= m_Path
.Length()-1; i
>= 0; i
--)
281 if (m_Path
[(unsigned int) i
] == wxT('/'))
283 if ((i
> 1) && (m_Path
[(unsigned int) (i
-1)] == wxT('/')) && (m_Path
[(unsigned int) (i
-2)] == wxT(':')))
294 else if (m_Path
[(unsigned int) i
] == wxT(':')) {
301 for (i
= 0; i
< (int) m_Path
.Length(); i
++)
303 if (m_Path
[(unsigned int) i
] == wxT(':'))
309 if (i
== (int) m_Path
.Length())
310 m_Path
= wxEmptyString
;
314 m_Path
.Remove(pathpos
+1);
321 wxFSFile
* wxFileSystem::OpenFile(const wxString
& location
)
323 wxString loc
= MakeCorrectPath(location
);
331 for (i
= 0; i
< ln
; i
++)
336 case wxT('/') : case wxT(':') : case wxT('#') : meta
= loc
[i
];
339 m_LastName
= wxEmptyString
;
341 // try relative paths first :
342 if (meta
!= wxT(':'))
344 node
= m_Handlers
.GetFirst();
347 wxFileSystemHandler
*h
= (wxFileSystemHandler
*) node
-> GetData();
348 if (h
->CanOpen(m_Path
+ loc
))
350 s
= h
->OpenFile(*this, m_Path
+ loc
);
351 if (s
) { m_LastName
= m_Path
+ loc
; break; }
353 node
= node
->GetNext();
357 // if failed, try absolute paths :
360 node
= m_Handlers
.GetFirst();
363 wxFileSystemHandler
*h
= (wxFileSystemHandler
*) node
->GetData();
366 s
= h
->OpenFile(*this, loc
);
367 if (s
) { m_LastName
= loc
; break; }
369 node
= node
->GetNext();
377 wxString
wxFileSystem::FindFirst(const wxString
& spec
, int flags
)
380 wxString
spec2(spec
);
382 m_FindFileHandler
= NULL
;
384 for (int i
= spec2
.Length()-1; i
>= 0; i
--)
385 if (spec2
[(unsigned int) i
] == wxT('\\')) spec2
.GetWritableChar(i
) = wxT('/'); // wanna be windows-safe
387 node
= m_Handlers
.GetFirst();
390 m_FindFileHandler
= (wxFileSystemHandler
*) node
-> GetData();
391 if (m_FindFileHandler
-> CanOpen(m_Path
+ spec2
))
392 return m_FindFileHandler
-> FindFirst(m_Path
+ spec2
, flags
);
393 node
= node
->GetNext();
396 node
= m_Handlers
.GetFirst();
399 m_FindFileHandler
= (wxFileSystemHandler
*) node
-> GetData();
400 if (m_FindFileHandler
-> CanOpen(spec2
))
401 return m_FindFileHandler
-> FindFirst(spec2
, flags
);
402 node
= node
->GetNext();
405 return wxEmptyString
;
410 wxString
wxFileSystem::FindNext()
412 if (m_FindFileHandler
== NULL
) return wxEmptyString
;
413 else return m_FindFileHandler
-> FindNext();
418 void wxFileSystem::AddHandler(wxFileSystemHandler
*handler
)
420 m_Handlers
.Append(handler
);
424 void wxFileSystem::CleanUpHandlers()
426 m_Handlers
.DeleteContents(TRUE
);
435 class wxFileSystemModule
: public wxModule
437 DECLARE_DYNAMIC_CLASS(wxFileSystemModule
)
440 virtual bool OnInit()
442 wxFileSystem::AddHandler(new wxLocalFSHandler
);
445 virtual void OnExit()
447 wxFileSystem::CleanUpHandlers();
451 IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule
, wxModule
)
454 // (wxUSE_FS_INET || wxUSE_FS_ZIP) && wxUSE_STREAMS