Inherit wxURL from wxURI, providing assignment, copy construction, comparison, and less duplication of code. Change wxURI a bit to meet some of Vadim's reccommendations - move accessors into header, and finish some of his other reccom. Change assignment to use const wxString& instead of const wxChar*. Change wxURI docs to reflect that it inherits from wxObject. Made preliminary docs for the wxURL transition. Add some unit tests for the transition.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30136 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Ryan Norton
2004-10-28 06:49:46 +00:00
parent 68ca6f5252
commit b60b2ec8ac
8 changed files with 167 additions and 228 deletions

View File

@@ -207,6 +207,8 @@ All:
- Norwegian (Bokm<6B>l) translation added (Hans F. Nordhaug) - Norwegian (Bokm<6B>l) translation added (Hans F. Nordhaug)
- wxDynamicLibrary::HasSymbol() added - wxDynamicLibrary::HasSymbol() added
- added wxTextInputStream::operator>>(wchar_t) for compilers which support this - added wxTextInputStream::operator>>(wchar_t) for compilers which support this
- added wxURI
- changed wxURL to inherit from wxURI and provide assignment and comparison
All (GUI): All (GUI):

View File

@@ -28,7 +28,7 @@ furthur functionality.
\wxheading{Derived from} \wxheading{Derived from}
No base class \helpref{wxObject}{wxobject}
\wxheading{Include files} \wxheading{Include files}

View File

@@ -1,8 +1,13 @@
\section{\class{wxURL}}\label{wxurl} \section{\class{wxURL}}\label{wxurl}
Parses URLs.
Supports standard assignment operators, copy constructors,
and comparison operators.
\wxheading{Derived from} \wxheading{Derived from}
\helpref{wxObject}{wxobject} \helpref{wxURI}{wxuri}
\wxheading{Include files} \wxheading{Include files}

View File

@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: uri.h // Name: uri.h
// Purpose: wxURI - Class for parsing/validating URIs // Purpose: wxURI - Class for parsing URIs
// Author: Ryan Norton // Author: Ryan Norton
// Modified By: // Modified By:
// Created: 07/01/2004 // Created: 07/01/2004
@@ -63,22 +63,22 @@ public:
void Create(const wxString& uri); void Create(const wxString& uri);
bool HasScheme() const; bool HasScheme() const { return (m_fields & wxURI_SCHEME) == wxURI_SCHEME; }
bool HasUser() const; bool HasUser() const { return (m_fields & wxURI_USER) == wxURI_USER; }
bool HasServer() const; bool HasServer() const { return (m_fields & wxURI_SERVER) == wxURI_SERVER; }
bool HasPort() const; bool HasPort() const { return (m_fields & wxURI_PORT) == wxURI_PORT; }
bool HasPath() const; bool HasPath() const { return (m_fields & wxURI_PATH) == wxURI_PATH; }
bool HasQuery() const; bool HasQuery() const { return (m_fields & wxURI_QUERY) == wxURI_QUERY; }
bool HasFragment() const; bool HasFragment() const { return (m_fields & wxURI_FRAGMENT) == wxURI_FRAGMENT; }
const wxString& GetScheme() const; const wxString& GetScheme() const { return m_scheme; }
const wxString& GetPath() const; const wxString& GetPath() const { return m_path; }
const wxString& GetQuery() const; const wxString& GetQuery() const { return m_query; }
const wxString& GetFragment() const; const wxString& GetFragment() const { return m_fragment; }
const wxString& GetPort() const; const wxString& GetPort() const { return m_port; }
const wxString& GetUser() const; const wxString& GetUser() const { return m_user; }
const wxString& GetServer() const; const wxString& GetServer() const { return m_server; }
const wxURIHostType& GetHostType() const; const wxURIHostType& GetHostType() const { return m_hostType; }
wxString Get() const; wxString Get() const;
@@ -86,10 +86,11 @@ public:
bool IsReference() const; bool IsReference() const;
wxURI& operator = (const wxURI& uri); wxURI& operator = (const wxURI& uri);
wxURI& operator = (const wxChar* string); wxURI& operator = (const wxString& string);
bool operator == (const wxURI& uri) const; bool operator == (const wxURI& uri) const;
protected: protected:
wxURI& Assign(const wxURI& uri);
void Clear(); void Clear();

View File

@@ -2,7 +2,7 @@
// Name: url.h // Name: url.h
// Purpose: URL parser // Purpose: URL parser
// Author: Guilhem Lavaux // Author: Guilhem Lavaux
// Modified by: // Modified by: Ryan Norton
// Created: 20/07/1997 // Created: 20/07/1997
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) 1997, 1998 Guilhem Lavaux // Copyright: (c) 1997, 1998 Guilhem Lavaux
@@ -20,7 +20,7 @@
#if wxUSE_URL #if wxUSE_URL
#include "wx/object.h" #include "wx/uri.h"
#include "wx/protocol/protocol.h" #include "wx/protocol/protocol.h"
#if wxUSE_PROTOCOL_HTTP #if wxUSE_PROTOCOL_HTTP
@@ -48,14 +48,18 @@ public:
}; };
#endif // wxUSE_URL_NATIVE #endif // wxUSE_URL_NATIVE
class WXDLLIMPEXP_NET wxURL : public wxObject class WXDLLIMPEXP_NET wxURL : public wxURI
{ {
public: public:
wxURL(const wxString& url); wxURL(const wxString& sUrl);
wxURL(const wxURI& url);
virtual ~wxURL(); virtual ~wxURL();
wxString GetProtocolName() const { return m_protoinfo->m_protoname; } wxURL& operator = (const wxString& url);
wxString GetHostName() const { return m_hostname; } wxURL& operator = (const wxURI& url);
wxString GetProtocolName() const { return m_scheme; }
wxString GetHostName() const { return m_server; }
wxString GetURL() const { return m_url; } wxString GetURL() const { return m_url; }
wxProtocol& GetProtocol() { return *m_protocol; } wxProtocol& GetProtocol() { return *m_protocol; }
wxURLError GetError() const { return m_error; } wxURLError GetError() const { return m_error; }
@@ -95,13 +99,10 @@ protected:
wxProtocol *m_protocol; wxProtocol *m_protocol;
wxURLError m_error; wxURLError m_error;
wxString m_protoname, m_hostname, m_servname, m_path, m_url; wxString m_url;
wxString m_user, m_password;
bool m_useProxy; bool m_useProxy;
bool PrepProto(wxString& url); void Init(const wxString&);
bool PrepHost(wxString& url);
bool PrepPath(wxString& url);
bool ParseURL(); bool ParseURL();
void CleanData(); void CleanData();
bool FetchProtocol(); bool FetchProtocol();
@@ -110,10 +111,6 @@ protected:
friend class wxURLModule; friend class wxURLModule;
private: private:
// VZ: can't use default copy ctor for this class, should write a correct
// one! (TODO)
DECLARE_NO_COPY_CLASS(wxURL)
DECLARE_DYNAMIC_CLASS(wxURL) DECLARE_DYNAMIC_CLASS(wxURL)
}; };

View File

@@ -8,6 +8,11 @@
// Licence: wxWindows // Licence: wxWindows
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
//
//TODO: RN: I had some massive doxygen docs, I need to move these
//in a presentable form in these sources
//
// =========================================================================== // ===========================================================================
// declarations // declarations
// =========================================================================== // ===========================================================================
@@ -64,7 +69,7 @@ wxURI::wxURI(const wxString& uri) : m_hostType(wxURI_REGNAME), m_fields(0)
wxURI::wxURI(const wxURI& uri) : m_hostType(wxURI_REGNAME), m_fields(0) wxURI::wxURI(const wxURI& uri) : m_hostType(wxURI_REGNAME), m_fields(0)
{ {
*this = uri; Assign(uri);
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -136,61 +141,12 @@ bool wxURI::IsEscape(const wxChar*& uri)
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// HasXXX // Get
// ---------------------------------------------------------------------------
bool wxURI::HasScheme() const
{ return (m_fields & wxURI_SCHEME) == wxURI_SCHEME; }
bool wxURI::HasUser() const
{ return (m_fields & wxURI_USER) == wxURI_USER; }
bool wxURI::HasServer() const
{ return (m_fields & wxURI_SERVER) == wxURI_SERVER; }
bool wxURI::HasPort() const
{ return (m_fields & wxURI_PORT) == wxURI_PORT; }
bool wxURI::HasPath() const
{ return (m_fields & wxURI_PATH) == wxURI_PATH; }
bool wxURI::HasQuery() const
{ return (m_fields & wxURI_QUERY) == wxURI_QUERY; }
bool wxURI::HasFragment() const
{ return (m_fields & wxURI_FRAGMENT) == wxURI_FRAGMENT; }
// ---------------------------------------------------------------------------
// GetXXX
// //
// The normal Get() actually builds the entire URI into a useable // Get() actually builds the entire URI into a useable
// representation, including proper identification characters such as slashes // representation, including proper identification characters such as slashes
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const wxString& wxURI::GetScheme() const
{ return m_scheme; }
const wxString& wxURI::GetPath() const
{ return m_path; }
const wxString& wxURI::GetQuery() const
{ return m_query; }
const wxString& wxURI::GetFragment() const
{ return m_fragment; }
const wxString& wxURI::GetPort() const
{ return m_port; }
const wxString& wxURI::GetUser() const
{ return m_user; }
const wxString& wxURI::GetServer() const
{ return m_server; }
const wxURIHostType& wxURI::GetHostType() const
{ return m_hostType; }
wxString wxURI::Get() const wxString wxURI::Get() const
{ {
wxString ret; wxString ret;
@@ -228,36 +184,28 @@ wxString wxURI::Get() const
wxURI& wxURI::operator = (const wxURI& uri) wxURI& wxURI::operator = (const wxURI& uri)
{ {
if (HasScheme()) return Assign(uri);
m_scheme = uri.m_scheme; }
wxURI& wxURI::Assign(const wxURI& uri)
{
//assign fields
m_fields = uri.m_fields;
if (HasServer()) //ref over components
{ m_scheme = uri.m_scheme;
if (HasUser()) m_user = uri.m_user;
m_user = uri.m_user; m_server = uri.m_server;
m_hostType = uri.m_hostType;
m_server = uri.m_server; m_port = uri.m_port;
m_hostType = uri.m_hostType; m_path = uri.m_path;
m_query = uri.m_query;
if (HasPort()) m_fragment = uri.m_fragment;
m_port = uri.m_port;
}
if (HasPath())
m_path = uri.m_path;
if (HasQuery())
m_query = uri.m_query;
if (HasFragment())
m_fragment = uri.m_fragment;
return *this; return *this;
} }
wxURI& wxURI::operator = (const wxChar* string) wxURI& wxURI::operator = (const wxString& string)
{ {
Create(string); Create(string);
return *this; return *this;

View File

@@ -32,7 +32,7 @@
#include <ctype.h> #include <ctype.h>
IMPLEMENT_CLASS(wxProtoInfo, wxObject) IMPLEMENT_CLASS(wxProtoInfo, wxObject)
IMPLEMENT_CLASS(wxURL, wxObject) IMPLEMENT_CLASS(wxURL, wxURI)
// Protocols list // Protocols list
wxProtoInfo *wxURL::ms_protocols = NULL; wxProtoInfo *wxURL::ms_protocols = NULL;
@@ -49,14 +49,39 @@ USE_PROTOCOL(wxFTP)
#endif #endif
// -------------------------------------------------------------- // --------------------------------------------------------------
// wxURL //
// wxURL
//
// -------------------------------------------------------------- // --------------------------------------------------------------
// -------------------------------------------------------------- wxURL::wxURL(const wxString& url) : wxURI(url)
// --------- wxURL CONSTRUCTOR DESTRUCTOR ----------------------- {
// -------------------------------------------------------------- Init(url);
ParseURL();
}
wxURL::wxURL(const wxString& url) wxURL::wxURL(const wxURI& url) : wxURI(url)
{
Init(url.Get());
ParseURL();
}
wxURL& wxURL::operator = (const wxURI& url)
{
wxURI::operator = (url);
Init(url.Get());
ParseURL();
return *this;
}
wxURL& wxURL::operator = (const wxString& url)
{
wxURI::operator = (url);
Init(url);
ParseURL();
return *this;
}
void wxURL::Init(const wxString& url)
{ {
m_protocol = NULL; m_protocol = NULL;
m_error = wxURL_NOERR; m_error = wxURL_NOERR;
@@ -81,21 +106,23 @@ wxURL::wxURL(const wxString& url)
m_proxy = ms_proxyDefault; m_proxy = ms_proxyDefault;
#endif // wxUSE_SOCKETS #endif // wxUSE_SOCKETS
ParseURL();
} }
// --------------------------------------------------------------
// ParseURL
//
// Builds the URL and takes care of the old protocol stuff
// --------------------------------------------------------------
bool wxURL::ParseURL() bool wxURL::ParseURL()
{ {
wxString last_url = m_url;
// If the URL was already parsed (m_protocol != NULL), pass this section. // If the URL was already parsed (m_protocol != NULL), pass this section.
if (!m_protocol) if (!m_protocol)
{ {
// Clean up // Clean up
CleanData(); CleanData();
// Extract protocol name // Make sure we have a protocol/scheme
if (!PrepProto(last_url)) if (!HasScheme())
{ {
m_error = wxURL_SNTXERR; m_error = wxURL_SNTXERR;
return false; return false;
@@ -111,22 +138,14 @@ bool wxURL::ParseURL()
// Do we need a host name ? // Do we need a host name ?
if (m_protoinfo->m_needhost) if (m_protoinfo->m_needhost)
{ {
// Extract it // Make sure we have one, then
if (!PrepHost(last_url)) if (!HasServer())
{ {
m_error = wxURL_SNTXERR; m_error = wxURL_SNTXERR;
return false; return false;
} }
} }
// Extract full path
if (!PrepPath(last_url))
{
m_error = wxURL_NOPATH;
return false;
}
} }
// URL parse finished.
#if wxUSE_SOCKETS #if wxUSE_SOCKETS
if (m_useProxy) if (m_useProxy)
@@ -135,11 +154,9 @@ bool wxURL::ParseURL()
delete m_protocol; delete m_protocol;
// Third, we rebuild the URL. // Third, we rebuild the URL.
m_url = m_protoname + wxT(":"); m_url = m_scheme + wxT(":");
if (m_protoinfo->m_needhost) if (m_protoinfo->m_needhost)
m_url = m_url + wxT("//") + m_hostname; m_url = m_url + wxT("//") + m_server;
m_url += m_path;
// We initialize specific variables. // We initialize specific variables.
m_protocol = m_proxy; // FIXME: we should clone the protocol m_protocol = m_proxy; // FIXME: we should clone the protocol
@@ -170,87 +187,6 @@ wxURL::~wxURL()
#endif #endif
} }
// --------------------------------------------------------------
// --------- wxURL urls decoders --------------------------------
// --------------------------------------------------------------
bool wxURL::PrepProto(wxString& url)
{
int pos;
// Find end
pos = url.Find(wxT(':'));
if (pos == wxNOT_FOUND)
return false;
m_protoname = url(0, pos);
url = url(pos+1, url.Length());
return true;
}
bool wxURL::PrepHost(wxString& url)
{
wxString temp_url;
int pos, pos2;
if ((url.GetChar(0) != wxT('/')) || (url.GetChar(1) != wxT('/')))
return false;
url = url(2, url.Length());
pos = url.Find(wxT('/'));
if (pos == wxNOT_FOUND)
pos = url.Length();
if (pos == 0)
return false;
temp_url = url(0, pos);
url = url(url.Find(wxT('/')), url.Length());
// Retrieve service number
pos2 = temp_url.Find(wxT(':'), true);
if (pos2 != wxNOT_FOUND && pos2 < pos)
{
m_servname = temp_url(pos2+1, pos);
if (!m_servname.IsNumber())
return false;
temp_url = temp_url(0, pos2);
}
// Retrieve user and password.
pos2 = temp_url.Find(wxT('@'));
// Even if pos2 equals wxNOT_FOUND, this code is right.
m_hostname = temp_url(pos2+1, temp_url.Length());
m_user = wxT("");
m_password = wxT("");
if (pos2 == wxNOT_FOUND)
return true;
temp_url = temp_url(0, pos2);
pos2 = temp_url.Find(wxT(':'));
if (pos2 == wxNOT_FOUND)
return false;
m_user = temp_url(0, pos2);
m_password = temp_url(pos2+1, url.Length());
return true;
}
bool wxURL::PrepPath(wxString& url)
{
if (url.Length() != 0)
m_path = ConvertToValidURI(url);
else
m_path = wxT("/");
return true;
}
bool wxURL::FetchProtocol() bool wxURL::FetchProtocol()
{ {
@@ -258,14 +194,13 @@ bool wxURL::FetchProtocol()
while (info) while (info)
{ {
if (m_protoname == info->m_protoname) if (m_scheme == info->m_protoname)
{ {
if (m_servname.IsNull()) if (m_port.IsNull())
m_servname = info->m_servname; m_port = info->m_servname;
m_protoinfo = info;
m_protoinfo = info; m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject(); return true;
return true;
} }
info = info->next; info = info->next;
} }
@@ -285,10 +220,17 @@ wxInputStream *wxURL::GetInputStream()
} }
m_error = wxURL_NOERR; m_error = wxURL_NOERR;
if (m_user != wxT("")) if (HasUser())
{ {
m_protocol->SetUser(m_user); size_t dwPasswordPos = m_user.find(':');
m_protocol->SetPassword(m_password);
if (dwPasswordPos == wxString::npos)
m_protocol->SetUser(m_user);
else
{
m_protocol->SetUser(m_user(0, dwPasswordPos));
m_protocol->SetPassword(m_user(dwPasswordPos+1, m_user.length() + 1));
}
} }
#if wxUSE_URL_NATIVE #if wxUSE_URL_NATIVE
@@ -310,13 +252,13 @@ wxInputStream *wxURL::GetInputStream()
// m_protoinfo is NULL when we use a proxy // m_protoinfo is NULL when we use a proxy
if (!m_useProxy && m_protoinfo->m_needhost) if (!m_useProxy && m_protoinfo->m_needhost)
{ {
if (!addr.Hostname(m_hostname)) if (!addr.Hostname(m_server))
{ {
m_error = wxURL_NOHOST; m_error = wxURL_NOHOST;
return NULL; return NULL;
} }
addr.Service(m_servname); addr.Service(m_port);
if (!m_protocol->Connect(addr, true)) // Watcom needs the 2nd arg for some reason if (!m_protocol->Connect(addr, true)) // Watcom needs the 2nd arg for some reason
{ {

View File

@@ -25,6 +25,9 @@
#include "wx/cppunit.h" #include "wx/cppunit.h"
// Test wxURL & wxURI compat?
#define TEST_URL 0
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// test class // test class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -46,6 +49,9 @@ private:
CPPUNIT_TEST( BackwardsResolving ); CPPUNIT_TEST( BackwardsResolving );
CPPUNIT_TEST( Assignment ); CPPUNIT_TEST( Assignment );
CPPUNIT_TEST( Comparison ); CPPUNIT_TEST( Comparison );
#if TEST_URL
CPPUNIT_TEST( URLCompat );
#endif
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void IPv4(); void IPv4();
@@ -59,6 +65,10 @@ private:
void Assignment(); void Assignment();
void Comparison(); void Comparison();
#if 1
void URLCompat();
#endif
DECLARE_NO_COPY_CLASS(URITestCase) DECLARE_NO_COPY_CLASS(URITestCase)
}; };
@@ -264,3 +274,37 @@ void URITestCase::Comparison()
{ {
CPPUNIT_ASSERT(wxURI(wxT("http://mysite.com")) == wxURI(wxT("http://mysite.com"))); CPPUNIT_ASSERT(wxURI(wxT("http://mysite.com")) == wxURI(wxT("http://mysite.com")));
} }
#if TEST_URL
#include "wx/url.h"
void URITestCase::URLCompat()
{
wxURL url(wxT("http://user:password@wxwidgets.org"));
CPPUNIT_ASSERT(url.GetError() == wxURL_NOERR);
wxInputStream* pInput = url.GetInputStream();
CPPUNIT_ASSERT( pInput != NULL );
CPPUNIT_ASSERT( url == wxURL(wxT("http://user:password@wxwidgets.org")) );
wxURI uri(wxT("http://user:password@wxwidgets.org"));
CPPUNIT_ASSERT( url == uri );
wxURL urlcopy(uri);
CPPUNIT_ASSERT( urlcopy == url );
CPPUNIT_ASSERT( urlcopy == uri );
wxURI uricopy(url);
CPPUNIT_ASSERT( uricopy == url );
CPPUNIT_ASSERT( uricopy == urlcopy );
CPPUNIT_ASSERT( uricopy == uri );
}
#endif