Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Uri.cs
Go to the documentation of this file.
7using System.Text;
10
11namespace System;
12
14[TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
15public class Uri : ISerializable
16{
17 [Flags]
18 internal enum Flags : ulong
19 {
20 Zero = 0uL,
25 PathNotCanonical = 0x10uL,
36 ShouldBeCompressed = 0x2000uL,
37 FirstSlashAbsent = 0x4000uL,
38 BackslashInPath = 0x8000uL,
39 IndexMask = 0xFFFFuL,
40 HostTypeMask = 0x70000uL,
42 IPv6HostType = 0x10000uL,
43 IPv4HostType = 0x20000uL,
44 DnsHostType = 0x30000uL,
45 UncHostType = 0x40000uL,
46 BasicHostType = 0x50000uL,
47 UnusedHostType = 0x60000uL,
48 UnknownHostType = 0x70000uL,
49 UserEscaped = 0x80000uL,
50 AuthorityFound = 0x100000uL,
51 HasUserInfo = 0x200000uL,
52 LoopbackHost = 0x400000uL,
53 NotDefaultPort = 0x800000uL,
54 UserDrivenParsing = 0x1000000uL,
55 CanonicalDnsHost = 0x2000000uL,
56 ErrorOrParsingRecursion = 0x4000000uL,
57 DosPath = 0x8000000uL,
58 UncPath = 0x10000000uL,
59 ImplicitFile = 0x20000000uL,
60 MinimalUriInfoSet = 0x40000000uL,
61 AllUriInfoSet = 0x80000000uL,
62 IdnHost = 0x100000000uL,
63 HasUnicode = 0x200000000uL,
64 HostUnicodeNormalized = 0x400000000uL,
65 RestUnicodeNormalized = 0x800000000uL,
66 UnicodeHost = 0x1000000000uL,
67 IntranetUri = 0x2000000000uL,
68 UserIriCanonical = 0x8000000000uL,
69 PathIriCanonical = 0x10000000000uL,
70 QueryIriCanonical = 0x20000000000uL,
71 FragmentIriCanonical = 0x40000000000uL,
72 IriCanonical = 0x78000000000uL,
73 UnixPath = 0x100000000000uL,
76 Debug_LeftConstructor = 9223372036854775808uL
77 }
78
79 private sealed class UriInfo
80 {
81 public Offset Offset;
82
83 public string String;
84
85 public string Host;
86
87 public string IdnHost;
88
89 public string PathAndQuery;
90
91 public string ScopeId;
92
94
96 {
97 get
98 {
99 if (_moreInfo == null)
100 {
102 }
103 return _moreInfo;
104 }
105 }
106 }
107
108 [StructLayout(LayoutKind.Sequential, Pack = 1)]
109 private struct Offset
110 {
111 public ushort Scheme;
112
113 public ushort User;
114
115 public ushort Host;
116
117 public ushort PortValue;
118
119 public ushort Path;
120
121 public ushort Query;
122
123 public ushort Fragment;
124
125 public ushort End;
126 }
127
128 private sealed class MoreInfo
129 {
130 public string Path;
131
132 public string Query;
133
134 public string Fragment;
135
136 public string AbsoluteUri;
137
138 public string RemoteUrl;
139 }
140
141 [Flags]
142 private enum Check
143 {
144 None = 0,
147 DotSlashAttn = 4,
148 DotSlashEscaped = 0x80,
149 BackslashInPath = 0x10,
150 ReservedFound = 0x20,
151 NotIriCanonical = 0x40,
152 FoundNonAscii = 8
153 }
154
155 public static readonly string UriSchemeFile = UriParser.FileUri.SchemeName;
156
157 public static readonly string UriSchemeFtp = UriParser.FtpUri.SchemeName;
158
159 public static readonly string UriSchemeSftp = "sftp";
160
161 public static readonly string UriSchemeFtps = "ftps";
162
163 public static readonly string UriSchemeGopher = UriParser.GopherUri.SchemeName;
164
165 public static readonly string UriSchemeHttp = UriParser.HttpUri.SchemeName;
166
167 public static readonly string UriSchemeHttps = UriParser.HttpsUri.SchemeName;
168
169 public static readonly string UriSchemeWs = UriParser.WsUri.SchemeName;
170
171 public static readonly string UriSchemeWss = UriParser.WssUri.SchemeName;
172
173 public static readonly string UriSchemeMailto = UriParser.MailToUri.SchemeName;
174
175 public static readonly string UriSchemeNews = UriParser.NewsUri.SchemeName;
176
177 public static readonly string UriSchemeNntp = UriParser.NntpUri.SchemeName;
178
179 public static readonly string UriSchemeSsh = "ssh";
180
181 public static readonly string UriSchemeTelnet = UriParser.TelnetUri.SchemeName;
182
183 public static readonly string UriSchemeNetTcp = UriParser.NetTcpUri.SchemeName;
184
185 public static readonly string UriSchemeNetPipe = UriParser.NetPipeUri.SchemeName;
186
187 public static readonly string SchemeDelimiter = "://";
188
189 private string _string;
190
192
194
195 internal Flags _flags;
196
197 private UriInfo _info;
198
199 private static readonly char[] s_pathDelims = new char[5] { ':', '\\', '/', '?', '#' };
200
201 private bool IsImplicitFile => (_flags & Flags.ImplicitFile) != 0;
202
203 private bool IsUncOrDosPath => (_flags & (Flags.DosPath | Flags.UncPath)) != 0;
204
205 private bool IsDosPath => (_flags & Flags.DosPath) != 0;
206
207 private bool IsUncPath => (_flags & Flags.UncPath) != 0;
208
209 private Flags HostType => _flags & Flags.HostTypeMask;
210
212
213 private bool IsNotAbsoluteUri => _syntax == null;
214
216
217 internal bool DisablePathAndQueryCanonicalization => (_flags & Flags.DisablePathAndQueryCanonicalization) != 0;
218
219 internal bool UserDrivenParsing => (_flags & Flags.UserDrivenParsing) != 0;
220
222 {
223 get
224 {
225 if (IsDosPath)
226 {
227 char c = _string[_info.Offset.Path];
228 if (c != '/' && c != '\\')
229 {
230 return 2;
231 }
232 return 3;
233 }
234 return 0;
235 }
236 }
237
238 public string AbsolutePath
239 {
240 get
241 {
243 {
245 }
246 string text = PrivateAbsolutePath;
247 if (IsDosPath && text[0] == '/')
248 {
249 text = text.Substring(1);
250 }
251 return text;
252 }
253 }
254
255 private string PrivateAbsolutePath
256 {
257 get
258 {
261 return moreInfo2.Path ?? (moreInfo2.Path = GetParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped));
262 }
263 }
264
265 public string AbsoluteUri
266 {
267 get
268 {
269 if (_syntax == null)
270 {
272 }
275 return moreInfo2.AbsoluteUri ?? (moreInfo2.AbsoluteUri = GetParts(UriComponents.AbsoluteUri, UriFormat.UriEscaped));
276 }
277 }
278
279 public string LocalPath
280 {
281 get
282 {
284 {
286 }
287 return GetLocalPath();
288 }
289 }
290
291 public string Authority
292 {
293 get
294 {
296 {
298 }
299 return GetParts(UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
300 }
301 }
302
304 {
305 get
306 {
308 {
310 }
311 if (_syntax.IsSimple)
312 {
314 }
315 else
316 {
318 }
319 return HostType switch
320 {
327 _ => UriHostNameType.Unknown,
328 };
329 }
330 }
331
332 public bool IsDefaultPort
333 {
334 get
335 {
337 {
339 }
340 if (_syntax.IsSimple)
341 {
343 }
344 else
345 {
347 }
348 return NotAny(Flags.NotDefaultPort);
349 }
350 }
351
352 public bool IsFile
353 {
354 get
355 {
357 {
359 }
360 return (object)_syntax.SchemeName == UriSchemeFile;
361 }
362 }
363
364 public bool IsLoopback
365 {
366 get
367 {
369 {
371 }
373 return InFact(Flags.LoopbackHost);
374 }
375 }
376
377 public string PathAndQuery
378 {
379 get
380 {
382 {
384 }
386 if (uriInfo.PathAndQuery == null)
387 {
388 string text = GetParts(UriComponents.PathAndQuery, UriFormat.UriEscaped);
389 if (IsDosPath && text[0] == '/')
390 {
391 text = text.Substring(1);
392 }
394 }
395 return uriInfo.PathAndQuery;
396 }
397 }
398
399 public string[] Segments
400 {
401 get
402 {
404 {
406 }
408 if (privateAbsolutePath.Length == 0)
409 {
410 return Array.Empty<string>();
411 }
413 int num = 0;
414 while (num < privateAbsolutePath.Length)
415 {
416 int num2 = privateAbsolutePath.IndexOf('/', num);
417 if (num2 == -1)
418 {
420 }
421 arrayBuilder.Add(privateAbsolutePath.Substring(num, num2 - num + 1));
422 num = num2 + 1;
423 }
424 return arrayBuilder.ToArray();
425 }
426 }
427
428 public bool IsUnc
429 {
430 get
431 {
433 {
435 }
436 return IsUncPath;
437 }
438 }
439
440 public string Host
441 {
442 get
443 {
445 {
447 }
448 return GetParts(UriComponents.Host, UriFormat.UriEscaped);
449 }
450 }
451
452 public int Port
453 {
454 get
455 {
457 {
459 }
460 if (_syntax.IsSimple)
461 {
463 }
464 else
465 {
467 }
468 if (InFact(Flags.NotDefaultPort))
469 {
470 return _info.Offset.PortValue;
471 }
472 return _syntax.DefaultPort;
473 }
474 }
475
476 public string Query
477 {
478 get
479 {
481 {
483 }
486 return moreInfo2.Query ?? (moreInfo2.Query = GetParts(UriComponents.Query | UriComponents.KeepDelimiter, UriFormat.UriEscaped));
487 }
488 }
489
490 public string Fragment
491 {
492 get
493 {
495 {
497 }
500 return moreInfo2.Fragment ?? (moreInfo2.Fragment = GetParts(UriComponents.Fragment | UriComponents.KeepDelimiter, UriFormat.UriEscaped));
501 }
502 }
503
504 public string Scheme
505 {
506 get
507 {
509 {
511 }
512 return _syntax.SchemeName;
513 }
514 }
515
517
518 public string DnsSafeHost
519 {
520 get
521 {
523 {
525 }
528 if (hostType == Flags.IPv6HostType || (hostType == Flags.BasicHostType && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical)))
529 {
530 return IdnHost;
531 }
532 return _info.Host;
533 }
534 }
535
536 public string IdnHost
537 {
538 get
539 {
541 {
543 }
544 if (_info?.IdnHost == null)
545 {
547 string text = _info.Host;
548 switch (HostType)
549 {
550 case Flags.DnsHostType:
552 break;
553 case Flags.IPv6HostType:
554 text = ((_info.ScopeId != null) ? string.Concat(text.AsSpan(1, text.Length - 2), _info.ScopeId) : text.Substring(1, text.Length - 2));
555 break;
556 case Flags.BasicHostType:
557 if (InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical))
558 {
561 UriHelper.UnescapeString(text, 0, text.Length, ref dest, '\uffff', '\uffff', '\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, _syntax, isQuery: false);
562 text = dest.ToString();
563 }
564 break;
565 }
567 }
568 return _info.IdnHost;
569 }
570 }
571
572 public bool IsAbsoluteUri => _syntax != null;
573
574 public bool UserEscaped => InFact(Flags.UserEscaped);
575
576 public string UserInfo
577 {
578 get
579 {
581 {
583 }
584 return GetParts(UriComponents.UserInfo, UriFormat.UriEscaped);
585 }
586 }
587
588 private void InterlockedSetFlags(Flags flags)
589 {
590 if (_syntax.IsSimple)
591 {
593 return;
594 }
595 lock (_info)
596 {
597 _flags |= flags;
598 }
599 }
600
601 internal static bool IriParsingStatic(UriParser syntax)
602 {
603 return syntax?.InFact(UriSyntaxFlags.AllowIriParsing) ?? true;
604 }
605
606 private bool NotAny(Flags flags)
607 {
608 return (_flags & flags) == 0;
609 }
610
611 private bool InFact(Flags flags)
612 {
613 return (_flags & flags) != 0;
614 }
615
617 {
618 return (allFlags & checkFlags) == 0;
619 }
620
622 {
623 return (allFlags & checkFlags) != 0;
624 }
625
627 {
628 Flags flags = _flags;
629 if ((flags & Flags.MinimalUriInfoSet) == Flags.Zero)
630 {
631 CreateUriInfo(flags);
632 }
633 return _info;
634 }
635
636 private void EnsureParseRemaining()
637 {
638 if ((_flags & Flags.AllUriInfoSet) == Flags.Zero)
639 {
641 }
642 }
643
645 {
647 if (uriInfo.Host == null && (!allowDnsOptimization || !InFact(Flags.CanonicalDnsHost)))
648 {
650 }
651 }
652
653 public Uri(string uriString)
654 {
655 if (uriString == null)
656 {
657 throw new ArgumentNullException("uriString");
658 }
660 CreateThis(uriString, dontEscape: false, UriKind.Absolute, in creationOptions);
661 }
662
663 [Obsolete("This constructor has been deprecated; the dontEscape parameter is always false. Use Uri(string) instead.")]
664 public Uri(string uriString, bool dontEscape)
665 {
666 if (uriString == null)
667 {
668 throw new ArgumentNullException("uriString");
669 }
671 CreateThis(uriString, dontEscape, UriKind.Absolute, in creationOptions);
672 }
673
674 [Obsolete("This constructor has been deprecated; the dontEscape parameter is always false. Use Uri(Uri, string) instead.")]
675 public Uri(Uri baseUri, string? relativeUri, bool dontEscape)
676 {
677 if ((object)baseUri == null)
678 {
679 throw new ArgumentNullException("baseUri");
680 }
681 if (!baseUri.IsAbsoluteUri)
682 {
683 throw new ArgumentOutOfRangeException("baseUri");
684 }
686 }
687
688 public Uri(string uriString, UriKind uriKind)
689 {
690 if (uriString == null)
691 {
692 throw new ArgumentNullException("uriString");
693 }
695 CreateThis(uriString, dontEscape: false, uriKind, in creationOptions);
696 }
697
698 public Uri(string uriString, in UriCreationOptions creationOptions)
699 {
700 if (uriString == null)
701 {
702 throw new ArgumentNullException("uriString");
703 }
704 CreateThis(uriString, dontEscape: false, UriKind.Absolute, in creationOptions);
705 }
706
707 public Uri(Uri baseUri, string? relativeUri)
708 {
709 if ((object)baseUri == null)
710 {
711 throw new ArgumentNullException("baseUri");
712 }
713 if (!baseUri.IsAbsoluteUri)
714 {
715 throw new ArgumentOutOfRangeException("baseUri");
716 }
717 CreateUri(baseUri, relativeUri, dontEscape: false);
718 }
719
721 {
722 string @string = serializationInfo.GetString("AbsoluteUri");
724 if (@string.Length != 0)
725 {
726 string uri = @string;
728 CreateThis(uri, dontEscape: false, UriKind.Absolute, in creationOptions);
729 return;
730 }
731 @string = serializationInfo.GetString("RelativeUri");
732 if (@string == null)
733 {
734 throw new ArgumentException(System.SR.Format(System.SR.InvalidNullArgument, "RelativeUri"), "serializationInfo");
735 }
736 string uri2 = @string;
739 }
740
745
747 {
748 if (IsAbsoluteUri)
749 {
750 serializationInfo.AddValue("AbsoluteUri", GetParts(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
751 return;
752 }
753 serializationInfo.AddValue("AbsoluteUri", string.Empty);
754 serializationInfo.AddValue("RelativeUri", GetParts(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
755 }
756
757 private void CreateUri(Uri baseUri, string relativeUri, bool dontEscape)
758 {
759 string uri = relativeUri;
760 bool dontEscape2 = dontEscape;
762 CreateThis(uri, dontEscape2, UriKind.RelativeOrAbsolute, in creationOptions);
763 if (baseUri.Syntax.IsSimple)
764 {
766 if (uri2 != null)
767 {
768 if ((object)this != uri2)
769 {
771 }
772 return;
773 }
774 }
775 else
776 {
777 dontEscape = false;
778 relativeUri = baseUri.Syntax.InternalResolve(baseUri, this, out var parsingError);
779 if (parsingError != null)
780 {
781 throw parsingError;
782 }
783 }
784 _flags = Flags.Zero;
785 _info = null;
786 _syntax = null;
788 string uri3 = relativeUri;
789 bool dontEscape3 = dontEscape;
792 }
793
794 public Uri(Uri baseUri, Uri relativeUri)
795 {
796 if ((object)baseUri == null)
797 {
798 throw new ArgumentNullException("baseUri");
799 }
800 if (!baseUri.IsAbsoluteUri)
801 {
802 throw new ArgumentOutOfRangeException("baseUri");
803 }
805 string newUriString = null;
806 bool userEscaped;
807 if (baseUri.Syntax.IsSimple)
808 {
809 userEscaped = InFact(Flags.UserEscaped);
810 Uri uri = ResolveHelper(baseUri, this, ref newUriString, ref userEscaped);
811 if (uri != null)
812 {
813 if ((object)this != uri)
814 {
816 }
817 return;
818 }
819 }
820 else
821 {
822 userEscaped = false;
823 newUriString = baseUri.Syntax.InternalResolve(baseUri, this, out var parsingError);
824 if (parsingError != null)
825 {
826 throw parsingError;
827 }
828 }
829 _flags = Flags.Zero;
830 _info = null;
831 _syntax = null;
833 string uri2 = newUriString;
834 bool dontEscape = userEscaped;
837 }
838
839 private static void GetCombinedString(Uri baseUri, string relativeStr, bool dontEscape, ref string result)
840 {
841 for (int i = 0; i < relativeStr.Length && relativeStr[i] != '/' && relativeStr[i] != '\\' && relativeStr[i] != '?' && relativeStr[i] != '#'; i++)
842 {
843 if (relativeStr[i] == ':')
844 {
845 if (i < 2)
846 {
847 break;
848 }
849 UriParser syntax = null;
850 if (CheckSchemeSyntax(relativeStr.AsSpan(0, i), ref syntax) != 0)
851 {
852 break;
853 }
854 if (baseUri.Syntax == syntax)
855 {
856 relativeStr = ((i + 1 >= relativeStr.Length) ? string.Empty : relativeStr.Substring(i + 1));
857 break;
858 }
859 result = relativeStr;
860 return;
861 }
862 }
863 if (relativeStr.Length == 0)
864 {
865 result = baseUri.OriginalString;
866 }
867 else
868 {
869 result = CombineUri(baseUri, relativeStr, dontEscape ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
870 }
871 }
872
893
894 private static bool StaticIsFile(UriParser syntax)
895 {
896 return syntax.InFact(UriSyntaxFlags.FileLikeUri);
897 }
898
899 private string GetLocalPath()
900 {
902 if (IsUncOrDosPath)
903 {
905 int num;
906 if (NotAny(Flags.HostNotCanonical | Flags.PathNotCanonical | Flags.ShouldBeCompressed))
907 {
908 num = (IsUncPath ? (_info.Offset.Host - 2) : _info.Offset.Path);
909 string text = ((IsImplicitFile && _info.Offset.Host == ((!IsDosPath) ? 2 : 0) && _info.Offset.Query == _info.Offset.End) ? _string : ((IsDosPath && (_string[num] == '/' || _string[num] == '\\')) ? _string.Substring(num + 1, _info.Offset.Query - num - 1) : _string.Substring(num, _info.Offset.Query - num)));
910 if (IsDosPath && text[1] == '|')
911 {
912 text = text.Remove(1, 1);
913 text = text.Insert(1, ":");
914 }
915 for (int i = 0; i < text.Length; i++)
916 {
917 if (text[i] == '/')
918 {
919 text = text.Replace('/', '\\');
920 break;
921 }
922 }
923 return text;
924 }
925 int destPosition = 0;
926 num = _info.Offset.Path;
927 string host = _info.Host;
928 char[] array = new char[host.Length + 3 + _info.Offset.Fragment - _info.Offset.Path];
929 if (IsUncPath)
930 {
931 array[0] = '\\';
932 array[1] = '\\';
933 destPosition = 2;
934 UriHelper.UnescapeString(host, 0, host.Length, array, ref destPosition, '\uffff', '\uffff', '\uffff', UnescapeMode.CopyOnly, _syntax, isQuery: false);
935 }
936 else if (_string[num] == '/' || _string[num] == '\\')
937 {
938 num++;
939 }
940 ushort num2 = (ushort)destPosition;
941 UnescapeMode unescapeMode = ((InFact(Flags.PathNotCanonical) && !IsImplicitFile) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : UnescapeMode.CopyOnly);
942 UriHelper.UnescapeString(_string, num, _info.Offset.Query, array, ref destPosition, '\uffff', '\uffff', '\uffff', unescapeMode, _syntax, isQuery: true);
943 if (array[1] == '|')
944 {
945 array[1] = ':';
946 }
947 if (InFact(Flags.ShouldBeCompressed))
948 {
950 }
951 for (ushort num3 = 0; num3 < (ushort)destPosition; num3++)
952 {
953 if (array[num3] == '/')
954 {
955 array[num3] = '\\';
956 }
957 }
958 return new string(array, 0, destPosition);
959 }
960 return GetUnescapedParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped);
961 }
962
963 public unsafe static UriHostNameType CheckHostName(string? name)
964 {
965 if (string.IsNullOrEmpty(name) || name.Length > 32767)
966 {
967 return UriHostNameType.Unknown;
968 }
969 int end = name.Length;
970 fixed (char* name2 = name)
971 {
972 if (name[0] == '[' && name[name.Length - 1] == ']' && IPv6AddressHelper.IsValid(name2, 1, ref end) && end == name.Length)
973 {
974 return UriHostNameType.IPv6;
975 }
976 end = name.Length;
977 if (IPv4AddressHelper.IsValid(name2, 0, ref end, allowIPv6: false, notImplicitFile: false, unknownScheme: false) && end == name.Length)
978 {
979 return UriHostNameType.IPv4;
980 }
981 end = name.Length;
982 bool notCanonical = false;
983 if (DomainNameHelper.IsValid(name2, 0, ref end, ref notCanonical, notImplicitFile: false) && end == name.Length)
984 {
985 return UriHostNameType.Dns;
986 }
987 end = name.Length;
988 notCanonical = false;
989 if (DomainNameHelper.IsValidByIri(name2, 0, ref end, ref notCanonical, notImplicitFile: false) && end == name.Length)
990 {
991 return UriHostNameType.Dns;
992 }
993 }
994 end = name.Length + 2;
995 name = "[" + name + "]";
996 fixed (char* name3 = name)
997 {
998 if (IPv6AddressHelper.IsValid(name3, 1, ref end) && end == name.Length)
999 {
1000 return UriHostNameType.IPv6;
1001 }
1002 }
1003 return UriHostNameType.Unknown;
1004 }
1005
1007 {
1008 if (IsNotAbsoluteUri)
1009 {
1011 }
1012 EnsureUriInfo();
1013 switch (part)
1014 {
1015 case UriPartial.Scheme:
1016 return GetParts(UriComponents.Scheme | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
1017 case UriPartial.Authority:
1018 if (NotAny(Flags.AuthorityFound) || IsDosPath)
1019 {
1020 return string.Empty;
1021 }
1022 return GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, UriFormat.UriEscaped);
1023 case UriPartial.Path:
1024 return GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo | UriComponents.Path, UriFormat.UriEscaped);
1025 case UriPartial.Query:
1026 return GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.UriEscaped);
1027 default:
1029 }
1030 }
1031
1032 public static string HexEscape(char character)
1033 {
1034 if (character > 'ÿ')
1035 {
1036 throw new ArgumentOutOfRangeException("character");
1037 }
1038 return string.Create(3, (byte)character, delegate(Span<char> chars, byte b)
1039 {
1040 chars[0] = '%';
1042 });
1043 }
1044
1045 public static char HexUnescape(string pattern, ref int index)
1046 {
1047 if (index < 0 || index >= pattern.Length)
1048 {
1049 throw new ArgumentOutOfRangeException("index");
1050 }
1051 if (pattern[index] == '%' && pattern.Length - index >= 3)
1052 {
1053 char c = UriHelper.DecodeHexChars(pattern[index + 1], pattern[index + 2]);
1054 if (c != '\uffff')
1055 {
1056 index += 3;
1057 return c;
1058 }
1059 }
1060 return pattern[index++];
1061 }
1062
1063 public static bool IsHexEncoding(string pattern, int index)
1064 {
1065 if (pattern.Length - index >= 3 && pattern[index] == '%' && IsHexDigit(pattern[index + 1]))
1066 {
1067 return IsHexDigit(pattern[index + 2]);
1068 }
1069 return false;
1070 }
1071
1072 public static bool CheckSchemeName([NotNullWhen(true)] string? schemeName)
1073 {
1074 if (string.IsNullOrEmpty(schemeName) || !UriHelper.IsAsciiLetter(schemeName[0]))
1075 {
1076 return false;
1077 }
1078 for (int num = schemeName.Length - 1; num > 0; num--)
1079 {
1080 if (!UriHelper.IsAsciiLetterOrDigit(schemeName[num]) && schemeName[num] != '+' && schemeName[num] != '-' && schemeName[num] != '.')
1081 {
1082 return false;
1083 }
1084 }
1085 return true;
1086 }
1087
1088 public static bool IsHexDigit(char character)
1089 {
1091 }
1092
1093 public static int FromHex(char digit)
1094 {
1095 int num = System.HexConverter.FromChar(digit);
1096 if (num == 255)
1097 {
1098 throw new ArgumentException(null, "digit");
1099 }
1100 return num;
1101 }
1102
1103 public override int GetHashCode()
1104 {
1105 if (IsNotAbsoluteUri)
1106 {
1107 return OriginalString.GetHashCode();
1108 }
1111 string text = moreInfo2.RemoteUrl ?? (moreInfo2.RemoteUrl = GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped));
1112 if (IsUncOrDosPath)
1113 {
1114 return StringComparer.OrdinalIgnoreCase.GetHashCode(text);
1115 }
1116 return text.GetHashCode();
1117 }
1118
1119 public override string ToString()
1120 {
1121 if (_syntax == null)
1122 {
1123 return _string;
1124 }
1125 EnsureUriInfo();
1126 if (_info.String == null)
1127 {
1128 if (_syntax.IsSimple)
1129 {
1131 }
1132 else
1133 {
1134 _info.String = GetParts(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
1135 }
1136 }
1137 return _info.String;
1138 }
1139
1140 public static bool operator ==(Uri? uri1, Uri? uri2)
1141 {
1142 if ((object)uri1 == uri2)
1143 {
1144 return true;
1145 }
1146 if ((object)uri1 == null || (object)uri2 == null)
1147 {
1148 return false;
1149 }
1150 return uri1.Equals(uri2);
1151 }
1152
1153 public static bool operator !=(Uri? uri1, Uri? uri2)
1154 {
1155 if ((object)uri1 == uri2)
1156 {
1157 return false;
1158 }
1159 if ((object)uri1 == null || (object)uri2 == null)
1160 {
1161 return true;
1162 }
1163 return !uri1.Equals(uri2);
1164 }
1165
1166 public override bool Equals([NotNullWhen(true)] object? comparand)
1167 {
1168 if (comparand == null)
1169 {
1170 return false;
1171 }
1172 if (this == comparand)
1173 {
1174 return true;
1175 }
1176 Uri result = comparand as Uri;
1177 if ((object)result == null)
1178 {
1180 {
1181 return false;
1182 }
1183 if (!(comparand is string text))
1184 {
1185 return false;
1186 }
1187 if ((object)text == OriginalString)
1188 {
1189 return true;
1190 }
1191 if (!TryCreate(text, UriKind.RelativeOrAbsolute, out result))
1192 {
1193 return false;
1194 }
1195 }
1197 {
1198 return false;
1199 }
1200 if ((object)OriginalString == result.OriginalString)
1201 {
1202 return true;
1203 }
1204 if (IsAbsoluteUri != result.IsAbsoluteUri)
1205 {
1206 return false;
1207 }
1208 if (IsNotAbsoluteUri)
1209 {
1210 return OriginalString.Equals(result.OriginalString);
1211 }
1212 if ((NotAny(Flags.AllUriInfoSet) || result.NotAny(Flags.AllUriInfoSet)) && string.Equals(_string, result._string, IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
1213 {
1214 return true;
1215 }
1216 EnsureUriInfo();
1217 result.EnsureUriInfo();
1219 {
1220 if (InFact(Flags.CanonicalDnsHost) && result.InFact(Flags.CanonicalDnsHost))
1221 {
1222 int num = _info.Offset.Host;
1223 int num2 = _info.Offset.Path;
1224 int num3 = result._info.Offset.Host;
1225 int path = result._info.Offset.Path;
1226 string @string = result._string;
1227 if (num2 - num > path - num3)
1228 {
1229 num2 = num + path - num3;
1230 }
1231 while (num < num2)
1232 {
1233 if (_string[num] != @string[num3])
1234 {
1235 return false;
1236 }
1237 if (@string[num3] == ':')
1238 {
1239 break;
1240 }
1241 num++;
1242 num3++;
1243 }
1244 if (num < _info.Offset.Path && _string[num] != ':')
1245 {
1246 return false;
1247 }
1248 if (num3 < path && @string[num3] != ':')
1249 {
1250 return false;
1251 }
1252 }
1253 else
1254 {
1257 if (!_info.Host.Equals(result._info.Host))
1258 {
1259 return false;
1260 }
1261 }
1262 if (Port != result.Port)
1263 {
1264 return false;
1265 }
1266 }
1270 string a = moreInfo3.RemoteUrl ?? (moreInfo3.RemoteUrl = GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped));
1272 string b = moreInfo3.RemoteUrl ?? (moreInfo3.RemoteUrl = result.GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped));
1273 return string.Equals(a, b, IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
1274 }
1275
1277 {
1278 if ((object)uri == null)
1279 {
1280 throw new ArgumentNullException("uri");
1281 }
1283 {
1285 }
1286 if (Scheme == uri.Scheme && Host == uri.Host && Port == uri.Port)
1287 {
1288 string absolutePath = uri.AbsolutePath;
1291 {
1292 text = "./" + text;
1293 }
1294 text += uri.GetParts(UriComponents.Query | UriComponents.Fragment, UriFormat.UriEscaped);
1295 return new Uri(text, UriKind.Relative);
1296 }
1297 return uri;
1298 }
1299
1300 private static bool CheckForColonInFirstPathSegment(string uriString)
1301 {
1302 int num = uriString.IndexOfAny(s_pathDelims);
1303 if (num >= 0)
1304 {
1305 return uriString[num] == ':';
1306 }
1307 return false;
1308 }
1309
1310 internal static string InternalEscapeString(string rawString)
1311 {
1312 if (rawString != null)
1313 {
1315 }
1316 return string.Empty;
1317 }
1318
1319 private unsafe static ParsingError ParseScheme(string uriString, ref Flags flags, ref UriParser syntax)
1320 {
1321 int length = uriString.Length;
1322 if (length == 0)
1323 {
1324 return ParsingError.EmptyUriString;
1325 }
1326 if (length >= 65520)
1327 {
1328 return ParsingError.SizeLimit;
1329 }
1330 fixed (char* uriString2 = uriString)
1331 {
1334 if (err != 0)
1335 {
1336 return err;
1337 }
1338 flags |= (Flags)num;
1339 }
1340 return ParsingError.None;
1341 }
1342
1344 {
1346 if (parsingError == ParsingError.None)
1347 {
1348 return null;
1349 }
1350 _flags |= Flags.ErrorOrParsingRecursion;
1351 return GetException(parsingError);
1352 }
1353
1355 {
1356 int num = (int)(_flags & Flags.IndexMask);
1357 int num2 = _string.Length;
1358 string newHost = null;
1359 _flags &= ~(Flags.IndexMask | Flags.UserDrivenParsing);
1360 fixed (char* ptr = (((_flags & Flags.HostUnicodeNormalized) == Flags.Zero) ? OriginalString : _string))
1361 {
1362 if (num2 > num && UriHelper.IsLWS(ptr[num2 - 1]))
1363 {
1364 num2--;
1365 while (num2 != num && UriHelper.IsLWS(ptr[--num2]))
1366 {
1367 }
1368 num2++;
1369 }
1370 if (_syntax.IsAllSet(UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowDOSPath) && NotAny(Flags.ImplicitFile) && num + 1 < num2)
1371 {
1372 int i;
1373 for (i = num; i < num2; i++)
1374 {
1375 char c;
1376 if ((c = ptr[i]) != '\\' && c != '/')
1377 {
1378 break;
1379 }
1380 }
1381 if (_syntax.InFact(UriSyntaxFlags.FileLikeUri) || i - num <= 3)
1382 {
1383 if (i - num >= 2)
1384 {
1385 _flags |= Flags.AuthorityFound;
1386 }
1387 char c;
1388 if (i + 1 < num2 && ((c = ptr[i + 1]) == ':' || c == '|') && UriHelper.IsAsciiLetter(ptr[i]))
1389 {
1390 if (i + 2 >= num2 || ((c = ptr[i + 2]) != '\\' && c != '/'))
1391 {
1392 if (_syntax.InFact(UriSyntaxFlags.FileLikeUri))
1393 {
1394 return ParsingError.MustRootedPath;
1395 }
1396 }
1397 else
1398 {
1399 _flags |= Flags.DosPath;
1400 if (_syntax.InFact(UriSyntaxFlags.MustHaveAuthority))
1401 {
1402 _flags |= Flags.AuthorityFound;
1403 }
1404 num = ((i == num || i - num == 2) ? i : (i - 1));
1405 }
1406 }
1407 else if (_syntax.InFact(UriSyntaxFlags.FileLikeUri) && i - num >= 2 && i - num != 3 && i < num2 && ptr[i] != '?' && ptr[i] != '#')
1408 {
1409 _flags |= Flags.UncPath;
1410 num = i;
1411 }
1412 }
1413 }
1414 if ((_flags & (Flags.DosPath | Flags.UncPath | Flags.UnixPath)) == Flags.Zero)
1415 {
1416 if (num + 2 <= num2)
1417 {
1418 char c2 = ptr[num];
1419 char c3 = ptr[num + 1];
1420 if (_syntax.InFact(UriSyntaxFlags.MustHaveAuthority))
1421 {
1422 if ((c2 != '/' && c2 != '\\') || (c3 != '/' && c3 != '\\'))
1423 {
1424 return ParsingError.BadAuthority;
1425 }
1426 _flags |= Flags.AuthorityFound;
1427 num += 2;
1428 }
1429 else if (_syntax.InFact(UriSyntaxFlags.OptionalAuthority) && (InFact(Flags.AuthorityFound) || (c2 == '/' && c3 == '/')))
1430 {
1431 _flags |= Flags.AuthorityFound;
1432 num += 2;
1433 }
1434 else if (_syntax.NotAny(UriSyntaxFlags.MailToLikeUri))
1435 {
1436 if ((_flags & (Flags.HasUnicode | Flags.HostUnicodeNormalized)) == Flags.HasUnicode)
1437 {
1438 _string = _string.Substring(0, num);
1439 }
1440 _flags |= (Flags)((ulong)num | 0x70000uL);
1441 return ParsingError.None;
1442 }
1443 }
1444 else
1445 {
1446 if (_syntax.InFact(UriSyntaxFlags.MustHaveAuthority))
1447 {
1448 return ParsingError.BadAuthority;
1449 }
1450 if (_syntax.NotAny(UriSyntaxFlags.MailToLikeUri))
1451 {
1452 if ((_flags & (Flags.HasUnicode | Flags.HostUnicodeNormalized)) == Flags.HasUnicode)
1453 {
1454 _string = _string.Substring(0, num);
1455 }
1456 _flags |= (Flags)((ulong)num | 0x70000uL);
1457 return ParsingError.None;
1458 }
1459 }
1460 }
1461 if (InFact(Flags.DosPath))
1462 {
1463 _flags |= (Flags)(((_flags & Flags.AuthorityFound) != Flags.Zero) ? 327680 : 458752);
1464 _flags |= (Flags)num;
1465 return ParsingError.None;
1466 }
1469 if (err != 0)
1470 {
1471 return err;
1472 }
1473 if (num < num2)
1474 {
1475 char c4 = ptr[num];
1476 if (c4 == '\\' && NotAny(Flags.ImplicitFile) && _syntax.NotAny(UriSyntaxFlags.AllowDOSPath))
1477 {
1478 return ParsingError.BadAuthorityTerminator;
1479 }
1480 }
1481 _flags |= (Flags)num;
1482 }
1483 if (IriParsing && newHost != null)
1484 {
1485 _string = newHost;
1486 }
1487 return ParsingError.None;
1488 }
1489
1490 private unsafe void CreateUriInfo(Flags cF)
1491 {
1492 UriInfo uriInfo = new UriInfo();
1493 uriInfo.Offset.End = (ushort)_string.Length;
1494 if (!UserDrivenParsing)
1495 {
1496 bool flag = false;
1497 int i;
1498 if ((cF & Flags.ImplicitFile) != Flags.Zero)
1499 {
1500 i = 0;
1501 while (UriHelper.IsLWS(_string[i]))
1502 {
1503 i++;
1504 uriInfo.Offset.Scheme++;
1505 }
1506 if (StaticInFact(cF, Flags.UncPath))
1507 {
1508 i += 2;
1509 for (int num = (int)(cF & Flags.IndexMask); i < num && (_string[i] == '/' || _string[i] == '\\'); i++)
1510 {
1511 }
1512 }
1513 }
1514 else
1515 {
1516 i = _syntax.SchemeName.Length;
1517 while (_string[i++] != ':')
1518 {
1519 uriInfo.Offset.Scheme++;
1520 }
1521 if ((cF & Flags.AuthorityFound) != Flags.Zero)
1522 {
1523 if (_string[i] == '\\' || _string[i + 1] == '\\')
1524 {
1525 flag = true;
1526 }
1527 i += 2;
1528 if ((cF & (Flags.DosPath | Flags.UncPath)) != Flags.Zero)
1529 {
1530 for (int num2 = (int)(cF & Flags.IndexMask); i < num2 && (_string[i] == '/' || _string[i] == '\\'); i++)
1531 {
1532 flag = true;
1533 }
1534 }
1535 }
1536 }
1537 if (_syntax.DefaultPort != -1)
1538 {
1540 }
1541 if ((cF & Flags.HostTypeMask) == Flags.HostTypeMask || StaticInFact(cF, Flags.DosPath))
1542 {
1543 uriInfo.Offset.User = (ushort)(cF & Flags.IndexMask);
1544 uriInfo.Offset.Host = uriInfo.Offset.User;
1545 uriInfo.Offset.Path = uriInfo.Offset.User;
1546 cF = (Flags)((ulong)cF & 0xFFFFFFFFFFFF0000uL);
1547 if (flag)
1548 {
1549 cF |= Flags.SchemeNotCanonical;
1550 }
1551 }
1552 else
1553 {
1554 uriInfo.Offset.User = (ushort)i;
1555 if (HostType == Flags.BasicHostType)
1556 {
1557 uriInfo.Offset.Host = (ushort)i;
1558 uriInfo.Offset.Path = (ushort)(cF & Flags.IndexMask);
1559 cF = (Flags)((ulong)cF & 0xFFFFFFFFFFFF0000uL);
1560 }
1561 else
1562 {
1563 if ((cF & Flags.HasUserInfo) != Flags.Zero)
1564 {
1565 for (; _string[i] != '@'; i++)
1566 {
1567 }
1568 i++;
1569 uriInfo.Offset.Host = (ushort)i;
1570 }
1571 else
1572 {
1573 uriInfo.Offset.Host = (ushort)i;
1574 }
1575 i = (int)(cF & Flags.IndexMask);
1576 cF = (Flags)((ulong)cF & 0xFFFFFFFFFFFF0000uL);
1577 if (flag)
1578 {
1579 cF |= Flags.SchemeNotCanonical;
1580 }
1581 uriInfo.Offset.Path = (ushort)i;
1582 bool flag2 = false;
1583 if ((cF & Flags.HasUnicode) != Flags.Zero)
1584 {
1586 }
1587 if (i < uriInfo.Offset.End)
1588 {
1589 fixed (char* ptr = OriginalString)
1590 {
1591 if (ptr[i] == ':')
1592 {
1593 int num3 = 0;
1594 if (++i < uriInfo.Offset.End)
1595 {
1596 num3 = ptr[i] - 48;
1597 if ((uint)num3 <= 9u)
1598 {
1599 flag2 = true;
1600 if (num3 == 0)
1601 {
1602 cF |= Flags.PortNotCanonical | Flags.E_PortNotCanonical;
1603 }
1604 for (i++; i < uriInfo.Offset.End; i++)
1605 {
1606 int num4 = ptr[i] - 48;
1607 if ((uint)num4 > 9u)
1608 {
1609 break;
1610 }
1611 num3 = num3 * 10 + num4;
1612 }
1613 }
1614 }
1615 if (flag2 && _syntax.DefaultPort != num3)
1616 {
1618 cF |= Flags.NotDefaultPort;
1619 }
1620 else
1621 {
1622 cF |= Flags.PortNotCanonical | Flags.E_PortNotCanonical;
1623 }
1624 uriInfo.Offset.Path = (ushort)i;
1625 }
1626 }
1627 }
1628 }
1629 }
1630 }
1631 cF |= Flags.MinimalUriInfoSet;
1633 Flags flags = _flags;
1634 while ((flags & Flags.MinimalUriInfoSet) == Flags.Zero)
1635 {
1636 Flags value = (Flags)(((ulong)flags & 0xFFFFFFFFFFFF0000uL) | (ulong)cF);
1637 ulong num5 = Interlocked.CompareExchange(ref Internal.Runtime.CompilerServices.Unsafe.As<Flags, ulong>(ref _flags), (ulong)value, (ulong)flags);
1638 if (num5 == (ulong)flags)
1639 {
1640 break;
1641 }
1642 flags = (Flags)num5;
1643 }
1644 }
1645
1646 private unsafe void CreateHostString()
1647 {
1648 if (!_syntax.IsSimple)
1649 {
1650 lock (_info)
1651 {
1652 if (NotAny(Flags.ErrorOrParsingRecursion))
1653 {
1654 _flags |= Flags.ErrorOrParsingRecursion;
1656 _flags &= ~Flags.ErrorOrParsingRecursion;
1657 return;
1658 }
1659 }
1660 }
1661 Flags flags = _flags;
1663 if (text.Length != 0)
1664 {
1665 if (HostType == Flags.BasicHostType)
1666 {
1667 int idx = 0;
1668 Check check;
1669 fixed (char* str = text)
1670 {
1671 check = CheckCanonical(str, ref idx, text.Length, '\uffff');
1672 }
1673 if ((check & Check.DisplayCanonical) == 0 && (NotAny(Flags.ImplicitFile) || (check & Check.ReservedFound) != 0))
1674 {
1675 flags |= Flags.HostNotCanonical;
1676 }
1677 if (InFact(Flags.ImplicitFile) && (check & (Check.EscapedCanonical | Check.ReservedFound)) != 0)
1678 {
1679 check &= ~Check.EscapedCanonical;
1680 }
1681 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
1682 {
1683 flags |= Flags.E_HostNotCanonical;
1684 if (NotAny(Flags.UserEscaped))
1685 {
1687 }
1688 }
1689 }
1690 else if (NotAny(Flags.CanonicalDnsHost))
1691 {
1692 if (_info.ScopeId != null)
1693 {
1694 flags |= Flags.HostNotCanonical | Flags.E_HostNotCanonical;
1695 }
1696 else
1697 {
1698 for (int i = 0; i < text.Length; i++)
1699 {
1700 if (_info.Offset.Host + i >= _info.Offset.End || text[i] != _string[_info.Offset.Host + i])
1701 {
1702 flags |= Flags.HostNotCanonical | Flags.E_HostNotCanonical;
1703 break;
1704 }
1705 }
1706 }
1707 }
1708 }
1709 _info.Host = text;
1710 InterlockedSetFlags(flags);
1711 }
1712
1713 private static string CreateHostStringHelper(string str, int idx, int end, ref Flags flags, ref string scopeId)
1714 {
1715 bool loopback = false;
1716 string text;
1717 switch (flags & Flags.HostTypeMask)
1718 {
1719 case Flags.DnsHostType:
1721 break;
1722 case Flags.IPv6HostType:
1724 break;
1725 case Flags.IPv4HostType:
1727 break;
1728 case Flags.UncHostType:
1730 break;
1731 case Flags.BasicHostType:
1732 text = ((!StaticInFact(flags, Flags.DosPath)) ? str.Substring(idx, end - idx) : string.Empty);
1733 if (text.Length == 0)
1734 {
1735 loopback = true;
1736 }
1737 break;
1738 case Flags.HostTypeMask:
1739 text = string.Empty;
1740 break;
1741 default:
1742 throw GetException(ParsingError.BadHostName);
1743 }
1744 if (loopback)
1745 {
1746 flags |= Flags.LoopbackHost;
1747 }
1748 return text;
1749 }
1750
1751 private unsafe void GetHostViaCustomSyntax()
1752 {
1753 if (_info.Host != null)
1754 {
1755 return;
1756 }
1757 string text = _syntax.InternalGetComponents(this, UriComponents.Host, UriFormat.UriEscaped);
1758 if (_info.Host == null)
1759 {
1760 if (text.Length >= 65520)
1761 {
1762 throw GetException(ParsingError.SizeLimit);
1763 }
1765 Flags flags = (Flags)((ulong)_flags & 0xFFFFFFFFFFF8FFFFuL);
1766 fixed (char* pString = text)
1767 {
1768 string newHost = null;
1769 if (CheckAuthorityHelper(pString, 0, text.Length, ref err, ref flags, _syntax, ref newHost) != text.Length)
1770 {
1771 flags = (Flags)((ulong)flags & 0xFFFFFFFFFFF8FFFFuL);
1772 flags |= Flags.HostTypeMask;
1773 }
1774 }
1775 if (err != 0 || (flags & Flags.HostTypeMask) == Flags.HostTypeMask)
1776 {
1777 _flags = (Flags)(((ulong)_flags & 0xFFFFFFFFFFF8FFFFuL) | 0x50000);
1778 }
1779 else
1780 {
1781 text = CreateHostStringHelper(text, 0, text.Length, ref flags, ref _info.ScopeId);
1782 for (int i = 0; i < text.Length; i++)
1783 {
1784 if (_info.Offset.Host + i >= _info.Offset.End || text[i] != _string[_info.Offset.Host + i])
1785 {
1786 _flags |= Flags.HostNotCanonical | Flags.E_HostNotCanonical;
1787 break;
1788 }
1789 }
1790 _flags = (Flags)(((ulong)_flags & 0xFFFFFFFFFFF8FFFFuL) | (ulong)(flags & Flags.HostTypeMask));
1791 }
1792 }
1793 string text2 = _syntax.InternalGetComponents(this, UriComponents.StrongPort, UriFormat.UriEscaped);
1794 int num = 0;
1795 if (string.IsNullOrEmpty(text2))
1796 {
1797 _flags &= ~Flags.NotDefaultPort;
1798 _flags |= Flags.PortNotCanonical | Flags.E_PortNotCanonical;
1800 }
1801 else
1802 {
1803 for (int j = 0; j < text2.Length; j++)
1804 {
1805 int num2 = text2[j] - 48;
1806 if (num2 < 0 || num2 > 9 || (num = num * 10 + num2) > 65535)
1807 {
1809 }
1810 }
1811 if (num != _info.Offset.PortValue)
1812 {
1813 if (num == _syntax.DefaultPort)
1814 {
1815 _flags &= ~Flags.NotDefaultPort;
1816 }
1817 else
1818 {
1819 _flags |= Flags.NotDefaultPort;
1820 }
1821 _flags |= Flags.PortNotCanonical | Flags.E_PortNotCanonical;
1822 _info.Offset.PortValue = (ushort)num;
1823 }
1824 }
1825 _info.Host = text;
1826 }
1827
1832
1834 {
1835 ushort num = (ushort)(((ushort)_flags & 0x3F80) >> 6);
1836 if (InFact(Flags.SchemeNotCanonical))
1837 {
1838 num = (ushort)(num | 1u);
1839 }
1840 if ((uriParts & UriComponents.Path) != 0)
1841 {
1842 if (InFact(Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath))
1843 {
1844 num = (ushort)(num | 0x10u);
1845 }
1846 else if (IsDosPath && _string[_info.Offset.Path + SecuredPathIndex - 1] == '|')
1847 {
1848 num = (ushort)(num | 0x10u);
1849 }
1850 }
1851 if (((ushort)uriParts & num) == 0)
1852 {
1854 if (uriPartsFromUserString != null)
1855 {
1857 }
1858 }
1859 return ReCreateParts(uriParts, num, UriFormat.UriEscaped);
1860 }
1861
1863 {
1864 ushort num = (ushort)((ushort)_flags & 0x7Fu);
1865 if ((uriParts & UriComponents.Path) != 0)
1866 {
1867 if ((_flags & (Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath)) != Flags.Zero)
1868 {
1869 num = (ushort)(num | 0x10u);
1870 }
1871 else if (IsDosPath && _string[_info.Offset.Path + SecuredPathIndex - 1] == '|')
1872 {
1873 num = (ushort)(num | 0x10u);
1874 }
1875 }
1876 if (((ushort)uriParts & num) == 0)
1877 {
1879 if (uriPartsFromUserString != null)
1880 {
1882 }
1883 }
1884 return ReCreateParts(uriParts, num, formatAs);
1885 }
1886
1888 {
1890 string @string = _string;
1892 if (@string.Length <= 512)
1893 {
1896 }
1897 else
1898 {
1899 valueStringBuilder = new System.Text.ValueStringBuilder(@string.Length);
1900 }
1902 if ((parts & UriComponents.Scheme) != 0)
1903 {
1904 dest.Append(_syntax.SchemeName);
1905 if (parts != UriComponents.Scheme)
1906 {
1907 dest.Append(':');
1908 if (InFact(Flags.AuthorityFound))
1909 {
1910 dest.Append('/');
1911 dest.Append('/');
1912 }
1913 }
1914 }
1916 if ((parts & UriComponents.UserInfo) != 0 && InFact(Flags.HasUserInfo))
1917 {
1919 if ((nonCanonical & 2u) != 0)
1920 {
1921 switch (formatAs)
1922 {
1923 case UriFormat.UriEscaped:
1924 if (NotAny(Flags.UserEscaped))
1925 {
1927 break;
1928 }
1929 InFact(Flags.E_UserNotCanonical);
1930 dest.Append(readOnlySpan);
1931 break;
1932 case UriFormat.SafeUnescaped:
1934 UriHelper.UnescapeString(format[..^1], ref dest, '@', '/', '\\', InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape, _syntax, isQuery: false);
1935 dest.Append('@');
1936 break;
1937 case UriFormat.Unescaped:
1938 UriHelper.UnescapeString(readOnlySpan, ref dest, '\uffff', '\uffff', '\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, _syntax, isQuery: false);
1939 break;
1940 default:
1941 dest.Append(readOnlySpan);
1942 break;
1943 }
1944 }
1945 else
1946 {
1947 dest.Append(readOnlySpan);
1948 }
1949 if (parts == UriComponents.UserInfo)
1950 {
1951 dest.Length--;
1952 }
1953 }
1954 if ((parts & UriComponents.Host) != 0)
1955 {
1956 string text = _info.Host;
1957 if (text.Length != 0)
1958 {
1959 UnescapeMode unescapeMode = ((formatAs != UriFormat.UriEscaped && HostType == Flags.BasicHostType && (nonCanonical & 4u) != 0) ? ((formatAs == UriFormat.Unescaped) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape)) : UnescapeMode.CopyOnly);
1962 if ((parts & UriComponents.NormalizedHost) != 0)
1963 {
1966 {
1967 dest2.Length = 0;
1968 }
1969 }
1970 UriHelper.UnescapeString((dest2.Length == 0) ? ((ReadOnlySpan<char>)text) : dest2.AsSpan(), ref dest, '/', '?', '#', unescapeMode, _syntax, isQuery: false);
1971 dest2.Dispose();
1972 if (((uint)parts & 0x80000000u) != 0 && HostType == Flags.IPv6HostType && _info.ScopeId != null)
1973 {
1974 dest.Length--;
1975 dest.Append(_info.ScopeId);
1976 dest.Append(']');
1977 }
1978 }
1979 }
1980 if ((parts & UriComponents.Port) != 0 && (InFact(Flags.NotDefaultPort) || ((parts & UriComponents.StrongPort) != 0 && _syntax.DefaultPort != -1)))
1981 {
1982 dest.Append(':');
1984 Span<char> destination = dest.AppendSpan(5);
1985 format = default(ReadOnlySpan<char>);
1986 int charsWritten;
1987 bool flag = portValue.TryFormat(destination, out charsWritten, format);
1989 }
1990 if ((parts & UriComponents.Path) != 0)
1991 {
1993 if (parts == UriComponents.Path)
1994 {
1995 int start = ((InFact(Flags.AuthorityFound) && dest.Length != 0 && dest[0] == '/') ? 1 : 0);
1996 format = dest.AsSpan(start);
1997 string result = format.ToString();
1998 dest.Dispose();
1999 return result;
2000 }
2001 }
2003 {
2004 int num = _info.Offset.Query + 1;
2005 if (parts != UriComponents.Query)
2006 {
2007 dest.Append('?');
2008 }
2010 if ((nonCanonical & 0x20u) != 0)
2011 {
2012 if (formatAs == UriFormat.UriEscaped)
2013 {
2014 if (NotAny(Flags.UserEscaped))
2015 {
2016 UriHelper.EscapeString(@string.AsSpan(num, _info.Offset.Fragment - num), ref dest, checkExistingEscaped: true, '#');
2017 goto IL_04d5;
2018 }
2019 }
2020 else
2021 {
2022 unescapeMode2 = formatAs switch
2023 {
2024 (UriFormat)32767 => (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag,
2025 UriFormat.Unescaped => UnescapeMode.Unescape | UnescapeMode.UnescapeAll,
2026 _ => InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape,
2027 };
2028 }
2029 }
2030 UriHelper.UnescapeString(@string, num, _info.Offset.Fragment, ref dest, '#', '\uffff', '\uffff', unescapeMode2, _syntax, isQuery: true);
2031 }
2032 goto IL_04d5;
2033 IL_04d5:
2034 if ((parts & UriComponents.Fragment) != 0 && _info.Offset.Fragment < _info.Offset.End)
2035 {
2036 int num2 = _info.Offset.Fragment + 1;
2037 if (parts != UriComponents.Fragment)
2038 {
2039 dest.Append('#');
2040 }
2042 if ((nonCanonical & 0x40u) != 0)
2043 {
2044 if (formatAs == UriFormat.UriEscaped)
2045 {
2046 if (NotAny(Flags.UserEscaped))
2047 {
2049 goto IL_05d8;
2050 }
2051 }
2052 else
2053 {
2054 unescapeMode3 = formatAs switch
2055 {
2056 (UriFormat)32767 => (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag,
2057 UriFormat.Unescaped => UnescapeMode.Unescape | UnescapeMode.UnescapeAll,
2058 _ => InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape,
2059 };
2060 }
2061 }
2062 UriHelper.UnescapeString(@string, num2, _info.Offset.End, ref dest, '#', '\uffff', '\uffff', unescapeMode3, _syntax, isQuery: false);
2063 }
2064 goto IL_05d8;
2065 IL_05d8:
2066 return dest.ToString();
2067 }
2068
2070 {
2071 switch (uriParts & ~UriComponents.KeepDelimiter)
2072 {
2073 case UriComponents.SchemeAndServer:
2074 if (!InFact(Flags.HasUserInfo))
2075 {
2077 }
2079 case UriComponents.HostAndPort:
2080 if (InFact(Flags.HasUserInfo))
2081 {
2082 if (InFact(Flags.NotDefaultPort) || _syntax.DefaultPort == -1)
2083 {
2084 return _string.Substring(_info.Offset.Host, _info.Offset.Path - _info.Offset.Host);
2085 }
2086 return string.Concat(_string.AsSpan(_info.Offset.Host, _info.Offset.Path - _info.Offset.Host), ":", _info.Offset.PortValue.ToString(CultureInfo.InvariantCulture));
2087 }
2088 goto case UriComponents.StrongAuthority;
2089 case UriComponents.AbsoluteUri:
2090 if (_info.Offset.Scheme == 0 && _info.Offset.End == _string.Length)
2091 {
2092 return _string;
2093 }
2094 return _string.Substring(_info.Offset.Scheme, _info.Offset.End - _info.Offset.Scheme);
2095 case UriComponents.HttpRequestUrl:
2096 if (InFact(Flags.HasUserInfo))
2097 {
2099 }
2100 if (_info.Offset.Scheme == 0 && _info.Offset.Fragment == _string.Length)
2101 {
2102 return _string;
2103 }
2108 if (_info.Offset.Scheme == 0 && _info.Offset.Fragment == _string.Length)
2109 {
2110 return _string;
2111 }
2113 case UriComponents.Scheme:
2114 if (uriParts != UriComponents.Scheme)
2115 {
2117 }
2118 return _syntax.SchemeName;
2119 case UriComponents.Host:
2120 {
2121 int num2 = _info.Offset.Path;
2122 if (InFact(Flags.PortNotCanonical | Flags.NotDefaultPort))
2123 {
2124 while (_string[--num2] != ':')
2125 {
2126 }
2127 }
2128 if (num2 - _info.Offset.Host != 0)
2129 {
2130 return _string.Substring(_info.Offset.Host, num2 - _info.Offset.Host);
2131 }
2132 return string.Empty;
2133 }
2134 case UriComponents.Path:
2135 {
2136 int num = ((uriParts != UriComponents.Path || !InFact(Flags.AuthorityFound) || _info.Offset.End <= _info.Offset.Path || _string[_info.Offset.Path] != '/') ? _info.Offset.Path : (_info.Offset.Path + 1));
2137 if (num >= _info.Offset.Query)
2138 {
2139 return string.Empty;
2140 }
2141 return _string.Substring(num, _info.Offset.Query - num);
2142 }
2143 case UriComponents.Query:
2144 {
2145 int num = ((uriParts != UriComponents.Query) ? _info.Offset.Query : (_info.Offset.Query + 1));
2146 if (num >= _info.Offset.Fragment)
2147 {
2148 return string.Empty;
2149 }
2150 return _string.Substring(num, _info.Offset.Fragment - num);
2151 }
2152 case UriComponents.Fragment:
2153 {
2154 int num = ((uriParts != UriComponents.Fragment) ? _info.Offset.Fragment : (_info.Offset.Fragment + 1));
2155 if (num >= _info.Offset.End)
2156 {
2157 return string.Empty;
2158 }
2159 return _string.Substring(num, _info.Offset.End - num);
2160 }
2162 if (_info.Offset.Path - _info.Offset.User != 0)
2163 {
2164 return _string.Substring(_info.Offset.User, _info.Offset.Path - _info.Offset.User);
2165 }
2166 return string.Empty;
2167 case UriComponents.StrongAuthority:
2168 if (!InFact(Flags.NotDefaultPort) && _syntax.DefaultPort != -1)
2169 {
2170 return string.Concat(_string.AsSpan(_info.Offset.User, _info.Offset.Path - _info.Offset.User), ":", _info.Offset.PortValue.ToString(CultureInfo.InvariantCulture));
2171 }
2173 case UriComponents.PathAndQuery:
2176 if (InFact(Flags.HasUserInfo))
2177 {
2179 }
2180 if (_info.Offset.Scheme == 0 && _info.Offset.End == _string.Length)
2181 {
2182 return _string;
2183 }
2184 return _string.Substring(_info.Offset.Scheme, _info.Offset.End - _info.Offset.Scheme);
2186 return _string.Substring(_info.Offset.Path, _info.Offset.End - _info.Offset.Path);
2187 case UriComponents.UserInfo:
2188 {
2189 if (NotAny(Flags.HasUserInfo))
2190 {
2191 return string.Empty;
2192 }
2193 int num = ((uriParts != UriComponents.UserInfo) ? _info.Offset.Host : (_info.Offset.Host - 1));
2194 if (_info.Offset.User >= num)
2195 {
2196 return string.Empty;
2197 }
2198 return _string.Substring(_info.Offset.User, num - _info.Offset.User);
2199 }
2200 default:
2201 return null;
2202 }
2203 }
2204
2205 private void GetLengthWithoutTrailingSpaces(string str, ref int length, int idx)
2206 {
2207 int num = length;
2208 while (num > idx && UriHelper.IsLWS(str[num - 1]))
2209 {
2210 num--;
2211 }
2212 length = num;
2213 }
2214
2215 private unsafe void ParseRemaining()
2216 {
2217 EnsureUriInfo();
2218 Flags flags = Flags.Zero;
2219 if (!UserDrivenParsing)
2220 {
2221 bool flag = (_flags & (Flags.HasUnicode | Flags.RestUnicodeNormalized)) == Flags.HasUnicode;
2222 int scheme = _info.Offset.Scheme;
2223 int length = _string.Length;
2224 Check check = Check.None;
2226 fixed (char* ptr = _string)
2227 {
2229 if (IsImplicitFile)
2230 {
2231 flags |= Flags.SchemeNotCanonical;
2232 }
2233 else
2234 {
2235 string schemeName = _syntax.SchemeName;
2236 int i;
2237 for (i = 0; i < schemeName.Length; i++)
2238 {
2239 if (schemeName[i] != ptr[scheme + i])
2240 {
2241 flags |= Flags.SchemeNotCanonical;
2242 }
2243 }
2244 if ((_flags & Flags.AuthorityFound) != Flags.Zero && (scheme + i + 3 >= length || ptr[scheme + i + 1] != '/' || ptr[scheme + i + 2] != '/'))
2245 {
2246 flags |= Flags.SchemeNotCanonical;
2247 }
2248 }
2249 if ((_flags & Flags.HasUserInfo) != Flags.Zero)
2250 {
2252 check = CheckCanonical(ptr, ref scheme, _info.Offset.Host, '@');
2253 if ((check & Check.DisplayCanonical) == 0)
2254 {
2255 flags |= Flags.UserNotCanonical;
2256 }
2257 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
2258 {
2259 flags |= Flags.E_UserNotCanonical;
2260 }
2261 if (IriParsing && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.BackslashInPath | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
2262 {
2263 flags |= Flags.UserIriCanonical;
2264 }
2265 }
2266 }
2268 int num = _info.Offset.Path;
2269 if (flag)
2270 {
2271 if (IsFile && !IsUncPath)
2272 {
2273 if (IsImplicitFile)
2274 {
2275 _string = string.Empty;
2276 }
2277 else
2278 {
2280 }
2281 }
2282 _info.Offset.Path = (ushort)_string.Length;
2284 }
2286 {
2287 if (flag)
2288 {
2289 _string += _originalUnicodeString.Substring(num);
2290 }
2291 string @string = _string;
2292 if (IsImplicitFile || (flags2 & UriSyntaxFlags.MayHaveQuery) == 0)
2293 {
2294 scheme = @string.Length;
2295 }
2296 else
2297 {
2298 scheme = @string.IndexOf('?');
2299 if (scheme == -1)
2300 {
2301 scheme = @string.Length;
2302 }
2303 }
2304 _info.Offset.Query = (ushort)scheme;
2305 _info.Offset.Fragment = (ushort)@string.Length;
2306 _info.Offset.End = (ushort)@string.Length;
2307 }
2308 else
2309 {
2310 if (flag)
2311 {
2312 int start = num;
2313 if (IsImplicitFile || (flags2 & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == 0)
2314 {
2315 num = _originalUnicodeString.Length;
2316 }
2317 else
2318 {
2320 int num2 = ((!_syntax.InFact(UriSyntaxFlags.MayHaveQuery)) ? span.IndexOf('#') : ((!_syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? span.IndexOf('?') : span.IndexOfAny('?', '#')));
2321 num = ((num2 == -1) ? _originalUnicodeString.Length : (num2 + num));
2322 }
2324 if (_string.Length > 65535)
2325 {
2327 throw exception;
2328 }
2329 length = _string.Length;
2331 {
2333 }
2334 }
2335 fixed (char* ptr2 = _string)
2336 {
2337 check = ((!IsImplicitFile && (flags2 & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) != 0) ? CheckCanonical(ptr2, ref scheme, length, ((flags2 & UriSyntaxFlags.MayHaveQuery) != 0) ? '?' : (_syntax.InFact(UriSyntaxFlags.MayHaveFragment) ? '#' : '\ufffe')) : CheckCanonical(ptr2, ref scheme, length, '\uffff'));
2338 if ((_flags & Flags.AuthorityFound) != Flags.Zero && (flags2 & UriSyntaxFlags.PathIsRooted) != 0 && (_info.Offset.Path == length || (ptr2[(int)_info.Offset.Path] != '/' && ptr2[(int)_info.Offset.Path] != '\\')))
2339 {
2340 flags |= Flags.FirstSlashAbsent;
2341 }
2342 }
2343 bool flag2 = false;
2344 if (IsDosPath || ((_flags & Flags.AuthorityFound) != Flags.Zero && ((flags2 & (UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath)) != 0 || _syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))))
2345 {
2346 if ((check & Check.DotSlashEscaped) != 0 && _syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))
2347 {
2348 flags |= Flags.PathNotCanonical | Flags.E_PathNotCanonical;
2349 flag2 = true;
2350 }
2351 if ((flags2 & UriSyntaxFlags.ConvertPathSlashes) != 0 && (check & Check.BackslashInPath) != 0)
2352 {
2353 flags |= Flags.PathNotCanonical | Flags.E_PathNotCanonical;
2354 flag2 = true;
2355 }
2356 if ((flags2 & UriSyntaxFlags.CompressPath) != 0 && ((flags & Flags.E_PathNotCanonical) != Flags.Zero || (check & Check.DotSlashAttn) != 0))
2357 {
2358 flags |= Flags.ShouldBeCompressed;
2359 }
2360 if ((check & Check.BackslashInPath) != 0)
2361 {
2362 flags |= Flags.BackslashInPath;
2363 }
2364 }
2365 else if ((check & Check.BackslashInPath) != 0)
2366 {
2367 flags |= Flags.E_PathNotCanonical;
2368 flag2 = true;
2369 }
2370 if ((check & Check.DisplayCanonical) == 0 && ((_flags & Flags.ImplicitFile) == Flags.Zero || (_flags & Flags.UserEscaped) != Flags.Zero || (check & Check.ReservedFound) != 0))
2371 {
2372 flags |= Flags.PathNotCanonical;
2373 flag2 = true;
2374 }
2375 if ((_flags & Flags.ImplicitFile) != Flags.Zero && (check & (Check.EscapedCanonical | Check.ReservedFound)) != 0)
2376 {
2377 check &= ~Check.EscapedCanonical;
2378 }
2379 if ((check & Check.EscapedCanonical) == 0)
2380 {
2381 flags |= Flags.E_PathNotCanonical;
2382 }
2383 if (IriParsing && !flag2 && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
2384 {
2385 flags |= Flags.PathIriCanonical;
2386 }
2387 if (flag)
2388 {
2389 int start2 = num;
2390 if (num < _originalUnicodeString.Length && _originalUnicodeString[num] == '?')
2391 {
2392 if ((flags2 & UriSyntaxFlags.MayHaveFragment) != 0)
2393 {
2394 num++;
2395 int num3 = _originalUnicodeString.AsSpan(num).IndexOf('#');
2396 num = ((num3 == -1) ? _originalUnicodeString.Length : (num3 + num));
2397 }
2398 else
2399 {
2400 num = _originalUnicodeString.Length;
2401 }
2403 if (_string.Length > 65535)
2404 {
2406 throw exception2;
2407 }
2408 length = _string.Length;
2410 {
2412 }
2413 }
2414 }
2415 _info.Offset.Query = (ushort)scheme;
2416 fixed (char* ptr3 = _string)
2417 {
2418 if (scheme < length && ptr3[scheme] == '?')
2419 {
2420 scheme++;
2421 check = CheckCanonical(ptr3, ref scheme, length, ((flags2 & UriSyntaxFlags.MayHaveFragment) != 0) ? '#' : '\ufffe');
2422 if ((check & Check.DisplayCanonical) == 0)
2423 {
2424 flags |= Flags.QueryNotCanonical;
2425 }
2426 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
2427 {
2428 flags |= Flags.E_QueryNotCanonical;
2429 }
2430 if (IriParsing && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.BackslashInPath | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
2431 {
2432 flags |= Flags.QueryIriCanonical;
2433 }
2434 }
2435 }
2436 if (flag)
2437 {
2438 int start3 = num;
2439 if (num < _originalUnicodeString.Length && _originalUnicodeString[num] == '#')
2440 {
2441 num = _originalUnicodeString.Length;
2443 if (_string.Length > 65535)
2444 {
2446 throw exception3;
2447 }
2448 length = _string.Length;
2450 }
2451 }
2452 _info.Offset.Fragment = (ushort)scheme;
2453 fixed (char* ptr4 = _string)
2454 {
2455 if (scheme < length && ptr4[scheme] == '#')
2456 {
2457 scheme++;
2458 check = CheckCanonical(ptr4, ref scheme, length, '\ufffe');
2459 if ((check & Check.DisplayCanonical) == 0)
2460 {
2461 flags |= Flags.FragmentNotCanonical;
2462 }
2463 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
2464 {
2465 flags |= Flags.E_FragmentNotCanonical;
2466 }
2467 if (IriParsing && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.BackslashInPath | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
2468 {
2469 flags |= Flags.FragmentIriCanonical;
2470 }
2471 }
2472 }
2473 _info.Offset.End = (ushort)scheme;
2474 }
2475 }
2476 flags |= Flags.AllUriInfoSet | Flags.RestUnicodeNormalized;
2477 InterlockedSetFlags(flags);
2478 }
2479
2480 private unsafe static int ParseSchemeCheckImplicitFile(char* uriString, int length, ref ParsingError err, ref Flags flags, ref UriParser syntax)
2481 {
2482 int i;
2483 for (i = 0; i < length && UriHelper.IsLWS(uriString[i]); i++)
2484 {
2485 }
2486 int j;
2487 for (j = i; j < length && uriString[j] != ':'; j++)
2488 {
2489 }
2490 if (IntPtr.Size == 4)
2491 {
2492 }
2493 if (i + 2 >= length || j == i)
2494 {
2495 err = ParsingError.BadFormat;
2496 return 0;
2497 }
2498 char c;
2499 if ((c = uriString[i + 1]) == ':' || c == '|')
2500 {
2501 if (UriHelper.IsAsciiLetter(uriString[i]))
2502 {
2503 if ((c = uriString[i + 2]) == '\\' || c == '/')
2504 {
2505 flags |= Flags.AuthorityFound | Flags.DosPath | Flags.ImplicitFile;
2507 return i;
2508 }
2509 err = ParsingError.MustRootedPath;
2510 return 0;
2511 }
2512 if (c == ':')
2513 {
2514 err = ParsingError.BadScheme;
2515 }
2516 else
2517 {
2518 err = ParsingError.BadFormat;
2519 }
2520 return 0;
2521 }
2522 if ((c = uriString[i]) == '/' || c == '\\')
2523 {
2524 if ((c = uriString[i + 1]) == '\\' || c == '/')
2525 {
2526 flags |= Flags.AuthorityFound | Flags.UncPath | Flags.ImplicitFile;
2528 for (i += 2; i < length; i++)
2529 {
2530 if ((c = uriString[i]) != '/' && c != '\\')
2531 {
2532 break;
2533 }
2534 }
2535 return i;
2536 }
2537 err = ParsingError.BadFormat;
2538 return 0;
2539 }
2540 if (j == length)
2541 {
2542 err = ParsingError.BadFormat;
2543 return 0;
2544 }
2545 err = CheckSchemeSyntax(new ReadOnlySpan<char>(uriString + i, j - i), ref syntax);
2546 if (err != 0)
2547 {
2548 return 0;
2549 }
2550 return j + 1;
2551 }
2552
2554 {
2555 if (span.Length == 0)
2556 {
2557 return ParsingError.BadScheme;
2558 }
2559 char c2 = span[0];
2560 switch (c2)
2561 {
2562 case 'A':
2563 case 'B':
2564 case 'C':
2565 case 'D':
2566 case 'E':
2567 case 'F':
2568 case 'G':
2569 case 'H':
2570 case 'I':
2571 case 'J':
2572 case 'K':
2573 case 'L':
2574 case 'M':
2575 case 'N':
2576 case 'O':
2577 case 'P':
2578 case 'Q':
2579 case 'R':
2580 case 'S':
2581 case 'T':
2582 case 'U':
2583 case 'V':
2584 case 'W':
2585 case 'X':
2586 case 'Y':
2587 case 'Z':
2588 c2 = (char)(c2 | 0x20u);
2589 break;
2590 default:
2591 return ParsingError.BadScheme;
2592 case 'a':
2593 case 'b':
2594 case 'c':
2595 case 'd':
2596 case 'e':
2597 case 'f':
2598 case 'g':
2599 case 'h':
2600 case 'i':
2601 case 'j':
2602 case 'k':
2603 case 'l':
2604 case 'm':
2605 case 'n':
2606 case 'o':
2607 case 'p':
2608 case 'q':
2609 case 'r':
2610 case 's':
2611 case 't':
2612 case 'u':
2613 case 'v':
2614 case 'w':
2615 case 'x':
2616 case 'y':
2617 case 'z':
2618 break;
2619 }
2620 switch (span.Length)
2621 {
2622 case 2:
2623 if (30579 == (((uint)c2 << 8) | ToLowerCaseAscii(span[1])))
2624 {
2626 return ParsingError.None;
2627 }
2628 break;
2629 case 3:
2630 switch ((int)(((uint)c2 << 16) | ((uint)ToLowerCaseAscii(span[1]) << 8) | ToLowerCaseAscii(span[2])))
2631 {
2632 case 6714480:
2634 return ParsingError.None;
2635 case 7828339:
2637 return ParsingError.None;
2638 }
2639 break;
2640 case 4:
2641 switch ((int)(((uint)c2 << 24) | ((uint)ToLowerCaseAscii(span[1]) << 16) | ((uint)ToLowerCaseAscii(span[2]) << 8) | ToLowerCaseAscii(span[3])))
2642 {
2643 case 1752462448:
2645 return ParsingError.None;
2646 case 1718185061:
2648 return ParsingError.None;
2649 }
2650 break;
2651 case 5:
2652 if (1752462448 == (((uint)c2 << 24) | ((uint)ToLowerCaseAscii(span[1]) << 16) | ((uint)ToLowerCaseAscii(span[2]) << 8) | ToLowerCaseAscii(span[3])) && ToLowerCaseAscii(span[4]) == 's')
2653 {
2655 return ParsingError.None;
2656 }
2657 break;
2658 case 6:
2659 if (1835100524 == (((uint)c2 << 24) | ((uint)ToLowerCaseAscii(span[1]) << 16) | ((uint)ToLowerCaseAscii(span[2]) << 8) | ToLowerCaseAscii(span[3])) && ToLowerCaseAscii(span[4]) == 't' && ToLowerCaseAscii(span[5]) == 'o')
2660 {
2662 return ParsingError.None;
2663 }
2664 break;
2665 }
2666 for (int i = 1; i < span.Length; i++)
2667 {
2668 char c3 = span[i];
2669 if ((uint)(c3 - 97) > 25u && (uint)(c3 - 65) > 25u && (uint)(c3 - 48) > 9u && c3 != '+' && c3 != '-' && c3 != '.')
2670 {
2671 return ParsingError.BadScheme;
2672 }
2673 }
2674 if (span.Length > 1024)
2675 {
2676 return ParsingError.SchemeLimit;
2677 }
2678 string lwrCaseScheme;
2679 fixed (char* ptr = span)
2680 {
2681 lwrCaseScheme = string.Create(span.Length, ((IntPtr)ptr, span.Length), delegate(Span<char> buffer, (IntPtr ip, int length) state)
2682 {
2683 int num = new ReadOnlySpan<char>((void*)state.ip, state.length).ToLowerInvariant(buffer);
2684 });
2685 }
2687 return ParsingError.None;
2688 static char ToLowerCaseAscii(char c)
2689 {
2690 if ((uint)(c - 65) > 25u)
2691 {
2692 return c;
2693 }
2694 return (char)(c | 0x20u);
2695 }
2696 }
2697
2698 private unsafe int CheckAuthorityHelper(char* pString, int idx, int length, ref ParsingError err, ref Flags flags, UriParser syntax, ref string newHost)
2699 {
2700 int i = length;
2701 int num = idx;
2702 int j = idx;
2703 newHost = null;
2704 bool justNormalized = false;
2705 bool flag = IriParsingStatic(syntax);
2706 bool flag2 = (flags & Flags.HasUnicode) != 0;
2707 bool flag3 = flag2 && (flags & Flags.HostUnicodeNormalized) == 0;
2709 char c;
2710 if (idx == length || (c = pString[idx]) == '/' || (c == '\\' && StaticIsFile(syntax)) || c == '#' || c == '?')
2711 {
2712 if (syntax.InFact(UriSyntaxFlags.AllowEmptyHost))
2713 {
2714 flags &= ~Flags.UncPath;
2715 if (StaticInFact(flags, Flags.ImplicitFile))
2716 {
2717 err = ParsingError.BadHostName;
2718 }
2719 else
2720 {
2721 flags |= Flags.BasicHostType;
2722 }
2723 }
2724 else
2725 {
2726 err = ParsingError.BadHostName;
2727 }
2728 if (flag3)
2729 {
2730 flags |= Flags.HostUnicodeNormalized;
2731 }
2732 return idx;
2733 }
2734 if (flag3)
2735 {
2736 newHost = _originalUnicodeString.Substring(0, num);
2737 }
2738 string text = null;
2739 if ((flags2 & UriSyntaxFlags.MayHaveUserInfo) != 0)
2740 {
2741 for (; j < i; j++)
2742 {
2743 if (j == i - 1 || pString[j] == '?' || pString[j] == '#' || pString[j] == '\\' || pString[j] == '/')
2744 {
2745 j = idx;
2746 break;
2747 }
2748 if (pString[j] != '@')
2749 {
2750 continue;
2751 }
2752 flags |= Flags.HasUserInfo;
2753 if (flag)
2754 {
2755 if (flag3)
2756 {
2757 text = IriHelper.EscapeUnescapeIri(pString, num, j + 1, UriComponents.UserInfo);
2758 newHost += text;
2759 if (newHost.Length > 65535)
2760 {
2761 err = ParsingError.SizeLimit;
2762 return idx;
2763 }
2764 }
2765 else
2766 {
2767 text = new string(pString, num, j - num + 1);
2768 }
2769 }
2770 j++;
2771 c = pString[j];
2772 break;
2773 }
2774 }
2775 bool notCanonical = (flags2 & UriSyntaxFlags.SimpleUserSyntax) == 0;
2776 if (c == '[' && syntax.InFact(UriSyntaxFlags.AllowIPv6Host) && IPv6AddressHelper.IsValid(pString, j + 1, ref i))
2777 {
2778 flags |= Flags.IPv6HostType;
2779 if (flag3)
2780 {
2781 newHost += new string(pString, j, i - j);
2782 flags |= Flags.HostUnicodeNormalized;
2783 justNormalized = true;
2784 }
2785 }
2786 else if (c <= '9' && c >= '0' && syntax.InFact(UriSyntaxFlags.AllowIPv4Host) && IPv4AddressHelper.IsValid(pString, j, ref i, allowIPv6: false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri)))
2787 {
2788 flags |= Flags.IPv4HostType;
2789 if (flag3)
2790 {
2791 newHost += new string(pString, j, i - j);
2792 flags |= Flags.HostUnicodeNormalized;
2793 justNormalized = true;
2794 }
2795 }
2796 else if ((flags2 & UriSyntaxFlags.AllowDnsHost) != 0 && !flag && DomainNameHelper.IsValid(pString, j, ref i, ref notCanonical, StaticNotAny(flags, Flags.ImplicitFile)))
2797 {
2798 flags |= Flags.DnsHostType;
2799 if (!notCanonical)
2800 {
2801 flags |= Flags.CanonicalDnsHost;
2802 }
2803 }
2804 else if ((flags2 & UriSyntaxFlags.AllowDnsHost) != 0 && (flag3 || syntax.InFact(UriSyntaxFlags.AllowIdn)) && DomainNameHelper.IsValidByIri(pString, j, ref i, ref notCanonical, StaticNotAny(flags, Flags.ImplicitFile)))
2805 {
2807 }
2808 else if ((flags2 & UriSyntaxFlags.AllowUncHost) != 0 && UncNameHelper.IsValid(pString, j, ref i, StaticNotAny(flags, Flags.ImplicitFile)) && i - j <= 256)
2809 {
2810 flags |= Flags.UncHostType;
2811 if (flag3)
2812 {
2813 newHost += new string(pString, j, i - j);
2814 flags |= Flags.HostUnicodeNormalized;
2815 justNormalized = true;
2816 }
2817 }
2818 if (i < length && pString[i] == '\\' && (flags & Flags.HostTypeMask) != Flags.Zero && !StaticIsFile(syntax))
2819 {
2820 if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
2821 {
2822 err = ParsingError.BadHostName;
2823 flags |= Flags.HostTypeMask;
2824 return i;
2825 }
2826 flags &= ~Flags.HostTypeMask;
2827 }
2828 else if (i < length && pString[i] == ':')
2829 {
2830 if (syntax.InFact(UriSyntaxFlags.MayHavePort))
2831 {
2832 int num2 = 0;
2833 int num3 = i;
2834 for (idx = i + 1; idx < length; idx++)
2835 {
2836 int num4 = pString[idx] - 48;
2837 switch (num4)
2838 {
2839 case 0:
2840 case 1:
2841 case 2:
2842 case 3:
2843 case 4:
2844 case 5:
2845 case 6:
2846 case 7:
2847 case 8:
2848 case 9:
2849 if ((num2 = num2 * 10 + num4) <= 65535)
2850 {
2851 continue;
2852 }
2853 break;
2854 default:
2855 if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost) && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri))
2856 {
2857 flags &= ~Flags.HostTypeMask;
2858 break;
2859 }
2860 err = ParsingError.BadPort;
2861 return idx;
2862 case -13:
2863 case -1:
2864 case 15:
2865 break;
2866 }
2867 break;
2868 }
2869 if (num2 > 65535)
2870 {
2871 if (!syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
2872 {
2873 err = ParsingError.BadPort;
2874 return idx;
2875 }
2876 flags &= ~Flags.HostTypeMask;
2877 }
2878 if (flag2 && justNormalized)
2879 {
2880 newHost += new string(pString, num3, idx - num3);
2881 }
2882 }
2883 else
2884 {
2885 flags &= ~Flags.HostTypeMask;
2886 }
2887 }
2888 if ((flags & Flags.HostTypeMask) == Flags.Zero)
2889 {
2890 flags &= ~Flags.HasUserInfo;
2891 if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
2892 {
2893 flags |= Flags.BasicHostType;
2894 for (i = idx; i < length && pString[i] != '/' && pString[i] != '?' && pString[i] != '#'; i++)
2895 {
2896 }
2897 if (flag3)
2898 {
2899 string text2 = new string(pString, num, i - num);
2900 try
2901 {
2902 newHost += text2.Normalize(NormalizationForm.FormC);
2903 }
2904 catch (ArgumentException)
2905 {
2906 err = ParsingError.BadHostName;
2907 }
2908 flags |= Flags.HostUnicodeNormalized;
2909 }
2910 }
2911 else if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
2912 {
2913 bool flag4 = false;
2914 int num5 = idx;
2915 for (i = idx; i < length && (!flag4 || (pString[i] != '/' && pString[i] != '?' && pString[i] != '#')); i++)
2916 {
2917 if (i < idx + 2 && pString[i] == '.')
2918 {
2919 flag4 = true;
2920 continue;
2921 }
2922 err = ParsingError.BadHostName;
2923 flags |= Flags.HostTypeMask;
2924 return idx;
2925 }
2926 flags |= Flags.BasicHostType;
2927 if (flag3)
2928 {
2929 string text3 = new string(pString, num5, i - num5);
2930 try
2931 {
2932 newHost += text3.Normalize(NormalizationForm.FormC);
2933 }
2934 catch (ArgumentException)
2935 {
2936 err = ParsingError.BadFormat;
2937 return idx;
2938 }
2939 flags |= Flags.HostUnicodeNormalized;
2940 }
2941 }
2942 else if (syntax.InFact(UriSyntaxFlags.MustHaveAuthority) || syntax.InFact(UriSyntaxFlags.MailToLikeUri))
2943 {
2944 err = ParsingError.BadHostName;
2945 flags |= Flags.HostTypeMask;
2946 return idx;
2947 }
2948 }
2949 return i;
2950 }
2951
2952 private unsafe void CheckAuthorityHelperHandleDnsIri(char* pString, int start, int end, bool hasUnicode, ref Flags flags, ref bool justNormalized, ref string newHost, ref ParsingError err)
2953 {
2954 flags |= Flags.DnsHostType;
2955 if (hasUnicode)
2956 {
2958 try
2959 {
2960 newHost += text.Normalize(NormalizationForm.FormC);
2961 }
2962 catch (ArgumentException)
2963 {
2964 err = ParsingError.BadHostName;
2965 }
2966 justNormalized = true;
2967 }
2968 flags |= Flags.HostUnicodeNormalized;
2969 }
2970
2971 private unsafe Check CheckCanonical(char* str, ref int idx, int end, char delim)
2972 {
2973 Check check = Check.None;
2974 bool flag = false;
2975 bool flag2 = false;
2976 bool iriParsing = IriParsing;
2977 int i;
2978 for (i = idx; i < end; i++)
2979 {
2980 char c = str[i];
2981 if (c <= '\u001f' || (c >= '\u007f' && c <= '\u009f'))
2982 {
2983 flag = true;
2984 flag2 = true;
2985 check |= Check.ReservedFound;
2986 continue;
2987 }
2988 if (c > '~')
2989 {
2990 if (iriParsing)
2991 {
2992 bool flag3 = false;
2993 check |= Check.FoundNonAscii;
2994 if (char.IsHighSurrogate(c))
2995 {
2996 if (i + 1 < end)
2997 {
2998 flag3 = IriHelper.CheckIriUnicodeRange(c, str[i + 1], out var _, isQuery: true);
2999 }
3000 }
3001 else
3002 {
3004 }
3005 if (!flag3)
3006 {
3007 check |= Check.NotIriCanonical;
3008 }
3009 }
3010 if (!flag)
3011 {
3012 flag = true;
3013 }
3014 continue;
3015 }
3016 if (c == delim || (delim == '?' && c == '#' && _syntax != null && _syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
3017 {
3018 break;
3019 }
3020 if (c == '?')
3021 {
3022 if (IsImplicitFile || (_syntax != null && !_syntax.InFact(UriSyntaxFlags.MayHaveQuery) && delim != '\ufffe'))
3023 {
3024 check |= Check.ReservedFound;
3025 flag2 = true;
3026 flag = true;
3027 }
3028 continue;
3029 }
3030 if (c == '#')
3031 {
3032 flag = true;
3033 if (IsImplicitFile || (_syntax != null && !_syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
3034 {
3035 check |= Check.ReservedFound;
3036 flag2 = true;
3037 }
3038 continue;
3039 }
3040 if (c == '/' || c == '\\')
3041 {
3042 if ((check & Check.BackslashInPath) == 0 && c == '\\')
3043 {
3044 check |= Check.BackslashInPath;
3045 }
3046 if ((check & Check.DotSlashAttn) == 0 && i + 1 != end && (str[i + 1] == '/' || str[i + 1] == '\\'))
3047 {
3048 check |= Check.DotSlashAttn;
3049 }
3050 continue;
3051 }
3052 if (c == '.')
3053 {
3054 if (((check & Check.DotSlashAttn) == 0 && i + 1 == end) || str[i + 1] == '.' || str[i + 1] == '/' || str[i + 1] == '\\' || str[i + 1] == '?' || str[i + 1] == '#')
3055 {
3056 check |= Check.DotSlashAttn;
3057 }
3058 continue;
3059 }
3060 if ((c > '"' || c == '!') && (c < '[' || c > '^'))
3061 {
3062 switch (c)
3063 {
3064 case '<':
3065 case '>':
3066 case '`':
3067 break;
3068 case '{':
3069 case '|':
3070 case '}':
3071 flag = true;
3072 continue;
3073 default:
3074 if (c != '%')
3075 {
3076 continue;
3077 }
3078 if (!flag2)
3079 {
3080 flag2 = true;
3081 }
3082 if (i + 2 < end && (c = UriHelper.DecodeHexChars(str[i + 1], str[i + 2])) != '\uffff')
3083 {
3084 if (c == '.' || c == '/' || c == '\\')
3085 {
3086 check |= Check.DotSlashEscaped;
3087 }
3088 i += 2;
3089 }
3090 else if (!flag)
3091 {
3092 flag = true;
3093 }
3094 continue;
3095 }
3096 }
3097 if (!flag)
3098 {
3099 flag = true;
3100 }
3101 if ((_flags & Flags.HasUnicode) != Flags.Zero)
3102 {
3103 check |= Check.NotIriCanonical;
3104 }
3105 }
3106 if (flag2)
3107 {
3108 if (!flag)
3109 {
3110 check |= Check.EscapedCanonical;
3111 }
3112 }
3113 else
3114 {
3115 check |= Check.DisplayCanonical;
3116 if (!flag)
3117 {
3118 check |= Check.EscapedCanonical;
3119 }
3120 }
3121 idx = i;
3122 return check;
3123 }
3124
3126 {
3127 if (InFact(Flags.FirstSlashAbsent))
3128 {
3129 dest.Append('/');
3130 }
3132 {
3133 return;
3134 }
3135 int length = dest.Length;
3137 if (formatAs == UriFormat.UriEscaped)
3138 {
3139 if (InFact(Flags.ShouldBeCompressed))
3140 {
3142 if (_syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) && !IsImplicitFile)
3143 {
3144 fixed (char* pch = dest)
3145 {
3146 int end = dest.Length;
3147 UnescapeOnly(pch, length, ref end, '.', '/', _syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\' : '\uffff');
3148 dest.Length = end;
3149 }
3150 }
3151 }
3152 else if (InFact(Flags.E_PathNotCanonical) && NotAny(Flags.UserEscaped))
3153 {
3156 {
3157 char[] array = readOnlySpan.ToArray();
3160 }
3162 }
3163 else
3164 {
3166 }
3167 }
3168 else
3169 {
3171 if (InFact(Flags.ShouldBeCompressed) && _syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) && !IsImplicitFile)
3172 {
3173 fixed (char* pch2 = dest)
3174 {
3175 int end2 = dest.Length;
3176 UnescapeOnly(pch2, length, ref end2, '.', '/', _syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\' : '\uffff');
3177 dest.Length = end2;
3178 }
3179 }
3180 }
3181 int num = length + securedPathIndex;
3182 if (securedPathIndex != 0 && dest[num - 1] == '|')
3183 {
3184 dest[num - 1] = ':';
3185 }
3186 if (InFact(Flags.ShouldBeCompressed) && dest.Length - num > 0)
3187 {
3188 dest.Length = num + Compress(dest.RawChars.Slice(num, dest.Length - num), _syntax);
3189 if (dest[length] == '\\')
3190 {
3191 dest[length] = '/';
3192 }
3193 if (formatAs == UriFormat.UriEscaped && NotAny(Flags.UserEscaped) && InFact(Flags.E_PathNotCanonical))
3194 {
3197 valueStringBuilder.Append(dest.AsSpan(length, dest.Length - length));
3199 ReadOnlySpan<char> stringToEscape = MemoryMarshal.CreateReadOnlySpan(ref valueStringBuilder.GetPinnableReference(), valueStringBuilder.Length);
3201 length = dest.Length;
3202 valueStringBuilder.Dispose();
3203 }
3204 }
3205 if (formatAs == UriFormat.UriEscaped || !InFact(Flags.PathNotCanonical))
3206 {
3207 return;
3208 }
3210 switch (formatAs)
3211 {
3212 case (UriFormat)32767:
3213 unescapeMode = (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag;
3214 if (IsImplicitFile)
3215 {
3216 unescapeMode &= ~UnescapeMode.Unescape;
3217 }
3218 break;
3219 case UriFormat.Unescaped:
3220 unescapeMode = ((!IsImplicitFile) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : UnescapeMode.CopyOnly);
3221 break;
3222 default:
3223 unescapeMode = (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape);
3224 if (IsImplicitFile)
3225 {
3226 unescapeMode &= ~UnescapeMode.Unescape;
3227 }
3228 break;
3229 }
3230 if (unescapeMode != 0)
3231 {
3234 valueStringBuilder2.Append(dest.AsSpan(length, dest.Length - length));
3237 {
3238 UriHelper.UnescapeString(pStr, 0, valueStringBuilder2.Length, ref dest, '?', '#', '\uffff', unescapeMode, _syntax, isQuery: false);
3239 }
3240 valueStringBuilder2.Dispose();
3241 }
3242 }
3243
3244 private unsafe static void UnescapeOnly(char* pch, int start, ref int end, char ch1, char ch2, char ch3)
3245 {
3246 if (end - start < 3)
3247 {
3248 return;
3249 }
3250 char* ptr = pch + end - 2;
3251 pch += start;
3252 char* ptr2 = null;
3253 while (pch < ptr)
3254 {
3255 if (*(pch++) != '%')
3256 {
3257 continue;
3258 }
3259 char c = UriHelper.DecodeHexChars(*(pch++), *(pch++));
3260 if (c != ch1 && c != ch2 && c != ch3)
3261 {
3262 continue;
3263 }
3264 ptr2 = pch - 2;
3265 *(ptr2 - 1) = c;
3266 while (pch < ptr)
3267 {
3268 if ((*(ptr2++) = *(pch++)) == '%')
3269 {
3270 c = UriHelper.DecodeHexChars(*(ptr2++) = *(pch++), *(ptr2++) = *(pch++));
3271 if (c == ch1 || c == ch2 || c == ch3)
3272 {
3273 ptr2 -= 2;
3274 *(ptr2 - 1) = c;
3275 }
3276 }
3277 }
3278 break;
3279 }
3280 ptr += 2;
3281 if (ptr2 == null)
3282 {
3283 return;
3284 }
3285 if (pch == ptr)
3286 {
3287 end -= (int)(pch - ptr2);
3288 return;
3289 }
3290 *(ptr2++) = *(pch++);
3291 if (pch == ptr)
3292 {
3293 end -= (int)(pch - ptr2);
3294 return;
3295 }
3296 *(ptr2++) = *(pch++);
3297 end -= (int)(pch - ptr2);
3298 }
3299
3300 private static void Compress(char[] dest, int start, ref int destLength, UriParser syntax)
3301 {
3303 }
3304
3306 {
3307 int num = 0;
3308 int num2 = 0;
3309 int num3 = 0;
3310 int num4 = 0;
3311 for (int num5 = span.Length - 1; num5 >= 0; num5--)
3312 {
3313 char c = span[num5];
3314 if (c == '\\' && syntax.InFact(UriSyntaxFlags.ConvertPathSlashes))
3315 {
3316 c = (span[num5] = '/');
3317 }
3318 if (c == '/')
3319 {
3320 num++;
3321 }
3322 else
3323 {
3324 if (num > 1)
3325 {
3326 num2 = num5 + 1;
3327 }
3328 num = 0;
3329 }
3330 if (c == '.')
3331 {
3332 num3++;
3333 continue;
3334 }
3335 if (num3 != 0)
3336 {
3337 if ((!syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) || (num3 <= 2 && c == '/')) && c == '/' && (num2 == num5 + num3 + 1 || (num2 == 0 && num5 + num3 + 1 == span.Length)) && num3 <= 2)
3338 {
3339 num2 = num5 + 1 + num3 + ((num2 != 0) ? 1 : 0);
3340 span.Slice(num2).CopyTo(span.Slice(num5 + 1));
3341 span = span.Slice(0, span.Length - (num2 - num5 - 1));
3342 num2 = num5;
3343 if (num3 == 2)
3344 {
3345 num4++;
3346 }
3347 num3 = 0;
3348 continue;
3349 }
3350 num3 = 0;
3351 }
3352 if (c == '/')
3353 {
3354 if (num4 != 0)
3355 {
3356 num4--;
3357 span.Slice(num2 + 1).CopyTo(span.Slice(num5 + 1));
3358 span = span.Slice(0, span.Length - (num2 - num5));
3359 }
3360 num2 = num5;
3361 }
3362 }
3363 if (span.Length != 0 && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath) && num <= 1)
3364 {
3365 if (num4 != 0 && span[0] != '/')
3366 {
3367 num2++;
3368 span.Slice(num2).CopyTo(span);
3369 return span.Length - num2;
3370 }
3371 if (num3 != 0 && (num2 == num3 || (num2 == 0 && num3 == span.Length)))
3372 {
3373 num3 += ((num2 != 0) ? 1 : 0);
3374 span.Slice(num3).CopyTo(span);
3375 return span.Length - num3;
3376 }
3377 }
3378 return span.Length;
3379 }
3380
3381 private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat)
3382 {
3383 char c = relativePart[0];
3384 if (basePart.IsDosPath && (c == '/' || c == '\\') && (relativePart.Length == 1 || (relativePart[1] != '/' && relativePart[1] != '\\')))
3385 {
3386 int num = basePart.OriginalString.IndexOf(':');
3387 if (basePart.IsImplicitFile)
3388 {
3389 return string.Concat(basePart.OriginalString.AsSpan(0, num + 1), relativePart);
3390 }
3391 num = basePart.OriginalString.IndexOf(':', num + 1);
3392 return string.Concat(basePart.OriginalString.AsSpan(0, num + 1), relativePart);
3393 }
3394 if (StaticIsFile(basePart.Syntax) && (c == '\\' || c == '/'))
3395 {
3396 if (relativePart.Length >= 2 && (relativePart[1] == '\\' || relativePart[1] == '/'))
3397 {
3398 if (!basePart.IsImplicitFile)
3399 {
3400 return "file:" + relativePart;
3401 }
3402 return relativePart;
3403 }
3404 if (basePart.IsUnc)
3405 {
3406 ReadOnlySpan<char> readOnlySpan = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped);
3407 for (int i = 1; i < readOnlySpan.Length; i++)
3408 {
3409 if (readOnlySpan[i] == '/')
3410 {
3411 readOnlySpan = readOnlySpan.Slice(0, i);
3412 break;
3413 }
3414 }
3415 if (basePart.IsImplicitFile)
3416 {
3417 return string.Concat("\\\\", basePart.GetParts(UriComponents.Host, UriFormat.Unescaped), readOnlySpan, relativePart);
3418 }
3419 return string.Concat("file://", basePart.GetParts(UriComponents.Host, uriFormat), readOnlySpan, relativePart);
3420 }
3421 return "file://" + relativePart;
3422 }
3423 bool flag = basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes);
3424 string text = null;
3425 if (c == '/' || (c == '\\' && flag))
3426 {
3427 if (relativePart.Length >= 2 && relativePart[1] == '/')
3428 {
3429 return basePart.Scheme + ":" + relativePart;
3430 }
3431 text = ((basePart.HostType != Flags.IPv6HostType) ? basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat) : $"{basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat)}[{basePart.DnsSafeHost}]{basePart.GetParts(UriComponents.Port | UriComponents.KeepDelimiter, uriFormat)}");
3432 if (!flag || c != '\\')
3433 {
3434 return text + relativePart;
3435 }
3436 return text + "/" + relativePart.AsSpan(1);
3437 }
3438 text = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat);
3439 int num2 = text.Length;
3440 char[] array = new char[num2 + relativePart.Length];
3441 if (num2 > 0)
3442 {
3443 text.CopyTo(0, array, 0, num2);
3444 while (num2 > 0)
3445 {
3446 if (array[--num2] == '/')
3447 {
3448 num2++;
3449 break;
3450 }
3451 }
3452 }
3454 c = (basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : '\uffff');
3455 char c2 = ((!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#' : '\uffff');
3456 ReadOnlySpan<char> readOnlySpan2 = string.Empty;
3457 if (c != '\uffff' || c2 != '\uffff')
3458 {
3459 int j;
3460 for (j = 0; j < relativePart.Length && array[num2 + j] != c && array[num2 + j] != c2; j++)
3461 {
3462 }
3463 if (j == 0)
3464 {
3466 }
3467 else if (j < relativePart.Length)
3468 {
3469 readOnlySpan2 = relativePart.AsSpan(j);
3470 }
3471 num2 += j;
3472 }
3473 else
3474 {
3475 num2 += relativePart.Length;
3476 }
3477 if (basePart.HostType == Flags.IPv6HostType)
3478 {
3479 text = ((!basePart.IsImplicitFile) ? (basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat) + "[" + basePart.DnsSafeHost + "]" + basePart.GetParts(UriComponents.Port | UriComponents.KeepDelimiter, uriFormat)) : ("\\\\[" + basePart.DnsSafeHost + "]"));
3480 }
3481 else if (basePart.IsImplicitFile)
3482 {
3483 if (basePart.IsDosPath)
3484 {
3485 Compress(array, 3, ref num2, basePart.Syntax);
3486 return string.Concat(array.AsSpan(1, num2 - 1), readOnlySpan2);
3487 }
3488 text = "\\\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
3489 }
3490 else
3491 {
3492 text = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
3493 }
3494 Compress(array, basePart.SecuredPathIndex, ref num2, basePart.Syntax);
3495 return string.Concat(text, array.AsSpan(0, num2), readOnlySpan2);
3496 }
3497
3498 private static string PathDifference(string path1, string path2, bool compareCase)
3499 {
3500 int num = -1;
3501 int i;
3502 for (i = 0; i < path1.Length && i < path2.Length && (path1[i] == path2[i] || (!compareCase && char.ToLowerInvariant(path1[i]) == char.ToLowerInvariant(path2[i]))); i++)
3503 {
3504 if (path1[i] == '/')
3505 {
3506 num = i;
3507 }
3508 }
3509 if (i == 0)
3510 {
3511 return path2;
3512 }
3513 if (i == path1.Length && i == path2.Length)
3514 {
3515 return string.Empty;
3516 }
3518 for (; i < path1.Length; i++)
3519 {
3520 if (path1[i] == '/')
3521 {
3522 stringBuilder.Append("../");
3523 }
3524 }
3525 if (stringBuilder.Length == 0 && path2.Length - 1 == num)
3526 {
3527 return "./";
3528 }
3529 return stringBuilder.Append(path2.AsSpan(num + 1)).ToString();
3530 }
3531
3532 [Obsolete("Uri.MakeRelative has been deprecated. Use MakeRelativeUri(Uri uri) instead.")]
3533 public string MakeRelative(Uri toUri)
3534 {
3535 if (toUri == null)
3536 {
3537 throw new ArgumentNullException("toUri");
3538 }
3539 if (IsNotAbsoluteUri || toUri.IsNotAbsoluteUri)
3540 {
3542 }
3543 if (Scheme == toUri.Scheme && Host == toUri.Host && Port == toUri.Port)
3544 {
3545 return PathDifference(AbsolutePath, toUri.AbsolutePath, !IsUncOrDosPath);
3546 }
3547 return toUri.ToString();
3548 }
3549
3550 [Obsolete("Uri.Canonicalize has been deprecated and is not supported.")]
3551 protected virtual void Canonicalize()
3552 {
3553 }
3554
3555 [Obsolete("Uri.Parse has been deprecated and is not supported.")]
3556 protected virtual void Parse()
3557 {
3558 }
3559
3560 [Obsolete("Uri.Escape has been deprecated and is not supported.")]
3561 protected virtual void Escape()
3562 {
3563 }
3564
3565 [Obsolete("Uri.Unescape has been deprecated. Use GetComponents() or static UnescapeDataString() to unescape a Uri component or a string.")]
3566 protected virtual string Unescape(string path)
3567 {
3568 char[] dest = new char[path.Length];
3569 int destPosition = 0;
3570 dest = UriHelper.UnescapeString(path, 0, path.Length, dest, ref destPosition, '\uffff', '\uffff', '\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, isQuery: false);
3571 return new string(dest, 0, destPosition);
3572 }
3573
3574 [Obsolete("Uri.EscapeString has been deprecated. Use GetComponents() or Uri.EscapeDataString to escape a Uri component or a string.")]
3575 protected static string EscapeString(string? str)
3576 {
3577 if (str != null)
3578 {
3580 }
3581 return string.Empty;
3582 }
3583
3584 [Obsolete("Uri.CheckSecurity has been deprecated and is not supported.")]
3585 protected virtual void CheckSecurity()
3586 {
3587 }
3588
3589 [Obsolete("Uri.IsReservedCharacter has been deprecated and is not supported.")]
3590 protected virtual bool IsReservedCharacter(char character)
3591 {
3592 if (character != ';' && character != '/' && character != ':' && character != '@' && character != '&' && character != '=' && character != '+' && character != '$')
3593 {
3594 return character == ',';
3595 }
3596 return true;
3597 }
3598
3599 [Obsolete("Uri.IsExcludedCharacter has been deprecated and is not supported.")]
3600 protected static bool IsExcludedCharacter(char character)
3601 {
3602 if (character > ' ' && character < '\u007f' && character != '<' && character != '>' && character != '#' && character != '%' && character != '"' && character != '{' && character != '}' && character != '|' && character != '\\' && character != '^' && character != '[' && character != ']')
3603 {
3604 return character == '`';
3605 }
3606 return true;
3607 }
3608
3609 [Obsolete("Uri.IsBadFileSystemCharacter has been deprecated and is not supported.")]
3610 protected virtual bool IsBadFileSystemCharacter(char character)
3611 {
3612 if (character >= ' ' && character != ';' && character != '/' && character != '?' && character != ':' && character != '&' && character != '=' && character != ',' && character != '*' && character != '<' && character != '>' && character != '"' && character != '|' && character != '\\')
3613 {
3614 return character == '^';
3615 }
3616 return true;
3617 }
3618
3620 {
3622 {
3624 }
3625 _string = uri ?? string.Empty;
3626 if (dontEscape)
3627 {
3628 _flags |= Flags.UserEscaped;
3629 }
3630 if (creationOptions.DangerousDisablePathAndQueryCanonicalization)
3631 {
3632 _flags |= Flags.DisablePathAndQueryCanonicalization;
3633 }
3636 if (e != null)
3637 {
3638 throw e;
3639 }
3640 }
3641
3643 {
3644 if (err == ParsingError.None)
3645 {
3646 if (IsImplicitFile)
3647 {
3648 if (NotAny(Flags.DosPath) && uriKind != UriKind.Absolute && (uriKind == UriKind.Relative || (_string.Length >= 2 && (_string[0] != '\\' || _string[1] != '\\'))))
3649 {
3650 _syntax = null;
3651 _flags &= Flags.UserEscaped;
3652 e = null;
3653 return;
3654 }
3655 if (uriKind == UriKind.Relative && InFact(Flags.DosPath))
3656 {
3657 _syntax = null;
3658 _flags &= Flags.UserEscaped;
3659 e = null;
3660 return;
3661 }
3662 }
3663 }
3664 else if (err > ParsingError.EmptyUriString)
3665 {
3666 _string = null;
3667 e = GetException(err);
3668 return;
3669 }
3670 bool flag = false;
3672 {
3673 _flags |= Flags.HasUnicode;
3674 flag = true;
3676 }
3677 if (_syntax != null)
3678 {
3679 if (_syntax.IsSimple)
3680 {
3681 if ((err = PrivateParseMinimal()) != 0)
3682 {
3683 if (uriKind != UriKind.Absolute && err <= ParsingError.EmptyUriString)
3684 {
3685 _syntax = null;
3686 e = null;
3687 _flags &= Flags.UserEscaped;
3688 return;
3689 }
3690 e = GetException(err);
3691 }
3692 else if (uriKind == UriKind.Relative)
3693 {
3694 e = GetException(ParsingError.CannotCreateRelative);
3695 }
3696 else
3697 {
3698 e = null;
3699 }
3700 if (flag)
3701 {
3702 try
3703 {
3705 return;
3706 }
3707 catch (UriFormatException ex)
3708 {
3709 e = ex;
3710 return;
3711 }
3712 }
3713 return;
3714 }
3716 _flags |= Flags.UserDrivenParsing;
3717 _syntax.InternalValidate(this, out e);
3718 if (e != null)
3719 {
3720 if (uriKind != UriKind.Absolute && err != 0 && err <= ParsingError.EmptyUriString)
3721 {
3722 _syntax = null;
3723 e = null;
3724 _flags &= Flags.UserEscaped;
3725 }
3726 return;
3727 }
3728 if (err != 0 || InFact(Flags.ErrorOrParsingRecursion))
3729 {
3730 _flags = Flags.UserDrivenParsing | (_flags & Flags.UserEscaped);
3731 }
3732 else if (uriKind == UriKind.Relative)
3733 {
3734 e = GetException(ParsingError.CannotCreateRelative);
3735 }
3736 if (flag)
3737 {
3738 try
3739 {
3741 }
3742 catch (UriFormatException ex2)
3743 {
3744 e = ex2;
3745 }
3746 }
3747 }
3748 else if (err != 0 && uriKind != UriKind.Absolute && err <= ParsingError.EmptyUriString)
3749 {
3750 e = null;
3751 _flags &= Flags.UserEscaped | Flags.HasUnicode;
3752 if (flag)
3753 {
3755 if (_string.Length > 65535)
3756 {
3757 err = ParsingError.SizeLimit;
3758 }
3759 }
3760 }
3761 else
3762 {
3763 _string = null;
3764 e = GetException(err);
3765 }
3766 }
3767
3768 private static bool CheckForUnicodeOrEscapedUnreserved(string data)
3769 {
3770 for (int i = 0; i < data.Length; i++)
3771 {
3772 char c = data[i];
3773 if (c == '%')
3774 {
3775 if ((uint)(i + 2) < (uint)data.Length)
3776 {
3777 char c2 = UriHelper.DecodeHexChars(data[i + 1], data[i + 2]);
3779 {
3780 return true;
3781 }
3782 i += 2;
3783 }
3784 }
3785 else if (c > '\u007f')
3786 {
3787 return true;
3788 }
3789 }
3790 return false;
3791 }
3792
3793 public static bool TryCreate([NotNullWhen(true)] string? uriString, UriKind uriKind, [NotNullWhen(true)] out Uri? result)
3794 {
3795 if (uriString == null)
3796 {
3797 result = null;
3798 return false;
3799 }
3800 UriFormatException e = null;
3802 result = CreateHelper(uriString, dontEscape: false, uriKind, ref e, in creationOptions);
3803 if (e == null)
3804 {
3805 return result != null;
3806 }
3807 return false;
3808 }
3809
3810 public static bool TryCreate([NotNullWhen(true)] string? uriString, in UriCreationOptions creationOptions, [NotNullWhen(true)] out Uri? result)
3811 {
3812 if (uriString == null)
3813 {
3814 result = null;
3815 return false;
3816 }
3817 UriFormatException e = null;
3818 result = CreateHelper(uriString, dontEscape: false, UriKind.Absolute, ref e, in creationOptions);
3819 if (e == null)
3820 {
3821 return result != null;
3822 }
3823 return false;
3824 }
3825
3826 public static bool TryCreate(Uri? baseUri, string? relativeUri, [NotNullWhen(true)] out Uri? result)
3827 {
3828 if (TryCreate(relativeUri, UriKind.RelativeOrAbsolute, out Uri result2))
3829 {
3830 if (!result2.IsAbsoluteUri)
3831 {
3832 return TryCreate(baseUri, result2, out result);
3833 }
3834 result = result2;
3835 return true;
3836 }
3837 result = null;
3838 return false;
3839 }
3840
3841 public static bool TryCreate(Uri? baseUri, Uri? relativeUri, [NotNullWhen(true)] out Uri? result)
3842 {
3843 result = null;
3844 if ((object)baseUri == null || (object)relativeUri == null)
3845 {
3846 return false;
3847 }
3848 if (baseUri.IsNotAbsoluteUri)
3849 {
3850 return false;
3851 }
3853 string newUriString = null;
3854 bool userEscaped;
3855 if (baseUri.Syntax.IsSimple)
3856 {
3857 userEscaped = relativeUri.UserEscaped;
3859 }
3860 else
3861 {
3862 userEscaped = false;
3864 if (parsingError != null)
3865 {
3866 return false;
3867 }
3868 }
3869 if ((object)result == null)
3870 {
3871 string uriString = newUriString;
3872 bool dontEscape = userEscaped;
3874 result = CreateHelper(uriString, dontEscape, UriKind.Absolute, ref parsingError, in creationOptions);
3875 }
3876 if (parsingError == null && result != null)
3877 {
3878 return result.IsAbsoluteUri;
3879 }
3880 return false;
3881 }
3882
3891
3893 {
3894 if (((uint)components & 0x80000000u) != 0 && components != UriComponents.SerializationInfoString)
3895 {
3897 }
3898 if (((uint)format & 0xFFFFFFFCu) != 0)
3899 {
3900 throw new ArgumentOutOfRangeException("format");
3901 }
3902 if (IsNotAbsoluteUri)
3903 {
3904 if (components == UriComponents.SerializationInfoString)
3905 {
3907 }
3909 }
3910 if (Syntax.IsSimple)
3911 {
3913 }
3915 }
3916
3918 {
3919 if ((object)uri1 == null)
3920 {
3921 if ((object)uri2 == null)
3922 {
3923 return 0;
3924 }
3925 return -1;
3926 }
3927 if ((object)uri2 == null)
3928 {
3929 return 1;
3930 }
3931 if (!uri1.IsAbsoluteUri || !uri2.IsAbsoluteUri)
3932 {
3933 if (!uri1.IsAbsoluteUri)
3934 {
3935 if (!uri2.IsAbsoluteUri)
3936 {
3937 return string.Compare(uri1.OriginalString, uri2.OriginalString, comparisonType);
3938 }
3939 return -1;
3940 }
3941 return 1;
3942 }
3943 return string.Compare(uri1.GetParts(partsToCompare, compareFormat), uri2.GetParts(partsToCompare, compareFormat), comparisonType);
3944 }
3945
3947 {
3949 {
3951 }
3953 }
3954
3955 public static bool IsWellFormedUriString([NotNullWhen(true)] string? uriString, UriKind uriKind)
3956 {
3957 if (!TryCreate(uriString, uriKind, out Uri result))
3958 {
3959 return false;
3960 }
3961 return result.IsWellFormedOriginalString();
3962 }
3963
3965 {
3967 {
3969 }
3970 fixed (char* ptr = _string)
3971 {
3972 int idx = 0;
3973 if (!IsAbsoluteUri)
3974 {
3976 {
3977 return false;
3978 }
3979 return (CheckCanonical(ptr, ref idx, _string.Length, '\ufffe') & (Check.EscapedCanonical | Check.BackslashInPath)) == Check.EscapedCanonical;
3980 }
3981 if (IsImplicitFile)
3982 {
3983 return false;
3984 }
3986 Flags flags = _flags & (Flags.E_CannotDisplayCanonical | Flags.IriCanonical);
3987 if ((flags & Flags.IriCanonical) != Flags.Zero)
3988 {
3989 if ((flags & (Flags.E_UserNotCanonical | Flags.UserIriCanonical)) == (Flags.E_UserNotCanonical | Flags.UserIriCanonical))
3990 {
3991 flags &= ~(Flags.E_UserNotCanonical | Flags.UserIriCanonical);
3992 }
3993 if ((flags & (Flags.E_PathNotCanonical | Flags.PathIriCanonical)) == (Flags.E_PathNotCanonical | Flags.PathIriCanonical))
3994 {
3995 flags &= ~(Flags.E_PathNotCanonical | Flags.PathIriCanonical);
3996 }
3997 if ((flags & (Flags.E_QueryNotCanonical | Flags.QueryIriCanonical)) == (Flags.E_QueryNotCanonical | Flags.QueryIriCanonical))
3998 {
3999 flags &= ~(Flags.E_QueryNotCanonical | Flags.QueryIriCanonical);
4000 }
4001 if ((flags & (Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical)) == (Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical))
4002 {
4003 flags &= ~(Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical);
4004 }
4005 }
4006 if ((flags & Flags.E_CannotDisplayCanonical & (Flags.E_UserNotCanonical | Flags.E_PathNotCanonical | Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical)) != Flags.Zero)
4007 {
4008 return false;
4009 }
4010 if (InFact(Flags.AuthorityFound))
4011 {
4013 if (idx >= _info.Offset.User || _string[idx - 1] == '\\' || _string[idx] == '\\')
4014 {
4015 return false;
4016 }
4017 if (InFact(Flags.DosPath | Flags.UncPath) && ++idx < _info.Offset.User && (_string[idx] == '/' || _string[idx] == '\\'))
4018 {
4019 return false;
4020 }
4021 }
4022 if (InFact(Flags.FirstSlashAbsent) && _info.Offset.Query > _info.Offset.Path)
4023 {
4024 return false;
4025 }
4026 if (InFact(Flags.BackslashInPath))
4027 {
4028 return false;
4029 }
4030 if (IsDosPath && _string[_info.Offset.Path + SecuredPathIndex - 1] == '|')
4031 {
4032 return false;
4033 }
4034 if ((_flags & Flags.CanonicalDnsHost) == Flags.Zero && HostType != Flags.IPv6HostType)
4035 {
4036 idx = _info.Offset.User;
4037 Check check = CheckCanonical(ptr, ref idx, _info.Offset.Path, '/');
4038 if ((check & (Check.EscapedCanonical | Check.BackslashInPath | Check.ReservedFound)) != Check.EscapedCanonical && (!IriParsing || (check & (Check.DisplayCanonical | Check.NotIriCanonical | Check.FoundNonAscii)) != (Check.DisplayCanonical | Check.FoundNonAscii)))
4039 {
4040 return false;
4041 }
4042 }
4043 if ((_flags & (Flags.SchemeNotCanonical | Flags.AuthorityFound)) == (Flags.SchemeNotCanonical | Flags.AuthorityFound))
4044 {
4045 idx = _syntax.SchemeName.Length;
4046 while (ptr[idx++] != ':')
4047 {
4048 }
4049 if (idx + 1 >= _string.Length || ptr[idx] != '/' || ptr[idx + 1] != '/')
4050 {
4051 return false;
4052 }
4053 }
4054 }
4055 return true;
4056 }
4057
4058 public static string UnescapeDataString(string stringToUnescape)
4059 {
4060 if (stringToUnescape == null)
4061 {
4062 throw new ArgumentNullException("stringToUnescape");
4063 }
4064 if (stringToUnescape.Length == 0)
4065 {
4066 return string.Empty;
4067 }
4068 int num = stringToUnescape.IndexOf('%');
4069 if (num == -1)
4070 {
4071 return stringToUnescape;
4072 }
4076 dest.Append(stringToUnescape.AsSpan(0, num));
4077 UriHelper.UnescapeString(stringToUnescape, num, stringToUnescape.Length, ref dest, '\uffff', '\uffff', '\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, isQuery: false);
4078 return dest.ToString();
4079 }
4080
4081 [Obsolete("Uri.EscapeUriString can corrupt the Uri string in some cases. Consider using Uri.EscapeDataString for query string components instead.", DiagnosticId = "SYSLIB0013", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
4086
4091
4092 internal unsafe string EscapeUnescapeIri(string input, int start, int end, UriComponents component)
4093 {
4094 fixed (char* pInput = input)
4095 {
4097 }
4098 }
4099
4100 private Uri(Flags flags, UriParser uriParser, string uri)
4101 {
4102 _flags = flags;
4104 _string = uri;
4105 }
4106
4108 {
4110 {
4112 }
4113 UriParser syntax = null;
4114 Flags flags = Flags.Zero;
4115 ParsingError parsingError = ParseScheme(uriString, ref flags, ref syntax);
4116 if (dontEscape)
4117 {
4118 flags |= Flags.UserEscaped;
4119 }
4120 if (creationOptions.DangerousDisablePathAndQueryCanonicalization)
4121 {
4122 flags |= Flags.DisablePathAndQueryCanonicalization;
4123 }
4124 if (parsingError != 0)
4125 {
4126 if (uriKind != UriKind.Absolute && parsingError <= ParsingError.EmptyUriString)
4127 {
4128 return new Uri(flags & Flags.UserEscaped, null, uriString);
4129 }
4130 return null;
4131 }
4132 Uri uri = new Uri(flags, syntax, uriString);
4133 try
4134 {
4136 if (e == null)
4137 {
4138 return uri;
4139 }
4140 return null;
4141 }
4142 catch (UriFormatException ex)
4143 {
4144 e = ex;
4145 return null;
4146 }
4147 }
4148
4149 internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped)
4150 {
4151 string text;
4152 if ((object)relativeUri != null)
4153 {
4154 if (relativeUri.IsAbsoluteUri)
4155 {
4156 return relativeUri;
4157 }
4158 text = relativeUri.OriginalString;
4159 userEscaped = relativeUri.UserEscaped;
4160 }
4161 else
4162 {
4163 text = string.Empty;
4164 }
4165 if (text.Length > 0 && (UriHelper.IsLWS(text[0]) || UriHelper.IsLWS(text[text.Length - 1])))
4166 {
4167 text = text.Trim(UriHelper.s_WSchars);
4168 }
4169 if (text.Length == 0)
4170 {
4171 newUriString = baseUri.GetParts(UriComponents.AbsoluteUri, baseUri.UserEscaped ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
4172 return null;
4173 }
4174 if (text[0] == '#' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
4175 {
4176 newUriString = baseUri.GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.UriEscaped) + text;
4177 return null;
4178 }
4179 if (text[0] == '?' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
4180 {
4181 newUriString = baseUri.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo | UriComponents.Path, UriFormat.UriEscaped) + text;
4182 return null;
4183 }
4184 if (text.Length >= 3 && (text[1] == ':' || text[1] == '|') && UriHelper.IsAsciiLetter(text[0]) && (text[2] == '\\' || text[2] == '/'))
4185 {
4186 if (baseUri.IsImplicitFile)
4187 {
4189 return null;
4190 }
4191 if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
4192 {
4193 newUriString = string.Concat(str1: (!baseUri.InFact(Flags.AuthorityFound)) ? (baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":/" : ":") : (baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":///" : "://"), str0: baseUri.Scheme, str2: text);
4194 return null;
4195 }
4196 }
4198 if ((object)newUriString == baseUri._string)
4199 {
4200 return baseUri;
4201 }
4202 return null;
4203 }
4204
4206 {
4207 switch (format)
4208 {
4209 case UriFormat.UriEscaped:
4211 case UriFormat.Unescaped:
4213 case UriFormat.SafeUnescaped:
4214 {
4215 if (_string.Length == 0)
4216 {
4217 return string.Empty;
4218 }
4221 UriHelper.UnescapeString(_string, ref dest, '\uffff', '\uffff', '\uffff', UnescapeMode.EscapeUnescape, null, isQuery: false);
4222 return dest.ToString();
4223 }
4224 default:
4225 throw new ArgumentOutOfRangeException("format");
4226 }
4227 }
4228
4230 {
4231 if (uriComponents == UriComponents.Scheme)
4232 {
4233 return _syntax.SchemeName;
4234 }
4235 if (((uint)uriComponents & 0x80000000u) != 0)
4236 {
4237 uriComponents |= UriComponents.AbsoluteUri;
4238 }
4240 if ((uriComponents & UriComponents.NormalizedHost) != 0)
4241 {
4243 }
4244 if ((uriComponents & UriComponents.Host) != 0)
4245 {
4247 }
4248 if (uriComponents == UriComponents.Port || uriComponents == UriComponents.StrongPort)
4249 {
4250 if ((_flags & Flags.NotDefaultPort) != Flags.Zero || (uriComponents == UriComponents.StrongPort && _syntax.DefaultPort != -1))
4251 {
4253 }
4254 return string.Empty;
4255 }
4256 if ((uriComponents & UriComponents.StrongPort) != 0)
4257 {
4259 }
4260 if (uriComponents == UriComponents.Host && (uriFormat == UriFormat.UriEscaped || (_flags & (Flags.HostNotCanonical | Flags.E_HostNotCanonical)) == Flags.Zero))
4261 {
4263 return _info.Host;
4264 }
4265 switch (uriFormat)
4266 {
4267 case UriFormat.UriEscaped:
4269 case UriFormat.Unescaped:
4270 case UriFormat.SafeUnescaped:
4271 case (UriFormat)32767:
4273 default:
4274 throw new ArgumentOutOfRangeException("uriFormat");
4275 }
4276 }
4277
4278 public bool IsBaseOf(Uri uri)
4279 {
4280 if ((object)uri == null)
4281 {
4282 throw new ArgumentNullException("uri");
4283 }
4284 if (!IsAbsoluteUri)
4285 {
4286 return false;
4287 }
4288 if (Syntax.IsSimple)
4289 {
4290 return IsBaseOfHelper(uri);
4291 }
4292 return Syntax.InternalIsBaseOf(this, uri);
4293 }
4294
4295 internal unsafe bool IsBaseOfHelper(Uri uriLink)
4296 {
4297 //The blocks IL_00a5, IL_00bf, IL_00c7, IL_00c8 are reachable both inside and outside the pinned region starting at IL_00a0. ILSpy has duplicated these blocks in order to place them both within and outside the `fixed` statement.
4299 {
4300 return false;
4301 }
4302 if (!uriLink.IsAbsoluteUri)
4303 {
4304 string newUriString = null;
4305 bool userEscaped = false;
4307 if ((object)uriLink == null)
4308 {
4309 UriFormatException e = null;
4310 string uriString = newUriString;
4311 bool dontEscape = userEscaped;
4313 uriLink = CreateHelper(uriString, dontEscape, UriKind.Absolute, ref e, in creationOptions);
4314 if (e != null)
4315 {
4316 return false;
4317 }
4318 }
4319 }
4320 if (Syntax.SchemeName != uriLink.Syntax.SchemeName)
4321 {
4322 return false;
4323 }
4324 string parts = GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.SafeUnescaped);
4325 string parts2 = uriLink.GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.SafeUnescaped);
4326 fixed (char* ptr3 = parts)
4327 {
4328 char* intPtr;
4329 char* selfPtr;
4330 int length;
4331 char* otherPtr;
4332 int length2;
4333 int ignoreCase;
4334 char* ptr2;
4335 if (parts2 != null)
4336 {
4337 fixed (char* ptr = &parts2.GetPinnableReference())
4338 {
4339 intPtr = (ptr2 = ptr);
4340 selfPtr = ptr3;
4341 length = parts.Length;
4342 otherPtr = ptr2;
4343 length2 = parts2.Length;
4344 ignoreCase = ((IsUncOrDosPath || uriLink.IsUncOrDosPath) ? 1 : 0);
4346 }
4347 }
4348 intPtr = (ptr2 = null);
4349 selfPtr = ptr3;
4350 length = parts.Length;
4351 otherPtr = ptr2;
4352 length2 = parts2.Length;
4353 ignoreCase = ((IsUncOrDosPath || uriLink.IsUncOrDosPath) ? 1 : 0);
4355 }
4356 }
4357
4359 {
4360 _info = null;
4361 _flags = otherUri._flags;
4362 if (InFact(Flags.MinimalUriInfoSet))
4363 {
4364 _flags &= ~(Flags.IndexMask | Flags.MinimalUriInfoSet | Flags.AllUriInfoSet);
4365 int num = otherUri._info.Offset.Path;
4366 if (InFact(Flags.NotDefaultPort))
4367 {
4368 while (otherUri._string[num] != ':' && num > otherUri._info.Offset.Host)
4369 {
4370 num--;
4371 }
4372 if (otherUri._string[num] != ':')
4373 {
4374 num = otherUri._info.Offset.Path;
4375 }
4376 }
4377 _flags |= (Flags)num;
4378 }
4379 _syntax = otherUri._syntax;
4380 _string = otherUri._string;
4381 _originalUnicodeString = otherUri._originalUnicodeString;
4382 }
4383}
bool ICollection< KeyValuePair< TKey, TValue > >. Remove(KeyValuePair< TKey, TValue > keyValuePair)
void CopyTo(KeyValuePair< TKey, TValue >[] array, int index)
void Add(TKey key, TValue value)
static bool TryGetUnicodeEquivalent(string hostname, ref System.Text.ValueStringBuilder dest)
static string ParseCanonicalName(string str, int start, int end, ref bool loopback)
static unsafe bool IsValid(char *name, int pos, ref int returnedEnd, ref bool notCanonical, bool notImplicitFile)
static string IdnEquivalent(string hostname)
static unsafe bool IsValidByIri(char *name, int pos, ref int returnedEnd, ref bool notCanonical, bool notImplicitFile)
static CultureInfo InvariantCulture
static void ToCharsBuffer(byte value, Span< char > buffer, int startingIndex=0, Casing casing=Casing.Upper)
static bool IsHexChar(int c)
static int FromChar(int c)
static unsafe bool IsValid(char *name, int start, ref int end, bool allowIPv6, bool notImplicitFile, bool unknownScheme)
static unsafe string ParseCanonicalName(string str, int start, int end, ref bool isLoopback)
static string ParseCanonicalName(string str, int start, ref bool isLoopback, ref string scopeId)
static unsafe bool IsValid(char *name, int start, ref int end)
static unsafe string EscapeUnescapeIri(char *pInput, int start, int end, UriComponents component)
Definition IriHelper.cs:84
static bool CheckIriUnicodeRange(char unicode, bool isQuery)
Definition IriHelper.cs:8
static string net_uri_BadAuthority
Definition SR.cs:14
static string net_uri_BadPort
Definition SR.cs:26
static string InvalidNullArgument
Definition SR.cs:86
static string net_uri_EmptyUri
Definition SR.cs:38
static string net_uri_BadScheme
Definition SR.cs:28
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_uri_BadFormat
Definition SR.cs:18
static string net_uri_PortOutOfRange
Definition SR.cs:46
static string net_uri_SizeLimit
Definition SR.cs:48
static string net_uri_MustRootedPath
Definition SR.cs:42
static string net_uri_NotAbsolute
Definition SR.cs:16
static string net_uri_BadHostName
Definition SR.cs:24
static string net_uri_InvalidUriKind
Definition SR.cs:40
static string net_uri_SchemeLimit
Definition SR.cs:36
static string net_uri_UserDrivenParsing
Definition SR.cs:50
static string net_uri_GetComponentsCalledWhenCanonicalizationDisabled
Definition SR.cs:64
static string net_uri_BadAuthorityTerminator
Definition SR.cs:16
static string Argument_InvalidUriSubcomponent
Definition SR.cs:58
static string net_uri_CannotCreateRelative
Definition SR.cs:34
static string net_uri_NotJustSerialization
Definition SR.cs:52
Definition SR.cs:7
static StringComparer OrdinalIgnoreCase
static int CompareExchange(ref int location1, int value, int comparand)
static int Or(ref int location1, int value)
static string ParseCanonicalName(string str, int start, int end, ref bool loopback)
static unsafe bool IsValid(char *name, int start, ref int returnedEnd, bool notImplicitFile)
static bool IsLWS(char ch)
Definition UriHelper.cs:444
static ReadOnlySpan< bool > UnreservedReservedTable
Definition UriHelper.cs:12
static ReadOnlySpan< bool > UnreservedTable
Definition UriHelper.cs:29
static unsafe char[] UnescapeString(string input, int start, int end, char[] dest, ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery)
Definition UriHelper.cs:245
static bool IsAsciiLetterOrDigit(char character)
Definition UriHelper.cs:462
static string EscapeString(string stringToEscape, bool checkExistingEscaped, ReadOnlySpan< bool > unreserved, char forceEscape1='\0', char forceEscape2='\0')
Definition UriHelper.cs:110
static unsafe bool TestForSubPath(char *selfPtr, int selfLength, char *otherPtr, int otherLength, bool ignoreCase)
Definition UriHelper.cs:46
static bool IsAsciiLetter(char character)
Definition UriHelper.cs:457
static readonly char[] s_WSchars
Definition UriHelper.cs:10
static char DecodeHexChars(int first, int second)
Definition UriHelper.cs:415
static unsafe string StripBidiControlCharacters(ReadOnlySpan< char > strToClean, string backingString=null)
Definition UriHelper.cs:485
UriSyntaxFlags Flags
Definition UriParser.cs:85
bool IsAllSet(UriSyntaxFlags flags)
Definition UriParser.cs:226
string InternalGetComponents(Uri thisUri, UriComponents uriComponents, UriFormat uriFormat)
Definition UriParser.cs:336
static readonly UriParser FtpUri
Definition UriParser.cs:27
bool InternalIsBaseOf(Uri thisBaseUri, Uri uriLink)
Definition UriParser.cs:331
string InternalResolve(Uri thisBaseUri, Uri uriLink, out UriFormatException parsingError)
Definition UriParser.cs:326
static readonly UriParser NewsUri
Definition UriParser.cs:37
static readonly UriParser NetTcpUri
Definition UriParser.cs:47
static readonly UriParser WssUri
Definition UriParser.cs:25
static UriParser FindOrFetchAsUnknownV1Syntax(string lwrCaseScheme)
Definition UriParser.cs:270
static readonly UriParser GopherUri
Definition UriParser.cs:33
bool NotAny(UriSyntaxFlags flags)
Definition UriParser.cs:216
UriParser InternalOnNewUri()
Definition UriParser.cs:308
static readonly UriParser TelnetUri
Definition UriParser.cs:43
static readonly UriParser FileUri
Definition UriParser.cs:29
static readonly UriParser NetPipeUri
Definition UriParser.cs:49
void InternalValidate(Uri thisUri, out UriFormatException parsingError)
Definition UriParser.cs:320
static readonly UriParser HttpsUri
Definition UriParser.cs:21
bool InternalIsWellFormedOriginalString(Uri thisUri)
Definition UriParser.cs:341
static readonly UriParser NntpUri
Definition UriParser.cs:35
static readonly UriParser MailToUri
Definition UriParser.cs:39
string SchemeName
Definition UriParser.cs:81
bool InFact(UriSyntaxFlags flags)
Definition UriParser.cs:221
static readonly UriParser WsUri
Definition UriParser.cs:23
static readonly UriParser HttpUri
Definition UriParser.cs:19
string AbsoluteUri
Definition Uri.cs:136
string RemoteUrl
Definition Uri.cs:138
string Fragment
Definition Uri.cs:134
string PathAndQuery
Definition Uri.cs:89
MoreInfo _moreInfo
Definition Uri.cs:93
string IdnHost
Definition Uri.cs:87
string Host
Definition Uri.cs:85
MoreInfo MoreInfo
Definition Uri.cs:96
string ScopeId
Definition Uri.cs:91
string String
Definition Uri.cs:83
Offset Offset
Definition Uri.cs:81
static readonly string UriSchemeWs
Definition Uri.cs:169
static int FromHex(char digit)
Definition Uri.cs:1093
bool IsUncOrDosPath
Definition Uri.cs:203
string[] Segments
Definition Uri.cs:400
Uri(string uriString)
Definition Uri.cs:653
string GetUriPartsFromUserString(UriComponents uriParts)
Definition Uri.cs:2069
UriParser Syntax
Definition Uri.cs:211
static readonly string UriSchemeNews
Definition Uri.cs:175
UriParser _syntax
Definition Uri.cs:193
static void GetCombinedString(Uri baseUri, string relativeStr, bool dontEscape, ref string result)
Definition Uri.cs:839
string UserInfo
Definition Uri.cs:577
virtual void Escape()
Definition Uri.cs:3561
bool UserEscaped
Definition Uri.cs:574
void CreateThisFromUri(Uri otherUri)
Definition Uri.cs:4358
unsafe bool IsBaseOfHelper(Uri uriLink)
Definition Uri.cs:4295
Uri(string uriString, bool dontEscape)
Definition Uri.cs:664
bool IriParsing
Definition Uri.cs:215
void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatException e)
Definition Uri.cs:3642
unsafe string EscapeUnescapeIri(string input, int start, int end, UriComponents component)
Definition Uri.cs:4092
unsafe bool InternalIsWellFormedOriginalString()
Definition Uri.cs:3964
unsafe void CheckAuthorityHelperHandleDnsIri(char *pString, int start, int end, bool hasUnicode, ref Flags flags, ref bool justNormalized, ref string newHost, ref ParsingError err)
Definition Uri.cs:2952
void EnsureParseRemaining()
Definition Uri.cs:636
Uri(string uriString, in UriCreationOptions creationOptions)
Definition Uri.cs:698
string Host
Definition Uri.cs:441
static readonly string UriSchemeSftp
Definition Uri.cs:159
string IdnHost
Definition Uri.cs:537
void InterlockedSetFlags(Flags flags)
Definition Uri.cs:588
string PathAndQuery
Definition Uri.cs:378
Uri(string uriString, UriKind uriKind)
Definition Uri.cs:688
UriFormatException ParseMinimal()
Definition Uri.cs:1343
string DnsSafeHost
Definition Uri.cs:519
static Uri CreateHelper(string uriString, bool dontEscape, UriKind uriKind, ref UriFormatException e, in UriCreationOptions creationOptions=default(UriCreationOptions))
Definition Uri.cs:4107
static bool TryCreate([NotNullWhen(true)] string? uriString, UriKind uriKind, [NotNullWhen(true)] out Uri? result)
Definition Uri.cs:3793
virtual bool IsBadFileSystemCharacter(char character)
Definition Uri.cs:3610
static bool TryCreate(Uri? baseUri, string? relativeUri, [NotNullWhen(true)] out Uri? result)
Definition Uri.cs:3826
bool IsUncPath
Definition Uri.cs:207
string AbsolutePath
Definition Uri.cs:239
string GetComponentsHelper(UriComponents uriComponents, UriFormat uriFormat)
Definition Uri.cs:4229
bool IsFile
Definition Uri.cs:353
virtual void Canonicalize()
Definition Uri.cs:3551
string GetUnescapedParts(UriComponents uriParts, UriFormat formatAs)
Definition Uri.cs:1862
bool IsDefaultPort
Definition Uri.cs:333
static bool IsHexEncoding(string pattern, int index)
Definition Uri.cs:1063
static readonly string UriSchemeFtp
Definition Uri.cs:157
static string EscapeDataString(string stringToEscape)
Definition Uri.cs:4087
void ISerializable. GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
Definition Uri.cs:741
Uri MakeRelativeUri(Uri uri)
Definition Uri.cs:1276
string Query
Definition Uri.cs:477
virtual void CheckSecurity()
Definition Uri.cs:3585
static unsafe UriHostNameType CheckHostName(string? name)
Definition Uri.cs:963
Uri(SerializationInfo serializationInfo, StreamingContext streamingContext)
Definition Uri.cs:720
static string EscapeUriString(string stringToEscape)
Definition Uri.cs:4082
unsafe void GetHostViaCustomSyntax()
Definition Uri.cs:1751
bool UserDrivenParsing
Definition Uri.cs:219
string GetLeftPart(UriPartial part)
Definition Uri.cs:1006
static readonly string UriSchemeTelnet
Definition Uri.cs:181
Uri(Uri baseUri, string? relativeUri, bool dontEscape)
Definition Uri.cs:675
static readonly string UriSchemeFile
Definition Uri.cs:155
int SecuredPathIndex
Definition Uri.cs:222
string _originalUnicodeString
Definition Uri.cs:191
bool DisablePathAndQueryCanonicalization
Definition Uri.cs:217
static readonly string UriSchemeNetTcp
Definition Uri.cs:183
Flags _flags
Definition Uri.cs:195
bool IsDosPath
Definition Uri.cs:205
string AbsoluteUri
Definition Uri.cs:266
Uri(Flags flags, UriParser uriParser, string uri)
Definition Uri.cs:4100
static unsafe ParsingError ParseScheme(string uriString, ref Flags flags, ref UriParser syntax)
Definition Uri.cs:1319
static bool IriParsingStatic(UriParser syntax)
Definition Uri.cs:601
static bool CheckForUnicodeOrEscapedUnreserved(string data)
Definition Uri.cs:3768
static int Compare(Uri? uri1, Uri? uri2, UriComponents partsToCompare, UriFormat compareFormat, StringComparison comparisonType)
Definition Uri.cs:3917
bool IsLoopback
Definition Uri.cs:365
bool IsAbsoluteUri
Definition Uri.cs:572
static readonly string UriSchemeWss
Definition Uri.cs:171
static string HexEscape(char character)
Definition Uri.cs:1032
bool IsUnc
Definition Uri.cs:429
static readonly string UriSchemeNntp
Definition Uri.cs:177
string OriginalString
Definition Uri.cs:516
static readonly string UriSchemeGopher
Definition Uri.cs:163
static string CreateHostStringHelper(string str, int idx, int end, ref Flags flags, ref string scopeId)
Definition Uri.cs:1713
virtual string Unescape(string path)
Definition Uri.cs:3566
static bool operator==(Uri? uri1, Uri? uri2)
Definition Uri.cs:1140
static unsafe ParsingError CheckSchemeSyntax(ReadOnlySpan< char > span, ref UriParser syntax)
Definition Uri.cs:2553
string MakeRelative(Uri toUri)
Definition Uri.cs:3533
static readonly string UriSchemeMailto
Definition Uri.cs:173
bool NotAny(Flags flags)
Definition Uri.cs:606
Uri(Uri baseUri, Uri relativeUri)
Definition Uri.cs:794
string InternalGetComponents(UriComponents components, UriFormat format)
Definition Uri.cs:3892
static bool IsExcludedCharacter(char character)
Definition Uri.cs:3600
string Authority
Definition Uri.cs:292
static readonly string UriSchemeSsh
Definition Uri.cs:179
static bool StaticInFact(Flags allFlags, Flags checkFlags)
Definition Uri.cs:621
virtual bool IsReservedCharacter(char character)
Definition Uri.cs:3590
string PrivateAbsolutePath
Definition Uri.cs:256
static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat)
Definition Uri.cs:3381
bool IsNotAbsoluteUri
Definition Uri.cs:213
UriInfo EnsureUriInfo()
Definition Uri.cs:626
string GetParts(UriComponents uriParts, UriFormat formatAs)
Definition Uri.cs:1828
static bool CheckForColonInFirstPathSegment(string uriString)
Definition Uri.cs:1300
virtual void Parse()
Definition Uri.cs:3556
static bool TryCreate([NotNullWhen(true)] string? uriString, in UriCreationOptions creationOptions, [NotNullWhen(true)] out Uri? result)
Definition Uri.cs:3810
static readonly string UriSchemeHttps
Definition Uri.cs:167
static readonly char[] s_pathDelims
Definition Uri.cs:199
static bool CheckSchemeName([NotNullWhen(true)] string? schemeName)
Definition Uri.cs:1072
override string ToString()
Definition Uri.cs:1119
string ReCreateParts(UriComponents parts, ushort nonCanonical, UriFormat formatAs)
Definition Uri.cs:1887
static bool StaticIsFile(UriParser syntax)
Definition Uri.cs:894
static readonly string SchemeDelimiter
Definition Uri.cs:187
static bool IsWellFormedUriString([NotNullWhen(true)] string? uriString, UriKind uriKind)
Definition Uri.cs:3955
static string InternalEscapeString(string rawString)
Definition Uri.cs:1310
static unsafe void UnescapeOnly(char *pch, int start, ref int end, char ch1, char ch2, char ch3)
Definition Uri.cs:3244
void EnsureHostString(bool allowDnsOptimization)
Definition Uri.cs:644
void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
Definition Uri.cs:746
string GetLocalPath()
Definition Uri.cs:899
override bool Equals([NotNullWhen(true)] object? comparand)
Definition Uri.cs:1166
static char HexUnescape(string pattern, ref int index)
Definition Uri.cs:1045
static bool StaticNotAny(Flags allFlags, Flags checkFlags)
Definition Uri.cs:616
unsafe void CreateHostString()
Definition Uri.cs:1646
UriHostNameType HostNameType
Definition Uri.cs:304
void CreateThis(string uri, bool dontEscape, UriKind uriKind, in UriCreationOptions creationOptions=default(UriCreationOptions))
Definition Uri.cs:3619
string GetEscapedParts(UriComponents uriParts)
Definition Uri.cs:1833
static readonly string UriSchemeHttp
Definition Uri.cs:165
static string UnescapeDataString(string stringToUnescape)
Definition Uri.cs:4058
bool InFact(Flags flags)
Definition Uri.cs:611
static unsafe int ParseSchemeCheckImplicitFile(char *uriString, int length, ref ParsingError err, ref Flags flags, ref UriParser syntax)
Definition Uri.cs:2480
unsafe ParsingError PrivateParseMinimal()
Definition Uri.cs:1354
static UriFormatException GetException(ParsingError err)
Definition Uri.cs:873
static readonly string UriSchemeFtps
Definition Uri.cs:161
static bool IsHexDigit(char character)
Definition Uri.cs:1088
Uri(Uri baseUri, string? relativeUri)
Definition Uri.cs:707
unsafe void CreateUriInfo(Flags cF)
Definition Uri.cs:1490
string Scheme
Definition Uri.cs:505
unsafe int CheckAuthorityHelper(char *pString, int idx, int length, ref ParsingError err, ref Flags flags, UriParser syntax, ref string newHost)
Definition Uri.cs:2698
string Fragment
Definition Uri.cs:491
@ CustomParser_ParseMinimalAlreadyCalled
string _string
Definition Uri.cs:189
static bool TryCreate(Uri? baseUri, Uri? relativeUri, [NotNullWhen(true)] out Uri? result)
Definition Uri.cs:3841
Flags HostType
Definition Uri.cs:209
string GetRelativeSerializationString(UriFormat format)
Definition Uri.cs:4205
static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped)
Definition Uri.cs:4149
int Port
Definition Uri.cs:453
unsafe void ParseRemaining()
Definition Uri.cs:2215
static string PathDifference(string path1, string path2, bool compareCase)
Definition Uri.cs:3498
void CreateUri(Uri baseUri, string relativeUri, bool dontEscape)
Definition Uri.cs:757
static int Compress(Span< char > span, UriParser syntax)
Definition Uri.cs:3305
unsafe void GetCanonicalPath(ref System.Text.ValueStringBuilder dest, UriFormat formatAs)
Definition Uri.cs:3125
static string EscapeString(string? str)
Definition Uri.cs:3575
override int GetHashCode()
Definition Uri.cs:1103
unsafe Check CheckCanonical(char *str, ref int idx, int end, char delim)
Definition Uri.cs:2971
string LocalPath
Definition Uri.cs:280
static bool operator!=(Uri? uri1, Uri? uri2)
Definition Uri.cs:1153
string GetComponents(UriComponents components, UriFormat format)
Definition Uri.cs:3883
void GetLengthWithoutTrailingSpaces(string str, ref int length, int idx)
Definition Uri.cs:2205
static readonly string UriSchemeNetPipe
Definition Uri.cs:185
UriInfo _info
Definition Uri.cs:197
bool IsWellFormedOriginalString()
Definition Uri.cs:3946
bool IsBaseOf(Uri uri)
Definition Uri.cs:4278
bool IsImplicitFile
Definition Uri.cs:201
static void Compress(char[] dest, int start, ref int destLength, UriParser syntax)
Definition Uri.cs:3300
void GetObjectData(SerializationInfo info, StreamingContext context)
UriKind
Definition UriKind.cs:4
UriFormat
Definition UriFormat.cs:4
static int Size
Definition IntPtr.cs:21
ushort PortValue
Definition Uri.cs:117
ushort Path
Definition Uri.cs:119
ushort User
Definition Uri.cs:113
ushort Query
Definition Uri.cs:121
ushort End
Definition Uri.cs:125
ushort Host
Definition Uri.cs:115
ushort Scheme
Definition Uri.cs:111
ushort Fragment
Definition Uri.cs:123