]>
git.saurik.com Git - wxWidgets.git/blob - src/common/uri.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Implementation of a uri parser
7 // Copyright: (c) 2004 Ryan Norton
9 /////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
20 #pragma implementation "uri.h"
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
32 // ---------------------------------------------------------------------------
34 // ---------------------------------------------------------------------------
36 IMPLEMENT_CLASS(wxURI
, wxObject
);
38 // ===========================================================================
40 // ===========================================================================
42 // ---------------------------------------------------------------------------
44 // ---------------------------------------------------------------------------
46 // ---------------------------------------------------------------------------
50 // ---------------------------------------------------------------------------
52 // ---------------------------------------------------------------------------
54 // ---------------------------------------------------------------------------
56 wxURI::wxURI() : m_hostType(wxURI_REGNAME
), m_fields(0)
60 wxURI::wxURI(const wxString
& uri
) : m_hostType(wxURI_REGNAME
), m_fields(0)
65 wxURI::wxURI(const wxURI
& uri
) : wxObject(), m_hostType(wxURI_REGNAME
), m_fields(0)
70 // ---------------------------------------------------------------------------
71 // Destructor and cleanup
72 // ---------------------------------------------------------------------------
81 m_scheme
= m_userinfo
= m_server
= m_port
= m_path
=
82 m_query
= m_fragment
= wxEmptyString
;
84 m_hostType
= wxURI_REGNAME
;
89 // ---------------------------------------------------------------------------
92 // This creates the URI - all we do here is call the main parsing method
93 // ---------------------------------------------------------------------------
95 const wxChar
* wxURI::Create(const wxString
& uri
)
103 // ---------------------------------------------------------------------------
106 // TranslateEscape unencodes a 3 character URL escape sequence
108 // Escape encodes an invalid URI character into a 3 character sequence
110 // IsEscape determines if the input string contains an escape sequence,
111 // if it does, then it moves the input string past the escape sequence
113 // Unescape unencodes all 3 character URL escape sequences in a wxString
114 // ---------------------------------------------------------------------------
116 wxChar
wxURI::TranslateEscape(const wxChar
* s
)
118 wxASSERT_MSG( IsHex(s
[0]) && IsHex(s
[1]), wxT("Invalid escape sequence!"));
120 return (wxChar
)( CharToHex(s
[0]) << 4 ) | CharToHex(s
[1]);
123 wxString
wxURI::Unescape(const wxString
& uri
)
127 for(size_t i
= 0; i
< uri
.length(); ++i
)
129 if (uri
[i
] == wxT('%'))
131 new_uri
+= wxURI::TranslateEscape( &(uri
.c_str()[i
+1]) );
141 void wxURI::Escape(wxString
& s
, const wxChar
& c
)
143 const wxChar
* hdig
= wxT("0123456789abcdef");
145 s
+= hdig
[(c
>> 4) & 15];
149 bool wxURI::IsEscape(const wxChar
*& uri
)
151 // pct-encoded = "%" HEXDIG HEXDIG
152 if(*uri
== wxT('%') && IsHex(*(uri
+1)) && IsHex(*(uri
+2)))
158 // ---------------------------------------------------------------------------
162 // Gets the username and password via the old URL method.
163 // ---------------------------------------------------------------------------
164 wxString
wxURI::GetUser() const
166 size_t dwPasswordPos
= m_userinfo
.find(':');
168 if (dwPasswordPos
== wxString::npos
)
171 return m_userinfo(0, dwPasswordPos
);
174 wxString
wxURI::GetPassword() const
176 size_t dwPasswordPos
= m_userinfo
.find(':');
178 if (dwPasswordPos
== wxString::npos
)
181 return m_userinfo(dwPasswordPos
+1, m_userinfo
.length() + 1);
184 // ---------------------------------------------------------------------------
187 // BuildURI() builds the entire URI into a useable
188 // representation, including proper identification characters such as slashes
190 // BuildUnescapedURI() does the same thing as BuildURI(), only it unescapes
191 // the components that accept escape sequences
192 // ---------------------------------------------------------------------------
194 wxString
wxURI::BuildURI() const
199 ret
= ret
+ m_scheme
+ wxT(":");
206 ret
= ret
+ m_userinfo
+ wxT("@");
211 ret
= ret
+ wxT(":") + m_port
;
217 ret
= ret
+ wxT("?") + m_query
;
220 ret
= ret
+ wxT("#") + m_fragment
;
225 wxString
wxURI::BuildUnescapedURI() const
230 ret
= ret
+ m_scheme
+ wxT(":");
237 ret
= ret
+ wxURI::Unescape(m_userinfo
) + wxT("@");
239 if (m_hostType
== wxURI_REGNAME
)
240 ret
+= wxURI::Unescape(m_server
);
245 ret
= ret
+ wxT(":") + m_port
;
248 ret
+= wxURI::Unescape(m_path
);
251 ret
= ret
+ wxT("?") + wxURI::Unescape(m_query
);
254 ret
= ret
+ wxT("#") + wxURI::Unescape(m_fragment
);
259 // ---------------------------------------------------------------------------
261 // ---------------------------------------------------------------------------
263 wxURI
& wxURI::Assign(const wxURI
& uri
)
266 m_fields
= uri
.m_fields
;
268 //ref over components
269 m_scheme
= uri
.m_scheme
;
270 m_userinfo
= uri
.m_userinfo
;
271 m_server
= uri
.m_server
;
272 m_hostType
= uri
.m_hostType
;
275 m_query
= uri
.m_query
;
276 m_fragment
= uri
.m_fragment
;
281 wxURI
& wxURI::operator = (const wxURI
& uri
)
286 wxURI
& wxURI::operator = (const wxString
& string
)
292 // ---------------------------------------------------------------------------
294 // ---------------------------------------------------------------------------
296 bool wxURI::operator == (const wxURI
& uri
) const
300 if(m_scheme
!= uri
.m_scheme
)
303 else if (uri
.HasScheme())
311 if (m_userinfo
!= uri
.m_userinfo
)
314 else if (uri
.HasUserInfo())
317 if (m_server
!= uri
.m_server
||
318 m_hostType
!= uri
.m_hostType
)
323 if(m_port
!= uri
.m_port
)
326 else if (uri
.HasPort())
329 else if (uri
.HasServer())
335 if(m_path
!= uri
.m_path
)
338 else if (uri
.HasPath())
343 if (m_query
!= uri
.m_query
)
346 else if (uri
.HasQuery())
351 if (m_fragment
!= uri
.m_fragment
)
354 else if (uri
.HasFragment())
360 // ---------------------------------------------------------------------------
363 // if there is no authority or scheme, it is a reference
364 // ---------------------------------------------------------------------------
366 bool wxURI::IsReference() const
367 { return !HasScheme() || !HasServer(); }
369 // ---------------------------------------------------------------------------
372 // Master URI parsing method. Just calls the individual parsing methods
374 // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
375 // URI-reference = URI / relative
376 // ---------------------------------------------------------------------------
378 const wxChar
* wxURI::Parse(const wxChar
* uri
)
380 uri
= ParseScheme(uri
);
381 uri
= ParseAuthority(uri
);
382 uri
= ParsePath(uri
);
383 uri
= ParseQuery(uri
);
384 return ParseFragment(uri
);
387 // ---------------------------------------------------------------------------
390 // Individual parsers for each URI component
391 // ---------------------------------------------------------------------------
393 const wxChar
* wxURI::ParseScheme(const wxChar
* uri
)
395 wxASSERT(uri
!= NULL
);
397 //copy of the uri - used for figuring out
398 //length of each component
399 const wxChar
* uricopy
= uri
;
401 //Does the uri have a scheme (first character alpha)?
406 //scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
407 while (IsAlpha(*uri
) || IsDigit(*uri
) ||
416 if (*uri
== wxT(':'))
418 //mark the scheme as valid
419 m_fields
|= wxURI_SCHEME
;
421 //move reference point up to input buffer
425 //relative uri with relative path reference
426 m_scheme
= wxEmptyString
;
429 //relative uri with _possible_ relative path reference
434 const wxChar
* wxURI::ParseAuthority(const wxChar
* uri
)
436 // authority = [ userinfo "@" ] host [ ":" port ]
437 if (*uri
== wxT('/') && *(uri
+1) == wxT('/'))
441 uri
= ParseUserInfo(uri
);
442 uri
= ParseServer(uri
);
443 return ParsePort(uri
);
449 const wxChar
* wxURI::ParseUserInfo(const wxChar
* uri
)
451 wxASSERT(uri
!= NULL
);
453 //copy of the uri - used for figuring out
454 //length of each component
455 const wxChar
* uricopy
= uri
;
457 // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
458 while(*uri
&& *uri
!= wxT('@') && *uri
!= wxT('/') && *uri
!= wxT('#') && *uri
!= wxT('?'))
460 if(IsUnreserved(*uri
) ||
461 IsSubDelim(*uri
) || *uri
== wxT(':'))
462 m_userinfo
+= *uri
++;
463 else if (IsEscape(uri
))
465 m_userinfo
+= *uri
++;
466 m_userinfo
+= *uri
++;
467 m_userinfo
+= *uri
++;
470 Escape(m_userinfo
, *uri
++);
476 m_fields
|= wxURI_USERINFO
;
481 m_userinfo
= wxEmptyString
;
486 const wxChar
* wxURI::ParseServer(const wxChar
* uri
)
488 wxASSERT(uri
!= NULL
);
490 //copy of the uri - used for figuring out
491 //length of each component
492 const wxChar
* uricopy
= uri
;
494 // host = IP-literal / IPv4address / reg-name
495 // IP-literal = "[" ( IPv6address / IPvFuture ) "]"
496 if (*uri
== wxT('['))
498 ++uri
; //some compilers don't support *&ing a ++*
499 if (ParseIPv6address(uri
) && *uri
== wxT(']'))
502 m_hostType
= wxURI_IPV6ADDRESS
;
504 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
505 wxTmemcpy(theBuffer
, uricopy
, uri
-uricopy
);
506 theBuffer
.SetLength(uri
-uricopy
);
512 ++uri
; //some compilers don't support *&ing a ++*
513 if (ParseIPvFuture(uri
) && *uri
== wxT(']'))
516 m_hostType
= wxURI_IPVFUTURE
;
518 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
519 wxTmemcpy(theBuffer
, uricopy
, uri
-uricopy
);
520 theBuffer
.SetLength(uri
-uricopy
);
528 if (ParseIPv4address(uri
))
530 m_hostType
= wxURI_IPV4ADDRESS
;
532 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
533 wxTmemcpy(theBuffer
, uricopy
, uri
-uricopy
);
534 theBuffer
.SetLength(uri
-uricopy
);
540 if(m_hostType
== wxURI_REGNAME
)
543 // reg-name = *( unreserved / pct-encoded / sub-delims )
544 while(*uri
&& *uri
!= wxT('/') && *uri
!= wxT(':') && *uri
!= wxT('#') && *uri
!= wxT('?'))
546 if(IsUnreserved(*uri
) || IsSubDelim(*uri
))
548 else if (IsEscape(uri
))
555 Escape(m_server
, *uri
++);
559 //mark the server as valid
560 m_fields
|= wxURI_SERVER
;
566 const wxChar
* wxURI::ParsePort(const wxChar
* uri
)
568 wxASSERT(uri
!= NULL
);
579 //mark the port as valid
580 m_fields
|= wxURI_PORT
;
586 const wxChar
* wxURI::ParsePath(const wxChar
* uri
, bool bReference
, bool bNormalize
)
588 wxASSERT(uri
!= NULL
);
590 //copy of the uri - used for figuring out
591 //length of each component
592 const wxChar
* uricopy
= uri
;
594 /// hier-part = "//" authority path-abempty
599 /// relative-part = "//" authority path-abempty
604 /// path-abempty = *( "/" segment )
605 /// path-absolute = "/" [ segment-nz *( "/" segment ) ]
606 /// path-noscheme = segment-nz-nc *( "/" segment )
607 /// path-rootless = segment-nz *( "/" segment )
608 /// path-empty = 0<pchar>
611 /// segment-nz = 1*pchar
612 /// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
613 /// ; non-zero-length segment without any colon ":"
615 /// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
616 if (*uri
== wxT('/'))
620 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
622 if( IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
623 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/'))
625 else if (IsEscape(uri
))
632 Escape(m_path
, *uri
++);
637 wxStringBufferLength
theBuffer(m_path
, m_path
.length() + 1);
639 wxTmemcpy(theBuffer
, m_path
.c_str(), m_path
.length()+1);
641 Normalize(theBuffer
, true);
642 theBuffer
.SetLength(wxStrlen(theBuffer
));
644 //mark the path as valid
645 m_fields
|= wxURI_PATH
;
647 else if(*uri
) //Relative path
652 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
654 if(IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
655 *uri
== wxT('@') || *uri
== wxT('/'))
657 else if (IsEscape(uri
))
664 Escape(m_path
, *uri
++);
669 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
671 if(IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
672 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/'))
674 else if (IsEscape(uri
))
681 Escape(m_path
, *uri
++);
689 wxStringBufferLength
theBuffer(m_path
, m_path
.length() + 1);
691 wxTmemcpy(theBuffer
, m_path
.c_str(), m_path
.length()+1);
693 Normalize(theBuffer
);
694 theBuffer
.SetLength(wxStrlen(theBuffer
));
697 //mark the path as valid
698 m_fields
|= wxURI_PATH
;
706 const wxChar
* wxURI::ParseQuery(const wxChar
* uri
)
708 wxASSERT(uri
!= NULL
);
710 // query = *( pchar / "/" / "?" )
711 if (*uri
== wxT('?'))
714 while(*uri
&& *uri
!= wxT('#'))
716 if (IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
717 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/') || *uri
== wxT('?'))
719 else if (IsEscape(uri
))
726 Escape(m_query
, *uri
++);
729 //mark the server as valid
730 m_fields
|= wxURI_QUERY
;
737 const wxChar
* wxURI::ParseFragment(const wxChar
* uri
)
739 wxASSERT(uri
!= NULL
);
741 // fragment = *( pchar / "/" / "?" )
742 if (*uri
== wxT('#'))
747 if (IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
748 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/') || *uri
== wxT('?'))
749 m_fragment
+= *uri
++;
750 else if (IsEscape(uri
))
752 m_fragment
+= *uri
++;
753 m_fragment
+= *uri
++;
754 m_fragment
+= *uri
++;
757 Escape(m_fragment
, *uri
++);
760 //mark the server as valid
761 m_fields
|= wxURI_FRAGMENT
;
767 // ---------------------------------------------------------------------------
770 // Builds missing components of this uri from a base uri
772 // A version of the algorithm outlined in the RFC is used here
773 // (it is shown in comments)
775 // Note that an empty URI inherits all components
776 // ---------------------------------------------------------------------------
778 void wxURI::Resolve(const wxURI
& base
, int flags
)
780 wxASSERT_MSG(!base
.IsReference(),
781 wxT("wxURI to inherit from must not be a reference!"));
783 // If we arn't being strict, enable the older (pre-RFC2396)
784 // loophole that allows this uri to inherit other
785 // properties from the base uri - even if the scheme
787 if ( !(flags
& wxURI_STRICT
) &&
788 HasScheme() && base
.HasScheme() &&
789 m_scheme
== base
.m_scheme
)
791 m_fields
-= wxURI_SCHEME
;
795 // Do nothing if this is an absolute wxURI
796 // if defined(R.scheme) then
797 // T.scheme = R.scheme;
798 // T.authority = R.authority;
799 // T.path = remove_dot_segments(R.path);
800 // T.query = R.query;
806 //No scheme - inherit
807 m_scheme
= base
.m_scheme
;
808 m_fields
|= wxURI_SCHEME
;
810 // All we need to do for relative URIs with an
811 // authority component is just inherit the scheme
812 // if defined(R.authority) then
813 // T.authority = R.authority;
814 // T.path = remove_dot_segments(R.path);
815 // T.query = R.query;
821 //No authority - inherit
822 if (base
.HasUserInfo())
824 m_userinfo
= base
.m_userinfo
;
825 m_fields
|= wxURI_USERINFO
;
828 m_server
= base
.m_server
;
829 m_hostType
= base
.m_hostType
;
830 m_fields
|= wxURI_SERVER
;
834 m_port
= base
.m_port
;
835 m_fields
|= wxURI_PORT
;
839 // Simple path inheritance from base
842 // T.path = Base.path;
843 m_path
= base
.m_path
;
844 m_fields
|= wxURI_PATH
;
847 // if defined(R.query) then
848 // T.query = R.query;
850 // T.query = Base.query;
854 m_query
= base
.m_query
;
855 m_fields
|= wxURI_QUERY
;
860 // if (R.path starts-with "/") then
861 // T.path = remove_dot_segments(R.path);
863 // T.path = merge(Base.path, R.path);
864 // T.path = remove_dot_segments(T.path);
866 // T.query = R.query;
867 if (m_path
[0u] != wxT('/'))
870 const wxChar
* op
= m_path
.c_str();
871 const wxChar
* bp
= base
.m_path
.c_str() + base
.m_path
.Length();
873 //not a ending directory? move up
874 if (base
.m_path
[0] && *(bp
-1) != wxT('/'))
875 UpTree(base
.m_path
, bp
);
877 //normalize directories
878 while(*op
== wxT('.') && *(op
+1) == wxT('.') &&
879 (*(op
+2) == '\0' || *(op
+2) == wxT('/')) )
881 UpTree(base
.m_path
, bp
);
889 m_path
= base
.m_path
.substr(0, bp
- base
.m_path
.c_str()) +
890 m_path
.substr((op
- m_path
.c_str()), m_path
.Length());
894 //T.fragment = R.fragment;
897 // ---------------------------------------------------------------------------
900 // Moves a URI path up a directory
901 // ---------------------------------------------------------------------------
904 void wxURI::UpTree(const wxChar
* uristart
, const wxChar
*& uri
)
906 if (uri
!= uristart
&& *(uri
-1) == wxT('/'))
911 for(;uri
!= uristart
; --uri
)
913 if (*uri
== wxT('/'))
921 if (uri
== uristart
&& *uri
== wxT('/'))
926 // ---------------------------------------------------------------------------
929 // Normalizes directories in-place
931 // I.E. ./ and . are ignored
933 // ../ and .. are removed if a directory is before it, along
934 // with that directory (leading .. and ../ are kept)
935 // ---------------------------------------------------------------------------
938 void wxURI::Normalize(wxChar
* s
, bool bIgnoreLeads
)
948 if (*cp
== wxT('.') && (*(cp
+1) == wxT('/') || *(cp
+1) == '\0')
949 && (bp
== cp
|| *(cp
-1) == wxT('/')))
957 else if (*cp
== wxT('.') && *(cp
+1) == wxT('.') &&
958 (*(cp
+2) == wxT('/') || *(cp
+2) == '\0')
959 && (bp
== cp
|| *(cp
-1) == wxT('/')))
961 //.. _or_ ../ - go up the tree
964 UpTree((const wxChar
*)bp
, (const wxChar
*&)s
);
971 else if (!bIgnoreLeads
)
996 // ---------------------------------------------------------------------------
999 // Parses 1 to 4 hex values. Returns true if the first character of the input
1000 // string is a valid hex character. It is the caller's responsability to move
1001 // the input string back to its original position on failure.
1002 // ---------------------------------------------------------------------------
1004 bool wxURI::ParseH16(const wxChar
*& uri
)
1010 if(IsHex(*++uri
) && IsHex(*++uri
) && IsHex(*++uri
))
1016 // ---------------------------------------------------------------------------
1019 // Parses a certain version of an IP address and moves the input string past
1020 // it. Returns true if the input string contains the proper version of an ip
1021 // address. It is the caller's responsability to move the input string back
1022 // to its original position on failure.
1023 // ---------------------------------------------------------------------------
1025 bool wxURI::ParseIPv4address(const wxChar
*& uri
)
1027 //IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1029 //dec-octet = DIGIT ; 0-9
1030 // / %x31-39 DIGIT ; 10-99
1031 // / "1" 2DIGIT ; 100-199
1032 // / "2" %x30-34 DIGIT ; 200-249
1033 // / "25" %x30-35 ; 250-255
1040 //each ip part must be between 0-255 (dupe of version in for loop)
1041 if( IsDigit(*++uri
) && IsDigit(*++uri
) &&
1042 //100 or less (note !)
1043 !( (*(uri
-2) < wxT('2')) ||
1045 (*(uri
-2) == wxT('2') &&
1046 (*(uri
-1) < wxT('5') || (*(uri
-1) == wxT('5') && *uri
<= wxT('5')))
1054 if(IsDigit(*uri
))++uri
;
1056 //compilers should unroll this loop
1057 for(; iIPv4
< 4; ++iIPv4
)
1059 if (*uri
!= wxT('.') || !IsDigit(*++uri
))
1062 //each ip part must be between 0-255
1063 if( IsDigit(*++uri
) && IsDigit(*++uri
) &&
1064 //100 or less (note !)
1065 !( (*(uri
-2) < wxT('2')) ||
1067 (*(uri
-2) == wxT('2') &&
1068 (*(uri
-1) < wxT('5') || (*(uri
-1) == wxT('5') && *uri
<= wxT('5')))
1075 if(IsDigit(*uri
))++uri
;
1081 bool wxURI::ParseIPv6address(const wxChar
*& uri
)
1083 // IPv6address = 6( h16 ":" ) ls32
1084 // / "::" 5( h16 ":" ) ls32
1085 // / [ h16 ] "::" 4( h16 ":" ) ls32
1086 // / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1087 // / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1088 // / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1089 // / [ *4( h16 ":" ) h16 ] "::" ls32
1090 // / [ *5( h16 ":" ) h16 ] "::" h16
1091 // / [ *6( h16 ":" ) h16 ] "::"
1093 size_t numPrefix
= 0,
1096 bool bEndHex
= false;
1098 for( ; numPrefix
< 6; ++numPrefix
)
1107 if(*uri
!= wxT(':'))
1113 if(!bEndHex
&& !ParseH16(uri
))
1120 if (*uri
== wxT(':'))
1122 if (*++uri
!= wxT(':'))
1132 if (*uri
!= wxT(':') || *(uri
+1) != wxT(':'))
1137 while (*--uri
!= wxT(':')) {}
1140 const wxChar
* uristart
= uri
;
1142 // ls32 = ( h16 ":" h16 ) / IPv4address
1143 if (ParseH16(uri
) && *uri
== wxT(':') && ParseH16(uri
))
1148 if (ParseIPv4address(uri
))
1160 maxPostfix
= 4 - numPrefix
;
1164 bool bAllowAltEnding
= maxPostfix
== 0;
1166 for(; maxPostfix
!= 0; --maxPostfix
)
1168 if(!ParseH16(uri
) || *uri
!= wxT(':'))
1174 const wxChar
* uristart
= uri
;
1176 // ls32 = ( h16 ":" h16 ) / IPv4address
1177 if (ParseH16(uri
) && *uri
== wxT(':') && ParseH16(uri
))
1182 if (ParseIPv4address(uri
))
1187 if (!bAllowAltEnding
)
1191 if(numPrefix
<= 5 && ParseH16(uri
))
1197 bool wxURI::ParseIPvFuture(const wxChar
*& uri
)
1199 // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1200 if (*++uri
!= wxT('v') || !IsHex(*++uri
))
1203 while (IsHex(*++uri
)) {}
1205 if (*uri
!= wxT('.') || !(IsUnreserved(*++uri
) || IsSubDelim(*uri
) || *uri
== wxT(':')))
1208 while(IsUnreserved(*++uri
) || IsSubDelim(*uri
) || *uri
== wxT(':')) {}
1214 // ---------------------------------------------------------------------------
1217 // Converts a character into a numeric hexidecimal value, or 0 if the
1218 // passed in character is not a valid hex character
1219 // ---------------------------------------------------------------------------
1222 wxChar
wxURI::CharToHex(const wxChar
& c
)
1224 if ((c
>= wxT('A')) && (c
<= wxT('Z'))) return wxChar(c
- wxT('A') + 0x0A);
1225 if ((c
>= wxT('a')) && (c
<= wxT('z'))) return wxChar(c
- wxT('a') + 0x0a);
1226 if ((c
>= wxT('0')) && (c
<= wxT('9'))) return wxChar(c
- wxT('0') + 0x00);
1231 // ---------------------------------------------------------------------------
1234 // Returns true if the passed in character meets the criteria of the method
1235 // ---------------------------------------------------------------------------
1237 //! unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1238 bool wxURI::IsUnreserved (const wxChar
& c
)
1239 { return IsAlpha(c
) || IsDigit(c
) ||
1243 c
== wxT('~') //tilde
1247 bool wxURI::IsReserved (const wxChar
& c
)
1249 return IsGenDelim(c
) || IsSubDelim(c
);
1252 //! gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
1253 bool wxURI::IsGenDelim (const wxChar
& c
)
1255 return c
== wxT(':') ||
1264 //! sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
1265 //! / "*" / "+" / "," / ";" / "="
1266 bool wxURI::IsSubDelim (const wxChar
& c
)
1268 return c
== wxT('!') ||
1282 bool wxURI::IsHex(const wxChar
& c
)
1283 { return IsDigit(c
) || (c
>= wxT('a') && c
<= wxT('f')) || (c
>= wxT('A') && c
<= wxT('F')); }
1285 bool wxURI::IsAlpha(const wxChar
& c
)
1286 { return (c
>= wxT('a') && c
<= wxT('z')) || (c
>= wxT('A') && c
<= wxT('Z')); }
1288 bool wxURI::IsDigit(const wxChar
& c
)
1289 { return c
>= wxT('0') && c
<= wxT('9'); }
1292 // ---------------------------------------------------------------------------
1294 // wxURL Compatibility
1296 // ---------------------------------------------------------------------------
1300 #if WXWIN_COMPATIBILITY_2_4
1304 wxString
wxURL::GetProtocolName() const
1309 wxString
wxURL::GetHostName() const
1314 wxString
wxURL::GetPath() const
1319 //Note that this old code really doesn't convert to a URI that well and looks
1320 //more like a dirty hack than anything else...
1322 wxString
wxURL::ConvertToValidURI(const wxString
& uri
, const wxChar
* delims
)
1328 for (i
= 0; i
< uri
.Len(); i
++)
1330 wxChar c
= uri
.GetChar(i
);
1334 // GRG, Apr/2000: changed to "%20" instead of '+'
1336 out_str
+= wxT("%20");
1340 // GRG, Apr/2000: modified according to the URI definition (RFC 2396)
1342 // - Alphanumeric characters are never escaped
1343 // - Unreserved marks are never escaped
1344 // - Delimiters must be escaped if they appear within a component
1345 // but not if they are used to separate components. Here we have
1346 // no clear way to distinguish between these two cases, so they
1347 // are escaped unless they are passed in the 'delims' parameter
1348 // (allowed delimiters).
1350 static const wxChar marks
[] = wxT("-_.!~*()'");
1352 if ( !wxIsalnum(c
) && !wxStrchr(marks
, c
) && !wxStrchr(delims
, c
) )
1354 hexa_code
.Printf(wxT("%%%02X"), c
);
1355 out_str
+= hexa_code
;
1367 wxString
wxURL::ConvertFromURI(const wxString
& uri
)
1369 return wxURI::Unescape(uri
);
1372 #endif //WXWIN_COMPATIBILITY_2_4