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