]>
git.saurik.com Git - wxWidgets.git/blob - src/common/uri.cpp
8d5ab03e75d3720e4108152f30d4f1ad49ca6734
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
) : m_hostType(wxURI_REGNAME
), m_fields(0)
70 // ---------------------------------------------------------------------------
71 // Destructor and cleanup
72 // ---------------------------------------------------------------------------
81 m_scheme
= m_user
= m_server
= m_port
= m_path
=
82 m_query
= m_fragment
= wxT("");
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
) && IsHex(*(s
+1)), wxT("Invalid escape!"));
120 return CharToHex(*s
) * 0x10 + CharToHex(*++s
);
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]) );
139 void wxURI::Escape(wxString
& s
, const wxChar
& c
)
141 const wxChar
* hdig
= wxT("0123456789abcdef");
143 s
+= hdig
[(c
>> 4) & 15];
147 bool wxURI::IsEscape(const wxChar
*& uri
)
149 // pct-encoded = "%" HEXDIG HEXDIG
150 if(*uri
== wxT('%') && IsHex(*(uri
+1)) && IsHex(*(uri
+2)))
159 // ---------------------------------------------------------------------------
162 // BuildURI() builds the entire URI into a useable
163 // representation, including proper identification characters such as slashes
165 // BuildUnescapedURI() does the same thing as BuildURI(), only it unescapes
166 // the components that accept escape sequences
167 // ---------------------------------------------------------------------------
169 wxString
wxURI::BuildURI() const
174 ret
= ret
+ m_scheme
+ wxT(":");
181 ret
= ret
+ m_user
+ wxT("@");
186 ret
= ret
+ wxT(":") + m_port
;
192 ret
= ret
+ wxT("?") + m_query
;
195 ret
= ret
+ wxT("#") + m_fragment
;
200 wxString
wxURI::BuildUnescapedURI() const
205 ret
= ret
+ m_scheme
+ wxT(":");
212 ret
= ret
+ wxURI::Unescape(m_user
) + wxT("@");
214 if (m_hostType
== wxURI_REGNAME
)
215 ret
+= wxURI::Unescape(m_server
);
220 ret
= ret
+ wxT(":") + m_port
;
223 ret
+= wxURI::Unescape(m_path
);
226 ret
= ret
+ wxT("?") + wxURI::Unescape(m_query
);
229 ret
= ret
+ wxT("#") + wxURI::Unescape(m_fragment
);
234 // ---------------------------------------------------------------------------
236 // ---------------------------------------------------------------------------
238 wxURI
& wxURI::Assign(const wxURI
& uri
)
241 m_fields
= uri
.m_fields
;
243 //ref over components
244 m_scheme
= uri
.m_scheme
;
246 m_server
= uri
.m_server
;
247 m_hostType
= uri
.m_hostType
;
250 m_query
= uri
.m_query
;
251 m_fragment
= uri
.m_fragment
;
256 wxURI
& wxURI::operator = (const wxURI
& uri
)
261 wxURI
& wxURI::operator = (const wxString
& string
)
267 // ---------------------------------------------------------------------------
269 // ---------------------------------------------------------------------------
271 bool wxURI::operator == (const wxURI
& uri
) const
275 if(m_scheme
!= uri
.m_scheme
)
278 else if (uri
.HasScheme())
286 if (m_user
!= uri
.m_user
)
289 else if (uri
.HasUser())
292 if (m_server
!= uri
.m_server
||
293 m_hostType
!= uri
.m_hostType
)
298 if(m_port
!= uri
.m_port
)
301 else if (uri
.HasPort())
304 else if (uri
.HasServer())
310 if(m_path
!= uri
.m_path
)
313 else if (uri
.HasPath())
318 if (m_query
!= uri
.m_query
)
321 else if (uri
.HasQuery())
326 if (m_fragment
!= uri
.m_fragment
)
329 else if (uri
.HasFragment())
335 // ---------------------------------------------------------------------------
338 // if there is no authority or scheme, it is a reference
339 // ---------------------------------------------------------------------------
341 bool wxURI::IsReference() const
342 { return !HasScheme() || !HasServer(); }
344 // ---------------------------------------------------------------------------
347 // Master URI parsing method. Just calls the individual parsing methods
349 // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
350 // URI-reference = URI / relative-URITestCase
351 // ---------------------------------------------------------------------------
353 const wxChar
* wxURI::Parse(const wxChar
* uri
)
355 uri
= ParseScheme(uri
);
356 uri
= ParseAuthority(uri
);
357 uri
= ParsePath(uri
);
358 uri
= ParseQuery(uri
);
359 return ParseFragment(uri
);
362 // ---------------------------------------------------------------------------
365 // Individual parsers for each URI component
366 // ---------------------------------------------------------------------------
368 const wxChar
* wxURI::ParseScheme(const wxChar
* uri
)
370 wxASSERT(uri
!= NULL
);
372 //copy of the uri - used for figuring out
373 //length of each component
374 const wxChar
* uricopy
= uri
;
376 //Does the uri have a scheme (first character alpha)?
381 //scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
382 while (IsAlpha(*uri
) || IsDigit(*uri
) ||
391 if (*uri
== wxT(':'))
393 //mark the scheme as valid
394 m_fields
|= wxURI_SCHEME
;
396 //move reference point up to input buffer
400 //relative uri with relative path reference
404 //relative uri with _possible_ relative path reference
409 const wxChar
* wxURI::ParseAuthority(const wxChar
* uri
)
411 // authority = [ userinfo "@" ] host [ ":" port ]
412 if (*uri
== wxT('/') && *(uri
+1) == wxT('/'))
416 uri
= ParseUser(uri
);
417 uri
= ParseServer(uri
);
418 return ParsePort(uri
);
424 const wxChar
* wxURI::ParseUser(const wxChar
* uri
)
426 wxASSERT(uri
!= NULL
);
428 //copy of the uri - used for figuring out
429 //length of each component
430 const wxChar
* uricopy
= uri
;
432 // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
433 while(*uri
&& *uri
!= wxT('@') && *uri
!= wxT('/') && *uri
!= wxT('#') && *uri
!= wxT('?'))
435 if(IsUnreserved(*uri
) || IsEscape(uri
) ||
436 IsSubDelim(*uri
) || *uri
== wxT(':'))
439 Escape(m_user
, *uri
++);
445 m_fields
|= wxURI_USER
;
455 const wxChar
* wxURI::ParseServer(const wxChar
* uri
)
457 wxASSERT(uri
!= NULL
);
459 //copy of the uri - used for figuring out
460 //length of each component
461 const wxChar
* uricopy
= uri
;
463 // host = IP-literal / IPv4address / reg-name
464 // IP-literal = "[" ( IPv6address / IPvFuture ) "]"
465 if (*uri
== wxT('['))
467 if (ParseIPv6address(++uri
) && *uri
== wxT(']'))
470 m_hostType
= wxURI_IPV6ADDRESS
;
472 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
473 wxMemcpy(theBuffer
, uricopy
, uri
-uricopy
);
474 theBuffer
.SetLength(uri
-uricopy
);
480 if (ParseIPvFuture(++uri
) && *uri
== wxT(']'))
483 m_hostType
= wxURI_IPVFUTURE
;
485 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
486 wxMemcpy(theBuffer
, uricopy
, uri
-uricopy
);
487 theBuffer
.SetLength(uri
-uricopy
);
495 if (ParseIPv4address(uri
))
497 m_hostType
= wxURI_IPV4ADDRESS
;
499 wxStringBufferLength
theBuffer(m_server
, uri
- uricopy
);
500 wxMemcpy(theBuffer
, uricopy
, uri
-uricopy
);
501 theBuffer
.SetLength(uri
-uricopy
);
507 if(m_hostType
== wxURI_REGNAME
)
510 // reg-name = *( unreserved / pct-encoded / sub-delims )
511 while(*uri
&& *uri
!= wxT('/') && *uri
!= wxT(':') && *uri
!= wxT('#') && *uri
!= wxT('?'))
513 if(IsUnreserved(*uri
) || IsEscape(uri
) || IsSubDelim(*uri
))
516 Escape(m_server
, *uri
++);
520 //mark the server as valid
521 m_fields
|= wxURI_SERVER
;
527 const wxChar
* wxURI::ParsePort(const wxChar
* uri
)
529 wxASSERT(uri
!= NULL
);
540 //mark the port as valid
541 m_fields
|= wxURI_PORT
;
547 const wxChar
* wxURI::ParsePath(const wxChar
* uri
, bool bReference
, bool bNormalize
)
549 wxASSERT(uri
!= NULL
);
551 //copy of the uri - used for figuring out
552 //length of each component
553 const wxChar
* uricopy
= uri
;
555 /// hier-part = "//" authority path-abempty
560 /// relative-part = "//" authority path-abempty
565 /// path-abempty = *( "/" segment )
566 /// path-absolute = "/" [ segment-nz *( "/" segment ) ]
567 /// path-noscheme = segment-nz-nc *( "/" segment )
568 /// path-rootless = segment-nz *( "/" segment )
569 /// path-empty = 0<pchar>
572 /// segment-nz = 1*pchar
573 /// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
574 /// ; non-zero-length segment without any colon ":"
576 /// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
577 if (*uri
== wxT('/'))
581 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
583 if( IsUnreserved(*uri
) || IsSubDelim(*uri
) || IsEscape(uri
) ||
584 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/'))
587 Escape(m_path
, *uri
++);
592 wxStringBufferLength
theBuffer(m_path
, m_path
.length() + 1);
594 wxMemcpy(theBuffer
, m_path
.c_str(), m_path
.length()+1);
596 Normalize(theBuffer
, true);
597 theBuffer
.SetLength(wxStrlen(theBuffer
));
599 //mark the path as valid
600 m_fields
|= wxURI_PATH
;
602 else if(*uri
) //Relative path
607 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
609 if(IsUnreserved(*uri
) || IsSubDelim(*uri
) || IsEscape(uri
) ||
610 *uri
== wxT('@') || *uri
== wxT('/'))
613 Escape(m_path
, *uri
++);
618 while(*uri
&& *uri
!= wxT('#') && *uri
!= wxT('?'))
620 if(IsUnreserved(*uri
) || IsSubDelim(*uri
) || IsEscape(uri
) ||
621 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/'))
624 Escape(m_path
, *uri
++);
632 wxStringBufferLength
theBuffer(m_path
, m_path
.length() + 1);
634 wxMemcpy(theBuffer
, m_path
.c_str(), m_path
.length()+1);
636 Normalize(theBuffer
);
637 theBuffer
.SetLength(wxStrlen(theBuffer
));
640 //mark the path as valid
641 m_fields
|= wxURI_PATH
;
649 const wxChar
* wxURI::ParseQuery(const wxChar
* uri
)
651 wxASSERT(uri
!= NULL
);
653 // query = *( pchar / "/" / "?" )
654 if (*uri
== wxT('?'))
657 while(*uri
&& *uri
!= wxT('#'))
659 if (IsUnreserved(*uri
) || IsSubDelim(*uri
) || IsEscape(uri
) ||
660 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/') || *uri
== wxT('?'))
663 Escape(m_query
, *uri
++);
666 //mark the server as valid
667 m_fields
|= wxURI_QUERY
;
674 const wxChar
* wxURI::ParseFragment(const wxChar
* uri
)
676 wxASSERT(uri
!= NULL
);
678 // fragment = *( pchar / "/" / "?" )
679 if (*uri
== wxT('#'))
684 if (IsUnreserved(*uri
) || IsSubDelim(*uri
) || IsEscape(uri
) ||
685 *uri
== wxT(':') || *uri
== wxT('@') || *uri
== wxT('/') || *uri
== wxT('?'))
686 m_fragment
+= *uri
++;
688 Escape(m_fragment
, *uri
++);
691 //mark the server as valid
692 m_fields
|= wxURI_FRAGMENT
;
698 // ---------------------------------------------------------------------------
701 // Builds missing components of this uri from a base uri
703 // A version of the algorithm outlined in the RFC is used here
704 // (it is shown in comments)
706 // Note that an empty URI inherits all components
707 // ---------------------------------------------------------------------------
709 void wxURI::Resolve(const wxURI
& base
, int flags
)
711 wxASSERT_MSG(!base
.IsReference(),
712 wxT("wxURI to inherit from must not be a reference!"));
714 // If we arn't being strict, enable the older (pre-RFC2396)
715 // loophole that allows this uri to inherit other
716 // properties from the base uri - even if the scheme
718 if ( !(flags
& wxURI_STRICT
) &&
719 HasScheme() && base
.HasScheme() &&
720 m_scheme
== base
.m_scheme
)
722 m_fields
-= wxURI_SCHEME
;
726 // Do nothing if this is an absolute wxURI
727 // if defined(R.scheme) then
728 // T.scheme = R.scheme;
729 // T.authority = R.authority;
730 // T.path = remove_dot_segments(R.path);
731 // T.query = R.query;
738 m_scheme
= base
.m_scheme
;
739 m_fields
|= wxURI_SCHEME
;
741 // All we need to do for relative URIs with an
742 // authority component is just inherit the scheme
743 // if defined(R.authority) then
744 // T.authority = R.authority;
745 // T.path = remove_dot_segments(R.path);
746 // T.query = R.query;
752 //No authority - inherit
755 m_user
= base
.m_user
;
756 m_fields
|= wxURI_USER
;
759 m_server
= base
.m_server
;
760 m_hostType
= base
.m_hostType
;
761 m_fields
|= wxURI_SERVER
;
765 m_port
= base
.m_port
;
766 m_fields
|= wxURI_PORT
;
770 // Simple path inheritance from base
773 // T.path = Base.path;
774 m_path
= base
.m_path
;
775 m_fields
|= wxURI_PATH
;
778 // if defined(R.query) then
779 // T.query = R.query;
781 // T.query = Base.query;
785 m_query
= base
.m_query
;
786 m_fields
|= wxURI_QUERY
;
791 // if (R.path starts-with "/") then
792 // T.path = remove_dot_segments(R.path);
794 // T.path = merge(Base.path, R.path);
795 // T.path = remove_dot_segments(T.path);
797 // T.query = R.query;
798 if (m_path
[0u] != wxT('/'))
801 const wxChar
* op
= m_path
.c_str();
802 const wxChar
* bp
= base
.m_path
.c_str() + base
.m_path
.Length();
804 //not a ending directory? move up
805 if (base
.m_path
[0] && *(bp
-1) != wxT('/'))
806 UpTree(base
.m_path
, bp
);
808 //normalize directories
809 while(*op
== wxT('.') && *(op
+1) == wxT('.') &&
810 (*(op
+2) == '\0' || *(op
+2) == wxT('/')) )
812 UpTree(base
.m_path
, bp
);
820 m_path
= base
.m_path
.substr(0, bp
- base
.m_path
.c_str()) +
821 m_path
.substr((op
- m_path
.c_str()), m_path
.Length());
825 //T.fragment = R.fragment;
828 // ---------------------------------------------------------------------------
831 // Moves a URI path up a directory
832 // ---------------------------------------------------------------------------
835 void wxURI::UpTree(const wxChar
* uristart
, const wxChar
*& uri
)
837 if (uri
!= uristart
&& *(uri
-1) == wxT('/'))
842 for(;uri
!= uristart
; --uri
)
844 if (*uri
== wxT('/'))
852 if (uri
== uristart
&& *uri
== wxT('/'))
857 // ---------------------------------------------------------------------------
860 // Normalizes directories in-place
862 // I.E. ./ and . are ignored
864 // ../ and .. are removed if a directory is before it, along
865 // with that directory (leading .. and ../ are kept)
866 // ---------------------------------------------------------------------------
869 void wxURI::Normalize(wxChar
* s
, bool bIgnoreLeads
)
879 if (*cp
== wxT('.') && (*(cp
+1) == wxT('/') || *(cp
+1) == '\0')
880 && (bp
== cp
|| *(cp
-1) == wxT('/')))
888 else if (*cp
== wxT('.') && *(cp
+1) == wxT('.') &&
889 (*(cp
+2) == wxT('/') || *(cp
+2) == '\0')
890 && (bp
== cp
|| *(cp
-1) == wxT('/')))
892 //.. _or_ ../ - go up the tree
895 UpTree((const wxChar
*)bp
, (const wxChar
*&)s
);
902 else if (!bIgnoreLeads
)
927 // ---------------------------------------------------------------------------
930 // Parses 1 to 4 hex values. Returns true if the first character of the input
931 // string is a valid hex character. It is the caller's responsability to move
932 // the input string back to its original position on failure.
933 // ---------------------------------------------------------------------------
935 bool wxURI::ParseH16(const wxChar
*& uri
)
941 if(IsHex(*++uri
) && IsHex(*++uri
) && IsHex(*++uri
))
947 // ---------------------------------------------------------------------------
950 // Parses a certain version of an IP address and moves the input string past
951 // it. Returns true if the input string contains the proper version of an ip
952 // address. It is the caller's responsability to move the input string back
953 // to its original position on failure.
954 // ---------------------------------------------------------------------------
956 bool wxURI::ParseIPv4address(const wxChar
*& uri
)
958 //IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
960 //dec-octet = DIGIT ; 0-9
961 // / %x31-39 DIGIT ; 10-99
962 // / "1" 2DIGIT ; 100-199
963 // / "2" %x30-34 DIGIT ; 200-249
964 // / "25" %x30-35 ; 250-255
971 //each ip part must be between 0-255 (dupe of version in for loop)
972 if( IsDigit(*++uri
) && IsDigit(*++uri
) &&
973 //100 or less (note !)
974 !( (*(uri
-2) < wxT('2')) ||
976 (*(uri
-2) == wxT('2') &&
977 (*(uri
-1) < wxT('5') || (*(uri
-1) == wxT('5') && *uri
<= wxT('5')))
985 if(IsDigit(*uri
))++uri
;
987 //compilers should unroll this loop
988 for(; iIPv4
< 4; ++iIPv4
)
990 if (*uri
!= wxT('.') || !IsDigit(*++uri
))
993 //each ip part must be between 0-255
994 if( IsDigit(*++uri
) && IsDigit(*++uri
) &&
995 //100 or less (note !)
996 !( (*(uri
-2) < wxT('2')) ||
998 (*(uri
-2) == wxT('2') &&
999 (*(uri
-1) < wxT('5') || (*(uri
-1) == wxT('5') && *uri
<= wxT('5')))
1006 if(IsDigit(*uri
))++uri
;
1012 bool wxURI::ParseIPv6address(const wxChar
*& uri
)
1014 // IPv6address = 6( h16 ":" ) ls32
1015 // / "::" 5( h16 ":" ) ls32
1016 // / [ h16 ] "::" 4( h16 ":" ) ls32
1017 // / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1018 // / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1019 // / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1020 // / [ *4( h16 ":" ) h16 ] "::" ls32
1021 // / [ *5( h16 ":" ) h16 ] "::" h16
1022 // / [ *6( h16 ":" ) h16 ] "::"
1024 size_t numPrefix
= 0,
1027 bool bEndHex
= false;
1029 for( ; numPrefix
< 6; ++numPrefix
)
1038 if(*uri
!= wxT(':'))
1044 if(!bEndHex
&& !ParseH16(uri
))
1051 if (*uri
== wxT(':'))
1053 if (*++uri
!= wxT(':'))
1063 if (*uri
!= wxT(':') || *(uri
+1) != wxT(':'))
1068 while (*--uri
!= wxT(':')) {}
1071 const wxChar
* uristart
= uri
;
1073 // ls32 = ( h16 ":" h16 ) / IPv4address
1074 if (ParseH16(uri
) && *uri
== wxT(':') && ParseH16(uri
))
1079 if (ParseIPv4address(uri
))
1091 maxPostfix
= 4 - numPrefix
;
1095 bool bAllowAltEnding
= maxPostfix
== 0;
1097 for(; maxPostfix
!= 0; --maxPostfix
)
1099 if(!ParseH16(uri
) || *uri
!= wxT(':'))
1105 const wxChar
* uristart
= uri
;
1107 // ls32 = ( h16 ":" h16 ) / IPv4address
1108 if (ParseH16(uri
) && *uri
== wxT(':') && ParseH16(uri
))
1113 if (ParseIPv4address(uri
))
1118 if (!bAllowAltEnding
)
1122 if(numPrefix
<= 5 && ParseH16(uri
))
1128 bool wxURI::ParseIPvFuture(const wxChar
*& uri
)
1130 // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1131 if (*++uri
!= wxT('v') || !IsHex(*++uri
))
1134 while (IsHex(*++uri
)) {}
1136 if (*uri
!= wxT('.') || !(IsUnreserved(*++uri
) || IsSubDelim(*uri
) || *uri
== wxT(':')))
1139 while(IsUnreserved(*++uri
) || IsSubDelim(*uri
) || *uri
== wxT(':')) {}
1145 // ---------------------------------------------------------------------------
1148 // Converts a character into a numeric hexidecimal value, or 0 if the
1149 // passed in character is not a valid hex character
1150 // ---------------------------------------------------------------------------
1153 wxInt32
wxURI::CharToHex(const wxChar
& c
)
1155 if ((c
>= wxT('A')) && (c
<= wxT('Z'))) return c
- wxT('A') + 0x0A;
1156 if ((c
>= wxT('a')) && (c
<= wxT('z'))) return c
- wxT('a') + 0x0a;
1157 if ((c
>= wxT('0')) && (c
<= wxT('9'))) return c
- wxT('0') + 0x00;
1162 // ---------------------------------------------------------------------------
1165 // Returns true if the passed in character meets the criteria of the method
1166 // ---------------------------------------------------------------------------
1168 //! unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1169 bool wxURI::IsUnreserved (const wxChar
& c
)
1170 { return IsAlpha(c
) || IsDigit(c
) ||
1174 c
== wxT('~') //tilde
1178 bool wxURI::IsReserved (const wxChar
& c
)
1180 return IsGenDelim(c
) || IsSubDelim(c
);
1183 //! gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
1184 bool wxURI::IsGenDelim (const wxChar
& c
)
1186 return c
== wxT(':') ||
1195 //! sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
1196 //! / "*" / "+" / "," / ";" / "="
1197 bool wxURI::IsSubDelim (const wxChar
& c
)
1199 return c
== wxT('!') ||
1213 bool wxURI::IsHex(const wxChar
& c
)
1214 { return IsDigit(c
) || (c
>= wxT('a') && c
<= wxT('f')) || (c
>= wxT('A') && c
<= wxT('F')); }
1216 bool wxURI::IsAlpha(const wxChar
& c
)
1217 { return (c
>= wxT('a') && c
<= wxT('z')) || (c
>= wxT('A') && c
<= wxT('Z')); }
1219 bool wxURI::IsDigit(const wxChar
& c
)
1220 { return c
>= wxT('0') && c
<= wxT('9'); }
1223 // ---------------------------------------------------------------------------
1225 // wxURL Compatability
1227 // ---------------------------------------------------------------------------
1231 #if WXWIN_COMPATIBILITY_2_4
1235 //Note that this old code really doesn't convert to a URI that well and looks
1236 //more like a dirty hack than anything else...
1238 wxString
wxURL::ConvertToValidURI(const wxString
& uri
, const wxChar
* delims
)
1244 for (i
= 0; i
< uri
.Len(); i
++)
1246 wxChar c
= uri
.GetChar(i
);
1250 // GRG, Apr/2000: changed to "%20" instead of '+'
1252 out_str
+= wxT("%20");
1256 // GRG, Apr/2000: modified according to the URI definition (RFC 2396)
1258 // - Alphanumeric characters are never escaped
1259 // - Unreserved marks are never escaped
1260 // - Delimiters must be escaped if they appear within a component
1261 // but not if they are used to separate components. Here we have
1262 // no clear way to distinguish between these two cases, so they
1263 // are escaped unless they are passed in the 'delims' parameter
1264 // (allowed delimiters).
1266 static const wxChar marks
[] = wxT("-_.!~*()'");
1268 if ( !wxIsalnum(c
) && !wxStrchr(marks
, c
) && !wxStrchr(delims
, c
) )
1270 hexa_code
.Printf(wxT("%%%02X"), c
);
1271 out_str
+= hexa_code
;
1283 wxString
wxURL::ConvertFromURI(const wxString
& uri
)
1285 return wxURI::Unescape(uri
);
1288 #endif //WXWIN_COMPATIBILITY_2_4