Merge pull request #2964 from ludovic-henry/sgen-monocontext
[mono.git] / mcs / class / referencesource / System / net / System / UriScheme.cs
1 //depot/DevDiv/private/Whidbey_Xws/ndp/fx/src/Net/System/UriScheme.cs#4 - edit change 914456 (text)
2 /*++
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7     UriScheme.cs
8
9 Abstract:
10     Provides extensibility contract for System.Uri
11     The contains only public API definition.
12
13     For remaining internal stuff please refer to the _UriSyntax.cs file.
14
15 Author:
16
17     Alexei Vopilov    19-Dec-2003
18
19 Revision History:
20     Alexei Vopilov    60-July-2004  - Changed the extensiblity model to be based purely on derivation, also has cut Config extensibility option
21
22
23 --*/
24 namespace System {
25     using System.Net;
26     using System.Globalization;
27     using System.Security.Permissions;
28
29     //
30     // The class is used as a base for custom uri parsing and derived Uri factoring.
31     // A set of protected .ctors allows to hookup on the builtin parser behaviors.
32     //
33     // A developer must implement at least internal default .ctor to participate in the Uri extensibility game.
34     //
35     public abstract partial class UriParser {
36
37         internal string SchemeName
38         {
39             get
40             {
41                 return m_Scheme;
42             }
43         }
44         internal int DefaultPort {
45             get {
46                 return m_Port;
47             }
48         }
49
50         private const UriSyntaxFlags SchemeOnlyFlags = UriSyntaxFlags.MayHavePath;
51         // This is a "scheme-only" base parser, everything after the scheme is
52         // returned as the path component.
53         // The user parser will need to do the majority of the work itself.
54         //
55         // However when the ctor is called from OnCreateUri context the calling parser
56         // settings will later override the result on the base class
57         //
58         protected UriParser(): this (SchemeOnlyFlags) { }
59
60         //
61         // Is called on each Uri ctor for every non-simple parser i.e. the one that does have
62         // user code.
63         //
64         protected virtual UriParser OnNewUri()
65         {
66             return this;
67         }
68         //
69         // Is called whenever a parser gets registered with some scheme
70         // The base implementaion is a nop.
71         //
72         protected virtual void OnRegister(string schemeName, int defaultPort)
73         {
74
75         }
76         //
77         // Parses and validates a Uri object, is called at the Uri ctor time.
78         //
79         // This method returns a non null parsingError if Uri being created is invalid:
80         //
81         protected virtual void InitializeAndValidate(Uri uri, out UriFormatException parsingError)
82         {
83             parsingError = uri.ParseMinimal();
84         }
85         //
86         // Resolves a relative Uri object into new AbsoluteUri.
87         //
88         //  baseUri         - The baseUri used to resolve this Uri.
89         //  relativeuri     - A relative Uri string passed by the application.
90         //
91         // This method returns:
92         // The result Uri value used to represent a new Uri
93         //
94         protected virtual string Resolve(Uri baseUri, Uri relativeUri, out UriFormatException parsingError)
95         {
96             if (baseUri.UserDrivenParsing)
97                 throw new InvalidOperationException(SR.GetString(SR.net_uri_UserDrivenParsing, this.GetType().FullName));
98
99             if (!baseUri.IsAbsoluteUri)
100                 throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
101
102
103             string newUriString = null;
104             bool userEscaped = false;
105             Uri result = Uri.ResolveHelper(baseUri, relativeUri, ref newUriString, ref userEscaped, out parsingError);
106
107             if (parsingError != null)
108                 return null;
109
110             if (result != null)
111                 return result.OriginalString;
112
113             return newUriString;
114         }
115
116         //
117         //
118         //
119         protected virtual  bool IsBaseOf(Uri baseUri, Uri relativeUri)
120         {
121             return baseUri.IsBaseOfHelper(relativeUri);
122         }
123
124         //
125         // This method is invoked to allow a cutsom parser to override the
126         // internal parser when serving application with Uri componenet strings.
127         // The output format depends on the "format" parameter
128         //
129         // Parameters:
130         //  uriComponents   - Which components are to be retrieved.
131         //  uriFormat       - The requested output format.
132         //
133         // This method returns:
134         // The final result. The base impementaion could be invoked to get a suggested value
135         //
136         protected virtual string GetComponents(Uri uri, UriComponents components, UriFormat format)
137         {
138             if (((components & UriComponents.SerializationInfoString) != 0) && components != UriComponents.SerializationInfoString)
139                 throw new ArgumentOutOfRangeException("components", components, SR.GetString(SR.net_uri_NotJustSerialization));
140
141             if ((format & ~UriFormat.SafeUnescaped) != 0)
142                 throw new ArgumentOutOfRangeException("format");
143
144             if (uri.UserDrivenParsing)
145                 throw new InvalidOperationException(SR.GetString(SR.net_uri_UserDrivenParsing, this.GetType().FullName));
146
147             if (!uri.IsAbsoluteUri)
148                 throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
149
150             return uri.GetComponentsHelper(components, format);
151         }
152
153         //
154         //
155         //
156         protected virtual bool IsWellFormedOriginalString(Uri uri)
157         {
158             return uri.InternalIsWellFormedOriginalString();
159         }
160
161         //
162         // Static Registration methods
163         //
164         //
165         // Registers a custom Uri parser based on a scheme string
166         //
167         public static void Register(UriParser uriParser, string schemeName, int defaultPort)
168         {
169             ExceptionHelper.InfrastructurePermission.Demand();
170
171             if (uriParser == null)
172                 throw new ArgumentNullException("uriParser");
173
174             if (schemeName == null)
175                 throw new ArgumentNullException("schemeName");
176
177             if (schemeName.Length == 1)
178                 throw new ArgumentOutOfRangeException("schemeName");
179
180             if (!Uri.CheckSchemeName(schemeName))
181                 throw new ArgumentOutOfRangeException("schemeName");
182
183             if ((defaultPort >= 0xFFFF || defaultPort < 0) && defaultPort != -1)
184                 throw new ArgumentOutOfRangeException("defaultPort");
185
186             schemeName = schemeName.ToLower(CultureInfo.InvariantCulture);
187             FetchSyntax(uriParser, schemeName, defaultPort);
188         }
189         //
190         // Is a Uri scheme known to System.Uri?
191         //
192         public static bool IsKnownScheme(string schemeName)
193         {
194             if (schemeName == null)
195                 throw new ArgumentNullException("schemeName");
196
197             if (!Uri.CheckSchemeName(schemeName))
198                 throw new ArgumentOutOfRangeException("schemeName");
199
200             UriParser syntax = UriParser.GetSyntax(schemeName.ToLower(CultureInfo.InvariantCulture));
201             return syntax != null && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri);
202         }
203     }
204 }