[System] Uri handling from reference source
[mono.git] / mcs / class / System / System.Net / HttpListenerRequest.cs
index f1c47802cb94bef9e16534919ff1d10aba148b8c..a9c5bb9ee32bb7e7a7208fb5ff68081f11a143de 100644 (file)
@@ -146,6 +146,54 @@ namespace System.Net {
                        }
                }
 
+               static bool MaybeUri (string s)
+               {
+                       int p = s.IndexOf (':');
+                       if (p == -1)
+                               return false;
+
+                       if (p >= 10)
+                               return false;
+
+                       return IsPredefinedScheme (s.Substring (0, p));
+               }
+
+               //
+               // Using a simple block of if's is twice as slow as the compiler generated
+               // switch statement.   But using this tuned code is faster than the
+               // compiler generated code, with a million loops on x86-64:
+               //
+               // With "http": .10 vs .51 (first check)
+               // with "https": .16 vs .51 (second check)
+               // with "foo": .22 vs .31 (never found)
+               // with "mailto": .12 vs .51  (last check)
+               //
+               //
+               static bool IsPredefinedScheme (string scheme)
+               {
+                       if (scheme == null || scheme.Length < 3)
+                               return false;
+                       
+                       char c = scheme [0];
+                       if (c == 'h')
+                               return (scheme == "http" || scheme == "https");
+                       if (c == 'f')
+                               return (scheme == "file" || scheme == "ftp");
+                               
+                       if (c == 'n'){
+                               c = scheme [1];
+                               if (c == 'e')
+                                       return (scheme == "news" || scheme == "net.pipe" || scheme == "net.tcp");
+                               if (scheme == "nntp")
+                                       return true;
+                               return false;
+                       }
+                       if ((c == 'g' && scheme == "gopher") || (c == 'm' && scheme == "mailto"))
+                               return true;
+
+                       return false;
+               }
+
                internal void FinishInitialization ()
                {
                        string host = UserHostName;
@@ -156,7 +204,7 @@ namespace System.Net {
 
                        string path;
                        Uri raw_uri = null;
-                       if (Uri.MaybeUri (raw_url.ToLowerInvariant ()) && Uri.TryCreate (raw_url, UriKind.Absolute, out raw_uri))
+                       if (MaybeUri (raw_url.ToLowerInvariant ()) && Uri.TryCreate (raw_url, UriKind.Absolute, out raw_uri))
                                path = raw_uri.PathAndQuery;
                        else
                                path = raw_url;