From b60b2ec8ac57d569c4831eb98113f7cb713a117a Mon Sep 17 00:00:00 2001 From: Ryan Norton Date: Thu, 28 Oct 2004 06:49:46 +0000 Subject: [PATCH] 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 --- docs/changes.txt | 2 + docs/latex/wx/uri.tex | 2 +- docs/latex/wx/url.tex | 7 +- include/wx/uri.h | 37 ++++----- include/wx/url.h | 27 +++---- src/common/uri.cpp | 102 ++++++------------------ src/common/url.cpp | 178 ++++++++++++++---------------------------- tests/uris/uris.cpp | 44 +++++++++++ 8 files changed, 169 insertions(+), 230 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 787f7f6fe3..656d436e48 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -207,6 +207,8 @@ All: - Norwegian (Bokmå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): diff --git a/docs/latex/wx/uri.tex b/docs/latex/wx/uri.tex index 0badfc0aa9..a09ec9475e 100644 --- a/docs/latex/wx/uri.tex +++ b/docs/latex/wx/uri.tex @@ -28,7 +28,7 @@ furthur functionality. \wxheading{Derived from} -No base class +\helpref{wxObject}{wxobject} \wxheading{Include files} diff --git a/docs/latex/wx/url.tex b/docs/latex/wx/url.tex index 187ab2bc42..59a734a680 100644 --- a/docs/latex/wx/url.tex +++ b/docs/latex/wx/url.tex @@ -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} diff --git a/include/wx/uri.h b/include/wx/uri.h index 03a9fba8db..473ab42e1b 100644 --- a/include/wx/uri.h +++ b/include/wx/uri.h @@ -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; - - 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; + 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 { 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(); diff --git a/include/wx/url.h b/include/wx/url.h index 25bf2bb5ae..3e41a473d1 100644 --- a/include/wx/url.h +++ b/include/wx/url.h @@ -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) }; diff --git a/src/common/uri.cpp b/src/common/uri.cpp index e37c99ccd0..0c9a16f65b 100644 --- a/src/common/uri.cpp +++ b/src/common/uri.cpp @@ -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()) - 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; + return Assign(uri); +} - if (HasFragment()) - m_fragment = uri.m_fragment; +wxURI& wxURI::Assign(const wxURI& uri) +{ + //assign fields + m_fields = uri.m_fields; + + //ref over components + m_scheme = uri.m_scheme; + m_user = uri.m_user; + m_server = uri.m_server; + m_hostType = uri.m_hostType; + m_port = uri.m_port; + m_path = uri.m_path; + m_query = uri.m_query; + m_fragment = uri.m_fragment; return *this; } -wxURI& wxURI::operator = (const wxChar* string) +wxURI& wxURI::operator = (const wxString& string) { Create(string); return *this; diff --git a/src/common/url.cpp b/src/common/url.cpp index cbe5866c76..7d2da23724 100644 --- a/src/common/url.cpp +++ b/src/common/url.cpp @@ -32,7 +32,7 @@ #include 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 +// // -------------------------------------------------------------- -// -------------------------------------------------------------- -// --------- wxURL CONSTRUCTOR DESTRUCTOR ----------------------- -// -------------------------------------------------------------- +wxURL::wxURL(const wxString& url) : wxURI(url) +{ + Init(url); + ParseURL(); +} + +wxURL::wxURL(const wxURI& url) : wxURI(url) +{ + Init(url.Get()); + ParseURL(); +} -wxURL::wxURL(const wxString& url) +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,14 +194,13 @@ 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; - - m_protoinfo = info; - m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject(); - return true; + if (m_port.IsNull()) + m_port = info->m_servname; + m_protoinfo = info; + m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject(); + return true; } info = info->next; } @@ -285,10 +220,17 @@ wxInputStream *wxURL::GetInputStream() } m_error = wxURL_NOERR; - if (m_user != wxT("")) + if (HasUser()) { - m_protocol->SetUser(m_user); - m_protocol->SetPassword(m_password); + size_t dwPasswordPos = m_user.find(':'); + + 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 @@ -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 { diff --git a/tests/uris/uris.cpp b/tests/uris/uris.cpp index 69a9128d9c..1aaf9df01f 100644 --- a/tests/uris/uris.cpp +++ b/tests/uris/uris.cpp @@ -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 -- 2.45.2