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