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)
- wxDynamicLibrary::HasSymbol() added
- 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):

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,6 +8,11 @@
// Licence: wxWindows
/////////////////////////////////////////////////////////////////////////////
//
//TODO: RN: I had some massive doxygen docs, I need to move these
//in a presentable form in these sources
//
// ===========================================================================
// 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)
{
*this = uri;
Assign(uri);
}
// ---------------------------------------------------------------------------
@@ -136,61 +141,12 @@ bool wxURI::IsEscape(const wxChar*& uri)
}
// ---------------------------------------------------------------------------
// HasXXX
// ---------------------------------------------------------------------------
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
// Get
//
// 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
// ---------------------------------------------------------------------------
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 ret;
@@ -228,36 +184,28 @@ wxString wxURI::Get() const
wxURI& wxURI::operator = (const wxURI& uri)
{
if (HasScheme())
return Assign(uri);
}
wxURI& wxURI::Assign(const wxURI& uri)
{
//assign fields
m_fields = uri.m_fields;
//ref over components
m_scheme = uri.m_scheme;
if (HasServer())
{
if (HasUser())
m_user = uri.m_user;
m_server = uri.m_server;
m_hostType = uri.m_hostType;
if (HasPort())
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;
}
wxURI& wxURI::operator = (const wxChar* string)
wxURI& wxURI::operator = (const wxString& string)
{
Create(string);
return *this;

View File

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

View File

@@ -25,6 +25,9 @@
#include "wx/cppunit.h"
// Test wxURL & wxURI compat?
#define TEST_URL 0
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
@@ -46,6 +49,9 @@ private:
CPPUNIT_TEST( BackwardsResolving );
CPPUNIT_TEST( Assignment );
CPPUNIT_TEST( Comparison );
#if TEST_URL
CPPUNIT_TEST( URLCompat );
#endif
CPPUNIT_TEST_SUITE_END();
void IPv4();
@@ -59,6 +65,10 @@ private:
void Assignment();
void Comparison();
#if 1
void URLCompat();
#endif
DECLARE_NO_COPY_CLASS(URITestCase)
};
@@ -264,3 +274,37 @@ void URITestCase::Comparison()
{
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