18 [global::__DynamicallyInvokable]
22 private enum Flags : ulong
25 SchemeNotCanonical = 0x1,
26 UserNotCanonical = 0x2,
27 HostNotCanonical = 0x4,
28 PortNotCanonical = 0x8,
29 PathNotCanonical = 0x10,
30 QueryNotCanonical = 0x20,
31 FragmentNotCanonical = 0x40,
32 CannotDisplayCanonical = 0x7F,
33 E_UserNotCanonical = 0x80,
34 E_HostNotCanonical = 0x100,
35 E_PortNotCanonical = 0x200,
36 E_PathNotCanonical = 0x400,
37 E_QueryNotCanonical = 0x800,
38 E_FragmentNotCanonical = 0x1000,
39 E_CannotDisplayCanonical = 0x1F80,
40 ShouldBeCompressed = 0x2000,
41 FirstSlashAbsent = 0x4000,
42 BackslashInPath = 0x8000,
44 HostTypeMask = 0x70000,
46 IPv6HostType = 0x10000,
47 IPv4HostType = 0x20000,
48 DnsHostType = 0x30000,
49 UncHostType = 0x40000,
50 BasicHostType = 0x50000,
51 UnusedHostType = 0x60000,
52 UnknownHostType = 0x70000,
54 AuthorityFound = 0x100000,
55 HasUserInfo = 0x200000,
56 LoopbackHost = 0x400000,
57 NotDefaultPort = 0x800000,
58 UserDrivenParsing = 0x1000000,
59 CanonicalDnsHost = 0x2000000,
60 ErrorOrParsingRecursion = 0x4000000,
63 ImplicitFile = 0x20000000,
64 MinimalUriInfoSet = 0x40000000,
65 AllUriInfoSet = 0x80000000,
67 HasUnicode = 0x200000000,
68 HostUnicodeNormalized = 0x400000000,
69 RestUnicodeNormalized = 0x800000000,
70 UnicodeHost = 0x1000000000,
71 IntranetUri = 0x2000000000,
72 UseOrigUncdStrOffset = 0x4000000000,
73 UserIriCanonical = 0x8000000000,
74 PathIriCanonical = 0x10000000000,
75 QueryIriCanonical = 0x20000000000,
76 FragmentIriCanonical = 0x40000000000,
77 IriCanonical = 0x78000000000
84 public string ScopeId;
92 public MoreInfo MoreInfo;
95 [StructLayout(
LayoutKind.Sequential, Pack = 1)]
104 public ushort PortValue;
115 private class MoreInfo
127 public string RemoteUrl;
134 EscapedCanonical = 0x1,
135 DisplayCanonical = 0x2,
137 DotSlashEscaped = 0x80,
138 BackslashInPath = 0x10,
139 ReservedFound = 0x20,
140 NotIriCanonical = 0x40,
159 internal static readonly
string UriSchemeWs =
UriParser.WsUri.SchemeName;
161 internal static readonly
string UriSchemeWss =
UriParser.WssUri.SchemeName;
181 private const int c_Max16BitUtf8SequenceLength = 12;
183 internal const int c_MaxUriBufferSize = 65520;
185 private const int c_MaxUriSchemeName = 1024;
187 private string m_String;
189 private string m_originalUnicodeString;
193 private string m_DnsSafeHost;
195 private Flags m_Flags;
197 private UriInfo m_Info;
199 private bool m_iriParsing;
201 private static volatile IInternetSecurityManager s_ManagerRef =
null;
203 private static object s_IntranetLock =
new object();
205 private static volatile bool s_ConfigInitialized;
207 private static volatile bool s_ConfigInitializing;
211 private static volatile bool s_IriParsing = (!
UriParser.ShouldUseLegacyV2Quirks) ?
true :
false;
213 private static object s_initLock;
217 internal const char c_DummyChar =
'\uffff';
219 internal const char c_EOL =
'\ufffe';
221 internal static readonly
char[] HexLowerChars =
new char[16]
241 private static readonly
char[] _WSchars =
new char[4]
249 private bool IsImplicitFile => (m_Flags & Flags.ImplicitFile) != Flags.Zero;
251 private bool IsUncOrDosPath => (m_Flags & (Flags.DosPath | Flags.UncPath)) != Flags.Zero;
253 private bool IsDosPath => (m_Flags & Flags.DosPath) != Flags.Zero;
255 private bool IsUncPath => (m_Flags & Flags.UncPath) != Flags.Zero;
257 private Flags HostType => m_Flags & Flags.HostTypeMask;
259 private UriParser Syntax => m_Syntax;
261 private bool IsNotAbsoluteUri => m_Syntax ==
null;
263 private bool AllowIdn
267 if (m_Syntax !=
null && (m_Syntax.Flags & UriSyntaxFlags.AllowIdn) != 0)
273 return NotAny(Flags.IntranetUri);
283 internal bool UserDrivenParsing => (m_Flags & Flags.UserDrivenParsing) != Flags.Zero;
285 private ushort SecuredPathIndex
291 char c = m_String[m_Info.Offset.Path];
292 return (ushort)((c ==
'/' || c ==
'\\') ? 3 : 2);
301 [global::__DynamicallyInvokable]
302 public string AbsolutePath
304 [global::__DynamicallyInvokable]
307 if (IsNotAbsoluteUri)
311 string text = PrivateAbsolutePath;
312 if (IsDosPath && text[0] ==
'/')
314 text = text.Substring(1);
320 private string PrivateAbsolutePath
324 UriInfo uriInfo = EnsureUriInfo();
325 if (uriInfo.MoreInfo ==
null)
327 uriInfo.MoreInfo =
new MoreInfo();
329 string text = uriInfo.MoreInfo.Path;
332 text = GetParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
333 uriInfo.MoreInfo.Path = text;
342 [global::__DynamicallyInvokable]
345 [global::__DynamicallyInvokable]
348 if (m_Syntax ==
null)
352 UriInfo uriInfo = EnsureUriInfo();
353 if (uriInfo.MoreInfo ==
null)
355 uriInfo.MoreInfo =
new MoreInfo();
357 string text = uriInfo.MoreInfo.AbsoluteUri;
361 uriInfo.MoreInfo.AbsoluteUri = text;
370 [global::__DynamicallyInvokable]
371 public string LocalPath
373 [global::__DynamicallyInvokable]
376 if (IsNotAbsoluteUri)
380 return GetLocalPath();
387 [global::__DynamicallyInvokable]
390 [global::__DynamicallyInvokable]
393 if (IsNotAbsoluteUri)
404 [global::__DynamicallyInvokable]
407 [global::__DynamicallyInvokable]
410 if (IsNotAbsoluteUri)
414 if (m_Syntax.IsSimple)
420 EnsureHostString(allowDnsOptimization:
false);
424 case Flags.DnsHostType:
426 case Flags.IPv4HostType:
428 case Flags.IPv6HostType:
430 case Flags.BasicHostType:
432 case Flags.UncHostType:
434 case Flags.HostTypeMask:
445 [global::__DynamicallyInvokable]
446 public bool IsDefaultPort
448 [global::__DynamicallyInvokable]
451 if (IsNotAbsoluteUri)
455 if (m_Syntax.IsSimple)
461 EnsureHostString(allowDnsOptimization:
false);
463 return NotAny(Flags.NotDefaultPort);
470 [global::__DynamicallyInvokable]
473 [global::__DynamicallyInvokable]
476 if (IsNotAbsoluteUri)
480 return (
object)m_Syntax.SchemeName == UriSchemeFile;
487 [global::__DynamicallyInvokable]
488 public bool IsLoopback
490 [global::__DynamicallyInvokable]
493 if (IsNotAbsoluteUri)
497 EnsureHostString(allowDnsOptimization:
false);
498 return InFact(Flags.LoopbackHost);
505 [global::__DynamicallyInvokable]
508 [global::__DynamicallyInvokable]
511 if (IsNotAbsoluteUri)
516 if (IsDosPath && text[0] ==
'/')
518 text = text.Substring(1);
527 [global::__DynamicallyInvokable]
528 public string[] Segments
530 [global::__DynamicallyInvokable]
533 if (IsNotAbsoluteUri)
537 string[] array =
null;
540 string privateAbsolutePath = PrivateAbsolutePath;
541 if (privateAbsolutePath.Length == 0)
543 array =
new string[0];
549 for (
int num = 0; num < privateAbsolutePath.Length; num = num2 + 1)
551 num2 = privateAbsolutePath.IndexOf(
'/', num);
554 num2 = privateAbsolutePath.Length - 1;
556 arrayList.
Add(privateAbsolutePath.Substring(num, num2 - num + 1));
558 array = (
string[])arrayList.
ToArray(typeof(
string));
568 [global::__DynamicallyInvokable]
571 [global::__DynamicallyInvokable]
574 if (IsNotAbsoluteUri)
585 [global::__DynamicallyInvokable]
588 [global::__DynamicallyInvokable]
591 if (IsNotAbsoluteUri)
599 private static object InitializeLock
603 if (s_initLock ==
null)
605 object value =
new object();
615 [global::__DynamicallyInvokable]
618 [global::__DynamicallyInvokable]
621 if (IsNotAbsoluteUri)
625 if (m_Syntax.IsSimple)
631 EnsureHostString(allowDnsOptimization:
false);
633 if (InFact(Flags.NotDefaultPort))
635 return m_Info.Offset.PortValue;
637 return m_Syntax.DefaultPort;
644 [global::__DynamicallyInvokable]
647 [global::__DynamicallyInvokable]
650 if (IsNotAbsoluteUri)
654 UriInfo uriInfo = EnsureUriInfo();
655 if (uriInfo.MoreInfo ==
null)
657 uriInfo.MoreInfo =
new MoreInfo();
659 string text = uriInfo.MoreInfo.Query;
663 uriInfo.MoreInfo.Query = text;
672 [global::__DynamicallyInvokable]
675 [global::__DynamicallyInvokable]
678 if (IsNotAbsoluteUri)
682 UriInfo uriInfo = EnsureUriInfo();
683 if (uriInfo.MoreInfo ==
null)
685 uriInfo.MoreInfo =
new MoreInfo();
687 string text = uriInfo.MoreInfo.Fragment;
691 uriInfo.MoreInfo.Fragment = text;
700 [global::__DynamicallyInvokable]
703 [global::__DynamicallyInvokable]
706 if (IsNotAbsoluteUri)
710 return m_Syntax.SchemeName;
714 private bool OriginalStringSwitched
718 if (!m_iriParsing || !InFact(Flags.HasUnicode))
722 if (!InFact(Flags.IdnHost))
724 return InFact(Flags.UnicodeHost);
737 [global::__DynamicallyInvokable]
738 public string OriginalString
740 [global::__DynamicallyInvokable]
743 if (!OriginalStringSwitched)
747 return m_originalUnicodeString;
754 [global::__DynamicallyInvokable]
755 public string DnsSafeHost
757 [global::__DynamicallyInvokable]
760 if (IsNotAbsoluteUri)
764 if (AllowIdn && ((m_Flags & Flags.IdnHost) != Flags.Zero || (m_Flags & Flags.UnicodeHost) != Flags.Zero))
767 return m_Info.DnsSafeHost;
769 EnsureHostString(allowDnsOptimization:
false);
770 if (!
string.IsNullOrEmpty(m_Info.DnsSafeHost))
772 return m_Info.DnsSafeHost;
774 if (m_Info.Host.Length == 0)
778 string text = m_Info.Host;
779 if (HostType == Flags.IPv6HostType)
781 text = text.Substring(1, text.Length - 2);
782 if (m_Info.ScopeId !=
null)
784 text += m_Info.ScopeId;
787 else if (HostType == Flags.BasicHostType && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical))
789 char[] array =
new char[text.Length];
790 int destPosition = 0;
791 UriHelper.UnescapeString(text, 0, text.Length, array, ref destPosition,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, isQuery:
false);
792 text =
new string(array, 0, destPosition);
794 m_Info.DnsSafeHost = text;
801 [global::__DynamicallyInvokable]
802 public string IdnHost
804 [global::__DynamicallyInvokable]
807 string text = DnsSafeHost;
808 if (HostType == Flags.DnsHostType)
810 text = DomainNameHelper.IdnEquivalent(text);
818 [global::__DynamicallyInvokable]
819 public bool IsAbsoluteUri
821 [global::__DynamicallyInvokable]
824 return m_Syntax !=
null;
830 [global::__DynamicallyInvokable]
831 public bool UserEscaped
833 [global::__DynamicallyInvokable]
836 return InFact(Flags.UserEscaped);
843 [global::__DynamicallyInvokable]
846 [global::__DynamicallyInvokable]
849 if (IsNotAbsoluteUri)
857 internal bool HasAuthority => InFact(Flags.AuthorityFound);
859 internal static bool IriParsingStatic(
UriParser syntax)
863 if (syntax ==
null || !syntax.InFact(UriSyntaxFlags.AllowIriParsing))
865 return syntax ==
null;
872 private bool AllowIdnStatic(UriParser syntax, Flags flags)
874 if (syntax !=
null && (syntax.Flags & UriSyntaxFlags.AllowIdn) != 0)
880 return StaticNotAny(flags, Flags.IntranetUri);
889 private bool IsIntranet(
string schemeHost)
893 int num = -2147467259;
894 if (m_Syntax.SchemeName.Length > 32)
898 if (s_ManagerRef ==
null)
900 lock (s_IntranetLock)
902 if (s_ManagerRef ==
null)
904 Guid clsid = typeof(InternetSecurityManager).GUID;
905 Guid iid = typeof(IInternetSecurityManager).GUID;
906 UnsafeNclNativeMethods.CoCreateInstance(ref clsid, IntPtr.Zero, 21, ref iid, out
object o);
907 s_ManagerRef = (o as IInternetSecurityManager);
913 s_ManagerRef.MapUrlToZone(schemeHost.TrimStart(_WSchars), out pdwZone, 0);
932 num2 = ((pdwZone == 4) ? 1 : 0);
938 if ((num2 | (flag ? 1 : 0)) != 0)
940 for (
int i = 0; i < schemeHost.Length; i++)
942 if (schemeHost[i] ==
'.')
952 private void SetUserDrivenParsing()
954 m_Flags = (Flags.UserDrivenParsing | (m_Flags & Flags.UserEscaped));
957 private bool NotAny(Flags flags)
959 return (m_Flags & flags) == Flags.Zero;
962 private bool InFact(Flags flags)
964 return (m_Flags & flags) != Flags.Zero;
967 private static bool StaticNotAny(Flags allFlags, Flags checkFlags)
969 return (allFlags & checkFlags) == Flags.Zero;
972 private static bool StaticInFact(Flags allFlags, Flags checkFlags)
974 return (allFlags & checkFlags) != Flags.Zero;
977 private UriInfo EnsureUriInfo()
979 Flags flags = m_Flags;
980 if ((m_Flags & Flags.MinimalUriInfoSet) == Flags.Zero)
982 CreateUriInfo(flags);
987 private void EnsureParseRemaining()
989 if ((m_Flags & Flags.AllUriInfoSet) == Flags.Zero)
995 private void EnsureHostString(
bool allowDnsOptimization)
998 if (m_Info.Host ==
null && (!allowDnsOptimization || !InFact(Flags.CanonicalDnsHost)))
1012 [global::__DynamicallyInvokable]
1015 if (uriString ==
null)
1019 CreateThis(uriString, dontEscape:
false,
UriKind.Absolute);
1031 [Obsolete(
"The constructor has been deprecated. Please use new Uri(string). The dontEscape parameter is deprecated and is always false. http://go.microsoft.com/fwlink/?linkid=14202")]
1032 public Uri(
string uriString,
bool dontEscape)
1034 if (uriString ==
null)
1038 CreateThis(uriString, dontEscape,
UriKind.Absolute);
1051 [Obsolete(
"The constructor has been deprecated. Please new Uri(Uri, string). The dontEscape parameter is deprecated and is always false. http://go.microsoft.com/fwlink/?linkid=14202")]
1052 public Uri(
Uri baseUri,
string relativeUri,
bool dontEscape)
1054 if ((
object)baseUri ==
null)
1062 CreateUri(baseUri, relativeUri, dontEscape);
1078 [global::__DynamicallyInvokable]
1081 if (uriString ==
null)
1085 CreateThis(uriString, dontEscape:
false, uriKind);
1097 [global::__DynamicallyInvokable]
1100 if ((
object)baseUri ==
null)
1108 CreateUri(baseUri, relativeUri, dontEscape:
false);
1111 private void CreateUri(
Uri baseUri,
string relativeUri,
bool dontEscape)
1113 CreateThis(relativeUri, dontEscape,
UriKind.RelativeOrAbsolute);
1115 if (baseUri.Syntax.IsSimple)
1117 Uri uri = ResolveHelper(baseUri,
this, ref relativeUri, ref dontEscape, out e);
1124 if ((
object)uri !=
this)
1126 CreateThisFromUri(uri);
1134 relativeUri = baseUri.Syntax.InternalResolve(baseUri,
this, out e);
1140 m_Flags = Flags.Zero;
1143 CreateThis(relativeUri, dontEscape,
UriKind.Absolute);
1157 [global::__DynamicallyInvokable]
1160 if ((
object)baseUri ==
null)
1168 CreateThisFromUri(relativeUri);
1169 string newUriString =
null;
1172 if (baseUri.Syntax.IsSimple)
1174 userEscaped = InFact(Flags.UserEscaped);
1175 relativeUri = ResolveHelper(baseUri,
this, ref newUriString, ref userEscaped, out e);
1180 if (relativeUri !=
null)
1182 if ((
object)relativeUri !=
this)
1184 CreateThisFromUri(relativeUri);
1191 userEscaped =
false;
1192 newUriString = baseUri.Syntax.InternalResolve(baseUri,
this, out e);
1198 m_Flags = Flags.Zero;
1201 CreateThis(newUriString, userEscaped,
UriKind.Absolute);
1204 private unsafe
static ParsingError GetCombinedString(
Uri baseUri,
string relativeStr,
bool dontEscape, ref
string result)
1206 for (
int i = 0; i < relativeStr.Length && relativeStr[i] !=
'/' && relativeStr[i] !=
'\\' && relativeStr[i] !=
'?' && relativeStr[i] !=
'#'; i++)
1208 if (relativeStr[i] ==
':')
1212 string text = relativeStr.Substring(0, i);
1213 fixed (
char* ptr = text)
1216 if (CheckSchemeSyntax(ptr, (ushort)text.Length, ref syntax) == ParsingError.None)
1218 if (baseUri.Syntax != syntax)
1220 result = relativeStr;
1221 return ParsingError.None;
1223 relativeStr = ((i + 1 >= relativeStr.Length) ?
string.Empty : relativeStr.Substring(i + 1));
1230 if (relativeStr.Length == 0)
1233 return ParsingError.None;
1235 result = CombineUri(baseUri, relativeStr, dontEscape ?
UriFormat.UriEscaped :
UriFormat.SafeUnescaped);
1236 return ParsingError.None;
1239 private static UriFormatException GetException(ParsingError err)
1243 case ParsingError.None:
1245 case ParsingError.BadFormat:
1246 return new UriFormatException(SR.GetString(
"net_uri_BadFormat"));
1247 case ParsingError.BadScheme:
1248 return new UriFormatException(SR.GetString(
"net_uri_BadScheme"));
1249 case ParsingError.BadAuthority:
1250 return new UriFormatException(SR.GetString(
"net_uri_BadAuthority"));
1251 case ParsingError.EmptyUriString:
1252 return new UriFormatException(SR.GetString(
"net_uri_EmptyUri"));
1253 case ParsingError.SchemeLimit:
1254 return new UriFormatException(SR.GetString(
"net_uri_SchemeLimit"));
1255 case ParsingError.SizeLimit:
1256 return new UriFormatException(SR.GetString(
"net_uri_SizeLimit"));
1257 case ParsingError.MustRootedPath:
1258 return new UriFormatException(SR.GetString(
"net_uri_MustRootedPath"));
1259 case ParsingError.BadHostName:
1260 return new UriFormatException(SR.GetString(
"net_uri_BadHostName"));
1261 case ParsingError.NonEmptyHost:
1262 return new UriFormatException(SR.GetString(
"net_uri_BadFormat"));
1263 case ParsingError.BadPort:
1264 return new UriFormatException(SR.GetString(
"net_uri_BadPort"));
1265 case ParsingError.BadAuthorityTerminator:
1266 return new UriFormatException(SR.GetString(
"net_uri_BadAuthorityTerminator"));
1267 case ParsingError.CannotCreateRelative:
1268 return new UriFormatException(SR.GetString(
"net_uri_CannotCreateRelative"));
1270 return new UriFormatException(SR.GetString(
"net_uri_BadFormat"));
1281 string @
string = serializationInfo.
GetString(
"AbsoluteUri");
1282 if (@
string.Length != 0)
1284 CreateThis(@
string, dontEscape:
false,
UriKind.Absolute);
1287 @
string = serializationInfo.
GetString(
"RelativeUri");
1288 if (@
string ==
null)
1292 CreateThis(@
string, dontEscape:
false,
UriKind.Relative);
1301 GetObjectData(serializationInfo, streamingContext);
1315 serializationInfo.
AddValue(
"AbsoluteUri",
string.Empty);
1319 private static bool StaticIsFile(
UriParser syntax)
1321 return syntax.InFact(UriSyntaxFlags.FileLikeUri);
1324 private static void InitializeUriConfig()
1326 if (!s_ConfigInitialized)
1328 lock (InitializeLock)
1330 if (!s_ConfigInitialized && !s_ConfigInitializing)
1332 s_ConfigInitializing =
true;
1333 UriSectionInternal section = UriSectionInternal.GetSection();
1334 if (section !=
null)
1336 s_IdnScope = section.IdnScope;
1337 if (UriParser.ShouldUseLegacyV2Quirks)
1339 s_IriParsing = section.IriParsing;
1341 SetEscapedDotSlashSettings(section,
"http");
1342 SetEscapedDotSlashSettings(section,
"https");
1343 SetEscapedDotSlashSettings(section, UriSchemeWs);
1344 SetEscapedDotSlashSettings(section, UriSchemeWss);
1346 s_ConfigInitialized =
true;
1347 s_ConfigInitializing =
false;
1353 private static void SetEscapedDotSlashSettings(UriSectionInternal uriSection,
string scheme)
1355 SchemeSettingInternal schemeSetting = uriSection.GetSchemeSetting(scheme);
1358 UriParser syntax = UriParser.GetSyntax(scheme);
1359 syntax.SetUpdatableFlags(UriSyntaxFlags.None);
1363 private string GetLocalPath()
1365 EnsureParseRemaining();
1368 EnsureHostString(allowDnsOptimization:
false);
1370 if (NotAny(Flags.HostNotCanonical | Flags.PathNotCanonical | Flags.ShouldBeCompressed))
1372 num = (IsUncPath ? (m_Info.Offset.Host - 2) : m_Info.Offset.Path);
1373 string text = (IsImplicitFile && m_Info.Offset.Host == ((!IsDosPath) ? 2 : 0) && m_Info.Offset.Query == m_Info.Offset.End) ? m_String : ((IsDosPath && (m_String[num] ==
'/' || m_String[num] ==
'\\')) ? m_String.Substring(num + 1, m_Info.Offset.Query - num - 1) : m_String.Substring(num, m_Info.Offset.Query - num));
1374 if (IsDosPath && text[1] ==
'|')
1376 text = text.Remove(1, 1);
1377 text = text.Insert(1,
":");
1379 for (
int i = 0; i < text.Length; i++)
1383 text = text.Replace(
'/',
'\\');
1389 int destPosition = 0;
1390 num = m_Info.Offset.Path;
1391 string host = m_Info.Host;
1392 char[] array =
new char[host.Length + 3 + m_Info.Offset.Fragment - m_Info.Offset.Path];
1398 UriHelper.UnescapeString(host, 0, host.Length, array, ref destPosition,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
false);
1400 else if (m_String[num] ==
'/' || m_String[num] ==
'\\')
1404 ushort num2 = (ushort)destPosition;
1405 UnescapeMode unescapeMode = (InFact(Flags.PathNotCanonical) && !IsImplicitFile) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : UnescapeMode.CopyOnly;
1406 UriHelper.UnescapeString(m_String, num, m_Info.Offset.Query, array, ref destPosition,
'\uffff',
'\uffff',
'\uffff', unescapeMode, m_Syntax, isQuery:
true);
1407 if (array[1] ==
'|')
1411 if (InFact(Flags.ShouldBeCompressed))
1413 array =
Compress(array, (ushort)(IsDosPath ? (num2 + 2) : num2), ref destPosition, m_Syntax);
1415 for (ushort num3 = 0; num3 < (ushort)destPosition; num3 = (ushort)(num3 + 1))
1417 if (array[num3] ==
'/')
1422 return new string(array, 0, destPosition);
1430 [global::__DynamicallyInvokable]
1433 if (name ==
null || name.Length == 0 || name.Length > 32767)
1437 int end = name.Length;
1438 fixed (
char* name2 = name)
1440 if (name[0] ==
'[' && name[name.Length - 1] ==
']' && IPv6AddressHelper.IsValid(name2, 1, ref end) && end == name.Length)
1445 if (IPv4AddressHelper.IsValid(name2, 0, ref end, allowIPv6:
false, notImplicitFile:
false, unknownScheme:
false) && end == name.Length)
1450 bool notCanonical =
false;
1451 if (DomainNameHelper.IsValid(name2, 0, ref end, ref notCanonical, notImplicitFile:
false) && end == name.Length)
1456 notCanonical =
false;
1457 if (DomainNameHelper.IsValidByIri(name2, 0, ref end, ref notCanonical, notImplicitFile:
false) && end == name.Length)
1462 end = name.Length + 2;
1463 name =
"[" + name +
"]";
1464 fixed (
char* name3 = name)
1466 if (IPv6AddressHelper.IsValid(name3, 1, ref end) && end == name.Length)
1481 if (IsNotAbsoluteUri)
1491 if (NotAny(Flags.AuthorityFound) || IsDosPath)
1493 return string.Empty;
1512 if (character >
'ÿ')
1516 char[] array =
new char[3];
1518 UriHelper.EscapeAsciiChar(character, array, ref pos);
1519 return new string(array);
1530 if (index < 0 || index >= pattern.Length)
1534 if (pattern[index] ==
'%' && pattern.Length - index >= 3)
1536 char c = UriHelper.EscapedAscii(pattern[index + 1], pattern[index + 2]);
1543 return pattern[index++];
1552 if (pattern.Length - index < 3)
1556 if (pattern[index] ==
'%' && UriHelper.EscapedAscii(pattern[index + 1], pattern[index + 2]) !=
'\uffff')
1563 internal static bool IsGenDelim(
char ch)
1565 if (ch !=
':' && ch !=
'/' && ch !=
'?' && ch !=
'#' && ch !=
'[' && ch !=
']')
1575 [global::__DynamicallyInvokable]
1578 if (schemeName ==
null || schemeName.Length == 0 || !IsAsciiLetter(schemeName[0]))
1582 for (
int num = schemeName.Length - 1; num > 0; num--)
1584 if (!IsAsciiLetterOrDigit(schemeName[num]) && schemeName[num] !=
'+' && schemeName[num] !=
'-' && schemeName[num] !=
'.')
1597 if ((character < '0' || character >
'9') && (character < 'A' || character >
'F'))
1599 if (character >=
'a')
1601 return character <=
'f';
1615 if ((digit >=
'0' && digit <=
'9') || (digit >=
'A' && digit <=
'F') || (digit >=
'a' && digit <=
'f'))
1619 return ((digit <=
'F') ? (digit - 65) : (digit - 97)) + 10;
1628 [global::__DynamicallyInvokable]
1632 if (IsNotAbsoluteUri)
1634 return CalculateCaseInsensitiveHashCode(OriginalString);
1636 UriInfo uriInfo = EnsureUriInfo();
1637 if (uriInfo.MoreInfo ==
null)
1639 uriInfo.MoreInfo =
new MoreInfo();
1641 int num = uriInfo.MoreInfo.Hash;
1644 string text = uriInfo.MoreInfo.RemoteUrl;
1649 num = CalculateCaseInsensitiveHashCode(text);
1654 uriInfo.MoreInfo.Hash = num;
1661 [global::__DynamicallyInvokable]
1665 if (m_Syntax ==
null)
1667 if (!m_iriParsing || !InFact(Flags.HasUnicode))
1669 return OriginalString;
1674 if (m_Info.String ==
null)
1676 if (Syntax.IsSimple)
1685 return m_Info.String;
1692 [global::__DynamicallyInvokable]
1694 public static bool operator ==(
Uri uri1,
Uri uri2)
1696 if ((
object)uri1 == uri2)
1700 if ((
object)uri1 ==
null || (
object)uri2 ==
null)
1704 return uri2.
Equals(uri1);
1711 [global::__DynamicallyInvokable]
1715 if ((
object)uri1 == uri2)
1719 if ((
object)uri1 ==
null || (
object)uri2 ==
null)
1723 return !uri2.
Equals(uri1);
1729 [global::__DynamicallyInvokable]
1731 public unsafe
override bool Equals(
object comparand)
1733 if (comparand ==
null)
1737 if (
this == comparand)
1741 Uri result = comparand as
Uri;
1742 if ((
object)result ==
null)
1744 string text = comparand as string;
1749 if (!TryCreate(text,
UriKind.RelativeOrAbsolute, out result))
1754 if ((
object)m_String == result.m_String)
1762 if (IsNotAbsoluteUri)
1766 if (NotAny(Flags.AllUriInfoSet) || result.NotAny(Flags.AllUriInfoSet))
1768 if (!IsUncOrDosPath)
1770 if (m_String.Length == result.m_String.Length)
1772 fixed (
char* ptr = m_String)
1774 fixed (
char* ptr2 = result.m_String)
1776 int num = m_String.Length - 1;
1777 while (num >= 0 && ptr[num] == ptr2[num])
1789 else if (
string.Compare(m_String, result.m_String,
StringComparison.OrdinalIgnoreCase) == 0)
1795 result.EnsureUriInfo();
1796 if (!UserDrivenParsing && !result.UserDrivenParsing && Syntax.IsSimple && result.Syntax.IsSimple)
1798 if (InFact(Flags.CanonicalDnsHost) && result.InFact(Flags.CanonicalDnsHost))
1800 ushort num2 = m_Info.Offset.Host;
1801 ushort num3 = m_Info.Offset.Path;
1802 ushort num4 = result.m_Info.Offset.Host;
1803 ushort path = result.m_Info.Offset.Path;
1804 string @
string = result.m_String;
1805 if (num3 - num2 > path - num4)
1807 num3 = (ushort)(num2 + path - num4);
1811 if (m_String[num2] != @
string[num4])
1815 if (@
string[num4] ==
':')
1819 num2 = (ushort)(num2 + 1);
1820 num4 = (ushort)(num4 + 1);
1822 if (num2 < m_Info.Offset.Path && m_String[num2] !=
':')
1826 if (num4 < path && @
string[num4] !=
':')
1833 EnsureHostString(allowDnsOptimization:
false);
1834 result.EnsureHostString(allowDnsOptimization:
false);
1835 if (!m_Info.Host.Equals(result.m_Info.Host))
1845 UriInfo info = m_Info;
1846 UriInfo info2 = result.m_Info;
1847 if (info.MoreInfo ==
null)
1849 info.MoreInfo =
new MoreInfo();
1851 if (info2.MoreInfo ==
null)
1853 info2.MoreInfo =
new MoreInfo();
1855 string text2 = info.MoreInfo.RemoteUrl;
1859 info.MoreInfo.RemoteUrl = text2;
1861 string text3 = info2.MoreInfo.RemoteUrl;
1865 info2.MoreInfo.RemoteUrl = text3;
1867 if (!IsUncOrDosPath)
1869 if (text2.Length != text3.Length)
1873 fixed (
char* ptr3 = text2)
1875 fixed (
char* ptr5 = text3)
1877 char* ptr4 = ptr3 + text2.Length;
1878 char* ptr6 = ptr5 + text2.Length;
1879 while (ptr4 != ptr3)
1881 if (*(--ptr4) != *(--ptr6))
1890 return string.Compare(info.MoreInfo.RemoteUrl, info2.MoreInfo.RemoteUrl, IsUncOrDosPath ?
StringComparison.OrdinalIgnoreCase :
StringComparison.Ordinal) == 0;
1899 [global::__DynamicallyInvokable]
1902 if ((
object)uri ==
null)
1906 if (IsNotAbsoluteUri || uri.IsNotAbsoluteUri)
1913 string text = PathDifference(AbsolutePath, absolutePath, !IsUncOrDosPath);
1914 if (CheckForColonInFirstPathSegment(text) && (!uri.IsDosPath || !absolutePath.Equals(text,
StringComparison.Ordinal)))
1924 private static bool CheckForColonInFirstPathSegment(
string uriString)
1926 char[] anyOf =
new char[5]
1934 int num = uriString.IndexOfAny(anyOf);
1937 return uriString[num] ==
':';
1942 internal static string InternalEscapeString(
string rawString)
1944 if (rawString ==
null)
1946 return string.Empty;
1949 char[] array = UriHelper.EscapeString(rawString, 0, rawString.Length,
null, ref destPos, isUriString:
true,
'?',
'#',
'%');
1954 return new string(array, 0, destPos);
1957 private unsafe
static ParsingError ParseScheme(
string uriString, ref Flags flags, ref UriParser syntax)
1959 int length = uriString.Length;
1962 return ParsingError.EmptyUriString;
1964 if (length >= 65520)
1966 return ParsingError.SizeLimit;
1968 fixed (
char* uriString2 = uriString)
1970 ParsingError err = ParsingError.None;
1971 ushort num = ParseSchemeCheckImplicitFile(uriString2, (ushort)length, ref err, ref flags, ref syntax);
1976 flags |= (Flags)num;
1978 return ParsingError.None;
1981 internal UriFormatException ParseMinimal()
1983 ParsingError parsingError = PrivateParseMinimal();
1984 if (parsingError == ParsingError.None)
1988 m_Flags |= Flags.ErrorOrParsingRecursion;
1989 return GetException(parsingError);
1992 private unsafe ParsingError PrivateParseMinimal()
1994 ushort num = (ushort)(m_Flags & Flags.IndexMask);
1995 ushort num2 = (ushort)m_String.Length;
1996 string newHost =
null;
1997 m_Flags &= ~(Flags.SchemeNotCanonical | Flags.UserNotCanonical | Flags.HostNotCanonical | Flags.PortNotCanonical | Flags.PathNotCanonical | Flags.QueryNotCanonical | Flags.FragmentNotCanonical | Flags.E_UserNotCanonical | Flags.E_HostNotCanonical | Flags.E_PortNotCanonical | Flags.E_PathNotCanonical | Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical | Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath | Flags.UserDrivenParsing);
1998 fixed (
char* ptr = (m_iriParsing && (m_Flags & Flags.HasUnicode) != Flags.Zero && (m_Flags & Flags.HostUnicodeNormalized) == Flags.Zero) ? m_originalUnicodeString : m_String)
2000 if (num2 > num && IsLWS(ptr[num2 - 1]))
2002 num2 = (ushort)(num2 - 1);
2003 while (num2 != num && IsLWS(ptr[(
int)(num2 = (ushort)(num2 - 1))]))
2006 num2 = (ushort)(num2 + 1);
2008 if (m_Syntax.IsAllSet(UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowDOSPath) && NotAny(Flags.ImplicitFile) && num + 1 < num2)
2012 while (num3 < num2 && ((c = ptr[(
int)num3]) ==
'\\' || c ==
'/'))
2014 num3 = (ushort)(num3 + 1);
2016 if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri) || num3 - num <= 3)
2018 if (num3 - num >= 2)
2020 m_Flags |= Flags.AuthorityFound;
2022 if (num3 + 1 < num2 && ((c = ptr[num3 + 1]) ==
':' || c ==
'|') && IsAsciiLetter(ptr[(
int)num3]))
2024 if (num3 + 2 >= num2 || ((c = ptr[num3 + 2]) !=
'\\' && c !=
'/'))
2026 if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri))
2028 return ParsingError.MustRootedPath;
2033 m_Flags |= Flags.DosPath;
2034 if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority))
2036 m_Flags |= Flags.AuthorityFound;
2038 num = ((num3 == num || num3 - num == 2) ? num3 : ((ushort)(num3 - 1)));
2041 else if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri) && num3 - num >= 2 && num3 - num != 3 && num3 < num2 && ptr[(int)num3] !=
'?' && ptr[(
int)num3] !=
'#')
2043 m_Flags |= Flags.UncPath;
2048 if ((m_Flags & (Flags.DosPath | Flags.UncPath)) == Flags.Zero)
2050 if (num + 2 <= num2)
2052 char c2 = ptr[(int)num];
2053 char c3 = ptr[num + 1];
2054 if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority))
2056 if ((c2 !=
'/' && c2 !=
'\\') || (c3 !=
'/' && c3 !=
'\\'))
2058 return ParsingError.BadAuthority;
2060 m_Flags |= Flags.AuthorityFound;
2061 num = (ushort)(num + 2);
2063 else if (m_Syntax.InFact(UriSyntaxFlags.OptionalAuthority) && (InFact(Flags.AuthorityFound) || (c2 ==
'/' && c3 ==
'/')))
2065 m_Flags |= Flags.AuthorityFound;
2066 num = (ushort)(num + 2);
2068 else if (m_Syntax.NotAny(UriSyntaxFlags.MailToLikeUri))
2070 m_Flags |= (Flags)((
long)num | 458752
L);
2071 return ParsingError.None;
2076 if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority))
2078 return ParsingError.BadAuthority;
2080 if (m_Syntax.NotAny(UriSyntaxFlags.MailToLikeUri))
2082 m_Flags |= (Flags)((
long)num | 458752
L);
2083 return ParsingError.None;
2087 if (InFact(Flags.DosPath))
2089 m_Flags |= (Flags)(((m_Flags & Flags.AuthorityFound) != Flags.Zero) ? 327680 : 458752);
2090 m_Flags |= (Flags)num;
2091 return ParsingError.None;
2093 ParsingError err = ParsingError.None;
2094 num = CheckAuthorityHelper(ptr, num, num2, ref err, ref m_Flags, m_Syntax, ref newHost);
2099 if (num < num2 && ptr[(
int)num] ==
'\\' && NotAny(Flags.ImplicitFile) && m_Syntax.NotAny(UriSyntaxFlags.AllowDOSPath))
2101 return ParsingError.BadAuthorityTerminator;
2103 m_Flags |= (Flags)num;
2105 if (s_IdnScope != 0 || m_iriParsing)
2107 PrivateParseMinimalIri(newHost, num);
2109 return ParsingError.None;
2112 private void PrivateParseMinimalIri(
string newHost, ushort idx)
2114 if (newHost !=
null)
2118 if ((!m_iriParsing && AllowIdn && ((m_Flags & Flags.IdnHost) != Flags.Zero || (m_Flags & Flags.UnicodeHost) != Flags.Zero)) || (m_iriParsing && (m_Flags & Flags.HasUnicode) == Flags.Zero && AllowIdn && (m_Flags & Flags.IdnHost) != Flags.Zero))
2120 m_Flags &= ~(Flags.SchemeNotCanonical | Flags.UserNotCanonical | Flags.HostNotCanonical | Flags.PortNotCanonical | Flags.PathNotCanonical | Flags.QueryNotCanonical | Flags.FragmentNotCanonical | Flags.E_UserNotCanonical | Flags.E_HostNotCanonical | Flags.E_PortNotCanonical | Flags.E_PathNotCanonical | Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical | Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath);
2121 m_Flags |= (Flags)m_String.Length;
2122 m_String += m_originalUnicodeString.Substring(idx, m_originalUnicodeString.Length - idx);
2124 if (m_iriParsing && (m_Flags & Flags.HasUnicode) != Flags.Zero)
2126 m_Flags |= Flags.UseOrigUncdStrOffset;
2130 private unsafe
void CreateUriInfo(Flags cF)
2132 UriInfo uriInfo =
new UriInfo();
2133 uriInfo.Offset.End = (ushort)m_String.Length;
2134 if (!UserDrivenParsing)
2138 if ((cF & Flags.ImplicitFile) != Flags.Zero)
2141 while (IsLWS(m_String[num]))
2143 num = (ushort)(num + 1);
2144 uriInfo.Offset.Scheme++;
2146 if (StaticInFact(cF, Flags.UncPath))
2148 num = (ushort)(num + 2);
2149 while (num < (ushort)(cF & Flags.IndexMask) && (m_String[num] ==
'/' || m_String[num] ==
'\\'))
2151 num = (ushort)(num + 1);
2157 num = (ushort)m_Syntax.SchemeName.Length;
2160 string @
string = m_String;
2162 num = (ushort)(num2 + 1);
2163 if (@
string[num2] ==
':')
2167 uriInfo.Offset.Scheme++;
2169 if ((cF & Flags.AuthorityFound) != Flags.Zero)
2171 if (m_String[num] ==
'\\' || m_String[num + 1] ==
'\\')
2175 num = (ushort)(num + 2);
2176 if ((cF & (Flags.DosPath | Flags.UncPath)) != Flags.Zero)
2178 while (num < (ushort)(cF & Flags.IndexMask) && (m_String[num] ==
'/' || m_String[num] ==
'\\'))
2181 num = (ushort)(num + 1);
2186 if (m_Syntax.DefaultPort != -1)
2188 uriInfo.Offset.PortValue = (ushort)m_Syntax.DefaultPort;
2190 if ((cF & Flags.HostTypeMask) == Flags.HostTypeMask || StaticInFact(cF, Flags.DosPath))
2192 uriInfo.Offset.User = (ushort)(cF & Flags.IndexMask);
2193 uriInfo.Offset.Host = uriInfo.Offset.User;
2194 uriInfo.Offset.Path = uriInfo.Offset.User;
2195 cF = (Flags)((
long)cF & -65536
L);
2198 cF |= Flags.SchemeNotCanonical;
2203 uriInfo.Offset.User = num;
2204 if (HostType == Flags.BasicHostType)
2206 uriInfo.Offset.Host = num;
2207 uriInfo.Offset.Path = (ushort)(cF & Flags.IndexMask);
2208 cF = (Flags)((
long)cF & -65536
L);
2212 if ((cF & Flags.HasUserInfo) != Flags.Zero)
2214 while (m_String[num] !=
'@')
2216 num = (ushort)(num + 1);
2218 num = (ushort)(num + 1);
2219 uriInfo.Offset.Host = num;
2223 uriInfo.Offset.Host = num;
2225 num = (ushort)(cF & Flags.IndexMask);
2226 cF = (Flags)((
long)cF & -65536
L);
2229 cF |= Flags.SchemeNotCanonical;
2231 uriInfo.Offset.Path = num;
2233 bool flag3 = (cF & Flags.UseOrigUncdStrOffset) != Flags.Zero;
2234 cF = (Flags)((long)cF & -274877906945L);
2237 uriInfo.Offset.End = (ushort)m_originalUnicodeString.Length;
2239 if (num < uriInfo.Offset.End)
2241 fixed (
char* ptr = flag3 ? m_originalUnicodeString : m_String)
2243 if (ptr[(
int)num] ==
':')
2246 if ((num = (ushort)(num + 1)) < uriInfo.Offset.End)
2248 num3 = (ushort)(ptr[(
int)num] - 48);
2249 if (num3 != 65535 && num3 != 15 && num3 != 65523)
2254 cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
2256 for (num = (ushort)(num + 1); num < uriInfo.Offset.End; num = (ushort)(num + 1))
2258 ushort num4 = (ushort)(ptr[(
int)num] - 48);
2259 if (num4 == ushort.MaxValue || num4 == 15 || num4 == 65523)
2263 num3 = num3 * 10 + num4;
2267 if (flag2 && uriInfo.Offset.PortValue != (ushort)num3)
2269 uriInfo.Offset.PortValue = (ushort)num3;
2270 cF |= Flags.NotDefaultPort;
2274 cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
2276 uriInfo.Offset.Path = num;
2283 cF |= Flags.MinimalUriInfoSet;
2284 uriInfo.DnsSafeHost = m_DnsSafeHost;
2287 if ((m_Flags & Flags.MinimalUriInfoSet) == Flags.Zero)
2290 m_Flags = (Flags)(((
long)m_Flags & -65536L) | (long)cF);
2295 private unsafe
void CreateHostString()
2297 if (!m_Syntax.IsSimple)
2301 if (NotAny(Flags.ErrorOrParsingRecursion))
2303 m_Flags |= Flags.ErrorOrParsingRecursion;
2304 GetHostViaCustomSyntax();
2305 m_Flags &= ~Flags.ErrorOrParsingRecursion;
2310 Flags flags = m_Flags;
2311 string text = CreateHostStringHelper(m_String, m_Info.Offset.Host, m_Info.Offset.Path, ref flags, ref m_Info.ScopeId);
2312 if (text.Length != 0)
2314 if (HostType == Flags.BasicHostType)
2318 fixed (
char* str = text)
2320 check = CheckCanonical(str, ref idx, (ushort)text.Length,
'\uffff');
2322 if ((check & Check.DisplayCanonical) == Check.None && (NotAny(Flags.ImplicitFile) || (check & Check.ReservedFound) != 0))
2324 flags |= Flags.HostNotCanonical;
2326 if (InFact(Flags.ImplicitFile) && (check & (Check.EscapedCanonical | Check.ReservedFound)) != 0)
2328 check &= ~Check.EscapedCanonical;
2330 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
2332 flags |= Flags.E_HostNotCanonical;
2333 if (NotAny(Flags.UserEscaped))
2336 char[] array = UriHelper.EscapeString(text, 0, text.Length,
null, ref destPos, isUriString:
true,
'?',
'#', IsImplicitFile ?
'\uffff' :
'%');
2339 text =
new string(array, 0, destPos);
2344 else if (NotAny(Flags.CanonicalDnsHost))
2346 if (m_Info.ScopeId !=
null)
2348 flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
2352 for (ushort num = 0; num < text.Length; num = (ushort)(num + 1))
2354 if (m_Info.Offset.Host + num >= m_Info.Offset.End || text[num] != m_String[m_Info.Offset.Host + num])
2356 flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
2370 private static string CreateHostStringHelper(
string str, ushort idx, ushort end, ref Flags flags, ref
string scopeId)
2372 bool loopback =
false;
2374 switch (flags & Flags.HostTypeMask)
2376 case Flags.DnsHostType:
2377 text = DomainNameHelper.ParseCanonicalName(str, idx, end, ref loopback);
2379 case Flags.IPv6HostType:
2380 text = IPv6AddressHelper.ParseCanonicalName(str, idx, ref loopback, ref scopeId);
2382 case Flags.IPv4HostType:
2383 text = IPv4AddressHelper.ParseCanonicalName(str, idx, end, ref loopback);
2385 case Flags.UncHostType:
2386 text = UncNameHelper.ParseCanonicalName(str, idx, end, ref loopback);
2388 case Flags.BasicHostType:
2389 text = ((!StaticInFact(flags, Flags.DosPath)) ? str.Substring(idx, end - idx) :
string.Empty);
2390 if (text.Length == 0)
2395 case Flags.HostTypeMask:
2396 text =
string.Empty;
2399 throw GetException(ParsingError.BadHostName);
2403 flags |= Flags.LoopbackHost;
2408 private unsafe
void GetHostViaCustomSyntax()
2410 if (m_Info.Host !=
null)
2415 if (m_Info.Host ==
null)
2417 if (text.Length >= 65520)
2419 throw GetException(ParsingError.SizeLimit);
2421 ParsingError err = ParsingError.None;
2422 Flags flags = (Flags)((
long)m_Flags & -458753
L);
2423 fixed (
char* pString = text)
2425 string newHost =
null;
2426 if (CheckAuthorityHelper(pString, 0, (ushort)text.Length, ref err, ref flags, m_Syntax, ref newHost) != (ushort)text.Length)
2428 flags = (Flags)((
long)flags & -458753
L);
2429 flags |= Flags.HostTypeMask;
2432 if (err != 0 || (flags & Flags.HostTypeMask) == Flags.HostTypeMask)
2434 m_Flags = (Flags)(((
long)m_Flags & -458753
L) | 0x50000);
2438 text = CreateHostStringHelper(text, 0, (ushort)text.Length, ref flags, ref m_Info.ScopeId);
2439 for (ushort num = 0; num < text.Length; num = (ushort)(num + 1))
2441 if (m_Info.Offset.Host + num >= m_Info.Offset.End || text[num] != m_String[m_Info.Offset.Host + num])
2443 m_Flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
2447 m_Flags = (Flags)(((
long)m_Flags & -458753
L) | (
long)(flags & Flags.HostTypeMask));
2452 if (text2 ==
null || text2.Length == 0)
2454 m_Flags &= ~Flags.NotDefaultPort;
2455 m_Flags |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
2456 m_Info.Offset.PortValue = 0;
2460 for (
int i = 0; i < text2.Length; i++)
2462 int num3 = text2[i] - 48;
2463 if (num3 < 0 || num3 > 9 || (num2 = num2 * 10 + num3) > 65535)
2465 throw new UriFormatException(SR.GetString(
"net_uri_PortOutOfRange", m_Syntax.GetType().FullName, text2));
2468 if (num2 != m_Info.Offset.PortValue)
2470 if (num2 == m_Syntax.DefaultPort)
2472 m_Flags &= ~Flags.NotDefaultPort;
2476 m_Flags |= Flags.NotDefaultPort;
2478 m_Flags |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
2479 m_Info.Offset.PortValue = (ushort)num2;
2485 internal string GetParts(UriComponents uriParts, UriFormat formatAs)
2487 return GetComponents(uriParts, formatAs);
2490 private string GetEscapedParts(UriComponents uriParts)
2492 ushort num = (ushort)(((ushort)m_Flags & 0x3F80) >> 6);
2493 if (InFact(Flags.SchemeNotCanonical))
2495 num = (ushort)(num | 1);
2499 if (InFact(Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath))
2501 num = (ushort)(num | 0x10);
2503 else if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] ==
'|')
2505 num = (ushort)(num | 0x10);
2508 if (((ushort)uriParts & num) == 0)
2510 string uriPartsFromUserString = GetUriPartsFromUserString(uriParts);
2511 if (uriPartsFromUserString !=
null)
2513 return uriPartsFromUserString;
2516 return ReCreateParts(uriParts, num,
UriFormat.UriEscaped);
2519 private string GetUnescapedParts(UriComponents uriParts, UriFormat formatAs)
2521 ushort num = (ushort)((ushort)m_Flags & 0x7F);
2524 if ((m_Flags & (Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath)) != Flags.Zero)
2526 num = (ushort)(num | 0x10);
2528 else if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] ==
'|')
2530 num = (ushort)(num | 0x10);
2533 if (((ushort)uriParts & num) == 0)
2535 string uriPartsFromUserString = GetUriPartsFromUserString(uriParts);
2536 if (uriPartsFromUserString !=
null)
2538 return uriPartsFromUserString;
2541 return ReCreateParts(uriParts, num, formatAs);
2544 private unsafe
string ReCreateParts(UriComponents parts, ushort nonCanonical, UriFormat formatAs)
2546 EnsureHostString(allowDnsOptimization:
false);
2547 string text = ((parts &
UriComponents.Host) == (UriComponents)0) ?
string.Empty : m_Info.Host;
2548 int num = (m_Info.Offset.End - m_Info.Offset.User) * ((formatAs !=
UriFormat.UriEscaped) ? 1 : 12);
2549 char[] array =
new char[text.Length + num + m_Syntax.SchemeName.Length + 3 + 1];
2553 m_Syntax.SchemeName.CopyTo(0, array, num, m_Syntax.SchemeName.Length);
2554 num += m_Syntax.SchemeName.Length;
2558 if (InFact(Flags.AuthorityFound))
2565 if ((parts &
UriComponents.UserInfo) != 0 && InFact(Flags.HasUserInfo))
2567 if ((nonCanonical & 2) != 0)
2572 if (NotAny(Flags.UserEscaped))
2574 array = UriHelper.EscapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, array, ref num, isUriString:
true,
'?',
'#',
'%');
2577 InFact(Flags.E_UserNotCanonical);
2578 m_String.CopyTo(m_Info.Offset.User, array, num, m_Info.Offset.Host - m_Info.Offset.User);
2579 num += m_Info.Offset.Host - m_Info.Offset.User;
2582 array = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host - 1, array, ref num,
'@',
'/',
'\\', InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape, m_Syntax, isQuery:
false);
2586 array = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, isQuery:
false);
2589 array = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
false);
2595 UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
false);
2604 UnescapeMode unescapeMode = (formatAs !=
UriFormat.UriEscaped && HostType == Flags.BasicHostType && (nonCanonical & 4) != 0) ? ((formatAs ==
UriFormat.Unescaped) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape)) : UnescapeMode.CopyOnly;
2607 fixed (
char* hostname = text)
2609 bool allAscii =
false;
2610 bool atLeastOneValidIdn =
false;
2613 text = DomainNameHelper.UnicodeEquivalent(hostname, 0, text.Length, ref allAscii, ref atLeastOneValidIdn);
2615 catch (UriFormatException)
2620 array = UriHelper.UnescapeString(text, 0, text.Length, array, ref num,
'/',
'?',
'#', unescapeMode, m_Syntax, isQuery:
false);
2621 if ((parts &
UriComponents.SerializationInfoString) != 0 && HostType == Flags.IPv6HostType && m_Info.ScopeId !=
null)
2623 m_Info.ScopeId.CopyTo(0, array, num - 1, m_Info.ScopeId.Length);
2624 num += m_Info.ScopeId.Length;
2625 array[num - 1] =
']';
2630 if ((nonCanonical & 8) == 0)
2632 if (InFact(Flags.NotDefaultPort))
2634 ushort num6 = m_Info.Offset.Path;
2635 while (m_String[num6 = (ushort)(num6 - 1)] !=
':')
2638 m_String.CopyTo(num6, array, num, m_Info.Offset.Path - num6);
2639 num += m_Info.Offset.Path - num6;
2641 else if ((parts &
UriComponents.StrongPort) != 0 && m_Syntax.DefaultPort != -1)
2645 text.CopyTo(0, array, num, text.Length);
2649 else if (InFact(Flags.NotDefaultPort) || ((parts &
UriComponents.StrongPort) != 0 && m_Syntax.DefaultPort != -1))
2653 text.CopyTo(0, array, num, text.Length);
2659 array = GetCanonicalPath(array, ref num, formatAs);
2663 if (InFact(Flags.AuthorityFound) && num != 0 && array[0] ==
'/')
2674 return new string(array, startIndex, num);
2676 return string.Empty;
2679 if ((parts &
UriComponents.Query) != 0 && m_Info.Offset.Query < m_Info.Offset.Fragment)
2681 ushort startIndex = (ushort)(m_Info.Offset.Query + 1);
2686 if ((nonCanonical & 0x20) != 0)
2691 if (NotAny(Flags.UserEscaped))
2693 array = UriHelper.EscapeString(m_String, startIndex, m_Info.Offset.Fragment, array, ref num, isUriString:
true,
'#',
'\uffff',
'%');
2697 UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.Fragment, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
true);
2700 case (UriFormat)32767:
2701 array = UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.Fragment, array, ref num,
'#',
'\uffff',
'\uffff', (UnescapeMode)((InFact(Flags.UserEscaped) ? 2 : 3) | 4), m_Syntax, isQuery:
true);
2704 array = UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.Fragment, array, ref num,
'#',
'\uffff',
'\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, isQuery:
true);
2707 array = UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.Fragment, array, ref num,
'#',
'\uffff',
'\uffff', InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape, m_Syntax, isQuery:
true);
2713 UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.Fragment, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
true);
2716 if ((parts &
UriComponents.Fragment) != 0 && m_Info.Offset.Fragment < m_Info.Offset.End)
2718 ushort startIndex = (ushort)(m_Info.Offset.Fragment + 1);
2723 if ((nonCanonical & 0x40) != 0)
2728 if (NotAny(Flags.UserEscaped))
2730 array = UriHelper.EscapeString(m_String, startIndex, m_Info.Offset.End, array, ref num, isUriString:
true, UriParser.ShouldUseLegacyV2Quirks ?
'#' :
'\uffff',
'\uffff',
'%');
2734 UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.End, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
false);
2737 case (UriFormat)32767:
2738 array = UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.End, array, ref num,
'#',
'\uffff',
'\uffff', (UnescapeMode)((InFact(Flags.UserEscaped) ? 2 : 3) | 4), m_Syntax, isQuery:
false);
2741 array = UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.End, array, ref num,
'#',
'\uffff',
'\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, isQuery:
false);
2744 array = UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.End, array, ref num,
'#',
'\uffff',
'\uffff', InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape, m_Syntax, isQuery:
false);
2750 UriHelper.UnescapeString(m_String, startIndex, m_Info.Offset.End, array, ref num,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.CopyOnly, m_Syntax, isQuery:
false);
2753 return new string(array, 0, num);
2756 private string GetUriPartsFromUserString(UriComponents uriParts)
2761 if (!InFact(Flags.HasUserInfo))
2763 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Path - m_Info.Offset.Scheme);
2765 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme) + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host);
2767 if (InFact(Flags.HasUserInfo))
2769 if (InFact(Flags.NotDefaultPort) || m_Syntax.DefaultPort == -1)
2771 return m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host);
2773 return m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host) +
":" + m_Info.Offset.PortValue.ToString(
CultureInfo.
InvariantCulture);
2777 if (m_Info.Offset.Scheme == 0 && m_Info.Offset.End == m_String.Length)
2781 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.End - m_Info.Offset.Scheme);
2783 if (InFact(Flags.HasUserInfo))
2785 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme) + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Fragment - m_Info.Offset.Host);
2787 if (m_Info.Offset.Scheme == 0 && m_Info.Offset.Fragment == m_String.Length)
2791 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Fragment - m_Info.Offset.Scheme);
2793 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Path - m_Info.Offset.Scheme);
2795 if (m_Info.Offset.Scheme == 0 && m_Info.Offset.Fragment == m_String.Length)
2799 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Fragment - m_Info.Offset.Scheme);
2803 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme);
2805 return m_Syntax.SchemeName;
2808 ushort num2 = m_Info.Offset.Path;
2809 if (InFact(Flags.PortNotCanonical | Flags.NotDefaultPort))
2811 while (m_String[num2 = (ushort)(num2 - 1)] !=
':')
2815 if (num2 - m_Info.Offset.Host != 0)
2817 return m_String.Substring(m_Info.Offset.Host, num2 - m_Info.Offset.Host);
2819 return string.Empty;
2823 ushort num = (uriParts !=
UriComponents.Path || !InFact(Flags.AuthorityFound) || m_Info.Offset.End <= m_Info.Offset.Path || m_String[m_Info.Offset.Path] !=
'/') ? m_Info.Offset.Path : ((ushort)(m_Info.Offset.Path + 1));
2824 if (num >= m_Info.Offset.Query)
2826 return string.Empty;
2828 return m_String.Substring(num, m_Info.Offset.Query - num);
2832 ushort num = (uriParts !=
UriComponents.Query) ? m_Info.Offset.Query : ((ushort)(m_Info.Offset.Query + 1));
2833 if (num >= m_Info.Offset.Fragment)
2835 return string.Empty;
2837 return m_String.Substring(num, m_Info.Offset.Fragment - num);
2841 ushort num = (uriParts !=
UriComponents.Fragment) ? m_Info.Offset.Fragment : ((ushort)(m_Info.Offset.Fragment + 1));
2842 if (num >= m_Info.Offset.End)
2844 return string.Empty;
2846 return m_String.Substring(num, m_Info.Offset.End - num);
2849 if (m_Info.Offset.Path - m_Info.Offset.User != 0)
2851 return m_String.Substring(m_Info.Offset.User, m_Info.Offset.Path - m_Info.Offset.User);
2853 return string.Empty;
2855 if (!InFact(Flags.NotDefaultPort) && m_Syntax.DefaultPort != -1)
2857 return m_String.Substring(m_Info.Offset.User, m_Info.Offset.Path - m_Info.Offset.User) +
":" + m_Info.Offset.PortValue.ToString(
CultureInfo.
InvariantCulture);
2861 return m_String.Substring(m_Info.Offset.Path, m_Info.Offset.Fragment - m_Info.Offset.Path);
2863 if (InFact(Flags.HasUserInfo))
2865 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme) + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.End - m_Info.Offset.Host);
2867 if (m_Info.Offset.Scheme == 0 && m_Info.Offset.End == m_String.Length)
2871 return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.End - m_Info.Offset.Scheme);
2873 return m_String.Substring(m_Info.Offset.Path, m_Info.Offset.End - m_Info.Offset.Path);
2876 if (NotAny(Flags.HasUserInfo))
2878 return string.Empty;
2880 ushort num = (uriParts !=
UriComponents.UserInfo) ? m_Info.Offset.Host : ((ushort)(m_Info.Offset.Host - 1));
2881 if (m_Info.Offset.User >= num)
2883 return string.Empty;
2885 return m_String.Substring(m_Info.Offset.User, num - m_Info.Offset.User);
2892 private unsafe
void ParseRemaining()
2895 Flags flags = Flags.Zero;
2896 if (!UserDrivenParsing)
2898 bool flag = m_iriParsing && (m_Flags & Flags.HasUnicode) != Flags.Zero && (m_Flags & Flags.RestUnicodeNormalized) == Flags.Zero;
2899 ushort scheme = m_Info.Offset.Scheme;
2900 ushort num = (ushort)m_String.Length;
2901 Check check = Check.None;
2902 UriSyntaxFlags flags2 = m_Syntax.Flags;
2903 fixed (
char* ptr = m_String)
2905 if (num > scheme && IsLWS(ptr[num - 1]))
2907 num = (ushort)(num - 1);
2908 while (num != scheme && IsLWS(ptr[(
int)(num = (ushort)(num - 1))]))
2911 num = (ushort)(num + 1);
2915 flags |= Flags.SchemeNotCanonical;
2920 ushort num3 = (ushort)m_Syntax.SchemeName.Length;
2923 if (m_Syntax.SchemeName[num2] != ptr[scheme + num2])
2925 flags |= Flags.SchemeNotCanonical;
2927 num2 = (ushort)(num2 + 1);
2929 if ((m_Flags & Flags.AuthorityFound) != Flags.Zero && (scheme + num2 + 3 >= num || ptr[scheme + num2 + 1] !=
'/' || ptr[scheme + num2 + 2] !=
'/'))
2931 flags |= Flags.SchemeNotCanonical;
2934 if ((m_Flags & Flags.HasUserInfo) != Flags.Zero)
2936 scheme = m_Info.Offset.User;
2937 check = CheckCanonical(ptr, ref scheme, m_Info.Offset.Host,
'@');
2938 if ((check & Check.DisplayCanonical) == Check.None)
2940 flags |= Flags.UserNotCanonical;
2942 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
2944 flags |= Flags.E_UserNotCanonical;
2946 if (m_iriParsing && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.BackslashInPath | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
2948 flags |= Flags.UserIriCanonical;
2952 scheme = m_Info.Offset.Path;
2953 ushort idx = m_Info.Offset.Path;
2960 m_String =
string.Empty;
2964 m_String = m_Syntax.SchemeName + SchemeDelimiter;
2967 m_Info.Offset.Path = (ushort)m_String.Length;
2968 scheme = m_Info.Offset.Path;
2970 if (IsImplicitFile || (flags2 & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == UriSyntaxFlags.None)
2972 FindEndOfComponent(m_originalUnicodeString, ref idx, (ushort)m_originalUnicodeString.Length,
'\uffff');
2976 FindEndOfComponent(m_originalUnicodeString, ref idx, (ushort)m_originalUnicodeString.Length, m_Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ?
'?' : (m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment) ?
'#' :
'\ufffe'));
2978 string text = EscapeUnescapeIri(m_originalUnicodeString, start, idx,
UriComponents.Path);
2981 if (UriParser.ShouldUseLegacyV2Quirks)
2990 catch (ArgumentException)
2992 UriFormatException exception = GetException(ParsingError.BadFormat);
2995 num = (ushort)m_String.Length;
2997 fixed (
char* ptr2 = m_String)
2999 check = ((!IsImplicitFile && (flags2 & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) != 0) ? CheckCanonical(ptr2, ref scheme, num, ((flags2 & UriSyntaxFlags.MayHaveQuery) != 0) ?
'?' : (m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment) ?
'#' :
'\ufffe')) : CheckCanonical(ptr2, ref scheme, num,
'\uffff'));
3000 if ((m_Flags & Flags.AuthorityFound) != Flags.Zero && (flags2 & UriSyntaxFlags.PathIsRooted) != 0 && (m_Info.Offset.Path == num || (ptr2[(
int)m_Info.Offset.Path] !=
'/' && ptr2[(
int)m_Info.Offset.Path] !=
'\\')))
3002 flags |= Flags.FirstSlashAbsent;
3006 if (IsDosPath || ((m_Flags & Flags.AuthorityFound) != Flags.Zero && ((flags2 & (UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath)) != 0 || m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))))
3008 if ((check & Check.DotSlashEscaped) != 0 && m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))
3010 flags |= (Flags.PathNotCanonical | Flags.E_PathNotCanonical);
3013 if ((flags2 & UriSyntaxFlags.ConvertPathSlashes) != 0 && (check & Check.BackslashInPath) != 0)
3015 flags |= (Flags.PathNotCanonical | Flags.E_PathNotCanonical);
3018 if ((flags2 & UriSyntaxFlags.CompressPath) != 0 && ((flags & Flags.E_PathNotCanonical) != Flags.Zero || (check & Check.DotSlashAttn) != 0))
3020 flags |= Flags.ShouldBeCompressed;
3022 if ((check & Check.BackslashInPath) != 0)
3024 flags |= Flags.BackslashInPath;
3027 else if ((check & Check.BackslashInPath) != 0)
3029 flags |= Flags.E_PathNotCanonical;
3032 if ((check & Check.DisplayCanonical) == Check.None && ((m_Flags & Flags.ImplicitFile) == Flags.Zero || (m_Flags & Flags.UserEscaped) != Flags.Zero || (check & Check.ReservedFound) != 0))
3034 flags |= Flags.PathNotCanonical;
3037 if ((m_Flags & Flags.ImplicitFile) != Flags.Zero && (check & (Check.EscapedCanonical | Check.ReservedFound)) != 0)
3039 check &= ~Check.EscapedCanonical;
3041 if ((check & Check.EscapedCanonical) == Check.None)
3043 flags |= Flags.E_PathNotCanonical;
3045 if (m_iriParsing && !flag2 && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
3047 flags |= Flags.PathIriCanonical;
3051 ushort start2 = idx;
3052 if (idx < m_originalUnicodeString.Length && m_originalUnicodeString[idx] ==
'?')
3054 idx = (ushort)(idx + 1);
3055 FindEndOfComponent(m_originalUnicodeString, ref idx, (ushort)m_originalUnicodeString.Length, ((flags2 & UriSyntaxFlags.MayHaveFragment) != 0) ?
'#' :
'\ufffe');
3056 string text2 = EscapeUnescapeIri(m_originalUnicodeString, start2, idx,
UriComponents.Query);
3059 if (UriParser.ShouldUseLegacyV2Quirks)
3068 catch (ArgumentException)
3070 UriFormatException exception2 = GetException(ParsingError.BadFormat);
3073 num = (ushort)m_String.Length;
3076 m_Info.Offset.Query = scheme;
3077 fixed (
char* ptr3 = m_String)
3079 if (scheme < num && ptr3[(
int)scheme] ==
'?')
3081 scheme = (ushort)(scheme + 1);
3082 check = CheckCanonical(ptr3, ref scheme, num, ((flags2 & UriSyntaxFlags.MayHaveFragment) != 0) ?
'#' :
'\ufffe');
3083 if ((check & Check.DisplayCanonical) == Check.None)
3085 flags |= Flags.QueryNotCanonical;
3087 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
3089 flags |= Flags.E_QueryNotCanonical;
3091 if (m_iriParsing && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.BackslashInPath | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
3093 flags |= Flags.QueryIriCanonical;
3099 ushort start3 = idx;
3100 if (idx < m_originalUnicodeString.Length && m_originalUnicodeString[idx] ==
'#')
3102 idx = (ushort)(idx + 1);
3103 FindEndOfComponent(m_originalUnicodeString, ref idx, (ushort)m_originalUnicodeString.Length,
'\ufffe');
3104 string text3 = EscapeUnescapeIri(m_originalUnicodeString, start3, idx,
UriComponents.Fragment);
3107 if (UriParser.ShouldUseLegacyV2Quirks)
3116 catch (ArgumentException)
3118 UriFormatException exception3 = GetException(ParsingError.BadFormat);
3121 num = (ushort)m_String.Length;
3124 m_Info.Offset.Fragment = scheme;
3125 fixed (
char* ptr4 = m_String)
3127 if (scheme < num && ptr4[(
int)scheme] ==
'#')
3129 scheme = (ushort)(scheme + 1);
3130 check = CheckCanonical(ptr4, ref scheme, num,
'\ufffe');
3131 if ((check & Check.DisplayCanonical) == Check.None)
3133 flags |= Flags.FragmentNotCanonical;
3135 if ((check & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical)
3137 flags |= Flags.E_FragmentNotCanonical;
3139 if (m_iriParsing && (check & (Check.EscapedCanonical | Check.DisplayCanonical | Check.BackslashInPath | Check.NotIriCanonical | Check.FoundNonAscii)) == (Check.DisplayCanonical | Check.FoundNonAscii))
3141 flags |= Flags.FragmentIriCanonical;
3145 m_Info.Offset.End = scheme;
3147 flags |= Flags.AllUriInfoSet;
3152 m_Flags |= Flags.RestUnicodeNormalized;
3155 private unsafe
static ushort ParseSchemeCheckImplicitFile(
char* uriString, ushort length, ref ParsingError err, ref Flags flags, ref UriParser syntax)
3158 while (num < length && IsLWS(uriString[(
int)num]))
3160 num = (ushort)(num + 1);
3163 while (num2 < length && uriString[(
int)num2] !=
':')
3165 num2 = (ushort)(num2 + 1);
3167 if (IntPtr.Size == 4 && num2 != length && num2 >= num + 2 && CheckKnownSchemes((
long*)(uriString + (int)num), (ushort)(num2 - num), ref syntax))
3169 return (ushort)(num2 + 1);
3171 if (num + 2 >= length || num2 == num)
3173 err = ParsingError.BadFormat;
3177 if ((c = uriString[num + 1]) ==
':' || c ==
'|')
3179 if (IsAsciiLetter(uriString[(
int)num]))
3181 if ((c = uriString[num + 2]) ==
'\\' || c ==
'/')
3183 flags |= (Flags.AuthorityFound | Flags.DosPath | Flags.ImplicitFile);
3184 syntax = UriParser.FileUri;
3187 err = ParsingError.MustRootedPath;
3192 err = ParsingError.BadScheme;
3196 err = ParsingError.BadFormat;
3200 if ((c = uriString[(
int)num]) ==
'/' || c ==
'\\')
3202 if ((c = uriString[num + 1]) ==
'\\' || c ==
'/')
3204 flags |= (Flags.AuthorityFound | Flags.UncPath | Flags.ImplicitFile);
3205 syntax = UriParser.FileUri;
3206 num = (ushort)(num + 2);
3207 while (num < length && ((c = uriString[(
int)num]) ==
'/' || c ==
'\\'))
3209 num = (ushort)(num + 1);
3213 err = ParsingError.BadFormat;
3218 err = ParsingError.BadFormat;
3221 if (num2 - num > 1024)
3223 err = ParsingError.SchemeLimit;
3226 char* ptr = stackalloc
char[num2 - num];
3231 ushort num3 = length;
3232 length = (ushort)(num3 + 1);
3233 intPtr[(int)num3] = uriString[(
int)num];
3234 num = (ushort)(num + 1);
3236 err = CheckSchemeSyntax(ptr, length, ref syntax);
3241 return (ushort)(num2 + 1);
3244 private unsafe
static bool CheckKnownSchemes(
long* lptr, ushort nChars, ref UriParser syntax)
3248 if (((
int)(*lptr) | 0x200020) == 7536759)
3250 syntax = UriParser.WsUri;
3255 switch (*lptr | 0x20002000200020)
3257 case 31525695615402088
L:
3261 syntax = UriParser.HttpUri;
3264 if ((*(ushort*)(lptr + 1) | 0x20) == 115)
3266 syntax = UriParser.HttpsUri;
3272 case 16326042577993847
L:
3275 syntax = UriParser.WssUri;
3279 case 28429436511125606
L:
3282 syntax = UriParser.FileUri;
3286 case 16326029693157478
L:
3289 syntax = UriParser.FtpUri;
3293 case 32370133429452910
L:
3296 syntax = UriParser.NewsUri;
3300 case 31525695615008878
L:
3303 syntax = UriParser.NntpUri;
3307 case 28147948650299509
L:
3310 syntax = UriParser.UuidUri;
3314 case 29273878621519975
L:
3315 if (nChars == 6 && (*(
int*)(lptr + 1) | 0x200020) == 7471205)
3317 syntax = UriParser.GopherUri;
3321 case 30399748462674029
L:
3322 if (nChars == 6 && (*(
int*)(lptr + 1) | 0x200020) == 7274612)
3324 syntax = UriParser.MailToUri;
3328 case 30962711301259380
L:
3329 if (nChars == 6 && (*(
int*)(lptr + 1) | 0x200020) == 7602277)
3331 syntax = UriParser.TelnetUri;
3335 case 12948347151515758
L:
3336 if (nChars == 8 && (lptr[1] | 0x20002000200020) == 28429453690994800L)
3338 syntax = UriParser.NetPipeUri;
3341 if (nChars == 7 && (lptr[1] | 0x20002000200020) == 16326029692043380L)
3343 syntax = UriParser.NetTcpUri;
3347 case 31525614009974892
L:
3350 syntax = UriParser.LdapUri;
3358 private unsafe
static ParsingError CheckSchemeSyntax(
char* ptr, ushort length, ref UriParser syntax)
3361 if (c < 'a' || c >
'z')
3363 if (c < 'A' || c >
'Z')
3365 return ParsingError.BadScheme;
3367 *ptr = (char)(c | 0x20);
3369 for (ushort num = 1; num < length; num = (ushort)(num + 1))
3371 char c2 = ptr[(int)num];
3372 if (c2 < 'a' || c2 >
'z')
3374 if (c2 >=
'A' && c2 <=
'Z')
3376 ptr[(int)num] = (
char)(c2 | 0x20);
3378 else if ((c2 < '0' || c2 >
'9') && c2 !=
'+' && c2 !=
'-' && c2 !=
'.')
3380 return ParsingError.BadScheme;
3384 string lwrCaseScheme =
new string(ptr, 0, length);
3385 syntax = UriParser.FindOrFetchAsUnknownV1Syntax(lwrCaseScheme);
3386 return ParsingError.None;
3389 private unsafe ushort CheckAuthorityHelper(
char* pString, ushort idx, ushort length, ref ParsingError err, ref Flags flags, UriParser syntax, ref
string newHost)
3395 bool justNormalized =
false;
3396 bool flag = s_IriParsing && IriParsingStatic(syntax);
3397 bool flag2 = (flags & Flags.HasUnicode) != Flags.Zero;
3398 bool flag3 = (flags & Flags.HostUnicodeNormalized) == Flags.Zero;
3399 UriSyntaxFlags flags2 = syntax.Flags;
3400 if ((flag2 && flag) & flag3)
3402 newHost = m_originalUnicodeString.Substring(0, num);
3405 if (idx == length || (c = pString[(
int)idx]) ==
'/' || (c ==
'\\' && StaticIsFile(syntax)) || c ==
'#' || c ==
'?')
3407 if (syntax.InFact(UriSyntaxFlags.AllowEmptyHost))
3409 flags &= ~Flags.UncPath;
3410 if (StaticInFact(flags, Flags.ImplicitFile))
3412 err = ParsingError.BadHostName;
3416 flags |= Flags.BasicHostType;
3421 err = ParsingError.BadHostName;
3423 if ((flag2 && flag) & flag3)
3425 flags |= Flags.HostUnicodeNormalized;
3430 if ((flags2 & UriSyntaxFlags.MayHaveUserInfo) != 0)
3434 if (num2 == i - 1 || pString[(
int)num2] ==
'?' || pString[(int)num2] ==
'#' || pString[(
int)num2] ==
'\\' || pString[(int)num2] ==
'/')
3439 if (pString[(
int)num2] ==
'@')
3441 flags |= Flags.HasUserInfo;
3442 if (flag || s_IdnScope != 0)
3444 if ((flag && flag2) & flag3)
3446 text = IriHelper.EscapeUnescapeIri(pString, num, num2 + 1,
UriComponents.UserInfo);
3449 if (UriParser.ShouldUseLegacyV2Quirks)
3454 catch (ArgumentException)
3456 err = ParsingError.BadFormat;
3463 text =
new string(pString, num, num2 - num + 1);
3466 num2 = (ushort)(num2 + 1);
3467 c = pString[(int)num2];
3470 num2 = (ushort)(num2 + 1);
3473 bool notCanonical = (flags2 & UriSyntaxFlags.SimpleUserSyntax) == UriSyntaxFlags.None;
3474 if (c ==
'[' && syntax.InFact(UriSyntaxFlags.AllowIPv6Host) && IPv6AddressHelper.IsValid(pString, num2 + 1, ref i))
3476 flags |= Flags.IPv6HostType;
3477 if (!s_ConfigInitialized)
3479 InitializeUriConfig();
3480 m_iriParsing = (s_IriParsing && IriParsingStatic(syntax));
3482 if ((flag2 && flag) & flag3)
3484 newHost +=
new string(pString, num2, i - num2);
3485 flags |= Flags.HostUnicodeNormalized;
3486 justNormalized =
true;
3489 else if (c <= '9' && c >=
'0' && syntax.InFact(UriSyntaxFlags.AllowIPv4Host) && IPv4AddressHelper.IsValid(pString, num2, ref i, allowIPv6:
false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri)))
3491 flags |= Flags.IPv4HostType;
3492 if ((flag2 && flag) & flag3)
3494 newHost +=
new string(pString, num2, i - num2);
3495 flags |= Flags.HostUnicodeNormalized;
3496 justNormalized =
true;
3499 else if ((flags2 & UriSyntaxFlags.AllowDnsHost) != 0 && !flag && DomainNameHelper.IsValid(pString, num2, ref i, ref notCanonical, StaticNotAny(flags, Flags.ImplicitFile)))
3501 flags |= Flags.DnsHostType;
3504 flags |= Flags.CanonicalDnsHost;
3506 if (s_IdnScope != 0)
3508 if (s_IdnScope ==
UriIdnScope.AllExceptIntranet && IsIntranet(
new string(pString, 0, i)))
3510 flags |= Flags.IntranetUri;
3512 if (AllowIdnStatic(syntax, flags))
3514 bool allAscii =
true;
3515 bool atLeastOneValidIdn =
false;
3516 string str = DomainNameHelper.UnicodeEquivalent(pString, num2, i, ref allAscii, ref atLeastOneValidIdn);
3517 if (atLeastOneValidIdn)
3519 if (StaticNotAny(flags, Flags.HasUnicode))
3521 m_originalUnicodeString = m_String;
3523 flags |= Flags.IdnHost;
3524 newHost = m_originalUnicodeString.Substring(0, num) + text + str;
3525 flags |= Flags.CanonicalDnsHost;
3526 m_DnsSafeHost =
new string(pString, num2, i - num2);
3527 justNormalized =
true;
3529 flags |= Flags.HostUnicodeNormalized;
3533 else if ((flags2 & UriSyntaxFlags.AllowDnsHost) != 0 && ((syntax.InFact(UriSyntaxFlags.AllowIriParsing) && flag3) || syntax.InFact(UriSyntaxFlags.AllowIdn)) && DomainNameHelper.IsValidByIri(pString, num2, ref i, ref notCanonical, StaticNotAny(flags, Flags.ImplicitFile)))
3535 CheckAuthorityHelperHandleDnsIri(pString, num2, i, num, flag, flag2, syntax, text, ref flags, ref justNormalized, ref newHost, ref err);
3537 else if ((flags2 & UriSyntaxFlags.AllowUncHost) != 0 && UncNameHelper.IsValid(pString, num2, ref i, StaticNotAny(flags, Flags.ImplicitFile)) && i - num2 <= 256)
3539 flags |= Flags.UncHostType;
3541 if (i < length && pString[i] ==
'\\' && (flags & Flags.HostTypeMask) != Flags.Zero && !StaticIsFile(syntax))
3543 if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
3545 err = ParsingError.BadHostName;
3546 flags |= Flags.HostTypeMask;
3549 flags &= ~Flags.HostTypeMask;
3551 else if (i < length && pString[i] ==
':')
3553 if (syntax.InFact(UriSyntaxFlags.MayHavePort))
3557 idx = (ushort)(i + 1);
3558 while (idx < length)
3560 ushort num5 = (ushort)(pString[(
int)idx] - 48);
3561 if (num5 >= 0 && num5 <= 9)
3563 if ((num3 = num3 * 10 + num5) > 65535)
3567 idx = (ushort)(idx + 1);
3570 if (num5 == ushort.MaxValue || num5 == 15 || num5 == 65523)
3574 if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost) && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri))
3576 flags &= ~Flags.HostTypeMask;
3579 err = ParsingError.BadPort;
3584 if (!syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
3586 err = ParsingError.BadPort;
3589 flags &= ~Flags.HostTypeMask;
3591 if ((flag && flag2) & justNormalized)
3593 newHost +=
new string(pString, num4, idx - num4);
3598 flags &= ~Flags.HostTypeMask;
3601 if ((flags & Flags.HostTypeMask) == Flags.Zero)
3603 flags &= ~Flags.HasUserInfo;
3604 if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
3606 flags |= Flags.BasicHostType;
3607 for (i = idx; i < length && pString[i] !=
'/' && pString[i] !=
'?' && pString[i] !=
'#'; i++)
3610 CheckAuthorityHelperHandleAnyHostIri(pString, num, i, flag, flag2, syntax, ref flags, ref newHost, ref err);
3612 else if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
3616 for (i = idx; i < length && (!flag4 || (pString[i] !=
'/' && pString[i] !=
'?' && pString[i] !=
'#')); i++)
3618 if (i < idx + 2 && pString[i] ==
'.')
3623 err = ParsingError.BadHostName;
3624 flags |= Flags.HostTypeMask;
3627 flags |= Flags.BasicHostType;
3628 if (flag && flag2 && StaticNotAny(flags, Flags.HostUnicodeNormalized))
3630 string text2 =
new string(pString, num6, i - num6);
3635 catch (ArgumentException)
3637 err = ParsingError.BadFormat;
3640 flags |= Flags.HostUnicodeNormalized;
3643 else if (syntax.InFact(UriSyntaxFlags.MustHaveAuthority) || (syntax.InFact(UriSyntaxFlags.MailToLikeUri) && !UriParser.ShouldUseLegacyV2Quirks))
3645 err = ParsingError.BadHostName;
3646 flags |= Flags.HostTypeMask;
3653 private unsafe
void CheckAuthorityHelperHandleDnsIri(
char* pString, ushort start,
int end,
int startInput,
bool iriParsing,
bool hasUnicode, UriParser syntax,
string userInfoString, ref Flags flags, ref
bool justNormalized, ref
string newHost, ref ParsingError err)
3655 flags |= Flags.DnsHostType;
3656 if (s_IdnScope ==
UriIdnScope.AllExceptIntranet && IsIntranet(
new string(pString, 0, end)))
3658 flags |= Flags.IntranetUri;
3660 if (AllowIdnStatic(syntax, flags))
3662 bool allAscii =
true;
3663 bool atLeastOneValidIdn =
false;
3664 string text = DomainNameHelper.IdnEquivalent(pString, start, end, ref allAscii, ref atLeastOneValidIdn);
3665 string text2 = DomainNameHelper.UnicodeEquivalent(text, pString, start, end);
3668 flags |= Flags.UnicodeHost;
3670 if (atLeastOneValidIdn)
3672 flags |= Flags.IdnHost;
3674 if (allAscii && atLeastOneValidIdn && StaticNotAny(flags, Flags.HasUnicode))
3676 m_originalUnicodeString = m_String;
3677 newHost = m_originalUnicodeString.Substring(0, startInput) + (StaticInFact(flags, Flags.HasUserInfo) ? userInfoString :
null);
3678 justNormalized =
true;
3680 else if (!iriParsing && (StaticInFact(flags, Flags.UnicodeHost) || StaticInFact(flags, Flags.IdnHost)))
3682 m_originalUnicodeString = m_String;
3683 newHost = m_originalUnicodeString.Substring(0, startInput) + (StaticInFact(flags, Flags.HasUserInfo) ? userInfoString :
null);
3684 justNormalized =
true;
3686 if (!allAscii || atLeastOneValidIdn)
3688 m_DnsSafeHost = text;
3690 justNormalized =
true;
3692 else if ((allAscii && !atLeastOneValidIdn) & iriParsing & hasUnicode)
3695 justNormalized =
true;
3698 else if (hasUnicode)
3700 string text3 = StripBidiControlCharacter(pString, start, end - start);
3705 catch (ArgumentException)
3707 err = ParsingError.BadHostName;
3709 justNormalized =
true;
3711 flags |= Flags.HostUnicodeNormalized;
3714 private unsafe
void CheckAuthorityHelperHandleAnyHostIri(
char* pString,
int startInput,
int end,
bool iriParsing,
bool hasUnicode, UriParser syntax, ref Flags flags, ref
string newHost, ref ParsingError err)
3716 if (!StaticNotAny(flags, Flags.HostUnicodeNormalized) || (!AllowIdnStatic(syntax, flags) && (!iriParsing || !hasUnicode)))
3720 string text =
new string(pString, startInput, end - startInput);
3721 if (AllowIdnStatic(syntax, flags))
3723 bool allAscii =
true;
3724 bool atLeastOneValidIdn =
false;
3725 string text2 = DomainNameHelper.UnicodeEquivalent(pString, startInput, end, ref allAscii, ref atLeastOneValidIdn);
3726 if (((allAscii && atLeastOneValidIdn) || !allAscii) && (!iriParsing || !hasUnicode))
3728 m_originalUnicodeString = m_String;
3729 newHost = m_originalUnicodeString.Substring(0, startInput);
3730 flags |= Flags.HasUnicode;
3732 if (atLeastOneValidIdn || !allAscii)
3735 string bidiStrippedHost =
null;
3736 m_DnsSafeHost = DomainNameHelper.IdnEquivalent(pString, startInput, end, ref allAscii, ref bidiStrippedHost);
3737 if (atLeastOneValidIdn)
3739 flags |= Flags.IdnHost;
3743 flags |= Flags.UnicodeHost;
3746 else if (iriParsing && hasUnicode)
3757 catch (ArgumentException)
3759 err = ParsingError.BadHostName;
3762 flags |= Flags.HostUnicodeNormalized;
3765 private unsafe
void FindEndOfComponent(
string input, ref ushort idx, ushort end,
char delim)
3767 fixed (
char* str = input)
3769 FindEndOfComponent(str, ref idx, end, delim);
3773 private unsafe
void FindEndOfComponent(
char* str, ref ushort idx, ushort end,
char delim)
3777 for (num = idx; num < end; num = (ushort)(num + 1))
3780 if (c == delim || (delim ==
'?' && c ==
'#' && m_Syntax !=
null && m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
3788 private unsafe Check CheckCanonical(
char* str, ref ushort idx, ushort end,
char delim)
3790 Check check = Check.None;
3795 for (num = idx; num < end; num = (ushort)(num + 1))
3798 if (c <=
'\u001f' || (c >=
'\u007f' && c <=
'\u009f'))
3802 check |= Check.ReservedFound;
3804 else if (c >
'z' && c !=
'~')
3809 check |= Check.FoundNonAscii;
3810 if (
char.IsHighSurrogate(c))
3814 bool surrogatePair =
false;
3815 flag3 = IriHelper.CheckIriUnicodeRange(c, str[num + 1], ref surrogatePair, isQuery:
true);
3820 flag3 = IriHelper.CheckIriUnicodeRange(c, isQuery:
true);
3824 check |= Check.NotIriCanonical;
3834 if (c == delim || (delim ==
'?' && c ==
'#' && m_Syntax !=
null && m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
3841 if (IsImplicitFile || (m_Syntax !=
null && !m_Syntax.InFact(UriSyntaxFlags.MayHaveQuery) && delim !=
'\ufffe'))
3843 check |= Check.ReservedFound;
3850 if (IsImplicitFile || (m_Syntax !=
null && !m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
3852 check |= Check.ReservedFound;
3858 if ((check & Check.BackslashInPath) == Check.None && c ==
'\\')
3860 check |= Check.BackslashInPath;
3862 if ((check & Check.DotSlashAttn) == Check.None && num + 1 != end && (str[num + 1] ==
'/' || str[num + 1] ==
'\\'))
3864 check |= Check.DotSlashAttn;
3868 if (((check & Check.DotSlashAttn) == Check.None && num + 1 == end) || str[num + 1] ==
'.' || str[num + 1] ==
'/' || str[num + 1] ==
'\\' || str[num + 1] ==
'?' || str[num + 1] ==
'#')
3870 check |= Check.DotSlashAttn;
3874 if (!flag && ((c <=
'"' && c !=
'!') || (c >=
'[' && c <= '^') || c == '>
' || c == '<
' || c == '`
')) 3888 if (num + 2 < end && (c = UriHelper.EscapedAscii(str[num + 1], str[num + 2])) != '\uffff
') 3890 if (c == '.
' || c == '/
' || c == '\\
') 3892 check |= Check.DotSlashEscaped; 3894 num = (ushort)(num + 2); 3909 check |= Check.EscapedCanonical; 3914 check |= Check.DisplayCanonical; 3917 check |= Check.EscapedCanonical; 3924 private unsafe char[] GetCanonicalPath(char[] dest, ref int pos, UriFormat formatAs) 3926 if (InFact(Flags.FirstSlashAbsent)) 3930 if (m_Info.Offset.Path == m_Info.Offset.Query) 3935 int securedPathIndex = SecuredPathIndex; 3936 if (formatAs == UriFormat.UriEscaped) 3938 if (InFact(Flags.ShouldBeCompressed)) 3940 m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path); 3941 end += m_Info.Offset.Query - m_Info.Offset.Path; 3942 if (m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) && !IsImplicitFile) 3944 char[] array = dest; 3945 fixed (char* pch = array) 3947 UnescapeOnly(pch, pos, ref end, '.
', '/
', m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\
' : '\uffff
'); 3951 else if (InFact(Flags.E_PathNotCanonical) && NotAny(Flags.UserEscaped)) 3953 string text = m_String; 3954 if (securedPathIndex != 0 && text[securedPathIndex + m_Info.Offset.Path - 1] == '|
') 3956 text = text.Remove(securedPathIndex + m_Info.Offset.Path - 1, 1); 3957 text = text.Insert(securedPathIndex + m_Info.Offset.Path - 1, ":"); 3959 dest = UriHelper.EscapeString(text, m_Info.Offset.Path, m_Info.Offset.Query, dest, ref end, isUriString: true, '?
', '#
', IsImplicitFile ? '\uffff
' : '%
'); 3963 m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path); 3964 end += m_Info.Offset.Query - m_Info.Offset.Path; 3969 m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path); 3970 end += m_Info.Offset.Query - m_Info.Offset.Path; 3971 if (InFact(Flags.ShouldBeCompressed) && m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) && !IsImplicitFile) 3973 char[] array = dest; 3974 fixed (char* pch2 = array) 3976 UnescapeOnly(pch2, pos, ref end, '.
', '/
', m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\
' : '\uffff
'); 3980 if (securedPathIndex != 0 && dest[securedPathIndex + pos - 1] == '|
') 3982 dest[securedPathIndex + pos - 1] = ':
'; 3984 if (InFact(Flags.ShouldBeCompressed)) 3986 dest = Compress(dest, (ushort)(pos + securedPathIndex), ref end, m_Syntax); 3987 if (dest[pos] == '\\
') 3991 if (formatAs == UriFormat.UriEscaped && NotAny(Flags.UserEscaped) && InFact(Flags.E_PathNotCanonical)) 3993 string input = new string(dest, pos, end - pos); 3994 dest = UriHelper.EscapeString(input, 0, end - pos, dest, ref pos, isUriString: true, '?
', '#
', IsImplicitFile ? '\uffff
' : '%
'); 3998 else if (m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) && InFact(Flags.BackslashInPath)) 4000 for (int i = pos; i < end; i++) 4002 if (dest[i] == '\\
') 4008 if (formatAs != UriFormat.UriEscaped && InFact(Flags.PathNotCanonical)) 4010 UnescapeMode unescapeMode; 4011 if (InFact(Flags.PathNotCanonical)) 4015 case (UriFormat)32767: 4016 unescapeMode = (UnescapeMode)((InFact(Flags.UserEscaped) ? 2 : 3) | 4); 4019 unescapeMode &= ~UnescapeMode.Unescape; 4022 case UriFormat.Unescaped: 4023 unescapeMode = ((!IsImplicitFile) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : UnescapeMode.CopyOnly); 4026 unescapeMode = (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape); 4029 unescapeMode &= ~UnescapeMode.Unescape; 4036 unescapeMode = UnescapeMode.CopyOnly; 4038 char[] array2 = new char[dest.Length]; 4039 Buffer.BlockCopy(dest, 0, array2, 0, end << 1); 4040 char[] array = array2; 4041 fixed (char* pStr = array) 4043 dest = UriHelper.UnescapeString(pStr, pos, end, dest, ref pos, '?
', '#
', '\uffff
', unescapeMode, m_Syntax, isQuery: false); 4053 private unsafe static void UnescapeOnly(char* pch, int start, ref int end, char ch1, char ch2, char ch3) 4055 if (end - start < 3) 4059 char* ptr = pch + end - 2; 4070 char* intPtr2 = pch; 4072 char digit = *intPtr2; 4073 char* intPtr3 = pch; 4075 char c = UriHelper.EscapedAscii(digit, *intPtr3); 4076 if (c != ch1 && c != ch2 && c != ch3) 4084 char* intPtr4 = ptr2; 4086 char* intPtr5 = pch; 4089 *intPtr4 = (c2 = *intPtr5); 4092 char* intPtr6 = ptr2; 4094 char* intPtr7 = pch; 4096 *intPtr6 = (c2 = *intPtr7); 4098 char* intPtr8 = ptr2; 4100 char* intPtr9 = pch; 4102 *intPtr8 = (c2 = *intPtr9); 4103 c = UriHelper.EscapedAscii(digit2, c2); 4104 if (c == ch1 || c == ch2 || c == ch3) 4120 end -= (int)(pch - ptr2); 4123 char* intPtr10 = ptr2; 4124 ptr2 = intPtr10 + 1; 4125 char* intPtr11 = pch; 4127 *intPtr10 = *intPtr11; 4130 end -= (int)(pch - ptr2); 4133 char* intPtr12 = ptr2; 4134 ptr2 = intPtr12 + 1; 4135 char* intPtr13 = pch; 4137 *intPtr12 = *intPtr13; 4138 end -= (int)(pch - ptr2); 4141 private static char[] Compress(char[] dest, ushort start, ref int destLength, UriParser syntax) 4147 ushort num5 = (ushort)((ushort)destLength - 1); 4148 for (start = (ushort)(start - 1); num5 != start; num5 = (ushort)(num5 - 1)) 4150 char c = dest[num5]; 4151 if (c == '\\
' && syntax.InFact(UriSyntaxFlags.ConvertPathSlashes)) 4153 c = (dest[num5] = '/
'); 4157 num = (ushort)(num + 1); 4163 num2 = (ushort)(num5 + 1); 4169 num3 = (ushort)(num3 + 1); 4174 bool flag = syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) && (num3 > 2 || c != '/
' || num5 == start); 4175 if (!flag && c == '/
') 4177 if ((num2 == num5 + num3 + 1 || (num2 == 0 && num5 + num3 + 1 == destLength)) && (UriParser.ShouldUseLegacyV2Quirks || num3 <= 2)) 4179 num2 = (ushort)(num5 + 1 + num3 + ((num2 != 0) ? 1 : 0)); 4180 Buffer.BlockCopy(dest, num2 << 1, dest, num5 + 1 << 1, destLength - num2 << 1); 4181 destLength -= num2 - num5 - 1; 4185 num4 = (ushort)(num4 + 1); 4191 else if (UriParser.ShouldUseLegacyV2Quirks && !flag && num4 == 0 && (num2 == num5 + num3 + 1 || (num2 == 0 && num5 + num3 + 1 == destLength))) 4193 num3 = (ushort)(num5 + 1 + num3); 4194 Buffer.BlockCopy(dest, num3 << 1, dest, num5 + 1 << 1, destLength - num3 << 1); 4195 destLength -= num3 - num5 - 1; 4206 num4 = (ushort)(num4 - 1); 4207 num2 = (ushort)(num2 + 1); 4208 Buffer.BlockCopy(dest, num2 << 1, dest, num5 + 1 << 1, destLength - num2 << 1); 4209 destLength -= num2 - num5 - 1; 4214 start = (ushort)(start + 1); 4215 if ((ushort)destLength > start && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath) && num <= 1) 4217 if (num4 != 0 && dest[start] != '/
') 4219 num2 = (ushort)(num2 + 1); 4220 Buffer.BlockCopy(dest, num2 << 1, dest, start << 1, destLength - num2 << 1); 4223 else if (num3 != 0 && (num2 == num3 + 1 || (num2 == 0 && num3 + 1 == destLength))) 4225 num3 = (ushort)(num3 + ((num2 != 0) ? 1 : 0)); 4226 Buffer.BlockCopy(dest, num3 << 1, dest, start << 1, destLength - num3 << 1); 4233 internal static int CalculateCaseInsensitiveHashCode(string text) 4235 return StringComparer.InvariantCultureIgnoreCase.GetHashCode(text); 4238 private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat) 4240 char c = relativePart[0]; 4241 if (basePart.IsDosPath && (c == '/
' || c == '\\
') && (relativePart.Length == 1 || (relativePart[1] != '/
' && relativePart[1] != '\\
'))) 4243 int num = basePart.OriginalString.IndexOf(':
'); 4244 if (basePart.IsImplicitFile) 4246 return basePart.OriginalString.Substring(0, num + 1) + relativePart; 4248 num = basePart.OriginalString.IndexOf(':
', num + 1); 4249 return basePart.OriginalString.Substring(0, num + 1) + relativePart; 4251 if (StaticIsFile(basePart.Syntax) && (c == '\\
' || c == '/
')) 4253 if (relativePart.Length >= 2 && (relativePart[1] == '\\
' || relativePart[1] == '/
')) 4255 if (!basePart.IsImplicitFile) 4257 return "file:" + relativePart; 4259 return relativePart; 4263 string text = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped); 4264 for (int i = 1; i < text.Length; i++) 4268 text = text.Substring(0, i); 4272 if (basePart.IsImplicitFile) 4274 return "\\\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped) + text + relativePart; 4276 return "file://" + basePart.GetParts(UriComponents.Host, uriFormat) + text + relativePart; 4278 return "file://" + relativePart; 4280 bool flag = basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes); 4281 string text2 = null; 4282 if (c == '/
' || (c == '\\
' && flag)) 4284 if (relativePart.Length >= 2 && relativePart[1] == '/
') 4286 return basePart.Scheme + ":" + relativePart; 4288 text2 = ((basePart.HostType != Flags.IPv6HostType) ? basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port, uriFormat) : (basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat) + "[" + basePart.DnsSafeHost + "]" + basePart.GetParts(UriComponents.Port | UriComponents.KeepDelimiter, uriFormat))); 4289 if (flag && c == '\\
') 4291 relativePart = "/" + relativePart.Substring(1); 4293 return text2 + relativePart; 4295 text2 = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat); 4296 int num2 = text2.Length; 4297 char[] array = new char[num2 + relativePart.Length]; 4300 text2.CopyTo(0, array, 0, num2); 4303 if (array[--num2] == '/
') 4310 relativePart.CopyTo(0, array, num2, relativePart.Length); 4311 c = (basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?
' : '\uffff
'); 4312 char c2 = (!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#
' : '\uffff
'; 4313 string text3 = string.Empty; 4314 if (c != '\uffff
' || c2 != '\uffff
') 4317 for (j = 0; j < relativePart.Length && array[num2 + j] != c && array[num2 + j] != c2; j++) 4322 text3 = relativePart; 4324 else if (j < relativePart.Length) 4326 text3 = relativePart.Substring(j); 4332 num2 += relativePart.Length; 4334 if (basePart.HostType == Flags.IPv6HostType) 4336 text2 = ((!basePart.IsImplicitFile) ? (basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat) + "[" + basePart.DnsSafeHost + "]" + basePart.GetParts(UriComponents.Port | UriComponents.KeepDelimiter, uriFormat)) : ("\\\\[" + basePart.DnsSafeHost + "]")); 4338 else if (basePart.IsImplicitFile) 4340 if (basePart.IsDosPath) 4342 array = Compress(array, 3, ref num2, basePart.Syntax); 4343 return new string(array, 1, num2 - 1) + text3; 4345 text2 = "\\\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped); 4349 text2 = basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port, uriFormat); 4351 array = Compress(array, basePart.SecuredPathIndex, ref num2, basePart.Syntax); 4352 return text2 + new string(array, 0, num2) + text3; 4355 private static string PathDifference(string path1, string path2, bool compareCase) 4359 for (i = 0; i < path1.Length && i < path2.Length && (path1[i] == path2[i] || (!compareCase && char.ToLower(path1[i], CultureInfo.InvariantCulture) == char.ToLower(path2[i], CultureInfo.InvariantCulture))); i++) 4361 if (path1[i] == '/
') 4370 if (i == path1.Length && i == path2.Length) 4372 return string.Empty; 4374 StringBuilder stringBuilder = new StringBuilder(); 4375 for (; i < path1.Length; i++) 4377 if (path1[i] == '/
') 4379 stringBuilder.Append("../"); 4382 if (stringBuilder.Length == 0 && path2.Length - 1 == num) 4386 return stringBuilder.ToString() + path2.Substring(num + 1); 4389 private static bool IsLWS(char ch) 4393 if (ch != ' ' && ch != '\n
' && ch != '\r
') 4402 private static bool IsAsciiLetter(char character) 4404 if (character < 'a
' || character > 'z
') 4406 if (character >= 'A') 4408 return character <= 'Z'; 4415 internal static bool IsAsciiLetterOrDigit(char character) 4417 if (!IsAsciiLetter(character)) 4419 if (character >= '0
') 4421 return character <= '9
'; 4428 internal static bool IsBidiControlCharacter(char ch) 4430 if (ch != '\u200e
' && ch != '\u200f
' && ch != '\u202a
' && ch != '\u202b
' && ch != '\u202c
' && ch != '\u202d
') 4432 return ch == '\u202e
'; 4437 internal unsafe static string StripBidiControlCharacter(char* strToClean, int start, int length) 4443 char[] array = new char[length]; 4445 for (int i = 0; i < length; i++) 4447 char c = strToClean[start + i]; 4448 if (c < '\u200e
' || c > '\u202e
' || !IsBidiControlCharacter(c)) 4453 return new string(array, 0, num); 4462 [Obsolete("The method has been deprecated. Please use MakeRelativeUri(Uri uri). http://go.microsoft.com/fwlink/?linkid=14202")] 4463 public string MakeRelative(Uri toUri) 4465 if ((object)toUri == null) 4467 throw new ArgumentNullException("toUri"); 4469 if (IsNotAbsoluteUri || toUri.IsNotAbsoluteUri) 4471 throw new InvalidOperationException(SR.GetString("net_uri_NotAbsolute")); 4473 if (Scheme == toUri.Scheme && Host == toUri.Host && Port == toUri.Port) 4475 return PathDifference(AbsolutePath, toUri.AbsolutePath, !IsUncOrDosPath); 4477 return toUri.ToString(); 4482 [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] 4483 protected virtual void Parse() 4490 [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] 4491 protected virtual void Canonicalize() 4497 [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] 4498 protected virtual void Escape() 4505 [Obsolete("The method has been deprecated. Please use GetComponents() or static UnescapeDataString() to unescape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")] 4506 protected virtual string Unescape(string path) 4508 char[] dest = new char[path.Length]; 4509 int destPosition = 0; 4510 dest = UriHelper.UnescapeString(path, 0, path.Length, dest, ref destPosition, '\uffff
', '\uffff
', '\uffff
', UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, isQuery: false); 4511 return new string(dest, 0, destPosition); 4517 [Obsolete("The method has been deprecated. Please use GetComponents() or static EscapeUriString() to escape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")] 4518 protected static string EscapeString(string str) 4522 return string.Empty; 4525 char[] array = UriHelper.EscapeString(str, 0, str.Length, null, ref destPos, isUriString: true, '?
', '#
', '%
'); 4530 return new string(array, 0, destPos); 4534 [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] 4535 protected virtual void CheckSecurity() 4537 bool flag = Scheme == "telnet"; 4543 [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] 4544 protected virtual bool IsReservedCharacter(char character) 4546 if (character != ';
' && character != '/
' && character != ':
' && character != '@
' && character != '&
' && character != '=
' && character != '+
' && character != '$
') 4548 return character == ',
'; 4556 [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] 4557 protected static bool IsExcludedCharacter(char character) 4559 if (character > ' ' && character < '\u007f
' && character != '<
' && character != '>
' && character != '#
' && character != '%
' && character != '"' && character != '{' && character != '}' && character != '|' && character != '\\' && character != '^' && character != '[' && character != ']') 4561 return character == '`'; 4569 [Obsolete("The method has been deprecated. It is not used by the system. http:
4572 if (character >=
' ' && character !=
';' && character !=
'/' && character !=
'?' && character !=
':' && character !=
'&' && character !=
'=' && character !=
',' && character !=
'*' && character !=
'<' && character !=
'>' && character !=
'"' && character !=
'|' && character !=
'\\')
4574 return character ==
'^';
4579 private void CreateThis(
string uri,
bool dontEscape,
UriKind uriKind)
4581 if (uriKind < UriKind.RelativeOrAbsolute || uriKind >
UriKind.Relative)
4585 m_String = ((uri ==
null) ?
string.Empty : uri);
4588 m_Flags |= Flags.UserEscaped;
4590 ParsingError err = ParseScheme(m_String, ref m_Flags, ref m_Syntax);
4591 InitializeUri(err, uriKind, out UriFormatException e);
4598 private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatException e)
4600 if (err == ParsingError.None)
4604 if (NotAny(Flags.DosPath) && uriKind !=
UriKind.Absolute && (uriKind ==
UriKind.Relative || (m_String.Length >= 2 && (m_String[0] !=
'\\' || m_String[1] !=
'\\'))))
4607 m_Flags &= Flags.UserEscaped;
4611 if (uriKind ==
UriKind.Relative && InFact(Flags.DosPath))
4614 m_Flags &= Flags.UserEscaped;
4620 else if (err > ParsingError.EmptyUriString)
4623 e = GetException(err);
4627 if (!s_ConfigInitialized && CheckForConfigLoad(m_String))
4629 InitializeUriConfig();
4631 m_iriParsing = (s_IriParsing && (m_Syntax ==
null || m_Syntax.InFact(UriSyntaxFlags.AllowIriParsing)));
4632 if (m_iriParsing && (CheckForUnicode(m_String) || CheckForEscapedUnreserved(m_String)))
4634 m_Flags |= Flags.HasUnicode;
4636 m_originalUnicodeString = m_String;
4638 if (m_Syntax !=
null)
4640 if (m_Syntax.IsSimple)
4642 if ((err = PrivateParseMinimal()) != 0)
4644 if (uriKind !=
UriKind.Absolute && err <= ParsingError.EmptyUriString)
4648 m_Flags &= Flags.UserEscaped;
4652 e = GetException(err);
4655 else if (uriKind ==
UriKind.Relative)
4657 e = GetException(ParsingError.CannotCreateRelative);
4663 if (m_iriParsing && flag)
4665 EnsureParseRemaining();
4669 m_Syntax = m_Syntax.InternalOnNewUri();
4670 m_Flags |= Flags.UserDrivenParsing;
4671 m_Syntax.InternalValidate(
this, out e);
4674 if (uriKind !=
UriKind.Absolute && err != 0 && err <= ParsingError.EmptyUriString)
4678 m_Flags &= Flags.UserEscaped;
4682 if (err != 0 || InFact(Flags.ErrorOrParsingRecursion))
4684 SetUserDrivenParsing();
4686 else if (uriKind ==
UriKind.Relative)
4688 e = GetException(ParsingError.CannotCreateRelative);
4690 if (m_iriParsing && flag)
4692 EnsureParseRemaining();
4695 else if (err != 0 && uriKind !=
UriKind.Absolute && err <= ParsingError.EmptyUriString)
4698 m_Flags &= (Flags.UserEscaped | Flags.HasUnicode);
4699 if (m_iriParsing && flag)
4701 m_String = EscapeUnescapeIri(m_originalUnicodeString, 0, m_originalUnicodeString.Length, (UriComponents)0);
4704 if (UriParser.ShouldUseLegacyV2Quirks)
4709 catch (ArgumentException)
4711 e = GetException(ParsingError.BadFormat);
4718 e = GetException(err);
4722 private unsafe
bool CheckForConfigLoad(
string data)
4724 bool result =
false;
4725 int length = data.Length;
4726 fixed (
char* ptr = data)
4728 for (
int i = 0; i < length; i++)
4730 if (ptr[i] >
'\u007f' || ptr[i] ==
'%' || (ptr[i] ==
'x' && i + 3 < length && ptr[i + 1] ==
'n' && ptr[i + 2] ==
'-' && ptr[i + 3] ==
'-'))
4740 private bool CheckForUnicode(
string data)
4742 bool result =
false;
4743 char[] dest =
new char[data.Length];
4744 int destPosition = 0;
4745 dest = UriHelper.UnescapeString(data, 0, data.Length, dest, ref destPosition,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.Unescape | UnescapeMode.UnescapeAll,
null, isQuery:
false);
4746 for (
int i = 0; i < destPosition; i++)
4748 if (dest[i] >
'\u007f')
4757 private unsafe
bool CheckForEscapedUnreserved(
string data)
4759 fixed (
char* ptr = data)
4761 for (
int i = 0; i < data.Length - 2; i++)
4763 if (ptr[i] ==
'%' && IsHexDigit(ptr[i + 1]) && IsHexDigit(ptr[i + 2]) && ptr[i + 1] >=
'0' && ptr[i + 1] <=
'7')
4765 char c = UriHelper.EscapedAscii(ptr[i + 1], ptr[i + 2]);
4766 if (c !=
'\uffff' && UriHelper.Is3986Unreserved(c))
4781 [global::__DynamicallyInvokable]
4784 if (uriString ==
null)
4790 result = CreateHelper(uriString, dontEscape:
false, uriKind, ref e);
4793 return result !=
null;
4803 [global::__DynamicallyInvokable]
4806 if (TryCreate(relativeUri,
UriKind.RelativeOrAbsolute, out
Uri result2))
4808 if (!result2.IsAbsoluteUri)
4810 return TryCreate(baseUri, result2, out result);
4826 [global::__DynamicallyInvokable]
4830 if ((
object)baseUri ==
null || (
object)relativeUri ==
null)
4834 if (baseUri.IsNotAbsoluteUri)
4838 string newUriString =
null;
4841 if (baseUri.Syntax.IsSimple)
4844 result = ResolveHelper(baseUri, relativeUri, ref newUriString, ref userEscaped, out e);
4848 userEscaped =
false;
4849 newUriString = baseUri.Syntax.InternalResolve(baseUri, relativeUri, out e);
4855 if ((
object)result ==
null)
4857 result = CreateHelper(newUriString, userEscaped,
UriKind.Absolute, ref e);
4859 if (e ==
null && result !=
null)
4861 return result.IsAbsoluteUri;
4873 [global::__DynamicallyInvokable]
4884 if (IsNotAbsoluteUri)
4888 return GetRelativeSerializationString(format);
4892 if (Syntax.IsSimple)
4894 return GetComponentsHelper(components, format);
4896 return Syntax.InternalGetComponents(
this, components, format);
4911 [global::__DynamicallyInvokable]
4914 if ((
object)uri1 ==
null)
4922 if ((
object)uri2 ==
null)
4938 return string.Compare(uri1.GetParts(partsToCompare, compareFormat), uri2.GetParts(partsToCompare, compareFormat), comparisonType);
4943 [global::__DynamicallyInvokable]
4946 if (IsNotAbsoluteUri || Syntax.IsSimple)
4948 return InternalIsWellFormedOriginalString();
4950 return Syntax.InternalIsWellFormedOriginalString(
this);
4957 [global::__DynamicallyInvokable]
4960 if (!TryCreate(uriString, uriKind, out
Uri result))
4964 return result.IsWellFormedOriginalString();
4967 internal unsafe
bool InternalIsWellFormedOriginalString()
4969 if (UserDrivenParsing)
4973 fixed (
char* ptr = m_String)
4978 if (!UriParser.ShouldUseLegacyV2Quirks && CheckForColonInFirstPathSegment(m_String))
4982 return (CheckCanonical(ptr, ref idx, (ushort)m_String.Length,
'\ufffe') & (Check.EscapedCanonical | Check.BackslashInPath)) == Check.EscapedCanonical;
4988 EnsureParseRemaining();
4989 Flags flags = m_Flags & (Flags.E_UserNotCanonical | Flags.E_HostNotCanonical | Flags.E_PortNotCanonical | Flags.E_PathNotCanonical | Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical | Flags.UserIriCanonical | Flags.PathIriCanonical | Flags.QueryIriCanonical | Flags.FragmentIriCanonical);
4990 if ((flags & Flags.E_CannotDisplayCanonical & (Flags.E_UserNotCanonical | Flags.E_PathNotCanonical | Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical)) != Flags.Zero && (!m_iriParsing || (m_iriParsing && ((flags & Flags.E_UserNotCanonical) == Flags.Zero || (flags & Flags.UserIriCanonical) == Flags.Zero) && ((flags & Flags.E_PathNotCanonical) == Flags.Zero || (flags & Flags.PathIriCanonical) == Flags.Zero) && ((flags & Flags.E_QueryNotCanonical) == Flags.Zero || (flags & Flags.QueryIriCanonical) == Flags.Zero) && ((flags & Flags.E_FragmentNotCanonical) == Flags.Zero || (flags & Flags.FragmentIriCanonical) == Flags.Zero))))
4994 if (InFact(Flags.AuthorityFound))
4996 idx = (ushort)(m_Info.Offset.Scheme + m_Syntax.SchemeName.Length + 2);
4997 if (idx >= m_Info.Offset.User || m_String[idx - 1] ==
'\\' || m_String[idx] ==
'\\')
5001 if (InFact(Flags.DosPath | Flags.UncPath) && (idx = (ushort)(idx + 1)) < m_Info.Offset.User && (m_String[idx] ==
'/' || m_String[idx] ==
'\\'))
5006 if (InFact(Flags.FirstSlashAbsent) && m_Info.Offset.Query > m_Info.Offset.Path)
5010 if (InFact(Flags.BackslashInPath))
5014 if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] ==
'|')
5018 if ((m_Flags & Flags.CanonicalDnsHost) == Flags.Zero && HostType != Flags.IPv6HostType)
5020 idx = m_Info.Offset.User;
5021 Check check = CheckCanonical(ptr, ref idx, m_Info.Offset.Path,
'/');
5022 if ((check & (Check.EscapedCanonical | Check.BackslashInPath | Check.ReservedFound)) != Check.EscapedCanonical && (!m_iriParsing || (m_iriParsing && (check & (Check.DisplayCanonical | Check.NotIriCanonical | Check.FoundNonAscii)) != (Check.DisplayCanonical | Check.FoundNonAscii))))
5027 if ((m_Flags & (Flags.SchemeNotCanonical | Flags.AuthorityFound)) == (Flags.SchemeNotCanonical | Flags.AuthorityFound))
5029 idx = (ushort)m_Syntax.SchemeName.Length;
5036 idx = (ushort)(num + 1);
5038 while (intPtr[(
int)num] !=
':');
5039 if (idx + 1 >= m_String.Length || ptr[(
int)idx] !=
'/' || ptr[idx + 1] !=
'/')
5053 [global::__DynamicallyInvokable]
5056 if (stringToUnescape ==
null)
5060 if (stringToUnescape.Length == 0)
5062 return string.Empty;
5064 fixed (
char* ptr = stringToUnescape)
5067 for (i = 0; i < stringToUnescape.Length && ptr[i] !=
'%'; i++)
5070 if (i == stringToUnescape.Length)
5072 return stringToUnescape;
5074 UnescapeMode unescapeMode = UnescapeMode.Unescape | UnescapeMode.UnescapeAll;
5076 char[] dest =
new char[stringToUnescape.Length];
5077 dest = UriHelper.UnescapeString(stringToUnescape, 0, stringToUnescape.Length, dest, ref i,
'\uffff',
'\uffff',
'\uffff', unescapeMode,
null, isQuery:
false);
5078 return new string(dest, 0, i);
5089 [global::__DynamicallyInvokable]
5092 if (stringToEscape ==
null)
5096 if (stringToEscape.Length == 0)
5098 return string.Empty;
5101 char[] array = UriHelper.EscapeString(stringToEscape, 0, stringToEscape.Length,
null, ref destPos, isUriString:
true,
'\uffff',
'\uffff',
'\uffff');
5104 return stringToEscape;
5106 return new string(array, 0, destPos);
5116 [global::__DynamicallyInvokable]
5119 if (stringToEscape ==
null)
5123 if (stringToEscape.Length == 0)
5125 return string.Empty;
5128 char[] array = UriHelper.EscapeString(stringToEscape, 0, stringToEscape.Length,
null, ref destPos, isUriString:
false,
'\uffff',
'\uffff',
'\uffff');
5131 return stringToEscape;
5133 return new string(array, 0, destPos);
5136 internal unsafe
string EscapeUnescapeIri(
string input,
int start,
int end,
UriComponents component)
5138 fixed (
char* pInput = input)
5140 return IriHelper.EscapeUnescapeIri(pInput, start, end, component);
5144 private Uri(Flags flags, UriParser uriParser,
string uri)
5147 m_Syntax = uriParser;
5151 internal static Uri CreateHelper(
string uriString,
bool dontEscape, UriKind uriKind, ref UriFormatException e)
5153 if (uriKind < UriKind.RelativeOrAbsolute || uriKind >
UriKind.Relative)
5155 throw new ArgumentException(SR.GetString(
"net_uri_InvalidUriKind", uriKind));
5157 UriParser syntax =
null;
5158 Flags flags = Flags.Zero;
5159 ParsingError parsingError = ParseScheme(uriString, ref flags, ref syntax);
5162 flags |= Flags.UserEscaped;
5164 if (parsingError != 0)
5166 if (uriKind !=
UriKind.Absolute && parsingError <= ParsingError.EmptyUriString)
5168 return new Uri(flags & Flags.UserEscaped,
null, uriString);
5172 Uri uri =
new Uri(flags, syntax, uriString);
5175 uri.InitializeUri(parsingError, uriKind, out e);
5182 catch (UriFormatException ex)
5184 UriFormatException ex2 = e = ex;
5189 internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref
string newUriString, ref
bool userEscaped, out UriFormatException e)
5192 string empty =
string.Empty;
5193 if ((
object)relativeUri !=
null)
5195 if (relativeUri.IsAbsoluteUri)
5199 empty = relativeUri.OriginalString;
5200 userEscaped = relativeUri.UserEscaped;
5204 empty =
string.Empty;
5206 if (empty.Length > 0 && (IsLWS(empty[0]) || IsLWS(empty[empty.Length - 1])))
5208 empty = empty.Trim(_WSchars);
5210 if (empty.Length == 0)
5215 if (empty[0] ==
'#' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
5220 if (empty[0] ==
'?' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
5225 if (empty.Length >= 3 && (empty[1] ==
':' || empty[1] ==
'|') && IsAsciiLetter(empty[0]) && (empty[2] ==
'\\' || empty[2] ==
'/'))
5227 if (baseUri.IsImplicitFile)
5229 newUriString = empty;
5232 if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
5234 newUriString =
string.Concat(str1: (!baseUri.InFact(Flags.AuthorityFound)) ? (baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ?
":/" :
":") : (baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ?
":///" :
"://"), str0: baseUri.Scheme, str2: empty);
5238 ParsingError combinedString = GetCombinedString(baseUri, empty, userEscaped, ref newUriString);
5239 if (combinedString != 0)
5241 e = GetException(combinedString);
5244 if ((
object)newUriString == baseUri.m_String)
5251 private string GetRelativeSerializationString(UriFormat format)
5257 if (m_String.Length == 0)
5259 return string.Empty;
5262 char[] array = UriHelper.EscapeString(m_String, 0, m_String.Length,
null, ref destPos, isUriString:
true,
'\uffff',
'\uffff',
'%');
5267 return new string(array, 0, destPos);
5270 return UnescapeDataString(m_String);
5273 if (m_String.Length == 0)
5275 return string.Empty;
5277 char[] dest =
new char[m_String.Length];
5278 int destPosition = 0;
5279 dest = UriHelper.UnescapeString(m_String, 0, m_String.Length, dest, ref destPosition,
'\uffff',
'\uffff',
'\uffff', UnescapeMode.EscapeUnescape,
null, isQuery:
false);
5280 return new string(dest, 0, destPosition);
5283 throw new ArgumentOutOfRangeException(
"format");
5287 internal string GetComponentsHelper(UriComponents uriComponents, UriFormat uriFormat)
5291 return m_Syntax.SchemeName;
5293 if ((uriComponents &
UriComponents.SerializationInfoString) != 0)
5297 EnsureParseRemaining();
5304 EnsureHostString(allowDnsOptimization:
true);
5308 if ((m_Flags & Flags.NotDefaultPort) != Flags.Zero || (uriComponents ==
UriComponents.StrongPort && m_Syntax.DefaultPort != -1))
5312 return string.Empty;
5318 if (uriComponents ==
UriComponents.Host && (uriFormat ==
UriFormat.UriEscaped || (m_Flags & (Flags.HostNotCanonical | Flags.E_HostNotCanonical)) == Flags.Zero))
5320 EnsureHostString(allowDnsOptimization:
false);
5326 return GetEscapedParts(uriComponents);
5329 case (UriFormat)32767:
5330 return GetUnescapedParts(uriComponents, uriFormat);
5332 throw new ArgumentOutOfRangeException(
"uriFormat");
5342 [global::__DynamicallyInvokable]
5345 if ((
object)uri ==
null)
5353 if (Syntax.IsSimple)
5355 return IsBaseOfHelper(uri);
5357 return Syntax.InternalIsBaseOf(
this, uri);
5360 internal unsafe
bool IsBaseOfHelper(
Uri uriLink)
5362 if (!IsAbsoluteUri || UserDrivenParsing)
5368 string newUriString =
null;
5369 bool userEscaped =
false;
5370 uriLink = ResolveHelper(
this, uriLink, ref newUriString, ref userEscaped, out UriFormatException e);
5375 if ((
object)uriLink ==
null)
5377 uriLink = CreateHelper(newUriString, userEscaped,
UriKind.Absolute, ref e);
5384 if (Syntax.SchemeName != uriLink.Syntax.SchemeName)
5390 fixed (
char* pMe = parts)
5392 fixed (
char* pShe = parts2)
5394 return UriHelper.TestForSubPath(pMe, (ushort)parts.Length, pShe, (ushort)parts2.Length, IsUncOrDosPath || uriLink.IsUncOrDosPath);
5399 private void CreateThisFromUri(Uri otherUri)
5402 m_Flags = otherUri.m_Flags;
5403 if (InFact(Flags.MinimalUriInfoSet))
5405 m_Flags &= ~(Flags.SchemeNotCanonical | Flags.UserNotCanonical | Flags.HostNotCanonical | Flags.PortNotCanonical | Flags.PathNotCanonical | Flags.QueryNotCanonical | Flags.FragmentNotCanonical | Flags.E_UserNotCanonical | Flags.E_HostNotCanonical | Flags.E_PortNotCanonical | Flags.E_PathNotCanonical | Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical | Flags.ShouldBeCompressed | Flags.FirstSlashAbsent | Flags.BackslashInPath | Flags.MinimalUriInfoSet | Flags.AllUriInfoSet);
5406 int num = otherUri.m_Info.Offset.Path;
5407 if (InFact(Flags.NotDefaultPort))
5409 while (otherUri.m_String[num] !=
':' && num > otherUri.m_Info.Offset.Host)
5413 if (otherUri.m_String[num] !=
':')
5415 num = otherUri.m_Info.Offset.Path;
5418 m_Flags |= (Flags)num;
5420 m_Syntax = otherUri.m_Syntax;
5421 m_String = otherUri.m_String;
5422 m_iriParsing = otherUri.m_iriParsing;
5423 if (otherUri.OriginalStringSwitched)
5425 m_originalUnicodeString = otherUri.m_originalUnicodeString;
5427 if (otherUri.AllowIdn && (otherUri.InFact(Flags.IdnHost) || otherUri.InFact(Flags.UnicodeHost)))
5429 m_DnsSafeHost = otherUri.m_DnsSafeHost;
UriKind
Defines the kinds of T:System.Uris for the M:System.Uri.IsWellFormedUriString(System....
static CultureInfo InvariantCulture
Gets the T:System.Globalization.CultureInfo object that is culture-independent (invariant).
static unsafe string UnescapeDataString(string stringToUnescape)
Converts a string to its unescaped representation.
static readonly string UriSchemeGopher
Specifies that the URI is accessed through the Gopher protocol. This field is read-only.
int Port
Gets the port number of this URI.
The P:System.Uri.LocalPath and P:System.Uri.Query data. Also see P:System.Uri.PathAndQuery.
bool UserEscaped
Indicates that the URI string was completely escaped before the T:System.Uri instance was created.
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
static bool IsHexEncoding(string pattern, int index)
Determines whether a character in a string is hexadecimal encoded.
Describes a set of security permissions applied to code. This class cannot be inherited.
static bool operator !=(Uri uri1, Uri uri2)
Determines whether two T:System.Uri instances do not have the same value.
UriHostNameType
Defines host name types for the M:System.Uri.CheckHostName(System.String) method.
Represents text as a sequence of UTF-16 code units.To browse the .NET Framework source code for this ...
static readonly string UriSchemeHttp
Specifies that the URI is accessed through the Hypertext Transfer Protocol (HTTP)....
Uri MakeRelativeUri(Uri uri)
Determines the difference between two T:System.Uri instances.
Uri(string uriString)
Initializes a new instance of the T:System.Uri class with the specified URI.
StringComparison
Specifies the culture, case, and sort rules to be used by certain overloads of the M:System....
static readonly string UriSchemeNetTcp
Specifies that the URI is accessed through the NetTcp scheme used by Windows Communication Foundation...
The P:System.Uri.Fragment data.
static string EscapeUriString(string stringToEscape)
Converts a URI string to its escaped representation.
No initialization action.
static char HexUnescape(string pattern, ref int index)
Converts a specified hexadecimal representation of a character to the character.
void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
Returns the data needed to serialize the current instance.
string AbsoluteUri
Gets the absolute URI.
LayoutKind
Controls the layout of an object when exported to unmanaged code.
The scheme and authority segments of the URI.
bool IsWellFormedOriginalString()
Indicates whether the string used to construct this T:System.Uri was well-formed and is not required ...
string Scheme
Gets the scheme name for this URI.
The exception that is thrown when the value of an argument is outside the allowable range of values a...
static readonly string UriSchemeFtp
Specifies that the URI is accessed through the File Transfer Protocol (FTP). This field is read-only.
static bool IsWellFormedUriString(string uriString, UriKind uriKind)
Indicates whether the string is well-formed by attempting to construct a URI with the string and ensu...
static readonly string UriSchemeNews
Specifies that the URI is an Internet news group and is accessed through the Network News Transport P...
The exception that is thrown when an unrecognized HRESULT is returned from a COM method call.
Uri(string uriString, UriKind uriKind)
Initializes a new instance of the T:System.Uri class with the specified URI. This constructor allows ...
Describes the source and destination of a given serialized stream, and provides an additional caller-...
override int GetHashCode()
Gets the hash code for the URI.
static readonly string UriSchemeMailto
Specifies that the URI is an e-mail address and is accessed through the Simple Mail Transport Protoco...
static bool TryCreate(string uriString, UriKind uriKind, out Uri result)
Creates a new T:System.Uri using the specified T:System.String instance and a T:System....
string DnsSafeHost
Gets an unescaped host name that is safe to use for DNS resolution.
UriComponents
Specifies the parts of a T:System.Uri.
The P:System.Uri.UserInfo data.
The environment variable is stored or retrieved from the HKEY_CURRENT_USER\Environment key in the Win...
The P:System.Uri.Host data.
The exception thrown when an invalid COM object is used.
Uri(Uri baseUri, Uri relativeUri)
Initializes a new instance of the T:System.Uri class based on the combination of a specified base T:S...
Uri(Uri baseUri, string relativeUri, bool dontEscape)
Initializes a new instance of the T:System.Uri class based on the specified base and relative URIs,...
bool IsAbsoluteUri
Gets whether the T:System.Uri instance is absolute.
SecurityAction
Specifies the security actions that can be performed using declarative security.
string AbsolutePath
Gets the absolute path of the URI.
void AddValue(string name, object value, Type type)
Adds a value into the T:System.Runtime.Serialization.SerializationInfo store, where value is associa...
bool IsBaseOf(Uri uri)
Determines whether the current T:System.Uri instance is a base of the specified T:System....
Uri(SerializationInfo serializationInfo, StreamingContext streamingContext)
Initializes a new instance of the T:System.Uri class from the specified instances of the T:System....
virtual bool IsBadFileSystemCharacter(char character)
Gets whether a character is invalid in a file system name.
static unsafe UriHostNameType CheckHostName(string name)
Determines whether the specified host name is a valid DNS name.
NormalizationForm
Defines the type of normalization to perform.
static readonly string UriSchemeNntp
Specifies that the URI is an Internet news group and is accessed through the Network News Transport P...
UriPartial
Defines the parts of a URI for the M:System.Uri.GetLeftPart(System.UriPartial) method.
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
static bool TryCreate(Uri baseUri, Uri relativeUri, out Uri result)
Creates a new T:System.Uri using the specified base and relative T:System.Uri instances.
string Query
Gets any query information included in the specified URI.
unsafe override bool Equals(object comparand)
Compares two T:System.Uri instances for equality.
static string EscapeDataString(string stringToEscape)
Converts a string to its escaped representation.
string GetLeftPart(UriPartial part)
Gets the specified portion of a T:System.Uri instance.
The P:System.Uri.Scheme data.
string OriginalString
Gets the original URI string that was passed to the T:System.Uri constructor.
GenericUriParserOptions
Specifies options for a T:System.UriParser.
string GetComponents(UriComponents components, UriFormat format)
Gets the specified components of the current instance using the specified escaping for special charac...
Stores all the data needed to serialize or deserialize an object. This class cannot be inherited.
static readonly string UriSchemeFile
Specifies that the URI is a pointer to a file. This field is read-only.
virtual int Add(object value)
Adds an object to the end of the T:System.Collections.ArrayList.
static int Compare(Uri uri1, Uri uri2, UriComponents partsToCompare, UriFormat compareFormat, StringComparison comparisonType)
Compares the specified parts of two URIs using the specified comparison rules.
The exception that is thrown when one of the arguments provided to a method is not valid.
UriFormat
Controls how URI information is escaped.
Allows an object to control its own serialization and deserialization.
static readonly string UriSchemeNetPipe
Specifies that the URI is accessed through the NetPipe scheme used by Windows Communication Foundatio...
static string HexEscape(char character)
Converts a specified character into its hexadecimal equivalent.
The P:System.Uri.Port data.
string GetString(string name)
Retrieves a T:System.String value from the T:System.Runtime.Serialization.SerializationInfo store.
string Fragment
Gets the escaped URI fragment.
Uri(Uri baseUri, string relativeUri)
Initializes a new instance of the T:System.Uri class based on the specified base URI and relative URI...
Specifies that the class can be serialized.
static bool IsHexDigit(char character)
Determines whether a specified character is a valid hexadecimal digit.
virtual int ErrorCode
Gets the HRESULT of the error.
The exception that is thrown when a method call is invalid for the object's current state.
static readonly string SchemeDelimiter
Specifies the characters that separate the communication protocol scheme from the address portion of ...
string IdnHost
The RFC 3490 compliant International Domain Name of the host, using Punycode as appropriate.
static bool CheckSchemeName(string schemeName)
Determines whether the specified scheme name is valid.
Uri(string uriString, bool dontEscape)
Initializes a new instance of the T:System.Uri class with the specified URI, with explicit control of...
Provides information about a specific culture (called a locale for unmanaged code development)....
static bool TryCreate(Uri baseUri, string relativeUri, out Uri result)
Creates a new T:System.Uri using the specified base and relative T:System.String instances.
SecurityPermissionFlag
Specifies access flags for the security permission object.
Provides an object representation of a uniform resource identifier (URI) and easy access to the parts...
The P:System.Uri.Query data.
static readonly string UriSchemeHttps
Specifies that the URI is accessed through the Secure Hypertext Transfer Protocol (HTTPS)....
Compresses the underlying stream.
static int FromHex(char digit)
Gets the decimal value of a hexadecimal digit.
UriIdnScope
Provides the possible values for the configuration setting of the T:System.Configuration....
Parses a new URI scheme. This is an abstract class.
void GetObjectData(SerializationInfo info, StreamingContext context)
Populates a T:System.Runtime.Serialization.SerializationInfo with the data needed to serialize the ta...
string Host
Gets the host component of this instance.
Provides atomic operations for variables that are shared by multiple threads.
The P:System.Uri.LocalPath data.
override string ToString()
Gets a canonical string representation for the specified T:System.Uri instance.
Provides a unified way of converting types of values to other types, as well as for accessing standar...
The P:System.Uri.Scheme, P:System.Uri.UserInfo, P:System.Uri.Host, P:System.Uri.Port,...
virtual object [] ToArray()
Copies the elements of the T:System.Collections.ArrayList to a new T:System.Object array.
Implements the T:System.Collections.IList interface using an array whose size is dynamically increase...