X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4cc52142b82bae7cd5f0159ca8990b551fb15893..562e60a0f2ef165ab75c999eb8002d547c3585aa:/src/common/uri.cpp diff --git a/src/common/uri.cpp b/src/common/uri.cpp index 7fdac5d033..bcdd7eae66 100644 --- a/src/common/uri.cpp +++ b/src/common/uri.cpp @@ -16,10 +16,6 @@ // headers // --------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "uri.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -27,13 +23,17 @@ #pragma hdrstop #endif +#ifndef WX_PRECOMP + #include "wx/crt.h" +#endif + #include "wx/uri.h" // --------------------------------------------------------------------------- // definitions // --------------------------------------------------------------------------- -IMPLEMENT_CLASS(wxURI, wxObject); +IMPLEMENT_CLASS(wxURI, wxObject) // =========================================================================== // implementation @@ -97,7 +97,10 @@ const wxChar* wxURI::Create(const wxString& uri) if (m_fields) Clear(); - return Parse(uri); + // FIXME-UTF8: rewrite ParseXXX() methods using iterators + // NB: using wxWxCharBuffer instead of just c_str() avoids keeping + // converted string in memory for longer than needed + return Parse(wxWxCharBuffer(uri.c_str())); } // --------------------------------------------------------------------------- @@ -113,26 +116,29 @@ const wxChar* wxURI::Create(const wxString& uri) // Unescape unencodes all 3 character URL escape sequences in a wxString // --------------------------------------------------------------------------- -wxChar wxURI::TranslateEscape(const wxChar* s) +wxUniChar wxURI::TranslateEscape(const wxString::const_iterator& s) { - wxASSERT_MSG( IsHex(s[0]) && IsHex(s[1]), wxT("Invalid escape sequence!")); + wxChar c1(*s); + wxChar c2(*(s + 1)); - return (wxChar)( CharToHex(s[0]) << 4 ) | CharToHex(s[1]); + wxASSERT_MSG( IsHex(c1) && IsHex(c2), wxT("Invalid escape sequence!")); + + return wx_truncate_cast(wxChar, (CharToHex(c1) << 4 ) | CharToHex(c2)); } wxString wxURI::Unescape(const wxString& uri) { wxString new_uri; - for(size_t i = 0; i < uri.length(); ++i) + for (wxString::const_iterator i = uri.begin(); i != uri.end(); ++i) { - if (uri[i] == wxT('%')) + if ( *i == wxT('%') ) { - new_uri += wxURI::TranslateEscape( &(uri.c_str()[i+1]) ); + new_uri += wxURI::TranslateEscape(i + 1); i += 2; } else - new_uri += uri[i]; + new_uri += *i; } return new_uri; @@ -150,10 +156,7 @@ bool wxURI::IsEscape(const wxChar*& uri) { // pct-encoded = "%" HEXDIG HEXDIG if(*uri == wxT('%') && IsHex(*(uri+1)) && IsHex(*(uri+2))) - { - uri += 3; return true; - } else return false; } @@ -378,7 +381,7 @@ bool wxURI::IsReference() const // URI-reference = URI / relative // --------------------------------------------------------------------------- -const wxChar* wxURI::Parse(const wxChar* uri) +const wxChar* wxURI::Parse(const wxChar *uri) { uri = ParseScheme(uri); uri = ParseAuthority(uri); @@ -393,7 +396,7 @@ const wxChar* wxURI::Parse(const wxChar* uri) // Individual parsers for each URI component // --------------------------------------------------------------------------- -const wxChar* wxURI::ParseScheme(const wxChar* uri) +const wxChar* wxURI::ParseScheme(const wxChar *uri) { wxASSERT(uri != NULL); @@ -439,11 +442,18 @@ const wxChar* wxURI::ParseAuthority(const wxChar* uri) // authority = [ userinfo "@" ] host [ ":" port ] if (*uri == wxT('/') && *(uri+1) == wxT('/')) { + //skip past the two slashes uri += 2; + // ############# DEVIATION FROM RFC ######################### + // Don't parse the server component for file URIs + if(m_scheme != wxT("file")) + { + //normal way uri = ParseUserInfo(uri); uri = ParseServer(uri); return ParsePort(uri); + } } return uri; @@ -460,9 +470,15 @@ const wxChar* wxURI::ParseUserInfo(const wxChar* uri) // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) while(*uri && *uri != wxT('@') && *uri != wxT('/') && *uri != wxT('#') && *uri != wxT('?')) { - if(IsUnreserved(*uri) || IsEscape(uri) || + if(IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == wxT(':')) m_userinfo += *uri++; + else if (IsEscape(uri)) + { + m_userinfo += *uri++; + m_userinfo += *uri++; + m_userinfo += *uri++; + } else Escape(m_userinfo, *uri++); } @@ -540,8 +556,14 @@ const wxChar* wxURI::ParseServer(const wxChar* uri) // reg-name = *( unreserved / pct-encoded / sub-delims ) while(*uri && *uri != wxT('/') && *uri != wxT(':') && *uri != wxT('#') && *uri != wxT('?')) { - if(IsUnreserved(*uri) || IsEscape(uri) || IsSubDelim(*uri)) + if(IsUnreserved(*uri) || IsSubDelim(*uri)) + m_server += *uri++; + else if (IsEscape(uri)) + { m_server += *uri++; + m_server += *uri++; + m_server += *uri++; + } else Escape(m_server, *uri++); } @@ -610,9 +632,15 @@ const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormali while(*uri && *uri != wxT('#') && *uri != wxT('?')) { - if( IsUnreserved(*uri) || IsSubDelim(*uri) || IsEscape(uri) || + if( IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/')) m_path += *uri++; + else if (IsEscape(uri)) + { + m_path += *uri++; + m_path += *uri++; + m_path += *uri++; + } else Escape(m_path, *uri++); } @@ -620,7 +648,8 @@ const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormali if (bNormalize) { wxStringBufferLength theBuffer(m_path, m_path.length() + 1); -#if wxUSE_STL +#if wxUSE_STL || wxUSE_UNICODE_UTF8 + // FIXME-UTF8: have some wxReadWriteStringBuffer instead? wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1); #endif Normalize(theBuffer, true); @@ -636,9 +665,15 @@ const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormali //no colon allowed while(*uri && *uri != wxT('#') && *uri != wxT('?')) { - if(IsUnreserved(*uri) || IsSubDelim(*uri) || IsEscape(uri) || + if(IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == wxT('@') || *uri == wxT('/')) m_path += *uri++; + else if (IsEscape(uri)) + { + m_path += *uri++; + m_path += *uri++; + m_path += *uri++; + } else Escape(m_path, *uri++); } @@ -647,9 +682,15 @@ const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormali { while(*uri && *uri != wxT('#') && *uri != wxT('?')) { - if(IsUnreserved(*uri) || IsSubDelim(*uri) || IsEscape(uri) || + if(IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/')) m_path += *uri++; + else if (IsEscape(uri)) + { + m_path += *uri++; + m_path += *uri++; + m_path += *uri++; + } else Escape(m_path, *uri++); } @@ -660,7 +701,8 @@ const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormali if (bNormalize) { wxStringBufferLength theBuffer(m_path, m_path.length() + 1); -#if wxUSE_STL +#if wxUSE_STL || wxUSE_UNICODE_UTF8 + // FIXME-UTF8: have some wxReadWriteStringBuffer instead? wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1); #endif Normalize(theBuffer); @@ -686,9 +728,15 @@ const wxChar* wxURI::ParseQuery(const wxChar* uri) ++uri; while(*uri && *uri != wxT('#')) { - if (IsUnreserved(*uri) || IsSubDelim(*uri) || IsEscape(uri) || + if (IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?')) m_query += *uri++; + else if (IsEscape(uri)) + { + m_query += *uri++; + m_query += *uri++; + m_query += *uri++; + } else Escape(m_query, *uri++); } @@ -711,9 +759,15 @@ const wxChar* wxURI::ParseFragment(const wxChar* uri) ++uri; while(*uri) { - if (IsUnreserved(*uri) || IsSubDelim(*uri) || IsEscape(uri) || + if (IsUnreserved(*uri) || IsSubDelim(*uri) || *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?')) m_fragment += *uri++; + else if (IsEscape(uri)) + { + m_fragment += *uri++; + m_fragment += *uri++; + m_fragment += *uri++; + } else Escape(m_fragment, *uri++); } @@ -828,18 +882,18 @@ void wxURI::Resolve(const wxURI& base, int flags) if (m_path[0u] != wxT('/')) { //Merge paths - const wxChar* op = m_path.c_str(); - const wxChar* bp = base.m_path.c_str() + base.m_path.Length(); + wxString::const_iterator op = m_path.begin(); + wxString::const_iterator bp = base.m_path.begin() + base.m_path.length(); //not a ending directory? move up if (base.m_path[0] && *(bp-1) != wxT('/')) - UpTree(base.m_path, bp); + UpTree(base.m_path.begin(), bp); //normalize directories while(*op == wxT('.') && *(op+1) == wxT('.') && (*(op+2) == '\0' || *(op+2) == wxT('/')) ) { - UpTree(base.m_path, bp); + UpTree(base.m_path.begin(), bp); if (*(op+2) == '\0') op += 2; @@ -847,8 +901,8 @@ void wxURI::Resolve(const wxURI& base, int flags) op += 3; } - m_path = base.m_path.substr(0, bp - base.m_path.c_str()) + - m_path.substr((op - m_path.c_str()), m_path.Length()); + m_path = base.m_path.substr(0, bp - base.m_path.begin()) + + m_path.substr((op - m_path.begin()), m_path.length()); } } @@ -862,7 +916,8 @@ void wxURI::Resolve(const wxURI& base, int flags) // --------------------------------------------------------------------------- //static -void wxURI::UpTree(const wxChar* uristart, const wxChar*& uri) +void wxURI::UpTree(wxString::const_iterator uristart, + wxString::const_iterator& uri) { if (uri != uristart && *(uri-1) == wxT('/')) { @@ -884,6 +939,30 @@ void wxURI::UpTree(const wxChar* uristart, const wxChar*& uri) //!!!// } +// FIXME-UTF8: fix Normalize() to use iterators instead of having this method! +/*static*/ void wxURI::UpTree(const wxChar* uristart, const wxChar*& uri) +{ + if (uri != uristart && *(uri-1) == wxT('/')) + { + uri -= 2; + } + + for(;uri != uristart; --uri) + { + if (*uri == wxT('/')) + { + ++uri; + break; + } + } + + //!!!TODO:HACK!!!// + if (uri == uristart && *uri == wxT('/')) + ++uri; + //!!!// +} +// end of FIXME-UTF8 + // --------------------------------------------------------------------------- // Normalize // @@ -1250,90 +1329,6 @@ bool wxURI::IsDigit(const wxChar& c) { return c >= wxT('0') && c <= wxT('9'); } -// --------------------------------------------------------------------------- -// -// wxURL Compatibility -// -// --------------------------------------------------------------------------- - -#if wxUSE_URL - -#if WXWIN_COMPATIBILITY_2_4 - -#include "wx/url.h" - -wxString wxURL::GetProtocolName() const -{ - return m_scheme; -} - -wxString wxURL::GetHostName() const -{ - return m_server; -} - -wxString wxURL::GetPath() const -{ - return m_path; -} - -//Note that this old code really doesn't convert to a URI that well and looks -//more like a dirty hack than anything else... - -wxString wxURL::ConvertToValidURI(const wxString& uri, const wxChar* delims) -{ - wxString out_str; - wxString hexa_code; - size_t i; - - for (i = 0; i < uri.Len(); i++) - { - wxChar c = uri.GetChar(i); - - if (c == wxT(' ')) - { - // GRG, Apr/2000: changed to "%20" instead of '+' - - out_str += wxT("%20"); - } - else - { - // GRG, Apr/2000: modified according to the URI definition (RFC 2396) - // - // - Alphanumeric characters are never escaped - // - Unreserved marks are never escaped - // - Delimiters must be escaped if they appear within a component - // but not if they are used to separate components. Here we have - // no clear way to distinguish between these two cases, so they - // are escaped unless they are passed in the 'delims' parameter - // (allowed delimiters). - - static const wxChar marks[] = wxT("-_.!~*()'"); - - if ( !wxIsalnum(c) && !wxStrchr(marks, c) && !wxStrchr(delims, c) ) - { - hexa_code.Printf(wxT("%%%02X"), c); - out_str += hexa_code; - } - else - { - out_str += c; - } - } - } - - return out_str; -} - -wxString wxURL::ConvertFromURI(const wxString& uri) -{ - return wxURI::Unescape(uri); -} - -#endif //WXWIN_COMPATIBILITY_2_4 - -#endif //wxUSE_URL - //end of uri.cpp