ROOT  6.06/09
Reference Guide
TUri.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Gerhard E. Bruckner 15/07/07
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TUri
13 
14 This class represents a RFC 3986 compatible URI.
15 See http://rfc.net/rfc3986.html.
16 It provides member functions to set and return the different
17 the different parts of an URI. The functionality is that of
18 a validating parser.
19 */
20 
21 #include <ctype.h> // for tolower()
22 #include "TUri.h"
23 #include "TObjArray.h"
24 #include "TObjString.h"
25 #include "TPRegexp.h"
26 
27 //RFC3986:
28 // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
29 const char* const kURI_pchar = "(?:[[:alpha:][:digit:]-._~!$&'()*+,;=:@]|%[0-9A-Fa-f][0-9A-Fa-f])";
30 
31 //unreserved characters, see chapter 2.3
32 const char* const kURI_unreserved = "[[:alpha:][:digit:]-._~]";
33 
34 // reserved characters, see chapter
35 // reserved = gen-delims / sub-delims
36 //const char* const kURI_reserved = "[:/?#[]@!$&'()*+,;=]";
37 
38 // gen-delims, see chapter 2.2
39 // delimiters of the generic URI components
40 //const char* const kURI_gendelims = "[:/?#[]@]";
41 
42 // sub-delims, see chapter 2.2
43 //const char* const kURI_subdelims = "[!$&'()*+,;=]";
44 
45 
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 /// Constructor that calls SetUri with a complete URI.
50 
51 TUri::TUri(const TString &uri)
52 {
53  SetUri(uri);
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Constructor that calls SetUri with a complete URI.
58 
59 TUri::TUri(const char *uri)
60 {
61  SetUri(uri);
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// TUri copy ctor.
66 
67 TUri::TUri(const TUri &uri) : TObject(uri)
68 {
69  fScheme = uri.fScheme;
70  fUserinfo = uri.fUserinfo;
71  fHost = uri.fHost;
72  fPort = uri.fPort;
73  fPath = uri.fPath;
74  fQuery = uri.fQuery;
75  fFragment = uri.fFragment;
76  fHasScheme = uri.fHasScheme;
78  fHasHost = uri.fHasHost;
79  fHasPort = uri.fHasPort;
80  fHasPath = uri.fHasPath;
81  fHasQuery = uri.fHasQuery;
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// TUri assignment operator.
87 
88 TUri &TUri::operator= (const TUri & rhs)
89 {
90  if (this != &rhs) {
92  fScheme = rhs.fScheme;
93  fUserinfo = rhs.fUserinfo;
94  fHost = rhs.fHost;
95  fPort = rhs.fPort;
96  fPath = rhs.fPath;
97  fQuery = rhs.fQuery;
98  fFragment = rhs.fFragment;
99  fHasScheme = rhs.fHasScheme;
101  fHasHost = rhs.fHasHost;
102  fHasPort = rhs.fHasPort;
103  fHasPath = rhs.fHasPath;
104  fHasQuery = rhs.fHasQuery;
106  }
107  return *this;
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 /// Implementation of a TUri Equivalence operator
112 /// that uses syntax-based normalisation
113 /// see chapter 6.2.2.
114 
115 Bool_t operator== (const TUri &u1, const TUri &u2)
116 {
117  // make temporary copies of the operands
118  TUri u11 = u1;
119  TUri u22 = u2;
120  // normalise them
121  u11.Normalise();
122  u22.Normalise();
123  // compare them as TStrings
124  return u11.GetUri() == u22.GetUri();
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// Returns the whole URI -
129 /// an implementation of chapter 5.3 component recomposition.
130 /// The result URI is composed out of the five basic parts.
131 /// ~~~ {.cpp}
132 /// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
133 /// hier-part = "//" authority path-abempty
134 /// / path-absolute
135 /// / path-rootless
136 /// / path-empty
137 /// ~~~
138 
139 const TString TUri::GetUri() const
140 {
141  TString result = "";
142  if (fHasScheme)
143  result = fScheme + ":";
144  result += GetHierPart();
145  if (fHasQuery)
146  result += TString("?") + fQuery;
147  if (fHasFragment)
148  result += TString("#") + fFragment;
149  return result;
150 }
151 
152 ////////////////////////////////////////////////////////////////////////////////
153 /// This functions implements the "remove_dot_segments" routine
154 /// of chapter 5.2.4 "for interpreting and removing the
155 /// special '.' and '..' complete path segments from a
156 /// referenced path".
157 
159 {
160  TString source = inp;
161  TString sink = TString(""); // sink buffer
162 
163  // Step 2 "While the source buffer is not empty, loop as follows:"
164  while (source.Length() > 0) {
165  // Rule 2.A
166  if (TPRegexp("^\\.\\.?/(.*)$").Substitute(source, "/$1") > 0)
167  continue;
168 
169  // Rule 2.B
170  if (TPRegexp("^/\\./(.*)$|^/\\.($)").Substitute(source, "/$1") > 0)
171  continue;
172 
173  // Rule 2.C
174  if (TPRegexp("^/\\.\\./(.*)$|^/\\.\\.($)").Substitute(source, "/$1") > 0) {
175  Ssiz_t last = sink.Last('/');
176  if (last == -1)
177  last = 0;
178  sink.Remove(last, sink.Length() - last);
179  continue;
180  }
181 
182  // Rule 2.D
183  if (source.CompareTo(".") == 0 || source.CompareTo("..") == 0) {
184  source.Remove(0, source.Length() - 11);
185  continue;
186  }
187 
188  // Rule 2.E
189  TPRegexp regexp = TPRegexp("^(/?[^/]*)(?:/|$)");
190  TObjArray *tokens = regexp.MatchS(source);
191  TString segment = ((TObjString*) tokens->At(1))->GetString();
192  sink += segment;
193  source.Remove(0, segment.Length());
194  delete tokens;
195  }
196 
197  // Step 3: return sink buffer
198  return sink;
199 }
200 
201 ////////////////////////////////////////////////////////////////////////////////
202 /// Returns kTRUE if instance qualifies as absolute-URI
203 /// absolute-URI = scheme ":" hier-part [ "?" query ]
204 /// cf. Appendix A.
205 
207 {
208  return (HasScheme() && HasHierPart() && !HasFragment());
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// Returns kTRUE if instance qualifies as relative-ref
213 /// relative-ref = relative-part [ "?" query ] [ "#" fragment ]
214 /// cf. Appendix A.
215 
217 {
218  return (!HasScheme() && HasRelativePart());
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 /// Returns kTRUE if instance qualifies as URI
223 /// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
224 /// cf. Appendix A.
225 
227 {
228  return (HasScheme() && HasHierPart());
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// Returns kTRUE if instance qualifies as URI-reference
233 /// URI-reference = URI / relative-ref
234 /// cf. Appendix A.
235 
237 {
238  return (IsUri() || IsRelative());
239 }
240 
241 ////////////////////////////////////////////////////////////////////////////////
242 /// Set scheme component of URI:
243 /// ~~~ {.cpp}
244 /// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
245 /// ~~~
246 
248 {
249  if (!scheme) {
250  fHasScheme = kFALSE;
251  return kTRUE;
252  }
253  if (IsScheme(scheme)) {
254  fScheme = scheme;
255  fHasScheme = kTRUE;
256  return kTRUE;
257  } else {
258  Error("SetScheme", "<scheme> component \"%s\" of URI is not compliant with RFC 3986.", scheme.Data());
259  return kFALSE;
260  }
261 }
262 
263 ////////////////////////////////////////////////////////////////////////////////
264 /// Returns kTRUE if string qualifies as URI scheme:
265 /// ~~~ {.cpp}
266 /// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
267 /// ~~~
268 
270 {
271  return TPRegexp(
272  "^[[:alpha:]][[:alpha:][:digit:]+-.]*$"
273  ).Match(string);
274 }
275 
276 ////////////////////////////////////////////////////////////////////////////////
277 /// Returns the authority part of the instance:
278 /// ~~~ {.cpp}
279 /// authority = [ userinfo "@" ] host [ ":" port ]
280 /// ~~~
281 
283 {
284  TString authority = fHasUserinfo ? fUserinfo + "@" + fHost : fHost;
285  if (fHasPort && !fPort.IsNull())
286  // add port only if not empty
287  authority += TString(":") + TString(fPort);
288  return (authority);
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Set query component of URI:
293 /// ~~~ {.cpp}
294 /// query = *( pchar / "/" / "?" )
295 /// ~~~
296 
298 {
299  if (!query) {
300  fHasQuery = kFALSE;
301  return kTRUE;
302  }
303  if (IsQuery(query)) {
304  fQuery = query;
305  fHasQuery = kTRUE;
306  return kTRUE;
307  } else {
308  Error("SetQuery", "<query> component \"%s\" of URI is not compliant with RFC 3986.", query.Data());
309  return kFALSE;
310  }
311 }
312 
313 ////////////////////////////////////////////////////////////////////////////////
314 /// Returns kTRUE if string qualifies as URI query:
315 /// ~~~ {.cpp}
316 /// query = *( pchar / "/" / "?" )
317 /// ~~~
318 
320 {
321  return TPRegexp(
322  TString("^([/?]|") + kURI_pchar + ")*$"
323  ).Match(string);
324 }
325 
326 ////////////////////////////////////////////////////////////////////////////////
327 /// Set authority part of URI:
328 /// ~~~ {.cpp}
329 /// authority = [ userinfo "@" ] host [ ":" port ]
330 /// ~~~
331 ///
332 /// Split into components {userinfo@, host, :port},
333 /// remember that according to the RFC, it is necessary to
334 /// distinguish between missing component (no delimiter)
335 /// and empty component (delimiter present).
336 
338 {
339  if (authority.IsNull()) {
341  fHasHost = kFALSE;
342  fHasPort = kFALSE;
343  return kTRUE;
344  }
345  TPRegexp regexp = TPRegexp("^(?:(.*@))?([^:]*)((?::.*)?)$");
346  TObjArray *tokens = regexp.MatchS(authority);
347 
348  if (tokens->GetEntries() != 4) {
349  Error("SetAuthority", "<authority> component \"%s\" of URI is not compliant with RFC 3986.", authority.Data());
350  return kFALSE;
351  }
352 
353  Bool_t valid = kTRUE;
354 
355  // handle userinfo
356  TString userinfo = ((TObjString*) tokens->At(1))->GetString();
357  if (userinfo.EndsWith("@")) {
358  userinfo.Remove(TString::kTrailing, '@');
359  valid &= SetUserInfo(userinfo);
360  }
361 
362  // handle host
363  TString host = ((TObjString*) tokens->At(2))->GetString();
364  valid &= SetHost(host);
365 
366  // handle port
367  TString port = ((TObjString*) tokens->At(3))->GetString();
368  if (port.BeginsWith(":")) {
369  port.Remove(TString::kLeading, ':');
370  valid &= SetPort(port);
371  }
372 
373  return valid;
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Returns kTRUE if string qualifies as valid URI authority:
378 /// ~~~ {.cpp}
379 /// authority = [ userinfo "@" ] host [ ":" port ]
380 /// ~~~
381 
383 {
384  // split into parts {userinfo, host, port}
385  TPRegexp regexp = TPRegexp("^(?:(.*)@)?([^:]*)(?::(.*))?$");
386  TObjArray *tokens = regexp.MatchS(string);
387  TString userinfo = ((TObjString*) tokens->At(1))->GetString();
388  TString host = ((TObjString*) tokens->At(2))->GetString();
389  TString port;
390  // port is optional
391  if (tokens->GetEntries() == 4)
392  port = ((TObjString*) tokens->At(3))->GetString();
393  else
394  port = "";
395  return (IsHost(host) && IsUserInfo(userinfo) && IsPort(port));
396 }
397 
398 ////////////////////////////////////////////////////////////////////////////////
399 /// Set userinfo component of URI:
400 /// ~~~ {.cpp}
401 /// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
402 /// ~~~
403 
405 {
406  if (userinfo.IsNull()) {
408  return kTRUE;
409  }
410  if (IsUserInfo(userinfo)) {
411  fUserinfo = userinfo;
413  return kTRUE;
414  } else {
415  Error("SetUserInfo", "<userinfo> component \"%s\" of URI is not compliant with RFC 3986.", userinfo.Data());
416  return kFALSE;
417  }
418 }
419 
420 ////////////////////////////////////////////////////////////////////////////////
421 /// Return kTRUE is string qualifies as valid URI userinfo:
422 /// ~~~ {.cpp}
423 /// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
424 /// ~~~
425 /// this equals to pchar without the '@' character
426 
428 {
429  return (TPRegexp(
430  "^" + TString(kURI_pchar) + "*$"
431  ).Match(string) > 0 && !TString(string).Contains("@"));
432 }
433 
434 ////////////////////////////////////////////////////////////////////////////////
435 /// Set host component of URI:
436 /// ~~~ {.cpp}
437 /// RFC 3986: host = IP-literal / IPv4address / reg-name
438 /// implemented: host = IPv4address / reg-name
439 /// ~~~
440 
442 {
443  if (IsHost(host)) {
444  fHost = host;
445  fHasHost = kTRUE;
446  return kTRUE;
447  } else {
448  Error("SetHost", "<host> component \"%s\" of URI is not compliant with RFC 3986.", host.Data());
449  return kFALSE;
450  }
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Set port component of URI:
455 /// ~~~ {.cpp}
456 /// port = *DIGIT
457 /// ~~~
458 
460 {
461  if (IsPort(port)) {
462  fPort = port;
463  fHasPort = kTRUE;
464  return kTRUE;
465  }
466  Error("SetPort", "<port> component \"%s\" of URI is not compliant with RFC 3986.", port.Data());
467  return kFALSE;
468 }
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// Set path component of URI:
472 /// ~~~ {.cpp}
473 /// path = path-abempty ; begins with "/" or is empty
474 /// / path-absolute ; begins with "/" but not "//"
475 /// / path-noscheme ; begins with a non-colon segment
476 /// / path-rootless ; begins with a segment
477 /// / path-empty ; zero characters
478 /// ~~~
479 
481 {
482  if (IsPath(path)) {
483  fPath = path;
484  fHasPath = kTRUE;
485  return kTRUE;
486  }
487  Error("SetPath", "<path> component \"%s\" of URI is not compliant with RFC 3986.", path.Data());
488  return kFALSE;
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Set fragment component of URI:
493 /// ~~~ {.cpp}
494 /// fragment = *( pchar / "/" / "?" )
495 /// ~~~
496 
498 {
499  if (IsFragment(fragment)) {
500  fFragment = fragment;
502  return kTRUE;
503  } else {
504  Error("SetFragment", "<fragment> component \"%s\" of URI is not compliant with RFC 3986.", fragment.Data());
505  return kFALSE;
506  }
507 }
508 
509 ////////////////////////////////////////////////////////////////////////////////
510 /// Returns kTRUE if string qualifies as valid fragment component
511 /// ~~~ {.cpp}
512 /// fragment = *( pchar / "/" / "?" )
513 /// ~~~
514 
516 {
517  return (TPRegexp(
518  "^(" + TString(kURI_pchar) + "|[/?])*$"
519  ).Match(string) > 0);
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 /// Display function,
524 /// - option "d" .. debug output
525 /// - anything else .. simply print URI.
526 
527 void TUri::Print(Option_t *option) const
528 {
529  if (strcmp(option, "d") != 0) {
530  Printf("%s", GetUri().Data());
531  return ;
532  }
533  // debug output
534  Printf("URI: <%s>", GetUri().Data());
535  Printf("(%c) |--scheme---------<%s>", fHasScheme ? 't' : 'f', fScheme.Data());
536  Printf(" |--hier-----------<%s>", GetHierPart().Data());
537  Printf("(%c) |--authority------<%s>", HasAuthority() ? 't' : 'f', GetAuthority().Data());
538  Printf("(%c) |--userinfo---<%s>", fHasUserinfo ? 't' : 'f', fUserinfo.Data());
539  Printf("(%c) |--host-------<%s>", fHasHost ? 't' : 'f', fHost.Data());
540  Printf("(%c) |--port-------<%s>", fHasPort ? 't' : 'f', fPort.Data());
541  Printf("(%c) |--path-------<%s>", fHasPath ? 't' : 'f', fPath.Data());
542  Printf("(%c) |--query------<%s>", fHasQuery ? 't' : 'f', fQuery.Data());
543  Printf("(%c) |--fragment---<%s>", fHasFragment ? 't' : 'f', fFragment.Data());
544  printf("path flags: ");
545  if (IsPathAbempty(fPath))
546  printf("abempty ");
547  if (IsPathAbsolute(fPath))
548  printf("absolute ");
549  if (IsPathRootless(fPath))
550  printf("rootless ");
551  if (IsPathEmpty(fPath))
552  printf("empty ");
553  printf("\nURI flags: ");
554  if (IsAbsolute())
555  printf("absolute-URI ");
556  if (IsRelative())
557  printf("relative-ref ");
558  if (IsUri())
559  printf("URI ");
560  if (IsReference())
561  printf("URI-reference ");
562  printf("\n");
563 }
564 
565 ////////////////////////////////////////////////////////////////////////////////
566 /// Initialize this URI object.
567 /// Set all TString members to empty string,
568 /// set all Bool_t members to kFALSE.
569 
571 {
572  fScheme = "";
573  fUserinfo = "";
574  fHost = "";
575  fPort = "";
576  fPath = "";
577  fQuery = "";
578  fFragment = "";
579 
580  fHasScheme = kFALSE;
582  fHasHost = kFALSE;
583  fHasPort = kFALSE;
584  fHasPath = kFALSE;
585  fHasQuery = kFALSE;
587 }
588 
589 ////////////////////////////////////////////////////////////////////////////////
590 /// Parse URI and set the member variables accordingly,
591 /// returns kTRUE if URI validates, and kFALSE otherwise:
592 /// ~~~ {.cpp}
593 /// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
594 /// hier-part = "//" authority path-abempty
595 /// / path-absolute
596 /// / path-rootless
597 /// / path-empty
598 /// ~~~
599 
601 {
602  // Reset member variables
603  Reset();
604 
605  // regular expression taken from appendix B
606  // reference points 12 3 4 5 6 7 8 9
607  TPRegexp regexp = TPRegexp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)([?]([^#]*))?(#(.*))?");
608  TObjArray *tokens = regexp.MatchS(uri);
609 
610  // collect bool values to see if all setters succeed
611  Bool_t valid = kTRUE;
612  //tokens->Print();
613  switch (tokens->GetEntries()) {
614  case 10:
615  // URI contains fragment delimiter '#'
616  valid &= SetFragment(((TObjString*) tokens->At(9))->GetString());
617  // fallthrough
618 
619  case 8:
620  // URI does not contain a fragment delimiter
621  // if there is a query delimiter '?', set query
622  if (!((TString)((TObjString*) tokens->At(6))->GetString()).IsNull())
623  valid &= SetQuery(((TObjString*) tokens->At(7))->GetString());
624  // fallthrough
625 
626  case 6:
627  // URI does not contain fragment or query delimiters
628  valid &= SetPath(((TObjString*) tokens->At(5))->GetString());
629  // if there is an authority delimiter '//', set authority
630  if (!((TString)((TObjString*) tokens->At(3))->GetString()).IsNull())
631  valid &= SetAuthority(((TObjString*) tokens->At(4))->GetString());
632  // if there is a scheme delimiter ':', set scheme
633  if (!((TString)((TObjString*) tokens->At(1))->GetString()).IsNull())
634  valid &= SetScheme(((TObjString*) tokens->At(2))->GetString());
635  break;
636 
637  default:
638  // regular expression did not match
639  Error("SetUri", "URI \"%s\" is not is not compliant with RFC 3986.", uri.Data());
640  valid = kFALSE;
641  }
642 
643  // reset member variables once again, if one at least setter failed
644  if (!valid)
645  Reset();
646 
647  delete tokens;
648  return valid;
649 }
650 
651 ////////////////////////////////////////////////////////////////////////////////
652 /// ~~~ {.cpp}
653 /// hier-part = "//" authority path-abempty
654 /// / path-absolute
655 /// / path-rootless
656 /// / path-empty
657 /// ~~~
658 
660 {
661  if (HasAuthority() && IsPathAbempty(fPath))
662  return (TString("//") + GetAuthority() + fPath);
663  else
664  return fPath;
665 }
666 
667 ////////////////////////////////////////////////////////////////////////////////
668 /// relative-part = "//" authority path-abempty
669 /// ~~~ {.cpp}
670 /// / path-absolute
671 /// / path-noscheme
672 /// / path-empty
673 /// ~~~
674 
676 {
677  if (HasAuthority() && IsPathAbempty(fPath))
678  return (TString("//") + GetAuthority() + fPath);
679  else
680  return fPath;
681 }
682 
683 ////////////////////////////////////////////////////////////////////////////////
684 /// returns hier-part component of URI
685 /// ~~~ {.cpp}
686 /// hier-part = "//" authority path-abempty
687 /// / path-absolute
688 /// / path-rootless
689 /// / path-empty
690 /// ~~~
691 
693 {
694  /* if ( IsPathAbsolute(hier) || IsPathRootless(hier) || IsPathEmpty(hier) ) {
695  SetPath (hier);
696  return kTRUE;
697  }
698  */
699 
700  // reference points: 1 2 3
701  TPRegexp regexp = TPRegexp("^(//([^/?#]*))?([^?#]*)$");
702  TObjArray *tokens = regexp.MatchS(hier);
703 
704  if (tokens->GetEntries() == 0) {
705  Error("SetHierPart", "<hier-part> component \"%s\" of URI is not compliant with RFC 3986.", hier.Data());
706  delete tokens;
707  return false;
708  }
709 
710  TString delm = ((TObjString*) tokens->At(1))->GetString();
711  TString auth = ((TObjString*) tokens->At(2))->GetString();
712  TString path = ((TObjString*) tokens->At(3))->GetString();
713 
714  Bool_t valid = kTRUE;
715 
716  if (!delm.IsNull() && IsPathAbempty(path)) {
717  // URI contains an authority delimiter '//' ...
718  valid &= SetAuthority(auth);
719  valid &= SetPath(path);
720  } else {
721  // URI does not contain an authority
722  if (IsPathAbsolute(path) || IsPathRootless(path) || IsPathEmpty(path))
723  valid &= SetPath(path);
724  else {
725  valid = kFALSE;
726  Error("SetHierPart", "<hier-part> component \"%s\" of URI is not compliant with RFC 3986.", hier.Data());
727  }
728  }
729  delete tokens;
730  return valid;
731 }
732 
733 ////////////////////////////////////////////////////////////////////////////////
734 /// Returns kTRUE if string qualifies as hier-part:
735 /// ~~~ {.cpp}
736 /// hier-part = "//" authority path-abempty
737 /// / path-absolute
738 /// / path-rootless
739 /// / path-empty
740 /// ~~~
741 
743 {
744  // use functionality of SetHierPart
745  // in order to avoid duplicate code
746  TUri uri;
747  return (uri.SetHierPart(string));
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Returns kTRUE is string qualifies as relative-part:
752 /// ~~~ {.cpp}
753 /// relative-part = "//" authority path-abempty
754 /// / path-absolute
755 /// / path-noscheme
756 /// / path-empty
757 /// ~~~
758 
760 {
761  // use functionality of SetRelativePart
762  // in order to avoid duplicate code
763  TUri uri;
764  return (uri.SetRelativePart(string));
765 }
766 
767 ////////////////////////////////////////////////////////////////////////////////
768 /// Returns kTRUE is string qualifies as relative-part:
769 /// ~~~ {.cpp}
770 /// relative-part = "//" authority path-abempty
771 /// / path-absolute
772 /// / path-noscheme
773 /// / path-empty
774 /// ~~~
775 
777 {
778  // reference points: 1 2 3
779  TPRegexp regexp = TPRegexp("^(//([^/?#]*))?([^?#]*)$");
780  TObjArray *tokens = regexp.MatchS(relative);
781 
782  if (tokens->GetEntries() == 0) {
783  Error("SetRelativePath", "<relative-part> component \"%s\" of URI is not compliant with RFC 3986.", relative.Data());
784  delete tokens;
785  return false;
786  }
787  TString delm = ((TObjString*) tokens->At(1))->GetString();
788  TString auth = ((TObjString*) tokens->At(2))->GetString();
789  TString path = ((TObjString*) tokens->At(3))->GetString();
790 
791  Bool_t valid = kTRUE;
792 
793  if (!delm.IsNull() && IsPathAbempty(path)) {
794  // URI contains an authority delimiter '//' ...
795  valid &= SetAuthority(auth);
796  valid &= SetPath(path);
797  } else {
798  // URI does not contain an authority
799  if (IsPathAbsolute(path) || IsPathNoscheme(path) || IsPathEmpty(path))
800  valid &= SetPath(path);
801  else {
802  valid = kFALSE;
803  Error("SetRelativePath", "<relative-part> component \"%s\" of URI is not compliant with RFC 3986.", relative.Data());
804  }
805  }
806  delete tokens;
807  return valid;
808 }
809 
810 ////////////////////////////////////////////////////////////////////////////////
811 /// Percent-encode and return the given string according to RFC 3986
812 /// in principle, this function cannot fail or produce an error.
813 
814 const TString TUri::PctEncode(const TString &source)
815 {
816  TString sink = "";
817  // iterate through source
818  for (Int_t i = 0; i < source.Length(); i++) {
819  if (IsUnreserved(TString(source(i)))) {
820  // unreserved character -> copy
821  sink = sink + source[i];
822  } else {
823  // reserved character -> encode to 2 digit hex
824  // preceded by '%'
825  char buffer[4];
826  sprintf(buffer, "%%%02X", source[i]);
827  sink = sink + buffer;
828  }
829  }
830  return sink;
831 }
832 
833 ////////////////////////////////////////////////////////////////////////////////
834 /// Returns kTRUE if string qualifies as valid host component:
835 /// host = IP-literal / IPv4address / reg-name
836 /// implemented: host = IPv4address / reg-name
837 
839 {
840  return (IsRegName(string) || IsIpv4(string));
841 }
842 
843 ////////////////////////////////////////////////////////////////////////////////
844 /// Returns kTRUE if string qualifies as valid path component:
845 /// ~~~ {.cpp}
846 /// path = path-abempty ; begins with "/" or is empty
847 /// / path-absolute ; begins with "/" but not "//"
848 /// / path-noscheme ; begins with a non-colon segment
849 /// / path-rootless ; begins with a segment
850 /// / path-empty ; zero characters
851 /// ~~~
852 
854 {
855  return (IsPathAbempty(string) ||
856  IsPathAbsolute(string) ||
857  IsPathNoscheme(string) ||
858  IsPathRootless(string) ||
859  IsPathEmpty(string));
860 }
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// Returns kTRUE if string qualifies as valid path-abempty component:
864 /// ~~~ {.cpp}
865 /// path-abempty = *( "/" segment )
866 /// segment = *pchar
867 /// ~~~
868 
870 {
871  return (TPRegexp(
872  TString("^(/") + TString(kURI_pchar) + "*)*$"
873  ).Match(string) > 0);
874 }
875 
876 ////////////////////////////////////////////////////////////////////////////////
877 /// Returns kTRUE if string qualifies as valid path-absolute component
878 /// ~~~ {.cpp}
879 /// path-absolute = "/" [ segment-nz *( "/" segment ) ]
880 /// segment-nz = 1*pchar
881 /// segment = *pchar
882 /// ~~~
883 
885 {
886  return (TPRegexp(
887  TString("^/(") + TString(kURI_pchar) + "+(/" + TString(kURI_pchar) + "*)*)?$"
888  ).Match(string) > 0);
889 }
890 
891 ////////////////////////////////////////////////////////////////////////////////
892 /// Returns kTRUE if string qualifies as valid path-noscheme component:
893 /// ~~~ {.cpp}
894 /// path-noscheme = segment-nz-nc *( "/" segment )
895 /// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
896 /// segment = *pchar
897 /// ~~~
898 
900 {
901  return (TPRegexp(
902  TString("^(([[:alpha:][:digit:]-._~!$&'()*+,;=@]|%[0-9A-Fa-f][0-9A-Fa-f])+)(/") + TString(kURI_pchar) + "*)*$"
903  ).Match(string) > 0);
904 }
905 
906 ////////////////////////////////////////////////////////////////////////////////
907 /// Returns kTRUE if string qualifies as valid path-rootless component:
908 /// ~~~ {.cpp}
909 /// path-rootless = segment-nz *( "/" segment )
910 /// ~~~
911 
913 {
914  return TPRegexp(
915  TString("^") + TString(kURI_pchar) + "+(/" + TString(kURI_pchar) + "*)*$"
916  ).Match(string);
917 }
918 
919 ////////////////////////////////////////////////////////////////////////////////
920 /// Returns kTRUE if string qualifies as valid path-empty component:
921 /// ~~~ {.cpp}
922 /// path-empty = 0<pchar>
923 /// ~~~
924 
926 {
927  return TString(string).IsNull();
928 }
929 
930 ////////////////////////////////////////////////////////////////////////////////
931 /// Returns kTRUE if string qualifies as valid port component:
932 /// ~~~ {.cpp}
933 /// RFC 3986: port = *DIGIT
934 /// ~~~
935 
937 {
938  return (TPRegexp("^[[:digit:]]*$").Match(string) > 0);
939 }
940 
941 ////////////////////////////////////////////////////////////////////////////////
942 /// Returns kTRUE if string qualifies as valid reg-name:
943 /// ~~~ {.cpp}
944 /// reg-name = *( unreserved / pct-encoded / sub-delims )
945 /// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
946 /// / "*" / "+" / "," / ";" / "="
947 /// ~~~
948 
950 {
951  return (TPRegexp(
952  "^([[:alpha:][:digit:]-._~!$&'()*+,;=]|%[0-9A-Fa-f][0-9A-Fa-f])*$").Match(string) > 0);
953 }
954 
955 ////////////////////////////////////////////////////////////////////////////////
956 /// Returns kTRUE, if string holds a valid IPv4 address
957 /// currently only decimal variant supported.
958 /// Existence of leading 0s or numeric range remains unchecked
959 /// IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet.
960 
962 {
963  return (TPRegexp(
964  "^([[:digit:]]{1,3}[.]){3}[[:digit:]]{1,3}$").Match(string) > 0);
965 }
966 
967 ////////////////////////////////////////////////////////////////////////////////
968 /// Returns kTRUE, if the given string does not contain
969 /// RFC 3986 reserved characters
970 /// ~~~ {.cpp}
971 /// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
972 /// ~~~
973 
975 {
976  return (TPRegexp(
977  "^" + TString(kURI_unreserved) + "*$").Match(string) > 0);
978 }
979 
980 ////////////////////////////////////////////////////////////////////////////////
981 /// Syntax based normalisation according to
982 /// RFC chapter 6.2.2.
983 
985 {
986  // case normalisation of host and scheme
987  // cf. chapter 6.2.2.1
988  fScheme.ToLower();
989  if (fHasHost) {
990  TString host = GetHost();
991  host.ToLower();
992  SetHost(host);
993  }
994  // percent-encoding normalisation (6.2.2.2) for
995  // userinfo, host (reg-name), path, query, fragment
1001 
1002  // path segment normalisation (6.2.2.3)
1003  if (fHasPath)
1005 }
1006 
1007 ////////////////////////////////////////////////////////////////////////////////
1008 /// Percent-decode the given string according to chapter 2.1
1009 /// we assume a valid pct-encoded string.
1010 
1012 {
1013  TString sink = "";
1014  Int_t i = 0;
1015  while (i < source.Length()) {
1016  if (source[i] == '%') {
1017  if (source.Length() < i+2) {
1018  // abort if out of bounds
1019  return sink;
1020  }
1021  // two hex digits follow -> decode to ASCII
1022  // upper nibble, bits 4-7
1023  char c1 = tolower(source[i + 1]) - '0';
1024  if (c1 > 9) // a-f
1025  c1 -= 39;
1026  // lower nibble, bits 0-3
1027  char c0 = tolower(source[i + 2]) - '0';
1028  if (c0 > 9) // a-f
1029  c0 -= 39;
1030  char decoded = c1 << 4 | c0;
1031  if (TPRegexp(kURI_unreserved).Match(decoded) > 0) {
1032  // we have an unreserved character -> store decoded version
1033  sink = sink + decoded;
1034  } else {
1035  // this is a reserved character
1036  TString pct = source(i,3);
1037  pct.ToUpper();
1038  sink = sink + pct;
1039  }
1040  // advance 2 characters
1041  i += 2;
1042  } else {
1043  // regular character -> copy
1044  sink = sink + source[i];
1045  }
1046  i++;
1047  }
1048  return sink;
1049 }
1050 
1051 ////////////////////////////////////////////////////////////////////////////////
1052 /// Normalise the percent-encoded parts of the string
1053 /// i.e. uppercase the hexadecimal digits
1054 /// %[:alpha:][:alpha:] -> %[:ALPHA:][:ALPHA:]
1055 
1056 TString const TUri::PctNormalise(const TString &source)
1057 {
1058  TString sink = "";
1059  Int_t i = 0;
1060  while (i < source.Length()) {
1061  if (source[i] == '%') {
1062  if (source.Length() < i+2) {
1063  // abort if out of bounds
1064  return sink;
1065  }
1066  TString pct = source(i,3);
1067  // uppercase the pct part
1068  pct.ToUpper();
1069  sink = sink + pct;
1070  // advance 2 characters
1071  i += 2;
1072  } else {
1073  // regular character -> copy
1074  sink = sink + source[i];
1075  }
1076  i++;
1077  }
1078  return sink;
1079 }
1080 
1081 ////////////////////////////////////////////////////////////////////////////////
1082 /// Percent-decode the given string according to chapter 2.1
1083 /// we assume a valid pct-encoded string.
1084 
1085 TString const TUri::PctDecode(const TString &source)
1086 {
1087  TString sink = "";
1088  Int_t i = 0;
1089  while (i < source.Length()) {
1090  if (source[i] == '%') {
1091  if (source.Length() < i+2) {
1092  // abort if out of bounds
1093  return sink;
1094  }
1095  // two hex digits follow -> decode to ASCII
1096  // upper nibble, bits 4-7
1097  char c1 = tolower(source[i + 1]) - '0';
1098  if (c1 > 9) // a-f
1099  c1 -= 39;
1100  // lower nibble, bits 0-3
1101  char c0 = tolower(source[i + 2]) - '0';
1102  if (c0 > 9) // a-f
1103  c0 -= 39;
1104  sink = sink + (char)(c1 << 4 | c0);
1105  // advance 2 characters
1106  i += 2;
1107  } else {
1108  // regular character -> copy
1109  sink = sink + source[i];
1110  }
1111  i++;
1112  }
1113  return sink;
1114 }
1115 
1116 ////////////////////////////////////////////////////////////////////////////////
1117 /// Transform a URI reference into its target URI using
1118 /// given a base URI.
1119 /// This is an implementation of the pseudocode in chapter 5.2.2.
1120 
1121 TUri TUri::Transform(const TUri &reference, const TUri &base)
1122 {
1123  TUri target;
1124  if (reference.HasScheme()) {
1125  target.SetScheme(reference.GetScheme());
1126  if (reference.HasAuthority())
1127  target.SetAuthority(reference.GetAuthority());
1128  if (reference.HasPath())
1129  target.SetPath(RemoveDotSegments(reference.GetPath()));
1130  if (reference.HasQuery())
1131  target.SetQuery(reference.GetQuery());
1132  } else {
1133  if (reference.HasAuthority()) {
1134  target.SetAuthority(reference.GetAuthority());
1135  if (reference.HasPath())
1136  target.SetPath(RemoveDotSegments(reference.GetPath()));
1137  if (reference.HasQuery())
1138  target.SetQuery(reference.GetQuery());
1139  } else {
1140  if (reference.GetPath().IsNull()) {
1141  target.SetPath(base.GetPath());
1142  if (reference.HasQuery()) {
1143  target.SetQuery(reference.GetQuery());
1144  } else {
1145  if (base.HasQuery())
1146  target.SetQuery(base.GetQuery());
1147  }
1148  } else {
1149  if (reference.GetPath().BeginsWith("/")) {
1150  target.SetPath(RemoveDotSegments(reference.GetPath()));
1151  } else {
1152  target.SetPath(RemoveDotSegments(MergePaths(reference, base)));
1153  }
1154  if (reference.HasQuery())
1155  target.SetQuery(reference.GetQuery());
1156  }
1157  if (base.HasAuthority())
1158  target.SetAuthority(base.GetAuthority());
1159  }
1160  if (base.HasScheme())
1161  target.SetScheme(base.GetScheme());
1162  }
1163  if (reference.HasFragment())
1164  target.SetFragment(reference.GetFragment());
1165  return target;
1166 }
1167 
1168 ////////////////////////////////////////////////////////////////////////////////
1169 /// RFC 3986, 5.3.2.
1170 /// If the base URI has a defined authority component and an empty
1171 /// path, then return a string consisting of "/" concatenated with the
1172 /// reference's path; otherwise,
1173 /// return a string consisting of the reference's path component
1174 /// appended to all but the last segment of the base URI's path (i.e.,
1175 /// excluding any characters after the right-most "/" in the base URI
1176 /// path, or excluding the entire base URI path if it does not contain
1177 /// any "/" characters).
1178 
1179 const TString TUri::MergePaths(const TUri &reference, const TUri &base)
1180 {
1181  TString result = "";
1182  if (base.HasAuthority() && base.GetPath().IsNull()) {
1183  result = TString("/") + reference.GetPath();
1184  } else {
1185  TString basepath = base.GetPath();
1186  Ssiz_t last = basepath.Last('/');
1187  if (last == -1)
1188  result = reference.GetPath();
1189  else
1190  result = basepath(0, last + 1) + reference.GetPath();
1191  }
1192  return result;
1193 }
Bool_t fHasUserinfo
Definition: TUri.h:68
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
An array of TObjects.
Definition: TObjArray.h:39
static Bool_t IsIpv4(const TString &)
Returns kTRUE, if string holds a valid IPv4 address currently only decimal variant supported...
Definition: TUri.cxx:961
static Bool_t IsAuthority(const TString &)
Returns kTRUE if string qualifies as valid URI authority: authority = [ userinfo "@" ] host [ ":" p...
Definition: TUri.cxx:382
const TString GetScheme() const
Definition: TUri.h:84
const char *const kURI_unreserved
Definition: TUri.cxx:32
const char *const kURI_pchar
Definition: TUri.cxx:29
const TString GetFragment() const
Definition: TUri.h:93
Bool_t SetPath(const TString &path)
Set path component of URI: path = path-abempty ; begins with "/" or is empty ...
Definition: TUri.cxx:480
Ssiz_t Length() const
Definition: TString.h:390
Collectable string class.
Definition: TObjString.h:32
static Bool_t IsRegName(const TString &)
Returns kTRUE if string qualifies as valid reg-name: reg-name = *( unreserved / pct-encoded / sub-...
Definition: TUri.cxx:949
const TString GetHierPart() const
hier-part = "//" authority path-abempty / path-absolute / path-rootless ...
Definition: TUri.cxx:659
const char Option_t
Definition: RtypesCore.h:62
void Normalise()
Syntax based normalisation according to RFC chapter 6.2.2.
Definition: TUri.cxx:984
const TString GetHost() const
Definition: TUri.h:89
TCanvas * c1
Definition: legend1.C:2
Bool_t SetHierPart(const TString &hier)
returns hier-part component of URI hier-part = "//" authority path-abempty / path-absol...
Definition: TUri.cxx:692
Bool_t fHasQuery
Definition: TUri.h:72
TObjArray * MatchS(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
Returns a TObjArray of matched substrings as TObjString's.
Definition: TPRegexp.cxx:366
TString fUserinfo
Definition: TUri.h:60
Bool_t fHasScheme
Definition: TUri.h:67
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1101
static Bool_t IsUserInfo(const TString &)
Return kTRUE is string qualifies as valid URI userinfo: userinfo = *( unreserved / pct-encoded / s...
Definition: TUri.cxx:427
Bool_t SetUserInfo(const TString &userinfo)
Set userinfo component of URI: userinfo = *( unreserved / pct-encoded / sub-delims / ":" )...
Definition: TUri.cxx:404
const TString GetAuthority() const
Returns the authority part of the instance: authority = [ userinfo "@" ] host [ ":" port ]...
Definition: TUri.cxx:282
Basic string class.
Definition: TString.h:137
Bool_t HasAuthority() const
Definition: TUri.h:97
Bool_t SetPort(const TString &port)
Set port component of URI: port = *DIGIT.
Definition: TUri.cxx:459
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1088
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Int_t Substitute(TString &s, const TString &replace, const TString &mods="", Int_t start=0, Int_t nMatchMax=10)
Substitute replaces the string s by a new string in which matching patterns are replaced by the repla...
Definition: TPRegexp.cxx:468
This class represents a RFC 3986 compatible URI.
Definition: TUri.h:39
Bool_t IsReference() const
Returns kTRUE if instance qualifies as URI-reference URI-reference = URI / relative-ref cf...
Definition: TUri.cxx:236
void Print(Option_t *option="") const
Display function,.
Definition: TUri.cxx:527
TString fPath
Definition: TUri.h:63
Bool_t fHasPort
Definition: TUri.h:70
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
static const TString PctDecode(const TString &source)
Percent-decode the given string according to chapter 2.1 we assume a valid pct-encoded string...
Definition: TUri.cxx:1085
Bool_t SetQuery(const TString &path)
Set query component of URI: query = *( pchar / "/" / "?" ).
Definition: TUri.cxx:297
TUri & operator=(const TUri &rhs)
TUri assignment operator.
Definition: TUri.cxx:88
const char * Data() const
Definition: TString.h:349
Bool_t IsUri() const
Returns kTRUE if instance qualifies as URI URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] ...
Definition: TUri.cxx:226
static const TString PctDecodeUnreserved(const TString &source)
Percent-decode the given string according to chapter 2.1 we assume a valid pct-encoded string...
Definition: TUri.cxx:1011
Bool_t SetUri(const TString &uri)
Parse URI and set the member variables accordingly, returns kTRUE if URI validates, and kFALSE otherwise: URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty.
Definition: TUri.cxx:600
Bool_t HasPath() const
Definition: TUri.h:101
Bool_t HasHierPart() const
Definition: TUri.h:96
TString fQuery
Definition: TUri.h:64
Bool_t operator==(const TUri &u1, const TUri &u2)
Implementation of a TUri Equivalence operator that uses syntax-based normalisation see chapter 6...
Definition: TUri.cxx:115
std::vector< std::vector< double > > Data
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.cxx:102
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Bool_t IsAbsolute() const
Returns kTRUE if instance qualifies as absolute-URI absolute-URI = scheme ":" hier-part [ "...
Definition: TUri.cxx:206
static const TString PctEncode(const TString &source)
Percent-encode and return the given string according to RFC 3986 in principle, this function cannot f...
Definition: TUri.cxx:814
Bool_t SetAuthority(const TString &authority)
Set authority part of URI: authority = [ userinfo "@" ] host [ ":" port ].
Definition: TUri.cxx:337
Bool_t IsRelative() const
Returns kTRUE if instance qualifies as relative-ref relative-ref = relative-part [ "...
Definition: TUri.cxx:216
static Bool_t IsPathNoscheme(const TString &)
Returns kTRUE if string qualifies as valid path-noscheme component: path-noscheme = segment-nz-nc *( ...
Definition: TUri.cxx:899
void Reset()
Initialize this URI object.
Definition: TUri.cxx:570
const TString GetPath() const
Definition: TUri.h:91
Bool_t fHasFragment
Definition: TUri.h:73
Bool_t SetScheme(const TString &scheme)
Set scheme component of URI: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ).
Definition: TUri.cxx:247
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
const TString GetUri() const
Returns the whole URI - an implementation of chapter 5.3 component recomposition. ...
Definition: TUri.cxx:139
return
Definition: TBase64.cxx:62
TString fScheme
Definition: TUri.h:59
static Bool_t IsPathEmpty(const TString &)
Returns kTRUE if string qualifies as valid path-empty component: path-empty = 0.
Definition: TUri.cxx:925
Bool_t fHasPath
Definition: TUri.h:71
TUri()
Definition: TUri.h:77
Bool_t HasFragment() const
Definition: TUri.h:103
TString fHost
Definition: TUri.h:61
const TString GetQuery() const
Definition: TUri.h:92
Bool_t SetFragment(const TString &fragment)
Set fragment component of URI: fragment = *( pchar / "/" / "?" ).
Definition: TUri.cxx:497
static TUri Transform(const TUri &reference, const TUri &base)
Transform a URI reference into its target URI using given a base URI.
Definition: TUri.cxx:1121
Bool_t IsNull() const
Definition: TString.h:387
const TString GetRelativePart() const
relative-part = "//" authority path-abempty / path-absolute / path-noscheme / path-empty ...
Definition: TUri.cxx:675
static Bool_t IsQuery(const TString &)
Returns kTRUE if string qualifies as URI query: query = *( pchar / "/" / "?" )...
Definition: TUri.cxx:319
#define Printf
Definition: TGeoToOCC.h:18
static Bool_t IsRelativePart(const TString &)
Returns kTRUE is string qualifies as relative-part: relative-part = "//" authority path-abempty ...
Definition: TUri.cxx:759
Bool_t fHasHost
Definition: TUri.h:69
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
int Ssiz_t
Definition: RtypesCore.h:63
static Bool_t IsPort(const TString &)
Returns kTRUE if string qualifies as valid port component: RFC 3986: port = *DIGIT...
Definition: TUri.cxx:936
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:493
Bool_t HasQuery() const
Definition: TUri.h:102
Mother of all ROOT objects.
Definition: TObject.h:58
Bool_t SetHost(const TString &host)
Set host component of URI: RFC 3986: host = IP-literal / IPv4address / reg-name implemented: host ...
Definition: TUri.cxx:441
Bool_t HasScheme() const
Definition: TUri.h:95
TString fFragment
Definition: TUri.h:65
static Bool_t IsPath(const TString &)
Returns kTRUE if string qualifies as valid path component: path = path-abempty ; begins w...
Definition: TUri.cxx:853
TString fPort
Definition: TUri.h:62
static Bool_t IsHost(const TString &)
Returns kTRUE if string qualifies as valid host component: host = IP-literal / IPv4address / reg-name...
Definition: TUri.cxx:838
static const TString MergePaths(const TUri &reference, const TUri &base)
RFC 3986, 5.3.2.
Definition: TUri.cxx:1179
static Bool_t IsPathAbempty(const TString &)
Returns kTRUE if string qualifies as valid path-abempty component: path-abempty = *( "/" segment ) s...
Definition: TUri.cxx:869
static Bool_t IsPathAbsolute(const TString &)
Returns kTRUE if string qualifies as valid path-absolute component path-absolute = "/" [ segment-nz *...
Definition: TUri.cxx:884
double result[121]
static Bool_t IsUnreserved(const TString &string)
Returns kTRUE, if the given string does not contain RFC 3986 reserved characters unreserved = ALPHA ...
Definition: TUri.cxx:974
Bool_t HasRelativePart() const
Definition: TUri.h:104
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
Bool_t SetRelativePart(const TString &)
Returns kTRUE is string qualifies as relative-part: relative-part = "//" authority path-abempty ...
Definition: TUri.cxx:776
static const TString PctNormalise(const TString &source)
Normalise the percent-encoded parts of the string i.e.
Definition: TUri.cxx:1056
const Bool_t kTRUE
Definition: Rtypes.h:91
Int_t Match(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10, TArrayI *pos=0)
The number of matches is returned, this equals the full match + sub-pattern matches.
Definition: TPRegexp.cxx:335
static Bool_t IsPathRootless(const TString &)
Returns kTRUE if string qualifies as valid path-rootless component: path-rootless = segment-nz *( "/"...
Definition: TUri.cxx:912
ClassImp(TUri) TUri
Constructor that calls SetUri with a complete URI.
Definition: TUri.cxx:46
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:385
static Bool_t IsFragment(const TString &)
Returns kTRUE if string qualifies as valid fragment component fragment = *( pchar / "/" / "...
Definition: TUri.cxx:515
static const TString RemoveDotSegments(const TString &)
This functions implements the "remove_dot_segments" routine of chapter 5.2.4 "for interpreting and re...
Definition: TUri.cxx:158
static Bool_t IsHierPart(const TString &)
Returns kTRUE if string qualifies as hier-part: hier-part = "//" authority path-abempty ...
Definition: TUri.cxx:742
static Bool_t IsScheme(const TString &)
Returns kTRUE if string qualifies as URI scheme: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "...
Definition: TUri.cxx:269