git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/SOC2011_WEBVIEW@68469 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
197 lines
6.2 KiB
C++
197 lines
6.2 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: webviewfilehandler.cpp
|
|
// Purpose: Custom handler for the file scheme to allow archive browsing
|
|
// Author: Steven Lamerton
|
|
// Id: $Id$
|
|
// Copyright: (c) 2011 Steven Lamerton
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#if wxUSE_WEB
|
|
|
|
#if defined(__BORLANDC__)
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include "wx/webviewfilehandler.h"
|
|
#include "wx/filesys.h"
|
|
#include "wx/tokenzr.h"
|
|
#include "wx/hashmap.h"
|
|
|
|
typedef wxStringToStringHashMap QueryMap;
|
|
|
|
QueryMap QueryStringToQueryMap(wxString query)
|
|
{
|
|
QueryMap map;
|
|
|
|
if(query.substr(0, 1) == "?")
|
|
query = query.substr(1);
|
|
|
|
wxStringTokenizer tokenizer(query, ";");
|
|
while(tokenizer.HasMoreTokens())
|
|
{
|
|
wxString token = tokenizer.GetNextToken();
|
|
size_t pos = token.find('=');
|
|
map[token.substr(0, pos)] = token.substr(pos + 1);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
wxString QueryMapToQueryString(QueryMap map)
|
|
{
|
|
wxString query = "?";
|
|
|
|
QueryMap::iterator it;
|
|
for(it = map.begin(); it != map.end(); ++it)
|
|
{
|
|
query = query + it->first + "=" + it->second + ";";
|
|
}
|
|
|
|
//Chop the end ; off
|
|
return query.substr(0, query.length() - 1);
|
|
}
|
|
|
|
//Taken from wx/filesys.cpp
|
|
static wxString EscapeFileNameCharsInURL(const char *in)
|
|
{
|
|
wxString s;
|
|
|
|
for ( const unsigned char *p = (const unsigned char*)in; *p; ++p )
|
|
{
|
|
const unsigned char c = *p;
|
|
|
|
if ( c == '/' || c == '-' || c == '.' || c == '_' || c == '~' ||
|
|
(c >= '0' && c <= '9') ||
|
|
(c >= 'a' && c <= 'z') ||
|
|
(c >= 'A' && c <= 'Z') )
|
|
{
|
|
s << c;
|
|
}
|
|
else
|
|
{
|
|
s << wxString::Format("%%%02x", c);
|
|
}
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
wxWebFileHandler::wxWebFileHandler()
|
|
{
|
|
m_name = "test";
|
|
m_fileSystem = new wxFileSystem();
|
|
}
|
|
|
|
wxFSFile* wxWebFileHandler::GetFile(const wxString &uri)
|
|
{
|
|
size_t pos = uri.find('?');
|
|
//There is no query string so we can load the file directly
|
|
if(pos == wxString::npos)
|
|
{
|
|
size_t doubleslash = uri.find("//");
|
|
//The path is incorrectly formed without // after the first protocol
|
|
if(doubleslash == wxString::npos)
|
|
return NULL;
|
|
|
|
wxString fspath = "file:" +
|
|
EscapeFileNameCharsInURL(uri.substr(doubleslash + 2));
|
|
return m_fileSystem->OpenFile(fspath);
|
|
}
|
|
//Otherwise we have a query string of some kind that we need to extract
|
|
else{
|
|
wxString lefturi = uri.substr(0, pos);
|
|
|
|
//We extract the query parts that we need
|
|
QueryMap map = QueryStringToQueryMap(uri.substr(pos));
|
|
wxString protocol = map["protocol"], path = map["path"];
|
|
|
|
//We now have the path and the protocol and so can format a correct uri
|
|
//to pass to wxFileSystem to get a wxFSFile
|
|
size_t doubleslash = uri.find("//");
|
|
//The path is incorrectly formed without // after the first protocol
|
|
if(doubleslash == wxString::npos)
|
|
return NULL;
|
|
|
|
wxString fspath = "file:" +
|
|
EscapeFileNameCharsInURL(lefturi.substr(doubleslash + 2))
|
|
+ "#" + protocol +":" + path;
|
|
return m_fileSystem->OpenFile(fspath);
|
|
}
|
|
}
|
|
|
|
wxString wxWebFileHandler::CombineURIs(const wxString &baseuri,
|
|
const wxString &newuri)
|
|
{
|
|
//If there is a colon in the path then we just return it
|
|
if(newuri.find(':') != wxString::npos)
|
|
{
|
|
return newuri;
|
|
}
|
|
//We have an absolute path and no query string
|
|
else if(newuri.substr(0, 1) == "/" && baseuri.find('?') == wxString::npos)
|
|
{
|
|
//By finding the next / after file:// we get to the end of the
|
|
//(optional) hostname
|
|
size_t pos = baseuri.find('/', 7);
|
|
//So we return up to the end of the hostname, plus the newuri
|
|
return baseuri.substr(0, pos) + newuri;
|
|
}
|
|
//We have an absolute path and a query string
|
|
else if(newuri.substr(0, 1) == "/" && baseuri.find('?') != wxString::npos)
|
|
{
|
|
QueryMap map = QueryStringToQueryMap(baseuri.substr(baseuri.find('?')));
|
|
//As the path is absolue simply replace the old path with the new one
|
|
map["path"] = newuri;
|
|
wxString newquery = QueryMapToQueryString(map);
|
|
return baseuri.substr(0, baseuri.find('?')) + newquery;
|
|
}
|
|
//We have a relative path and no query string
|
|
else if(baseuri.find('?') == wxString::npos)
|
|
{
|
|
//By finding the next / after file:// we get to the end of the
|
|
//(optional) hostname
|
|
size_t pos = baseuri.find('/', 7);
|
|
wxString path = baseuri.substr(pos);
|
|
//Then we remove the last filename
|
|
path = path.BeforeLast('/') + '/';
|
|
|
|
//If we have a colon in the path (i.e. we are on windows) we need to
|
|
//handle it specially
|
|
if(path.find(':') != wxString::npos)
|
|
{
|
|
wxFileName fn(path.AfterFirst('/').AfterFirst('/') + newuri);
|
|
fn.Normalize(wxPATH_NORM_DOTS, "", wxPATH_UNIX);
|
|
return baseuri.substr(0, pos) + '/' +
|
|
path.AfterFirst('/').BeforeFirst('/') + '/' +
|
|
fn.GetFullPath(wxPATH_UNIX);
|
|
}
|
|
else
|
|
{
|
|
//We can now use wxFileName to perform the normalisation
|
|
wxFileName fn(path + newuri);
|
|
fn.Normalize(wxPATH_NORM_DOTS, "", wxPATH_UNIX);
|
|
return baseuri.substr(0, pos) + fn.GetFullPath(wxPATH_UNIX);
|
|
}
|
|
}
|
|
//We have a relative path and a query string
|
|
else
|
|
{
|
|
QueryMap map = QueryStringToQueryMap(baseuri.substr(baseuri.find('?')));
|
|
wxString path = map["path"];
|
|
//Then we remove the last filename
|
|
path = path.BeforeLast('/') + '/';
|
|
|
|
//We can now use wxFileName to perform the normalisation
|
|
wxFileName fn(path + newuri);
|
|
fn.Normalize(wxPATH_NORM_DOTS, "", wxPATH_UNIX);
|
|
map["path"] = fn.GetFullPath(wxPATH_UNIX);
|
|
|
|
wxString newquery = QueryMapToQueryString(map);
|
|
return baseuri.substr(0, baseuri.find('?')) + newquery;
|
|
}
|
|
}
|
|
#endif // wxUSE_WEB
|