2004-06-09 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System / System / Uri.cs
index 26d6cc93d9aac5ebc8ad8ceffe4daa625535c62b..ddec91998adac4327992ea181c218c6c60e5db64 100755 (executable)
@@ -96,8 +96,6 @@ namespace System
 
                        host = EscapeString (host, false, true, false);
                        path = EscapeString (path);
-                       query = EscapeString (query);
-                       fragment = EscapeString (fragment, false, false, true);
                }
 
                public Uri (Uri baseUri, string relativeUri) 
@@ -114,25 +112,9 @@ namespace System
 
                        userEscaped = dontEscape;
 
-                       this.scheme = baseUri.scheme;
-                       this.host = baseUri.host;
-                       this.port = baseUri.port;
-                       this.userinfo = baseUri.userinfo;
-                       this.isUnc = baseUri.isUnc;
-                       this.isWindowsFilePath = baseUri.isWindowsFilePath;
-                       this.isUnixFilePath = baseUri.isUnixFilePath;
-                       this.isOpaquePart = baseUri.isOpaquePart;
-
                        if (relativeUri == null)
                                throw new NullReferenceException ("relativeUri");
 
-                       if (relativeUri == String.Empty) {
-                               this.path = baseUri.path;
-                               this.query = baseUri.query;
-                               this.fragment = baseUri.fragment;
-                               return;
-                       }
-
                        int pos = relativeUri.IndexOf (':');
                        if (pos != -1) {
 
@@ -147,18 +129,30 @@ namespace System
 
                                        host = EscapeString (host, false, true, false);
                                        path = EscapeString (path);
-                                       query = EscapeString (query);
-                                       fragment = EscapeString (fragment, false, false, true);
                                        return;
                                }
                        }
 
+                       this.scheme = baseUri.scheme;
+                       this.host = baseUri.host;
+                       this.port = baseUri.port;
+                       this.userinfo = baseUri.userinfo;
+                       this.isUnc = baseUri.isUnc;
+                       this.isWindowsFilePath = baseUri.isWindowsFilePath;
+                       this.isUnixFilePath = baseUri.isUnixFilePath;
+                       this.isOpaquePart = baseUri.isOpaquePart;
+
+                       if (relativeUri == String.Empty) {
+                               this.path = baseUri.path;
+                               this.query = baseUri.query;
+                               this.fragment = baseUri.fragment;
+                               return;
+                       }
+                       
                        // 8 fragment
                        pos = relativeUri.IndexOf ('#');
                        if (pos != -1) {
                                fragment = relativeUri.Substring (pos);
-                               if (!userEscaped)
-                                       fragment = EscapeString (fragment, false, false, true);
                                relativeUri = relativeUri.Substring (0, pos);
                        }
 
@@ -246,15 +240,18 @@ namespace System
                }               
                
                // Properties
-               
+
                public string AbsolutePath { 
                        get { return path; } 
                }
 
                public string AbsoluteUri { 
-                       get { 
-                               if (cachedAbsoluteUri == null)
-                                       cachedAbsoluteUri = GetLeftPart (UriPartial.Path) + query + fragment;
+                       get {
+                               if (cachedAbsoluteUri == null) {
+//                                     cachedAbsoluteUri = GetLeftPart (UriPartial.Path) + query + fragment;
+                                       string qf = IsFile ? query + fragment : EscapeString (query + fragment);
+                                       cachedAbsoluteUri = GetLeftPart (UriPartial.Path) + qf;
+                               }
                                return cachedAbsoluteUri;
                        } 
                }
@@ -302,7 +299,8 @@ namespace System
                                        return true;
                                        
                                try {
-                                       return IPAddress.IsLoopback (IPAddress.Parse (host));
+                                       if (IPAddress.Loopback.Equals (IPAddress.Parse (host)))
+                                               return true;
                                } catch (FormatException) {}
 
                                try {
@@ -324,9 +322,13 @@ namespace System
                        get {
                                if (!IsFile)
                                        return path;
+
+                               bool windows = (path.Length > 3 && path [1] == ':' &&
+                                               (path [2] == '\\' || path [2] == '/'));
+
                                if (!IsUnc) {
                                        string p = Unescape (path);
-                                       if (System.IO.Path.DirectorySeparatorChar == '\\')
+                                       if (System.IO.Path.DirectorySeparatorChar == '\\' || windows)
                                                return p.Replace ('/', '\\');
                                        else
                                                return p;
@@ -511,12 +513,12 @@ namespace System
                                uri = new Uri (s);
                        }
                        
-                       return ((this.scheme == uri.scheme) &&
-                               (this.userinfo == uri.userinfo) &&
-                               (this.host == uri.host) &&
-                               (this.port == uri.port) &&
-                               (this.path == uri.path) &&
-                               (this.query == uri.query));
+                       return ((this.scheme.ToLower () == uri.scheme.ToLower ()) &&
+                               (this.userinfo.ToLower () == uri.userinfo.ToLower ()) &&
+                               (this.host.ToLower () == uri.host.ToLower ()) &&
+                               (this.port == uri.port) &&
+                               (this.path == uri.path) &&
+                               (this.query.ToLower () == uri.query.ToLower ()));
                }               
                
                public override int GetHashCode () 
@@ -666,10 +668,7 @@ namespace System
                {
                        if (cachedToString != null) 
                                return cachedToString;
-                       if (IsFile && !IsUnc)
-                               cachedToString = Unescape (AbsoluteUri);
-                       else
-                               cachedToString = AbsoluteUri;
+                       cachedToString = Unescape (AbsoluteUri);
 
                        return cachedToString;
                }
@@ -757,7 +756,7 @@ namespace System
                                        s.Append (HexUnescape (str, ref i));
                                        i--;
                                } else
-                                       s.Append (c);                                   
+                                       s.Append (c);
                        }
                        return s.ToString ();
                }
@@ -928,10 +927,13 @@ namespace System
                                isUnc = true;
                        }
 
+                       if ((scheme != Uri.UriSchemeMailto) &&
+                                       (scheme != Uri.UriSchemeNews) &&
+                                       (scheme != Uri.UriSchemeFile))
                        path = Reduce (path);
                }
 
-               public static string Reduce (string path)
+               private static string Reduce (string path)
                {
                        path = path.Replace ('\\','/');
                        string [] parts = path.Split ('/');
@@ -961,7 +963,12 @@ namespace System
                                return "/";
 
                        result.Insert (0, "");
-                       return String.Join ("/", (string []) result.ToArray (typeof (string)));
+
+                       string res = String.Join ("/", (string []) result.ToArray (typeof (string)));
+                       if (path.EndsWith ("/"))
+                               res += '/';
+                               
+                       return res;
                }
                                
                private struct UriScheme