]>
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"
23 #include "wx/wfstream.h"
24 #include "wx/module.h"
25 #include "wx/filesys.h"
26 #include "wx/mimetype.h"
27 #include "wx/filename.h"
31 //--------------------------------------------------------------------------------
32 // wxFileSystemHandler
33 //--------------------------------------------------------------------------------
35 IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler
, wxObject
)
39 static wxFileTypeInfo
*gs_FSMimeFallbacks
= NULL
;
42 wxString
wxFileSystemHandler::GetMimeTypeFromExt(const wxString
& location
)
45 wxString ext
= wxEmptyString
, mime
= wxEmptyString
;
46 wxString loc
= GetRightLocation(location
);
48 int l
= loc
.Length(), l2
;
52 for (int i
= l
-1; i
>= 0; i
--) {
53 c
= loc
[(unsigned int) i
];
54 if (c
== wxT('#')) l2
= i
+ 1;
55 if (c
== wxT('.')) {ext
= loc
.Right(l2
-i
-1); break;}
56 if ((c
== wxT('/')) || (c
== wxT('\\')) || (c
== wxT(':'))) {return wxEmptyString
;}
59 static bool s_MinimalMimeEnsured
= FALSE
;
60 if (!s_MinimalMimeEnsured
) {
61 wxTheMimeTypesManager
-> AddFallbacks(gs_FSMimeFallbacks
);
62 s_MinimalMimeEnsured
= TRUE
;
65 ft
= wxTheMimeTypesManager
-> GetFileTypeFromExtension(ext
);
66 if ( !ft
|| !ft
-> GetMimeType(&mime
) ) {
80 wxString
wxFileSystemHandler::GetProtocol(const wxString
& location
) const
82 wxString s
= wxEmptyString
;
83 int i
, l
= location
.Length();
87 for (i
= l
-1; (i
>= 0) && ((location
[i
] != wxT('#')) || (!fnd
)); i
--) {
88 if ((location
[i
] == wxT(':')) && (i
!= 1 /*win: C:\path*/)) fnd
= TRUE
;
90 if (!fnd
) return wxT("file");
91 for (++i
; (i
< l
) && (location
[i
] != wxT(':')); i
++) s
<< location
[i
];
96 wxString
wxFileSystemHandler::GetLeftLocation(const wxString
& location
) const
102 for (i
= location
.Length()-1; i
>= 0; i
--) {
103 if ((location
[i
] == wxT(':')) && (i
!= 1 /*win: C:\path*/)) fnd
= TRUE
;
104 else if (fnd
&& (location
[i
] == wxT('#'))) return location
.Left(i
);
106 return wxEmptyString
;
109 wxString
wxFileSystemHandler::GetRightLocation(const wxString
& location
) const
111 int i
, l
= location
.Length();
113 for (i
= l
-1; (i
>= 0) && ((location
[i
] != wxT(':')) || (i
== 1) || (location
[i
-2] == wxT(':'))); i
--) {if (location
[i
] == wxT('#')) l2
= i
+ 1;}
114 if (i
== 0) return wxEmptyString
;
115 else return location
.Mid(i
+ 1, l2
- i
- 2);
118 wxString
wxFileSystemHandler::GetAnchor(const wxString
& location
) const
121 int l
= location
.Length();
123 for (int i
= l
-1; i
>= 0; i
--) {
125 if (c
== wxT('#')) return location
.Right(l
-i
-1);
126 else if ((c
== wxT('.')) || (c
== wxT('/')) || (c
== wxT('\\')) || (c
== wxT(':'))) return wxEmptyString
;
128 return wxEmptyString
;
132 wxString
wxFileSystemHandler::FindFirst(const wxString
& WXUNUSED(spec
),
135 return wxEmptyString
;
138 wxString
wxFileSystemHandler::FindNext()
140 return wxEmptyString
;
143 //--------------------------------------------------------------------------------
145 //--------------------------------------------------------------------------------
148 wxString
wxLocalFSHandler::ms_root
;
150 bool wxLocalFSHandler::CanOpen(const wxString
& location
)
152 return GetProtocol(location
) == wxT("file");
155 wxFSFile
* wxLocalFSHandler::OpenFile(wxFileSystem
& WXUNUSED(fs
), const wxString
& location
)
157 // location has Unix path separators
158 wxString right
= ms_root
+ GetRightLocation(location
);
159 wxFileName
fn(right
, wxPATH_UNIX
);
161 if (!wxFileExists(fn
.GetFullPath()))
162 return (wxFSFile
*) NULL
;
164 return new wxFSFile(new wxFileInputStream(fn
.GetFullPath()),
166 GetMimeTypeFromExt(location
),
168 wxDateTime(wxFileModificationTime(fn
.GetFullPath())));
172 wxString
wxLocalFSHandler::FindFirst(const wxString
& spec
, int flags
)
174 wxString right
= ms_root
+ GetRightLocation(spec
);
175 return wxFindFirstFile(right
, flags
);
178 wxString
wxLocalFSHandler::FindNext()
180 return wxFindNextFile();
185 //-----------------------------------------------------------------------------
187 //-----------------------------------------------------------------------------
189 IMPLEMENT_DYNAMIC_CLASS(wxFileSystem
, wxObject
)
192 wxList
wxFileSystem::m_Handlers
;
195 static wxString
MakeCorrectPath(const wxString
& path
)
202 for (i
= 0; i
< cnt
; i
++)
203 if (p
.GetChar(i
) == wxT('\\')) p
.GetWritableChar(i
) = wxT('/'); // Want to be windows-safe
205 if (p
.Left(2) == wxT("./")) { p
= p
.Mid(2); cnt
-= 2; }
207 if (cnt
< 3) return p
;
209 r
<< p
.GetChar(0) << p
.GetChar(1);
211 // skip trailing ../.., if any
212 for (i
= 2; i
< cnt
&& (p
.GetChar(i
) == wxT('/') || p
.GetChar(i
) == wxT('.')); i
++) r
<< p
.GetChar(i
);
214 // remove back references: translate dir1/../dir2 to dir2
218 if (p
.GetChar(i
) == wxT('/') && p
.GetChar(i
-1) == wxT('.') && p
.GetChar(i
-2) == wxT('.'))
220 for (j
= r
.Length() - 2; j
>= 0 && r
.GetChar(j
) != wxT('/') && r
.GetChar(j
) != wxT(':'); j
--) {}
221 if (j
>= 0 && r
.GetChar(j
) != wxT(':'))
223 for (j
= j
- 1; j
>= 0 && r
.GetChar(j
) != wxT('/') && r
.GetChar(j
) != wxT(':'); j
--) {}
229 for (; i
< cnt
; i
++) r
<< p
.GetChar(i
);
235 void wxFileSystem::ChangePathTo(const wxString
& location
, bool is_dir
)
239 m_Path
= MakeCorrectPath(location
);
243 if (m_Path
.Length() > 0 && m_Path
.Last() != wxT('/') && m_Path
.Last() != wxT(':'))
249 for (i
= m_Path
.Length()-1; i
>= 0; i
--)
251 if (m_Path
[(unsigned int) i
] == wxT('/'))
253 if ((i
> 1) && (m_Path
[(unsigned int) (i
-1)] == wxT('/')) && (m_Path
[(unsigned int) (i
-2)] == wxT(':')))
264 else if (m_Path
[(unsigned int) i
] == wxT(':')) {
271 for (i
= 0; i
< (int) m_Path
.Length(); i
++)
273 if (m_Path
[(unsigned int) i
] == wxT(':'))
279 if (i
== (int) m_Path
.Length())
280 m_Path
= wxEmptyString
;
284 m_Path
.Remove(pathpos
+1);
291 wxFSFile
* wxFileSystem::OpenFile(const wxString
& location
)
293 wxString loc
= MakeCorrectPath(location
);
301 for (i
= 0; i
< ln
; i
++)
305 case wxT('/') : case wxT(':') : case wxT('#') :
309 if (meta
!= 0) break;
311 m_LastName
= wxEmptyString
;
313 // try relative paths first :
314 if (meta
!= wxT(':'))
316 node
= m_Handlers
.GetFirst();
319 wxFileSystemHandler
*h
= (wxFileSystemHandler
*) node
-> GetData();
320 if (h
->CanOpen(m_Path
+ loc
))
322 s
= h
->OpenFile(*this, m_Path
+ loc
);
323 if (s
) { m_LastName
= m_Path
+ loc
; break; }
325 node
= node
->GetNext();
329 // if failed, try absolute paths :
332 node
= m_Handlers
.GetFirst();
335 wxFileSystemHandler
*h
= (wxFileSystemHandler
*) node
->GetData();
338 s
= h
->OpenFile(*this, loc
);
339 if (s
) { m_LastName
= loc
; break; }
341 node
= node
->GetNext();
349 wxString
wxFileSystem::FindFirst(const wxString
& spec
, int flags
)
352 wxString
spec2(spec
);
354 m_FindFileHandler
= NULL
;
356 for (int i
= spec2
.Length()-1; i
>= 0; i
--)
357 if (spec2
[(unsigned int) i
] == wxT('\\')) spec2
.GetWritableChar(i
) = wxT('/'); // Want to be windows-safe
359 node
= m_Handlers
.GetFirst();
362 m_FindFileHandler
= (wxFileSystemHandler
*) node
-> GetData();
363 if (m_FindFileHandler
-> CanOpen(m_Path
+ spec2
))
364 return m_FindFileHandler
-> FindFirst(m_Path
+ spec2
, flags
);
365 node
= node
->GetNext();
368 node
= m_Handlers
.GetFirst();
371 m_FindFileHandler
= (wxFileSystemHandler
*) node
-> GetData();
372 if (m_FindFileHandler
-> CanOpen(spec2
))
373 return m_FindFileHandler
-> FindFirst(spec2
, flags
);
374 node
= node
->GetNext();
377 return wxEmptyString
;
382 wxString
wxFileSystem::FindNext()
384 if (m_FindFileHandler
== NULL
) return wxEmptyString
;
385 else return m_FindFileHandler
-> FindNext();
390 void wxFileSystem::AddHandler(wxFileSystemHandler
*handler
)
392 m_Handlers
.Append(handler
);
396 void wxFileSystem::CleanUpHandlers()
398 m_Handlers
.DeleteContents(TRUE
);
407 class wxFileSystemModule
: public wxModule
409 DECLARE_DYNAMIC_CLASS(wxFileSystemModule
)
412 virtual bool OnInit()
414 wxFileSystem::AddHandler(new wxLocalFSHandler
);
417 gs_FSMimeFallbacks
= new wxFileTypeInfo
[6];
418 gs_FSMimeFallbacks
[0] =
419 wxFileTypeInfo("image/jpeg",
422 "JPEG image (from fallback)",
423 "jpg", "jpeg", NULL
);
424 gs_FSMimeFallbacks
[1] =
425 wxFileTypeInfo("image/gif",
428 "GIF image (from fallback)",
430 gs_FSMimeFallbacks
[2] =
431 wxFileTypeInfo("image/png",
434 "PNG image (from fallback)",
436 gs_FSMimeFallbacks
[3] =
437 wxFileTypeInfo("image/bmp",
440 "windows bitmap image (from fallback)",
442 gs_FSMimeFallbacks
[4] =
443 wxFileTypeInfo("text/html",
446 "HTML document (from fallback)",
447 "htm", "html", NULL
);
448 gs_FSMimeFallbacks
[5] =
449 // must terminate the table with this!
454 virtual void OnExit()
457 delete [] gs_FSMimeFallbacks
;
459 wxFileSystem::CleanUpHandlers();
463 IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule
, wxModule
)