]> git.saurik.com Git - wxWidgets.git/blob - src/common/filesys.cpp
added TODO list for cross compilation
[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_FS_INET || wxUSE_FS_ZIP) && wxUSE_STREAMS
20
21 #include "wx/wfstream.h"
22 #include "wx/module.h"
23 #include "wx/filesys.h"
24
25 //--------------------------------------------------------------------------------
26 // wxFileSystemHandler
27 //--------------------------------------------------------------------------------
28
29 IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler, wxObject)
30
31 wxMimeTypesManager wxFileSystemHandler::m_MimeMng;
32
33
34 wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
35 {
36 wxString ext = wxEmptyString, mime = wxEmptyString;
37 wxString loc = GetRightLocation(location);
38 char c;
39 int l = loc.Length(), l2;
40 wxFileType *ft;
41
42 l2 = l;
43 for (int i = l-1; i >= 0; i--) {
44 c = loc[i];
45 if (c == _T('#')) l2 = i + 1;
46 if (c == _T('.')) {ext = loc.Right(l2-i-1); break;}
47 if ((c == _T('/')) || (c == _T('\\')) || (c == _T(':'))) {return wxEmptyString;}
48 }
49 ft = m_MimeMng.GetFileTypeFromExtension(ext);
50 if (ft && (ft -> GetMimeType(&mime))) return mime;
51 else return wxEmptyString;
52 }
53
54
55
56 wxString wxFileSystemHandler::GetProtocol(const wxString& location) const
57 {
58 wxString s = wxEmptyString;
59 int i, l = location.Length();
60 bool fnd;
61
62 fnd = FALSE;
63 for (i = l-1; (i >= 0) && ((location[i] != _T('#')) || (!fnd)); i--) {
64 if ((location[i] == _T(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
65 }
66 if (!fnd) return _T("file");
67 for (++i; (i < l) && (location[i] != _T(':')); i++) s << location[i];
68 return s;
69 }
70
71
72 wxString wxFileSystemHandler::GetLeftLocation(const wxString& location) const
73 {
74 int i;
75 bool fnd;
76
77 fnd = FALSE;
78 for (i = location.Length()-1; i >= 0; i--) {
79 if ((location[i] == _T(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
80 else if (fnd && (location[i] == _T('#'))) return location.Left(i);
81 }
82 return wxEmptyString;
83 }
84
85 wxString wxFileSystemHandler::GetRightLocation(const wxString& location) const
86 {
87 int i, l = location.Length();
88 int l2 = l + 1;
89 for (i = l-1; (i >= 0) && ((location[i] != _T(':')) || (i == 1) || (location[i-2] == _T(':'))); i--) {if (location[i] == _T('#')) l2 = i + 1;}
90 if (i == 0) return wxEmptyString;
91 else return location.Mid(i + 1, l2 - i - 2);
92 }
93
94 wxString wxFileSystemHandler::GetAnchor(const wxString& location) const
95 {
96 char c;
97 int l = location.Length();
98
99 for (int i = l-1; i >= 0; i--) {
100 c = location[i];
101 if (c == _T('#')) return location.Right(l-i-1);
102 else if ((c == _T('.')) || (c == _T('/')) || (c == _T('\\')) || (c == _T(':'))) return wxEmptyString;
103 }
104 return wxEmptyString;
105 }
106
107 //--------------------------------------------------------------------------------
108 // wxLocalFSHandler
109 //--------------------------------------------------------------------------------
110
111 class wxLocalFSHandler : public wxFileSystemHandler
112 {
113 public:
114 virtual bool CanOpen(const wxString& location);
115 virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
116 };
117
118
119 bool wxLocalFSHandler::CanOpen(const wxString& location)
120 {
121 return GetProtocol(location) == _T("file");
122 }
123
124 wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
125 {
126 wxString right = GetRightLocation(location);
127 if (wxFileExists(right))
128 return new wxFSFile(new wxFileInputStream(right),
129 right,
130 GetMimeTypeFromExt(location),
131 GetAnchor(location));
132 else return (wxFSFile*) NULL;
133 }
134
135 //-----------------------------------------------------------------------------
136 // wxFileSystem
137 //-----------------------------------------------------------------------------
138
139 IMPLEMENT_DYNAMIC_CLASS(wxFileSystem, wxObject)
140
141
142 wxList wxFileSystem::m_Handlers;
143
144
145
146 void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
147 {
148 int i, pathpos = -1;
149 m_Path = location;
150
151 for (i = m_Path.Length()-1; i >= 0; i--)
152 if (m_Path[i] == _T('\\')) m_Path.GetWritableChar(i) = _T('/'); // wanna be windows-safe
153
154 if (is_dir == FALSE)
155 {
156 for (i = m_Path.Length()-1; i >= 0; i--)
157 {
158 if (m_Path[i] == _T('/'))
159 {
160 if ((i > 1) && (m_Path[i-1] == _T('/')) && (m_Path[i-2] == _T(':')))
161 {
162 i -= 2;
163 continue;
164 }
165 else
166 {
167 pathpos = i;
168 break;
169 }
170 }
171 else if (m_Path[i] == _T(':')) {
172 pathpos = i;
173 break;
174 }
175 }
176 if (pathpos == -1)
177 {
178 for (i = 0; i < (int) m_Path.Length(); i++)
179 {
180 if (m_Path[i] == _T(':'))
181 {
182 //m_Path << _T('/');
183 m_Path.Remove(i+1);
184 break;
185 }
186 }
187 if (i == (int) m_Path.Length())
188 m_Path = wxEmptyString;
189 }
190 else
191 {
192 if (m_Path[m_Path.Length()-1] != _T('/'))
193 m_Path << _T('/');
194 m_Path.Remove(pathpos+1);
195 }
196 }
197 }
198
199
200
201 wxFSFile* wxFileSystem::OpenFile(const wxString& location)
202 {
203 wxString loc = location;
204 int i, ln;
205 char meta;
206 wxFSFile *s = NULL;
207 wxNode *node;
208
209 ln = loc.Length();
210 meta = 0;
211 for (i = 0; i < ln; i++)
212 {
213 if (loc[i] == _T('\\')) loc.GetWritableChar(i) = _T('/'); // wanna be windows-safe
214 if (!meta) switch (loc[i])
215 {
216 case _T('/') : case _T(':') : case _T('#') : meta = loc[i];
217 }
218 }
219 m_LastName = wxEmptyString;
220
221 // try relative paths first :
222 if (meta != _T(':'))
223 {
224 node = m_Handlers.GetFirst();
225 while (node)
226 {
227 wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
228 if (h->CanOpen(m_Path + location))
229 {
230 s = h->OpenFile(*this, m_Path + location);
231 if (s) { m_LastName = m_Path + location; break; }
232 }
233 node = node->GetNext();
234 }
235 }
236
237 // if failed, try absolute paths :
238 if (s == NULL)
239 {
240 node = m_Handlers.GetFirst();
241 while (node)
242 {
243 wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
244 if (h->CanOpen(location))
245 {
246 s = h->OpenFile(*this, location);
247 if (s) { m_LastName = location; break; }
248 }
249 node = node->GetNext();
250 }
251 }
252 return (s);
253 }
254
255
256 void wxFileSystem::AddHandler(wxFileSystemHandler *handler)
257 {
258 m_Handlers.Append(handler);
259 }
260
261
262
263 ///// Module:
264
265 class wxFileSystemModule : public wxModule
266 {
267 DECLARE_DYNAMIC_CLASS(wxFileSystemModule)
268
269 public:
270 virtual bool OnInit()
271 {
272 wxFileSystem::AddHandler(new wxLocalFSHandler);
273 return TRUE;
274 }
275 virtual void OnExit() {}
276 };
277
278 IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule, wxModule)
279
280 #endif
281 // (wxUSE_FS_INET || wxUSE_FS_ZIP) && wxUSE_STREAMS
282