mscorlib(4.0.0.0) API with additions
UriParser.cs
3 using System.Net;
5 
6 namespace System
7 {
9  public abstract class UriParser
10  {
11  private enum UriQuirksVersion
12  {
13  V2 = 2,
14  V3
15  }
16 
17  private class BuiltInUriParser : UriParser
18  {
19  internal BuiltInUriParser(string lwrCaseScheme, int defaultPort, UriSyntaxFlags syntaxFlags)
20  : base(syntaxFlags | UriSyntaxFlags.SimpleUserSyntax | UriSyntaxFlags.BuiltInSyntax)
21  {
22  m_Scheme = lwrCaseScheme;
23  m_Port = defaultPort;
24  }
25  }
26 
27  private const UriSyntaxFlags SchemeOnlyFlags = UriSyntaxFlags.MayHavePath;
28 
29  private static readonly Dictionary<string, UriParser> m_Table;
30 
31  private static Dictionary<string, UriParser> m_TempTable;
32 
33  private UriSyntaxFlags m_Flags;
34 
35  private volatile UriSyntaxFlags m_UpdatableFlags;
36 
37  private volatile bool m_UpdatableFlagsUsed;
38 
39  private const UriSyntaxFlags c_UpdatableFlags = UriSyntaxFlags.UnEscapeDotsAndSlashes;
40 
41  private int m_Port;
42 
43  private string m_Scheme;
44 
45  internal const int NoDefaultPort = -1;
46 
47  private const int c_InitialTableSize = 25;
48 
49  internal static UriParser HttpUri;
50 
51  internal static UriParser HttpsUri;
52 
53  internal static UriParser WsUri;
54 
55  internal static UriParser WssUri;
56 
57  internal static UriParser FtpUri;
58 
59  internal static UriParser FileUri;
60 
61  internal static UriParser GopherUri;
62 
63  internal static UriParser NntpUri;
64 
65  internal static UriParser NewsUri;
66 
67  internal static UriParser MailToUri;
68 
69  internal static UriParser UuidUri;
70 
71  internal static UriParser TelnetUri;
72 
73  internal static UriParser LdapUri;
74 
75  internal static UriParser NetTcpUri;
76 
77  internal static UriParser NetPipeUri;
78 
79  internal static UriParser VsMacrosUri;
80 
81  private static readonly UriQuirksVersion s_QuirksVersion;
82 
83  private const int c_MaxCapacity = 512;
84 
85  private const UriSyntaxFlags UnknownV1SyntaxFlags = UriSyntaxFlags.OptionalAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.V1_UnknownUri | UriSyntaxFlags.AllowDOSPath | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
86 
87  private static readonly UriSyntaxFlags HttpSyntaxFlags;
88 
89  private const UriSyntaxFlags FtpSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
90 
91  private static readonly UriSyntaxFlags FileSyntaxFlags;
92 
93  private const UriSyntaxFlags VsmacrosSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.FileLikeUri | UriSyntaxFlags.AllowDOSPath | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.UnEscapeDotsAndSlashes | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
94 
95  private const UriSyntaxFlags GopherSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
96 
97  private const UriSyntaxFlags NewsSyntaxFlags = UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowIriParsing;
98 
99  private const UriSyntaxFlags NntpSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
100 
101  private const UriSyntaxFlags TelnetSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
102 
103  private const UriSyntaxFlags LdapSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
104 
105  private const UriSyntaxFlags MailtoSyntaxFlags = UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.MailToLikeUri | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
106 
107  private const UriSyntaxFlags NetPipeSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.UnEscapeDotsAndSlashes | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
108 
109  private const UriSyntaxFlags NetTcpSyntaxFlags = UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.UnEscapeDotsAndSlashes | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing;
110 
111  internal string SchemeName => m_Scheme;
112 
113  internal int DefaultPort => m_Port;
114 
115  internal static bool ShouldUseLegacyV2Quirks => s_QuirksVersion <= UriQuirksVersion.V2;
116 
117  internal UriSyntaxFlags Flags => m_Flags;
118 
119  internal bool IsSimple => InFact(UriSyntaxFlags.SimpleUserSyntax);
120 
122  protected UriParser()
123  : this(UriSyntaxFlags.MayHavePath)
124  {
125  }
126 
129  protected virtual UriParser OnNewUri()
130  {
131  return this;
132  }
133 
137  protected virtual void OnRegister(string schemeName, int defaultPort)
138  {
139  }
140 
144  protected virtual void InitializeAndValidate(Uri uri, out UriFormatException parsingError)
145  {
146  parsingError = uri.ParseMinimal();
147  }
148 
157  protected virtual string Resolve(Uri baseUri, Uri relativeUri, out UriFormatException parsingError)
158  {
159  if (baseUri.UserDrivenParsing)
160  {
161  throw new InvalidOperationException(SR.GetString("net_uri_UserDrivenParsing", GetType().FullName));
162  }
163  if (!baseUri.IsAbsoluteUri)
164  {
165  throw new InvalidOperationException(SR.GetString("net_uri_NotAbsolute"));
166  }
167  string newUriString = null;
168  bool userEscaped = false;
169  Uri uri = Uri.ResolveHelper(baseUri, relativeUri, ref newUriString, ref userEscaped, out parsingError);
170  if (parsingError != null)
171  {
172  return null;
173  }
174  if (uri != null)
175  {
176  return uri.OriginalString;
177  }
178  return newUriString;
179  }
180 
186  protected virtual bool IsBaseOf(Uri baseUri, Uri relativeUri)
187  {
188  return baseUri.IsBaseOfHelper(relativeUri);
189  }
190 
202  protected virtual string GetComponents(Uri uri, UriComponents components, UriFormat format)
203  {
204  if ((components & UriComponents.SerializationInfoString) != 0 && components != UriComponents.SerializationInfoString)
205  {
206  throw new ArgumentOutOfRangeException("components", components, SR.GetString("net_uri_NotJustSerialization"));
207  }
208  if ((format & (UriFormat)(-4)) != 0)
209  {
210  throw new ArgumentOutOfRangeException("format");
211  }
212  if (uri.UserDrivenParsing)
213  {
214  throw new InvalidOperationException(SR.GetString("net_uri_UserDrivenParsing", GetType().FullName));
215  }
216  if (!uri.IsAbsoluteUri)
217  {
218  throw new InvalidOperationException(SR.GetString("net_uri_NotAbsolute"));
219  }
220  return uri.GetComponentsHelper(components, format);
221  }
222 
227  protected virtual bool IsWellFormedOriginalString(Uri uri)
228  {
229  return uri.InternalIsWellFormedOriginalString();
230  }
231 
242  public static void Register(UriParser uriParser, string schemeName, int defaultPort)
243  {
244  ExceptionHelper.InfrastructurePermission.Demand();
245  if (uriParser == null)
246  {
247  throw new ArgumentNullException("uriParser");
248  }
249  if (schemeName == null)
250  {
251  throw new ArgumentNullException("schemeName");
252  }
253  if (schemeName.Length == 1)
254  {
255  throw new ArgumentOutOfRangeException("schemeName");
256  }
257  if (!Uri.CheckSchemeName(schemeName))
258  {
259  throw new ArgumentOutOfRangeException("schemeName");
260  }
261  if ((defaultPort >= 65535 || defaultPort < 0) && defaultPort != -1)
262  {
263  throw new ArgumentOutOfRangeException("defaultPort");
264  }
265  schemeName = schemeName.ToLower(CultureInfo.InvariantCulture);
266  FetchSyntax(uriParser, schemeName, defaultPort);
267  }
268 
275  public static bool IsKnownScheme(string schemeName)
276  {
277  if (schemeName == null)
278  {
279  throw new ArgumentNullException("schemeName");
280  }
281  if (!Uri.CheckSchemeName(schemeName))
282  {
283  throw new ArgumentOutOfRangeException("schemeName");
284  }
285  return GetSyntax(schemeName.ToLower(CultureInfo.InvariantCulture))?.NotAny(UriSyntaxFlags.V1_UnknownUri) ?? false;
286  }
287 
288  static UriParser()
289  {
290  s_QuirksVersion = (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5 ? UriQuirksVersion.V3 : UriQuirksVersion.V2);
291  HttpSyntaxFlags = (UriSyntaxFlags)(0x1E00F7D | (ShouldUseLegacyV2Quirks ? 33554432 : 0) | 0x4000000 | 0x10000000);
292  FileSyntaxFlags = (UriSyntaxFlags)(0xFD1 | ((!ShouldUseLegacyV2Quirks) ? 32 : 0) | 0x2000 | 0x200000 | 0x100000 | 0x400000 | 0x800000 | 0x1000000 | 0x2000000 | 0x4000000 | 0x10000000);
293  m_Table = new Dictionary<string, UriParser>(25);
294  m_TempTable = new Dictionary<string, UriParser>(25);
295  HttpUri = new BuiltInUriParser("http", 80, HttpSyntaxFlags);
296  m_Table[HttpUri.SchemeName] = HttpUri;
297  HttpsUri = new BuiltInUriParser("https", 443, HttpUri.m_Flags);
298  m_Table[HttpsUri.SchemeName] = HttpsUri;
299  WsUri = new BuiltInUriParser("ws", 80, HttpSyntaxFlags);
300  m_Table[WsUri.SchemeName] = WsUri;
301  WssUri = new BuiltInUriParser("wss", 443, HttpSyntaxFlags);
302  m_Table[WssUri.SchemeName] = WssUri;
303  FtpUri = new BuiltInUriParser("ftp", 21, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
304  m_Table[FtpUri.SchemeName] = FtpUri;
305  FileUri = new BuiltInUriParser("file", -1, FileSyntaxFlags);
306  m_Table[FileUri.SchemeName] = FileUri;
307  GopherUri = new BuiltInUriParser("gopher", 70, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
308  m_Table[GopherUri.SchemeName] = GopherUri;
309  NntpUri = new BuiltInUriParser("nntp", 119, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
310  m_Table[NntpUri.SchemeName] = NntpUri;
311  NewsUri = new BuiltInUriParser("news", -1, UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowIriParsing);
312  m_Table[NewsUri.SchemeName] = NewsUri;
313  MailToUri = new BuiltInUriParser("mailto", 25, UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.MailToLikeUri | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
314  m_Table[MailToUri.SchemeName] = MailToUri;
315  UuidUri = new BuiltInUriParser("uuid", -1, NewsUri.m_Flags);
316  m_Table[UuidUri.SchemeName] = UuidUri;
317  TelnetUri = new BuiltInUriParser("telnet", 23, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
318  m_Table[TelnetUri.SchemeName] = TelnetUri;
319  LdapUri = new BuiltInUriParser("ldap", 389, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
320  m_Table[LdapUri.SchemeName] = LdapUri;
321  NetTcpUri = new BuiltInUriParser("net.tcp", 808, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.UnEscapeDotsAndSlashes | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
322  m_Table[NetTcpUri.SchemeName] = NetTcpUri;
323  NetPipeUri = new BuiltInUriParser("net.pipe", -1, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.UnEscapeDotsAndSlashes | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
324  m_Table[NetPipeUri.SchemeName] = NetPipeUri;
325  VsMacrosUri = new BuiltInUriParser("vsmacros", -1, UriSyntaxFlags.MustHaveAuthority | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.FileLikeUri | UriSyntaxFlags.AllowDOSPath | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.CanonicalizeAsFilePath | UriSyntaxFlags.UnEscapeDotsAndSlashes | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
326  m_Table[VsMacrosUri.SchemeName] = VsMacrosUri;
327  }
328 
329  internal bool NotAny(UriSyntaxFlags flags)
330  {
331  return IsFullMatch(flags, UriSyntaxFlags.None);
332  }
333 
334  internal bool InFact(UriSyntaxFlags flags)
335  {
336  return !IsFullMatch(flags, UriSyntaxFlags.None);
337  }
338 
339  internal bool IsAllSet(UriSyntaxFlags flags)
340  {
341  return IsFullMatch(flags, flags);
342  }
343 
344  private bool IsFullMatch(UriSyntaxFlags flags, UriSyntaxFlags expected)
345  {
346  UriSyntaxFlags uriSyntaxFlags = ((flags & UriSyntaxFlags.UnEscapeDotsAndSlashes) != 0 && m_UpdatableFlagsUsed) ? ((m_Flags & ~UriSyntaxFlags.UnEscapeDotsAndSlashes) | m_UpdatableFlags) : m_Flags;
347  return (uriSyntaxFlags & flags) == expected;
348  }
349 
350  internal UriParser(UriSyntaxFlags flags)
351  {
352  m_Flags = flags;
353  m_Scheme = string.Empty;
354  }
355 
356  private static void FetchSyntax(UriParser syntax, string lwrCaseSchemeName, int defaultPort)
357  {
358  if (syntax.SchemeName.Length != 0)
359  {
360  throw new InvalidOperationException(SR.GetString("net_uri_NeedFreshParser", syntax.SchemeName));
361  }
362  lock (m_Table)
363  {
364  syntax.m_Flags &= ~UriSyntaxFlags.V1_UnknownUri;
365  UriParser value = null;
366  m_Table.TryGetValue(lwrCaseSchemeName, out value);
367  if (value != null)
368  {
369  throw new InvalidOperationException(SR.GetString("net_uri_AlreadyRegistered", value.SchemeName));
370  }
371  m_TempTable.TryGetValue(syntax.SchemeName, out value);
372  if (value != null)
373  {
374  lwrCaseSchemeName = value.m_Scheme;
375  m_TempTable.Remove(lwrCaseSchemeName);
376  }
377  syntax.OnRegister(lwrCaseSchemeName, defaultPort);
378  syntax.m_Scheme = lwrCaseSchemeName;
379  syntax.CheckSetIsSimpleFlag();
380  syntax.m_Port = defaultPort;
381  m_Table[syntax.SchemeName] = syntax;
382  }
383  }
384 
385  internal static UriParser FindOrFetchAsUnknownV1Syntax(string lwrCaseScheme)
386  {
387  UriParser value = null;
388  m_Table.TryGetValue(lwrCaseScheme, out value);
389  if (value != null)
390  {
391  return value;
392  }
393  m_TempTable.TryGetValue(lwrCaseScheme, out value);
394  if (value != null)
395  {
396  return value;
397  }
398  lock (m_Table)
399  {
400  if (m_TempTable.Count >= 512)
401  {
402  m_TempTable = new Dictionary<string, UriParser>(25);
403  }
404  value = new BuiltInUriParser(lwrCaseScheme, -1, UriSyntaxFlags.OptionalAuthority | UriSyntaxFlags.MayHaveUserInfo | UriSyntaxFlags.MayHavePort | UriSyntaxFlags.MayHavePath | UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment | UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowUncHost | UriSyntaxFlags.AllowDnsHost | UriSyntaxFlags.AllowIPv4Host | UriSyntaxFlags.AllowIPv6Host | UriSyntaxFlags.V1_UnknownUri | UriSyntaxFlags.AllowDOSPath | UriSyntaxFlags.PathIsRooted | UriSyntaxFlags.ConvertPathSlashes | UriSyntaxFlags.CompressPath | UriSyntaxFlags.AllowIdn | UriSyntaxFlags.AllowIriParsing);
405  m_TempTable[lwrCaseScheme] = value;
406  return value;
407  }
408  }
409 
410  internal static UriParser GetSyntax(string lwrCaseScheme)
411  {
412  UriParser value = null;
413  m_Table.TryGetValue(lwrCaseScheme, out value);
414  if (value == null)
415  {
416  m_TempTable.TryGetValue(lwrCaseScheme, out value);
417  }
418  return value;
419  }
420 
421  internal void CheckSetIsSimpleFlag()
422  {
423  Type type = GetType();
424  if (type == typeof(GenericUriParser) || type == typeof(HttpStyleUriParser) || type == typeof(FtpStyleUriParser) || type == typeof(FileStyleUriParser) || type == typeof(NewsStyleUriParser) || type == typeof(GopherStyleUriParser) || type == typeof(NetPipeStyleUriParser) || type == typeof(NetTcpStyleUriParser) || type == typeof(LdapStyleUriParser))
425  {
426  m_Flags |= UriSyntaxFlags.SimpleUserSyntax;
427  }
428  }
429 
430  internal void SetUpdatableFlags(UriSyntaxFlags flags)
431  {
432  m_UpdatableFlags = flags;
433  m_UpdatableFlagsUsed = true;
434  }
435 
436  internal UriParser InternalOnNewUri()
437  {
438  UriParser uriParser = OnNewUri();
439  if (this != uriParser)
440  {
441  uriParser.m_Scheme = m_Scheme;
442  uriParser.m_Port = m_Port;
443  uriParser.m_Flags = m_Flags;
444  }
445  return uriParser;
446  }
447 
448  internal void InternalValidate(Uri thisUri, out UriFormatException parsingError)
449  {
450  InitializeAndValidate(thisUri, out parsingError);
451  }
452 
453  internal string InternalResolve(Uri thisBaseUri, Uri uriLink, out UriFormatException parsingError)
454  {
455  return Resolve(thisBaseUri, uriLink, out parsingError);
456  }
457 
458  internal bool InternalIsBaseOf(Uri thisBaseUri, Uri uriLink)
459  {
460  return IsBaseOf(thisBaseUri, uriLink);
461  }
462 
463  internal string InternalGetComponents(Uri thisUri, UriComponents uriComponents, UriFormat uriFormat)
464  {
465  return GetComponents(thisUri, uriComponents, uriFormat);
466  }
467 
468  internal bool InternalIsWellFormedOriginalString(Uri thisUri)
469  {
470  return IsWellFormedOriginalString(thisUri);
471  }
472  }
473 }
static CultureInfo InvariantCulture
Gets the T:System.Globalization.CultureInfo object that is culture-independent (invariant).
Definition: CultureInfo.cs:263
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
virtual UriParser OnNewUri()
Invoked by a T:System.Uri constructor to get a T:System.UriParser instance
Definition: UriParser.cs:129
virtual void OnRegister(string schemeName, int defaultPort)
Invoked by the Framework when a T:System.UriParser method is registered.
Definition: UriParser.cs:137
Definition: __Canon.cs:3
The exception that is thrown when the value of an argument is outside the allowable range of values a...
UriParser()
Constructs a default URI parser.
Definition: UriParser.cs:122
static void Register(UriParser uriParser, string schemeName, int defaultPort)
Associates a scheme and port number with a T:System.UriParser.
Definition: UriParser.cs:242
UriComponents
Specifies the parts of a T:System.Uri.
Definition: UriComponents.cs:6
bool IsAbsoluteUri
Gets whether the T:System.Uri instance is absolute.
Definition: Uri.cs:820
static bool IsKnownScheme(string schemeName)
Indicates whether the parser for a scheme is registered.
Definition: UriParser.cs:275
int Count
Gets the number of key/value pairs contained in the T:System.Collections.Generic.Dictionary`2.
Definition: Dictionary.cs:890
virtual void InitializeAndValidate(Uri uri, out UriFormatException parsingError)
Initialize the state of the parser and validate the URI.
Definition: UriParser.cs:144
string OriginalString
Gets the original URI string that was passed to the T:System.Uri constructor.
Definition: Uri.cs:739
virtual string Resolve(Uri baseUri, Uri relativeUri, out UriFormatException parsingError)
Called by T:System.Uri constructors and Overload:System.Uri.TryCreate to resolve a relative URI.
Definition: UriParser.cs:157
virtual string GetComponents(Uri uri, UriComponents components, UriFormat format)
Gets the components from a URI.
Definition: UriParser.cs:202
Represents a collection of keys and values.To browse the .NET Framework source code for this type,...
Definition: Dictionary.cs:17
UriFormat
Controls how URI information is escaped.
Definition: UriFormat.cs:5
The exception that is thrown when a method call is invalid for the object's current state.
static bool CheckSchemeName(string schemeName)
Determines whether the specified scheme name is valid.
Definition: Uri.cs:1576
Provides information about a specific culture (called a locale for unmanaged code development)....
Definition: CultureInfo.cs:16
virtual bool IsWellFormedOriginalString(Uri uri)
Indicates whether a URI is well-formed.
Definition: UriParser.cs:227
Provides an object representation of a uniform resource identifier (URI) and easy access to the parts...
Definition: Uri.cs:19
bool TryGetValue(TKey key, out TValue value)
Gets the value associated with the specified key.
Definition: Dictionary.cs:1624
Parses a new URI scheme. This is an abstract class.
Definition: UriParser.cs:9
virtual bool IsBaseOf(Uri baseUri, Uri relativeUri)
Determines whether baseUri is a base URI for relativeUri .
Definition: UriParser.cs:186
The exception that is thrown when an invalid Uniform Resource Identifier (URI) is detected.