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