]>
git.saurik.com Git - wxWidgets.git/blob - src/common/webviewfilehandler.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: webviewfilehandler.cpp
3 // Purpose: Custom handler for the file scheme to allow archive browsing
4 // Author: Steven Lamerton
6 // Copyright: (c) 2011 Steven Lamerton
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
15 #if defined(__BORLANDC__)
19 #include "wx/webviewfilehandler.h"
20 #include "wx/filesys.h"
21 #include "wx/tokenzr.h"
23 //Taken from wx/filesys.cpp
24 static wxString
EscapeFileNameCharsInURL(const char *in
)
28 for ( const unsigned char *p
= (const unsigned char*)in
; *p
; ++p
)
30 const unsigned char c
= *p
;
32 if ( c
== '/' || c
== '-' || c
== '.' || c
== '_' || c
== '~' ||
33 (c
>= '0' && c
<= '9') ||
34 (c
>= 'a' && c
<= 'z') ||
35 (c
>= 'A' && c
<= 'Z') )
41 s
<< wxString::Format("%%%02x", c
);
48 wxWebFileHandler::wxWebFileHandler()
51 m_fileSystem
= new wxFileSystem();
54 wxFSFile
* wxWebFileHandler::GetFile(const wxString
&uri
)
56 size_t pos
= uri
.find('?');
57 //There is no query string so we can load the file directly
58 if(pos
== wxString::npos
)
60 size_t doubleslash
= uri
.find("//");
61 //The path is incorrectly formed without // after the first protocol
62 if(doubleslash
== wxString::npos
)
65 wxString fspath
= "file:" +
66 EscapeFileNameCharsInURL(uri
.substr(doubleslash
+ 2));
67 return m_fileSystem
->OpenFile(fspath
);
69 //Otherwise we have a query string of some kind that we need to extract
71 //First we extract the query string, this should have two parameters,
72 //protocol=type and path=path
73 wxString query
= uri
.substr(pos
+ 1), protocol
, path
;
74 //We also trim the query off the end as we handle it alone
75 wxString lefturi
= uri
.substr(0, pos
);
76 wxStringTokenizer
tokenizer(query
, ";");
77 while(tokenizer
.HasMoreTokens() && (protocol
== "" || path
== ""))
79 wxString token
= tokenizer
.GetNextToken();
80 if(token
.substr(0, 9) == "protocol=")
82 protocol
= token
.substr(9);
84 else if(token
.substr(0, 5) == "path=")
86 path
= token
.substr(5);
89 if(protocol
== "" || path
== "")
92 //We now have the path and the protocol and so can format a correct uri
93 //to pass to wxFileSystem to get a wxFSFile
94 size_t doubleslash
= uri
.find("//");
95 //The path is incorrectly formed without // after the first protocol
96 if(doubleslash
== wxString::npos
)
99 wxString fspath
= "file:" +
100 EscapeFileNameCharsInURL(lefturi
.substr(doubleslash
+ 2))
101 + "#" + protocol
+":" + path
;
102 return m_fileSystem
->OpenFile(fspath
);
106 wxString
wxWebFileHandler::CombineURIs(const wxString
&baseuri
,
107 const wxString
&newuri
)
109 //If there is a colon in the path then we just return it
110 if(newuri
.find(':') != wxString::npos
)
114 //We have an absolute path and no query string
115 else if(newuri
.substr(0, 1) == "/" && baseuri
.find('?') == wxString::npos
)
117 //By finding the next / after file:// we get to the end of the
118 //(optional) hostname
119 size_t pos
= baseuri
.find('/', 7);
120 //So we return up to the end of the hostname, plus the newuri
121 return baseuri
.substr(0, pos
) + newuri
;
123 //We have an absolute path and a query string
124 else if(newuri
.substr(0, 1) == "/" && baseuri
.find('?') != wxString::npos
)
126 wxString query
= baseuri
.substr(baseuri
.find('?') + 1);
128 wxStringTokenizer
tokenizer(query
, ";");
129 while(tokenizer
.HasMoreTokens())
131 wxString token
= tokenizer
.GetNextToken();
132 if(token
.substr(0, 5) == "path=")
134 //As the path is absolue simply replace the old path with the
136 newquery
= newquery
+ "path=" + newuri
;
142 //We need to add the separators back
143 if(tokenizer
.HasMoreTokens())
146 return baseuri
.substr(0, baseuri
.find('?')) + "?" + newquery
;
148 //We have a relative path and no query string
149 else if(baseuri
.find('?') == wxString::npos
)
151 //By finding the next / after file:// we get to the end of the
152 //(optional) hostname
153 size_t pos
= baseuri
.find('/', 7);
154 wxString path
= baseuri
.substr(pos
);
155 //Then we remove the last filename
156 path
= path
.BeforeLast('/') + '/';
157 //Ensure that we have the leading / so we can normalise properly
158 if(path
.substr(0, 1) != "/")
161 //If we have a colon in the path (i.e. we are on windows) we need to
162 //handle it specially
163 if(path
.find(':') != wxString::npos
)
165 wxFileName
fn(path
.AfterFirst('/').AfterFirst('/') + newuri
);
166 fn
.Normalize(wxPATH_NORM_DOTS
, "", wxPATH_UNIX
);
167 return baseuri
.substr(0, pos
) + '/' +
168 path
.AfterFirst('/').BeforeFirst('/') + '/' +
169 fn
.GetFullPath(wxPATH_UNIX
);
173 //We can now use wxFileName to perform the normalisation
174 wxFileName
fn(path
+ newuri
);
175 fn
.Normalize(wxPATH_NORM_DOTS
, "", wxPATH_UNIX
);
176 return baseuri
.substr(0, pos
) + fn
.GetFullPath(wxPATH_UNIX
);
179 //We have a relative path and a query string
182 wxString query
= baseuri
.substr(baseuri
.find('?') + 1);
184 wxStringTokenizer
tokenizer(query
, ";");
185 while(tokenizer
.HasMoreTokens())
187 wxString token
= tokenizer
.GetNextToken();
188 if(token
.substr(0, 5) == "path=")
190 wxString path
= token
.substr(6);
191 //Then we remove the last filename
192 path
= path
.BeforeLast('/') + '/';
193 //Ensure that we have the leading / so we can normalise properly
194 //if(path.substr(0, 1) != "/")
195 // path = "/" + path;
197 //We can now use wxFileName to perform the normalisation
198 wxFileName
fn(path
+ newuri
);
199 fn
.Normalize(wxPATH_NORM_DOTS
, "", wxPATH_UNIX
);
200 newquery
= newquery
+ "path=" + fn
.GetFullPath(wxPATH_UNIX
);
206 //We need to add the separators back
207 if(tokenizer
.HasMoreTokens())
210 return baseuri
.substr(0, baseuri
.find('?')) + "?" + newquery
;