]>
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 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
28 // ---------------------------------------------------------------------------
30 // ---------------------------------------------------------------------------
32 IMPLEMENT_CLASS(wxURI
, wxObject
)
34 // ===========================================================================
36 // ===========================================================================
38 // ---------------------------------------------------------------------------
40 // ---------------------------------------------------------------------------
42 // ---------------------------------------------------------------------------
46 // ---------------------------------------------------------------------------
48 // ---------------------------------------------------------------------------
50 // ---------------------------------------------------------------------------
52 wxURI::wxURI() : m_hostType(wxURI_REGNAME
), m_fields(0)
56 wxURI::wxURI(const wxString
& uri
) : m_hostType(wxURI_REGNAME
), m_fields(0)
61 wxURI::wxURI(const wxURI
& uri
) : wxObject(), m_hostType(wxURI_REGNAME
), m_fields(0)
66 // ---------------------------------------------------------------------------
67 // Destructor and cleanup
68 // ---------------------------------------------------------------------------
77 m_scheme
= m_userinfo
= m_server
= m_port
= m_path
=
78 m_query
= m_fragment
= wxEmptyString
;
80 m_hostType
= wxURI_REGNAME
;
85 // ---------------------------------------------------------------------------
88 // This creates the URI - all we do here is call the main parsing method
89 // ---------------------------------------------------------------------------
91 const wxChar
* wxURI::Create(const wxString
& uri
)
99 // ---------------------------------------------------------------------------
102 // TranslateEscape unencodes a 3 character URL escape sequence
104 // Escape encodes an invalid URI character into a 3 character sequence
106 // IsEscape determines if the input string contains an escape sequence,
107 // if it does, then it moves the input string past the escape sequence
109 // Unescape unencodes all 3 character URL escape sequences in a wxString
110 // ---------------------------------------------------------------------------
112 wxChar
wxURI::TranslateEscape(const wxChar
* s
)
114 wxASSERT_MSG( IsHex(s
[0]) && IsHex(s
[1]), wxT("Invalid escape sequence!"));
116 return wx_truncate_cast(wxChar
, (CharToHex(s
[0]) << 4 ) | CharToHex(s
[1]));
119 wxString
wxURI::Unescape(const wxString
& uri
)
123 for(size_t i
= 0; i
< uri
.length(); ++i
)
125 if (uri
[i
] == wxT('%'))
127 new_uri
+= wxURI::TranslateEscape( &(uri
.c_str()[i
+1]) );
137 void wxURI::Escape(wxString
& s
, const wxChar
& c
)
139 const wxChar
* hdig
= wxT("0123456789abcdef");
141 s
+= hdig
[(c
>> 4) & 15];
145 bool wxURI::IsEscape(const wxChar
*& uri
)
147 // pct-encoded = "%" HEXDIG HEXDIG
148 if(*uri
== wxT('%') && IsHex(*(uri
+1)) && IsHex(*(uri
+2)))
154 // ---------------------------------------------------------------------------
158 // Gets the username and password via the old URL method.
159 // ---------------------------------------------------------------------------
160 wxString
wxURI::GetUser() const
162 size_t dwPasswordPos
= m_userinfo
.find(':');
164 if (dwPasswordPos
== wxString::npos
)
167 return m_userinfo(0, dwPasswordPos
);
170 wxString
wxURI::GetPassword() const
172 size_t dwPasswordPos
= m_userinfo
.find(':');
174 if (dwPasswordPos
== wxString::npos
)
177 return m_userinfo(dwPasswordPos
+1, m_userinfo
.length() + 1);
180 // ---------------------------------------------------------------------------
183 // BuildURI() builds the entire URI into a useable
184 // representation, including proper identification characters such as slashes
186 // BuildUnescapedURI() does the same thing as BuildURI(), only it unescapes
187 // the components that accept escape sequences
188 // ---------------------------------------------------------------------------
190 wxString
wxURI::BuildURI() const
195 ret
= ret
+ m_scheme
+ wxT(":");
202 ret
= ret
+ m_userinfo
+ wxT("@");
207 ret
= ret
+ wxT(":") + m_port
;
213 ret
= ret
+ wxT("?") + m_query
;
216 ret
= ret
+ wxT("#") + m_fragment
;
221 wxString
wxURI::BuildUnescapedURI() const
226 ret
= ret
+ m_scheme
+ wxT(":");
233 ret
= ret
+ wxURI::Unescape(m_userinfo
) + wxT("@");
235 if (m_hostType
== wxURI_REGNAME
)
236 ret
+= wxURI::Unescape(m_server
);
241 ret
= ret
+ wxT(":") + m_port
;
244 ret
+= wxURI::Unescape(m_path
);
247 ret
= ret
+ wxT("?") + wxURI::Unescape(m_query
);
250 ret
= ret
+ wxT("#") + wxURI::Unescape(m_fragment
);
255 // ---------------------------------------------------------------------------
257 // ---------------------------------------------------------------------------
259 wxURI
& wxURI::Assign(const wxURI
& uri
)
262 m_fields
= uri
.m_fields
;
264 //ref over components
265 m_scheme
= uri
.m_scheme
;
266 m_userinfo
= uri
.m_userinfo
;
267 m_server
= uri
.m_server
;
268 m_hostType
= uri
.m_hostType
;
271 m_query
= uri
.m_query
;
272 m_fragment
= uri
.m_fragment
;
277 wxURI
& wxURI::operator = (const wxURI
& uri
)
282 wxURI
& wxURI::operator = (const wxString
& string
)
288 // ---------------------------------------------------------------------------
290 // ---------------------------------------------------------------------------
292 bool wxURI::operator == (const wxURI
& uri
) const
296 if(m_scheme
!= uri
.m_scheme
)
299 else if (uri
.HasScheme())
307 if (m_userinfo
!= uri
.m_userinfo
)
310 else if (uri
.HasUserInfo())
313 if (m_server
!= uri
.m_server
||
314 m_hostType
!= uri
.m_hostType
)
319 if(m_port
!= uri
.m_port
)
322 else if (uri
.HasPort())
325 else if (uri
.HasServer())
331 if(m_path
!= uri
.m_path
)
334 else if (uri
.HasPath())
339 if (m_query
!= uri
.m_query
)
342 else if (uri
.HasQuery())
347 if (m_fragment
!= uri
.m_fragment
)
350 else if (uri
.HasFragment())
356 // ---------------------------------------------------------------------------
359 // if there is no authority or scheme, it is a reference
360 // ---------------------------------------------------------------------------
362 bool wxURI::IsReference() const
363 { return !HasScheme() || !HasServer(); }
365 // ---------------------------------------------------------------------------
368 // Master URI parsing method. Just calls the individual parsing methods
370 // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
371 // URI-reference = URI / relative
372 // ---------------------------------------------------------------------------
374 const wxChar
* wxURI::Parse(const wxChar
* uri
)
376 uri
= ParseScheme(uri
);
377 uri
= ParseAuthority(uri
);
378 uri
= ParsePath(uri
);
379 uri
= ParseQuery(uri
);
380 return ParseFragment(uri
);
383 // ---------------------------------------------------------------------------
386 // Individual parsers for each URI component
387 // ---------------------------------------------------------------------------
389 const wxChar
* wxURI::ParseScheme(const wxChar
* uri
)
391 wxASSERT(uri
!= NULL
);
393 //copy of the uri - used for figuring out
394 //length of each component
395 const wxChar
* uricopy
= uri
;
397 //Does the uri have a scheme (first character alpha)?
402 //scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
403 while (IsAlpha(*uri
) || IsDigit(*uri
) ||
412 if (*uri
== wxT(':'))
414 //mark the scheme as valid
415 m_fields
|= wxURI_SCHEME
;
417 //move reference point up to input buffer
421 //relative uri with relative path reference
422 m_scheme
= wxEmptyString
;
425 //relative uri with _possible_ relative path reference
430 const wxChar
* wxURI::ParseAuthority(const wxChar
* uri
)
432 // authority = [ userinfo "@" ] host [ ":" port ]
433 if (*uri
== wxT('/') && *(uri
+1) == wxT('/'))
437 uri
= ParseUserInfo(uri
);
438 uri
= ParseServer(uri
);
439 return ParsePort(uri
);
445 const wxChar
* wxURI::ParseUserInfo(const wxChar
* uri
)
447 wxASSERT(uri
!= NULL
);
449 //copy of the uri - used for figuring out
450 //length of each component
451 const wxChar
* uricopy
= uri
;
453 // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
454 while(*uri
&& *uri
!= wxT('@') && *uri
!= wxT('/') && *uri
!= wxT('#') && *uri
!= wxT('?'))
456 if(IsUnreserved(*uri
) ||
457 IsSubDelim(*uri
) || *uri
== wxT(':'))
458 m_userinfo
+= *uri
++;
459 else if (IsEscape(uri
))
461 m_userinfo
+= *uri
++;
462 m_userinfo
+= *uri
++;
463 m_userinfo
+= *uri
++;
466 Escape(m_userinfo
, *uri
++);
472 m_fields
|= wxURI_USERINFO
;
477 m_userinfo
= wxEmptyString
;
482 const wxChar
* wxURI::ParseServer(const wxChar
* uri
)
484 wxASSERT(uri
!= NULL
);
486 //copy of the uri - used for figuring out
487 //length of each component
488 const wxChar
* uricopy
= uri
;
490 // host = IP-literal / IPv4address / reg-name
491 // IP-literal = "[" ( IPv6address / IPvFuture ) "]"
492 if (*uri
== wxT('['))
494 ++uri
; //some compilers don't support *&ing a ++*
495 if (ParseIPv6address(uri
) && *uri
== wxT(']'))
498 m_hostType
= wxURI_IPV6ADDRESS
;
500 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
501 wxTmemcpy(theBuffer
, uricopy
, uri
-uricopy
);
502 theBuffer
.SetLength(uri
-uricopy
);
508 ++uri
; //some compilers don't support *&ing a ++*
509 if (ParseIPvFuture(uri
) && *uri
== wxT(']'))
512 m_hostType
= wxURI_IPVFUTURE
;
514 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
515 wxTmemcpy(theBuffer
, uricopy
, uri
-uricopy
);
516 theBuffer
.SetLength(uri
-uricopy
);
524 if (ParseIPv4address(uri
))
526 m_hostType
= wxURI_IPV4ADDRESS
;
528 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
529 wxTmemcpy(theBuffer
, uricopy
, uri
-uricopy
);
530 theBuffer
.SetLength(uri
-uricopy
);
536 if(m_hostType
== wxURI_REGNAME
)
539 // reg-name = *( unreserved / pct-encoded / sub-delims )
540 while(*uri
&& *uri
!= wxT('/') && *uri
!= wxT(':') && *uri
!= wxT('#') && *uri
!= wxT('?'))
542 if(IsUnreserved(*uri
) || IsSubDelim(*uri
))
544 else if (IsEscape(uri
))
551 Escape(m_server
, *uri
++);
555 //mark the server as valid
556 m_fields
|= wxURI_SERVER
;
562 const wxChar
* wxURI::ParsePort(const wxChar
* uri
)
564 wxASSERT(uri
!= NULL
);
575 //mark the port as valid
576 m_fields
|= wxURI_PORT
;
582 const wxChar
* wxURI::ParsePath(const wxChar
* uri
, bool bReference
, bool bNormalize
)
584 wxASSERT(uri
!= NULL
);
586 //copy of the uri - used for figuring out
587 //length of each component
588 const wxChar
* uricopy
= uri
;
590 /// hier-part = "//" authority path-abempty
595 /// relative-part = "//" authority path-abempty
600 /// path-abempty = *( "/" segment )
601 /// path-absolute = "/" [ segment-nz *( "/" segment ) ]
602 /// path-noscheme = segment-nz-nc *( "/" segment )
603 /// path-rootless = segment-nz *( "/" segment )
604 /// path-empty = 0<pchar>
607 /// segment-nz = 1*pchar
608 /// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
609 /// ; non-zero-length segment without any colon ":"
611 /// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
612 if (*uri
== wxT('/'))
616 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
618 if( IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
619 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/'))
621 else if (IsEscape(uri
))
628 Escape(m_path
, *uri
++);
633 wxStringBufferLength
theBuffer(m_path
, m_path
.length() + 1);
635 wxTmemcpy(theBuffer
, m_path
.c_str(), m_path
.length()+1);
637 Normalize(theBuffer
, true);
638 theBuffer
.SetLength(wxStrlen(theBuffer
));
640 //mark the path as valid
641 m_fields
|= wxURI_PATH
;
643 else if(*uri
) //Relative path
648 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
650 if(IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
651 *uri
== wxT('@') || *uri
== wxT('/'))
653 else if (IsEscape(uri
))
660 Escape(m_path
, *uri
++);
665 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
667 if(IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
668 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/'))
670 else if (IsEscape(uri
))
677 Escape(m_path
, *uri
++);
685 wxStringBufferLength
theBuffer(m_path
, m_path
.length() + 1);
687 wxTmemcpy(theBuffer
, m_path
.c_str(), m_path
.length()+1);
689 Normalize(theBuffer
);
690 theBuffer
.SetLength(wxStrlen(theBuffer
));
693 //mark the path as valid
694 m_fields
|= wxURI_PATH
;
702 const wxChar
* wxURI::ParseQuery(const wxChar
* uri
)
704 wxASSERT(uri
!= NULL
);
706 // query = *( pchar / "/" / "?" )
707 if (*uri
== wxT('?'))
710 while(*uri
&& *uri
!= wxT('#'))
712 if (IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
713 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/') || *uri
== wxT('?'))
715 else if (IsEscape(uri
))
722 Escape(m_query
, *uri
++);
725 //mark the server as valid
726 m_fields
|= wxURI_QUERY
;
733 const wxChar
* wxURI::ParseFragment(const wxChar
* uri
)
735 wxASSERT(uri
!= NULL
);
737 // fragment = *( pchar / "/" / "?" )
738 if (*uri
== wxT('#'))
743 if (IsUnreserved(*uri
) || IsSubDelim(*uri
) ||
744 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/') || *uri
== wxT('?'))
745 m_fragment
+= *uri
++;
746 else if (IsEscape(uri
))
748 m_fragment
+= *uri
++;
749 m_fragment
+= *uri
++;
750 m_fragment
+= *uri
++;
753 Escape(m_fragment
, *uri
++);
756 //mark the server as valid
757 m_fields
|= wxURI_FRAGMENT
;
763 // ---------------------------------------------------------------------------
766 // Builds missing components of this uri from a base uri
768 // A version of the algorithm outlined in the RFC is used here
769 // (it is shown in comments)
771 // Note that an empty URI inherits all components
772 // ---------------------------------------------------------------------------
774 void wxURI::Resolve(const wxURI
& base
, int flags
)
776 wxASSERT_MSG(!base
.IsReference(),
777 wxT("wxURI to inherit from must not be a reference!"));
779 // If we arn't being strict, enable the older (pre-RFC2396)
780 // loophole that allows this uri to inherit other
781 // properties from the base uri - even if the scheme
783 if ( !(flags
& wxURI_STRICT
) &&
784 HasScheme() && base
.HasScheme() &&
785 m_scheme
== base
.m_scheme
)
787 m_fields
-= wxURI_SCHEME
;
791 // Do nothing if this is an absolute wxURI
792 // if defined(R.scheme) then
793 // T.scheme = R.scheme;
794 // T.authority = R.authority;
795 // T.path = remove_dot_segments(R.path);
796 // T.query = R.query;
802 //No scheme - inherit
803 m_scheme
= base
.m_scheme
;
804 m_fields
|= wxURI_SCHEME
;
806 // All we need to do for relative URIs with an
807 // authority component is just inherit the scheme
808 // if defined(R.authority) then
809 // T.authority = R.authority;
810 // T.path = remove_dot_segments(R.path);
811 // T.query = R.query;
817 //No authority - inherit
818 if (base
.HasUserInfo())
820 m_userinfo
= base
.m_userinfo
;
821 m_fields
|= wxURI_USERINFO
;
824 m_server
= base
.m_server
;
825 m_hostType
= base
.m_hostType
;
826 m_fields
|= wxURI_SERVER
;
830 m_port
= base
.m_port
;
831 m_fields
|= wxURI_PORT
;
835 // Simple path inheritance from base
838 // T.path = Base.path;
839 m_path
= base
.m_path
;
840 m_fields
|= wxURI_PATH
;
843 // if defined(R.query) then
844 // T.query = R.query;
846 // T.query = Base.query;
850 m_query
= base
.m_query
;
851 m_fields
|= wxURI_QUERY
;
856 // if (R.path starts-with "/") then
857 // T.path = remove_dot_segments(R.path);
859 // T.path = merge(Base.path, R.path);
860 // T.path = remove_dot_segments(T.path);
862 // T.query = R.query;
863 if (m_path
[0u] != wxT('/'))
866 const wxChar
* op
= m_path
.c_str();
867 const wxChar
* bp
= base
.m_path
.c_str() + base
.m_path
.Length();
869 //not a ending directory? move up
870 if (base
.m_path
[0] && *(bp
-1) != wxT('/'))
871 UpTree(base
.m_path
, bp
);
873 //normalize directories
874 while(*op
== wxT('.') && *(op
+1) == wxT('.') &&
875 (*(op
+2) == '\0' || *(op
+2) == wxT('/')) )
877 UpTree(base
.m_path
, bp
);
885 m_path
= (wxString
)base
.m_path
.substr(0, bp
- base
.m_path
.c_str()) +
886 (wxString
)m_path
.substr((op
- m_path
.c_str()), m_path
.Length());
890 //T.fragment = R.fragment;
893 // ---------------------------------------------------------------------------
896 // Moves a URI path up a directory
897 // ---------------------------------------------------------------------------
900 void wxURI::UpTree(const wxChar
* uristart
, const wxChar
*& uri
)
902 if (uri
!= uristart
&& *(uri
-1) == wxT('/'))
907 for(;uri
!= uristart
; --uri
)
909 if (*uri
== wxT('/'))
917 if (uri
== uristart
&& *uri
== wxT('/'))
922 // ---------------------------------------------------------------------------
925 // Normalizes directories in-place
927 // I.E. ./ and . are ignored
929 // ../ and .. are removed if a directory is before it, along
930 // with that directory (leading .. and ../ are kept)
931 // ---------------------------------------------------------------------------
934 void wxURI::Normalize(wxChar
* s
, bool bIgnoreLeads
)
944 if (*cp
== wxT('.') && (*(cp
+1) == wxT('/') || *(cp
+1) == '\0')
945 && (bp
== cp
|| *(cp
-1) == wxT('/')))
953 else if (*cp
== wxT('.') && *(cp
+1) == wxT('.') &&
954 (*(cp
+2) == wxT('/') || *(cp
+2) == '\0')
955 && (bp
== cp
|| *(cp
-1) == wxT('/')))
957 //.. _or_ ../ - go up the tree
960 UpTree((const wxChar
*)bp
, (const wxChar
*&)s
);
967 else if (!bIgnoreLeads
)
992 // ---------------------------------------------------------------------------
995 // Parses 1 to 4 hex values. Returns true if the first character of the input
996 // string is a valid hex character. It is the caller's responsability to move
997 // the input string back to its original position on failure.
998 // ---------------------------------------------------------------------------
1000 bool wxURI::ParseH16(const wxChar
*& uri
)
1006 if(IsHex(*++uri
) && IsHex(*++uri
) && IsHex(*++uri
))
1012 // ---------------------------------------------------------------------------
1015 // Parses a certain version of an IP address and moves the input string past
1016 // it. Returns true if the input string contains the proper version of an ip
1017 // address. It is the caller's responsability to move the input string back
1018 // to its original position on failure.
1019 // ---------------------------------------------------------------------------
1021 bool wxURI::ParseIPv4address(const wxChar
*& uri
)
1023 //IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1025 //dec-octet = DIGIT ; 0-9
1026 // / %x31-39 DIGIT ; 10-99
1027 // / "1" 2DIGIT ; 100-199
1028 // / "2" %x30-34 DIGIT ; 200-249
1029 // / "25" %x30-35 ; 250-255
1036 //each ip part must be between 0-255 (dupe of version in for loop)
1037 if( IsDigit(*++uri
) && IsDigit(*++uri
) &&
1038 //100 or less (note !)
1039 !( (*(uri
-2) < wxT('2')) ||
1041 (*(uri
-2) == wxT('2') &&
1042 (*(uri
-1) < wxT('5') || (*(uri
-1) == wxT('5') && *uri
<= wxT('5')))
1050 if(IsDigit(*uri
))++uri
;
1052 //compilers should unroll this loop
1053 for(; iIPv4
< 4; ++iIPv4
)
1055 if (*uri
!= wxT('.') || !IsDigit(*++uri
))
1058 //each ip part must be between 0-255
1059 if( IsDigit(*++uri
) && IsDigit(*++uri
) &&
1060 //100 or less (note !)
1061 !( (*(uri
-2) < wxT('2')) ||
1063 (*(uri
-2) == wxT('2') &&
1064 (*(uri
-1) < wxT('5') || (*(uri
-1) == wxT('5') && *uri
<= wxT('5')))
1071 if(IsDigit(*uri
))++uri
;
1077 bool wxURI::ParseIPv6address(const wxChar
*& uri
)
1079 // IPv6address = 6( h16 ":" ) ls32
1080 // / "::" 5( h16 ":" ) ls32
1081 // / [ h16 ] "::" 4( h16 ":" ) ls32
1082 // / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1083 // / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1084 // / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1085 // / [ *4( h16 ":" ) h16 ] "::" ls32
1086 // / [ *5( h16 ":" ) h16 ] "::" h16
1087 // / [ *6( h16 ":" ) h16 ] "::"
1089 size_t numPrefix
= 0,
1092 bool bEndHex
= false;
1094 for( ; numPrefix
< 6; ++numPrefix
)
1103 if(*uri
!= wxT(':'))
1109 if(!bEndHex
&& !ParseH16(uri
))
1116 if (*uri
== wxT(':'))
1118 if (*++uri
!= wxT(':'))
1128 if (*uri
!= wxT(':') || *(uri
+1) != wxT(':'))
1133 while (*--uri
!= wxT(':')) {}
1136 const wxChar
* uristart
= uri
;
1138 // ls32 = ( h16 ":" h16 ) / IPv4address
1139 if (ParseH16(uri
) && *uri
== wxT(':') && ParseH16(uri
))
1144 if (ParseIPv4address(uri
))
1156 maxPostfix
= 4 - numPrefix
;
1160 bool bAllowAltEnding
= maxPostfix
== 0;
1162 for(; maxPostfix
!= 0; --maxPostfix
)
1164 if(!ParseH16(uri
) || *uri
!= wxT(':'))
1170 const wxChar
* uristart
= uri
;
1172 // ls32 = ( h16 ":" h16 ) / IPv4address
1173 if (ParseH16(uri
) && *uri
== wxT(':') && ParseH16(uri
))
1178 if (ParseIPv4address(uri
))
1183 if (!bAllowAltEnding
)
1187 if(numPrefix
<= 5 && ParseH16(uri
))
1193 bool wxURI::ParseIPvFuture(const wxChar
*& uri
)
1195 // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1196 if (*++uri
!= wxT('v') || !IsHex(*++uri
))
1199 while (IsHex(*++uri
)) {}
1201 if (*uri
!= wxT('.') || !(IsUnreserved(*++uri
) || IsSubDelim(*uri
) || *uri
== wxT(':')))
1204 while(IsUnreserved(*++uri
) || IsSubDelim(*uri
) || *uri
== wxT(':')) {}
1210 // ---------------------------------------------------------------------------
1213 // Converts a character into a numeric hexidecimal value, or 0 if the
1214 // passed in character is not a valid hex character
1215 // ---------------------------------------------------------------------------
1218 wxChar
wxURI::CharToHex(const wxChar
& c
)
1220 if ((c
>= wxT('A')) && (c
<= wxT('Z'))) return wxChar(c
- wxT('A') + 0x0A);
1221 if ((c
>= wxT('a')) && (c
<= wxT('z'))) return wxChar(c
- wxT('a') + 0x0a);
1222 if ((c
>= wxT('0')) && (c
<= wxT('9'))) return wxChar(c
- wxT('0') + 0x00);
1227 // ---------------------------------------------------------------------------
1230 // Returns true if the passed in character meets the criteria of the method
1231 // ---------------------------------------------------------------------------
1233 //! unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1234 bool wxURI::IsUnreserved (const wxChar
& c
)
1235 { return IsAlpha(c
) || IsDigit(c
) ||
1239 c
== wxT('~') //tilde
1243 bool wxURI::IsReserved (const wxChar
& c
)
1245 return IsGenDelim(c
) || IsSubDelim(c
);
1248 //! gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
1249 bool wxURI::IsGenDelim (const wxChar
& c
)
1251 return c
== wxT(':') ||
1260 //! sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
1261 //! / "*" / "+" / "," / ";" / "="
1262 bool wxURI::IsSubDelim (const wxChar
& c
)
1264 return c
== wxT('!') ||
1278 bool wxURI::IsHex(const wxChar
& c
)
1279 { return IsDigit(c
) || (c
>= wxT('a') && c
<= wxT('f')) || (c
>= wxT('A') && c
<= wxT('F')); }
1281 bool wxURI::IsAlpha(const wxChar
& c
)
1282 { return (c
>= wxT('a') && c
<= wxT('z')) || (c
>= wxT('A') && c
<= wxT('Z')); }
1284 bool wxURI::IsDigit(const wxChar
& c
)
1285 { return c
>= wxT('0') && c
<= wxT('9'); }