1
/////////////////////////////////////////////////////////////////////////////
3
// Purpose: Implementation of a uri parser
6
// RCS-ID: $Id: uri.cpp,v 1.26.2.1 2006/02/09 03:12:27 VZ Exp $
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('/'))
439
//skip past the two slashes
442
// ############# DEVIATION FROM RFC #########################
443
// Don't parse the server component for file URIs
444
if(m_scheme != wxT("file"))
447
uri = ParseUserInfo(uri);
448
uri = ParseServer(uri);
449
return ParsePort(uri);
456
const wxChar* wxURI::ParseUserInfo(const wxChar* uri)
458
wxASSERT(uri != NULL);
460
//copy of the uri - used for figuring out
461
//length of each component
462
const wxChar* uricopy = uri;
464
// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
465
while(*uri && *uri != wxT('@') && *uri != wxT('/') && *uri != wxT('#') && *uri != wxT('?'))
467
if(IsUnreserved(*uri) ||
468
IsSubDelim(*uri) || *uri == wxT(':'))
469
m_userinfo += *uri++;
470
else if (IsEscape(uri))
472
m_userinfo += *uri++;
473
m_userinfo += *uri++;
474
m_userinfo += *uri++;
477
Escape(m_userinfo, *uri++);
483
m_fields |= wxURI_USERINFO;
488
m_userinfo = wxEmptyString;
493
const wxChar* wxURI::ParseServer(const wxChar* uri)
495
wxASSERT(uri != NULL);
497
//copy of the uri - used for figuring out
498
//length of each component
499
const wxChar* uricopy = uri;
501
// host = IP-literal / IPv4address / reg-name
502
// IP-literal = "[" ( IPv6address / IPvFuture ) "]"
503
if (*uri == wxT('['))
505
++uri; //some compilers don't support *&ing a ++*
506
if (ParseIPv6address(uri) && *uri == wxT(']'))
509
m_hostType = wxURI_IPV6ADDRESS;
511
wxStringBufferLength theBuffer(m_server, uri - uricopy);
512
wxTmemcpy(theBuffer, uricopy, uri-uricopy);
513
theBuffer.SetLength(uri-uricopy);
519
++uri; //some compilers don't support *&ing a ++*
520
if (ParseIPvFuture(uri) && *uri == wxT(']'))
523
m_hostType = wxURI_IPVFUTURE;
525
wxStringBufferLength theBuffer(m_server, uri - uricopy);
526
wxTmemcpy(theBuffer, uricopy, uri-uricopy);
527
theBuffer.SetLength(uri-uricopy);
535
if (ParseIPv4address(uri))
537
m_hostType = wxURI_IPV4ADDRESS;
539
wxStringBufferLength theBuffer(m_server, uri - uricopy);
540
wxTmemcpy(theBuffer, uricopy, uri-uricopy);
541
theBuffer.SetLength(uri-uricopy);
547
if(m_hostType == wxURI_REGNAME)
550
// reg-name = *( unreserved / pct-encoded / sub-delims )
551
while(*uri && *uri != wxT('/') && *uri != wxT(':') && *uri != wxT('#') && *uri != wxT('?'))
553
if(IsUnreserved(*uri) || IsSubDelim(*uri))
555
else if (IsEscape(uri))
562
Escape(m_server, *uri++);
566
//mark the server as valid
567
m_fields |= wxURI_SERVER;
573
const wxChar* wxURI::ParsePort(const wxChar* uri)
575
wxASSERT(uri != NULL);
586
//mark the port as valid
587
m_fields |= wxURI_PORT;
593
const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormalize)
595
wxASSERT(uri != NULL);
597
//copy of the uri - used for figuring out
598
//length of each component
599
const wxChar* uricopy = uri;
601
/// hier-part = "//" authority path-abempty
606
/// relative-part = "//" authority path-abempty
611
/// path-abempty = *( "/" segment )
612
/// path-absolute = "/" [ segment-nz *( "/" segment ) ]
613
/// path-noscheme = segment-nz-nc *( "/" segment )
614
/// path-rootless = segment-nz *( "/" segment )
615
/// path-empty = 0<pchar>
618
/// segment-nz = 1*pchar
619
/// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
620
/// ; non-zero-length segment without any colon ":"
622
/// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
623
if (*uri == wxT('/'))
627
while(*uri && *uri != wxT('#') && *uri != wxT('?'))
629
if( IsUnreserved(*uri) || IsSubDelim(*uri) ||
630
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/'))
632
else if (IsEscape(uri))
639
Escape(m_path, *uri++);
644
wxStringBufferLength theBuffer(m_path, m_path.length() + 1);
646
wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1);
648
Normalize(theBuffer, true);
649
theBuffer.SetLength(wxStrlen(theBuffer));
651
//mark the path as valid
652
m_fields |= wxURI_PATH;
654
else if(*uri) //Relative path
659
while(*uri && *uri != wxT('#') && *uri != wxT('?'))
661
if(IsUnreserved(*uri) || IsSubDelim(*uri) ||
662
*uri == wxT('@') || *uri == wxT('/'))
664
else if (IsEscape(uri))
671
Escape(m_path, *uri++);
676
while(*uri && *uri != wxT('#') && *uri != wxT('?'))
678
if(IsUnreserved(*uri) || IsSubDelim(*uri) ||
679
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/'))
681
else if (IsEscape(uri))
688
Escape(m_path, *uri++);
696
wxStringBufferLength theBuffer(m_path, m_path.length() + 1);
698
wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1);
700
Normalize(theBuffer);
701
theBuffer.SetLength(wxStrlen(theBuffer));
704
//mark the path as valid
705
m_fields |= wxURI_PATH;
713
const wxChar* wxURI::ParseQuery(const wxChar* uri)
715
wxASSERT(uri != NULL);
717
// query = *( pchar / "/" / "?" )
718
if (*uri == wxT('?'))
721
while(*uri && *uri != wxT('#'))
723
if (IsUnreserved(*uri) || IsSubDelim(*uri) ||
724
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?'))
726
else if (IsEscape(uri))
733
Escape(m_query, *uri++);
736
//mark the server as valid
737
m_fields |= wxURI_QUERY;
744
const wxChar* wxURI::ParseFragment(const wxChar* uri)
746
wxASSERT(uri != NULL);
748
// fragment = *( pchar / "/" / "?" )
749
if (*uri == wxT('#'))
754
if (IsUnreserved(*uri) || IsSubDelim(*uri) ||
755
*uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?'))
756
m_fragment += *uri++;
757
else if (IsEscape(uri))
759
m_fragment += *uri++;
760
m_fragment += *uri++;
761
m_fragment += *uri++;
764
Escape(m_fragment, *uri++);
767
//mark the server as valid
768
m_fields |= wxURI_FRAGMENT;
774
// ---------------------------------------------------------------------------
777
// Builds missing components of this uri from a base uri
779
// A version of the algorithm outlined in the RFC is used here
780
// (it is shown in comments)
782
// Note that an empty URI inherits all components
783
// ---------------------------------------------------------------------------
785
void wxURI::Resolve(const wxURI& base, int flags)
787
wxASSERT_MSG(!base.IsReference(),
788
wxT("wxURI to inherit from must not be a reference!"));
790
// If we arn't being strict, enable the older (pre-RFC2396)
791
// loophole that allows this uri to inherit other
792
// properties from the base uri - even if the scheme
794
if ( !(flags & wxURI_STRICT) &&
795
HasScheme() && base.HasScheme() &&
796
m_scheme == base.m_scheme )
798
m_fields -= wxURI_SCHEME;
802
// Do nothing if this is an absolute wxURI
803
// if defined(R.scheme) then
804
// T.scheme = R.scheme;
805
// T.authority = R.authority;
806
// T.path = remove_dot_segments(R.path);
807
// T.query = R.query;
813
//No scheme - inherit
814
m_scheme = base.m_scheme;
815
m_fields |= wxURI_SCHEME;
817
// All we need to do for relative URIs with an
818
// authority component is just inherit the scheme
819
// if defined(R.authority) then
820
// T.authority = R.authority;
821
// T.path = remove_dot_segments(R.path);
822
// T.query = R.query;
828
//No authority - inherit
829
if (base.HasUserInfo())
831
m_userinfo = base.m_userinfo;
832
m_fields |= wxURI_USERINFO;
835
m_server = base.m_server;
836
m_hostType = base.m_hostType;
837
m_fields |= wxURI_SERVER;
841
m_port = base.m_port;
842
m_fields |= wxURI_PORT;
846
// Simple path inheritance from base
849
// T.path = Base.path;
850
m_path = base.m_path;
851
m_fields |= wxURI_PATH;
854
// if defined(R.query) then
855
// T.query = R.query;
857
// T.query = Base.query;
861
m_query = base.m_query;
862
m_fields |= wxURI_QUERY;
867
// if (R.path starts-with "/") then
868
// T.path = remove_dot_segments(R.path);
870
// T.path = merge(Base.path, R.path);
871
// T.path = remove_dot_segments(T.path);
873
// T.query = R.query;
874
if (m_path[0u] != wxT('/'))
877
const wxChar* op = m_path.c_str();
878
const wxChar* bp = base.m_path.c_str() + base.m_path.Length();
880
//not a ending directory? move up
881
if (base.m_path[0] && *(bp-1) != wxT('/'))
882
UpTree(base.m_path, bp);
884
//normalize directories
885
while(*op == wxT('.') && *(op+1) == wxT('.') &&
886
(*(op+2) == '\0' || *(op+2) == wxT('/')) )
888
UpTree(base.m_path, bp);
896
m_path = base.m_path.substr(0, bp - base.m_path.c_str()) +
897
m_path.substr((op - m_path.c_str()), m_path.Length());
901
//T.fragment = R.fragment;
904
// ---------------------------------------------------------------------------
907
// Moves a URI path up a directory
908
// ---------------------------------------------------------------------------
911
void wxURI::UpTree(const wxChar* uristart, const wxChar*& uri)
913
if (uri != uristart && *(uri-1) == wxT('/'))
918
for(;uri != uristart; --uri)
920
if (*uri == wxT('/'))
928
if (uri == uristart && *uri == wxT('/'))
933
// ---------------------------------------------------------------------------
936
// Normalizes directories in-place
938
// I.E. ./ and . are ignored
940
// ../ and .. are removed if a directory is before it, along
941
// with that directory (leading .. and ../ are kept)
942
// ---------------------------------------------------------------------------
945
void wxURI::Normalize(wxChar* s, bool bIgnoreLeads)
955
if (*cp == wxT('.') && (*(cp+1) == wxT('/') || *(cp+1) == '\0')
956
&& (bp == cp || *(cp-1) == wxT('/')))
964
else if (*cp == wxT('.') && *(cp+1) == wxT('.') &&
965
(*(cp+2) == wxT('/') || *(cp+2) == '\0')
966
&& (bp == cp || *(cp-1) == wxT('/')))
968
//.. _or_ ../ - go up the tree
971
UpTree((const wxChar*)bp, (const wxChar*&)s);
978
else if (!bIgnoreLeads)
1003
// ---------------------------------------------------------------------------
1006
// Parses 1 to 4 hex values. Returns true if the first character of the input
1007
// string is a valid hex character. It is the caller's responsability to move
1008
// the input string back to its original position on failure.
1009
// ---------------------------------------------------------------------------
1011
bool wxURI::ParseH16(const wxChar*& uri)
1017
if(IsHex(*++uri) && IsHex(*++uri) && IsHex(*++uri))
1023
// ---------------------------------------------------------------------------
1026
// Parses a certain version of an IP address and moves the input string past
1027
// it. Returns true if the input string contains the proper version of an ip
1028
// address. It is the caller's responsability to move the input string back
1029
// to its original position on failure.
1030
// ---------------------------------------------------------------------------
1032
bool wxURI::ParseIPv4address(const wxChar*& uri)
1034
//IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1036
//dec-octet = DIGIT ; 0-9
1037
// / %x31-39 DIGIT ; 10-99
1038
// / "1" 2DIGIT ; 100-199
1039
// / "2" %x30-34 DIGIT ; 200-249
1040
// / "25" %x30-35 ; 250-255
1047
//each ip part must be between 0-255 (dupe of version in for loop)
1048
if( IsDigit(*++uri) && IsDigit(*++uri) &&
1049
//100 or less (note !)
1050
!( (*(uri-2) < wxT('2')) ||
1052
(*(uri-2) == wxT('2') &&
1053
(*(uri-1) < wxT('5') || (*(uri-1) == wxT('5') && *uri <= wxT('5')))
1061
if(IsDigit(*uri))++uri;
1063
//compilers should unroll this loop
1064
for(; iIPv4 < 4; ++iIPv4)
1066
if (*uri != wxT('.') || !IsDigit(*++uri))
1069
//each ip part must be between 0-255
1070
if( IsDigit(*++uri) && IsDigit(*++uri) &&
1071
//100 or less (note !)
1072
!( (*(uri-2) < wxT('2')) ||
1074
(*(uri-2) == wxT('2') &&
1075
(*(uri-1) < wxT('5') || (*(uri-1) == wxT('5') && *uri <= wxT('5')))
1082
if(IsDigit(*uri))++uri;
1088
bool wxURI::ParseIPv6address(const wxChar*& uri)
1090
// IPv6address = 6( h16 ":" ) ls32
1091
// / "::" 5( h16 ":" ) ls32
1092
// / [ h16 ] "::" 4( h16 ":" ) ls32
1093
// / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1094
// / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1095
// / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1096
// / [ *4( h16 ":" ) h16 ] "::" ls32
1097
// / [ *5( h16 ":" ) h16 ] "::" h16
1098
// / [ *6( h16 ":" ) h16 ] "::"
1100
size_t numPrefix = 0,
1103
bool bEndHex = false;
1105
for( ; numPrefix < 6; ++numPrefix)
1114
if(*uri != wxT(':'))
1120
if(!bEndHex && !ParseH16(uri))
1127
if (*uri == wxT(':'))
1129
if (*++uri != wxT(':'))
1139
if (*uri != wxT(':') || *(uri+1) != wxT(':'))
1144
while (*--uri != wxT(':')) {}
1147
const wxChar* uristart = uri;
1149
// ls32 = ( h16 ":" h16 ) / IPv4address
1150
if (ParseH16(uri) && *uri == wxT(':') && ParseH16(uri))
1155
if (ParseIPv4address(uri))
1167
maxPostfix = 4 - numPrefix;
1171
bool bAllowAltEnding = maxPostfix == 0;
1173
for(; maxPostfix != 0; --maxPostfix)
1175
if(!ParseH16(uri) || *uri != wxT(':'))
1181
const wxChar* uristart = uri;
1183
// ls32 = ( h16 ":" h16 ) / IPv4address
1184
if (ParseH16(uri) && *uri == wxT(':') && ParseH16(uri))
1189
if (ParseIPv4address(uri))
1194
if (!bAllowAltEnding)
1198
if(numPrefix <= 5 && ParseH16(uri))
1204
bool wxURI::ParseIPvFuture(const wxChar*& uri)
1206
// IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1207
if (*++uri != wxT('v') || !IsHex(*++uri))
1210
while (IsHex(*++uri)) {}
1212
if (*uri != wxT('.') || !(IsUnreserved(*++uri) || IsSubDelim(*uri) || *uri == wxT(':')))
1215
while(IsUnreserved(*++uri) || IsSubDelim(*uri) || *uri == wxT(':')) {}
1221
// ---------------------------------------------------------------------------
1224
// Converts a character into a numeric hexidecimal value, or 0 if the
1225
// passed in character is not a valid hex character
1226
// ---------------------------------------------------------------------------
1229
wxChar wxURI::CharToHex(const wxChar& c)
1231
if ((c >= wxT('A')) && (c <= wxT('Z'))) return wxChar(c - wxT('A') + 0x0A);
1232
if ((c >= wxT('a')) && (c <= wxT('z'))) return wxChar(c - wxT('a') + 0x0a);
1233
if ((c >= wxT('0')) && (c <= wxT('9'))) return wxChar(c - wxT('0') + 0x00);
1238
// ---------------------------------------------------------------------------
1241
// Returns true if the passed in character meets the criteria of the method
1242
// ---------------------------------------------------------------------------
1244
//! unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1245
bool wxURI::IsUnreserved (const wxChar& c)
1246
{ return IsAlpha(c) || IsDigit(c) ||
1250
c == wxT('~') //tilde
1254
bool wxURI::IsReserved (const wxChar& c)
1256
return IsGenDelim(c) || IsSubDelim(c);
1259
//! gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
1260
bool wxURI::IsGenDelim (const wxChar& c)
1262
return c == wxT(':') ||
1271
//! sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
1272
//! / "*" / "+" / "," / ";" / "="
1273
bool wxURI::IsSubDelim (const wxChar& c)
1275
return c == wxT('!') ||
1289
bool wxURI::IsHex(const wxChar& c)
1290
{ return IsDigit(c) || (c >= wxT('a') && c <= wxT('f')) || (c >= wxT('A') && c <= wxT('F')); }
1292
bool wxURI::IsAlpha(const wxChar& c)
1293
{ return (c >= wxT('a') && c <= wxT('z')) || (c >= wxT('A') && c <= wxT('Z')); }
1295
bool wxURI::IsDigit(const wxChar& c)
1296
{ return c >= wxT('0') && c <= wxT('9'); }