In corlib/System.Runtime.InteropServices:
[mono.git] / mcs / class / System.Web / System.Web / VirtualPathUtility.cs
1 //\r
2 // System.Web.VirtualPathUtility.cs\r
3 //\r
4 // Author:\r
5 //      Chris Toshok (toshok@ximian.com)\r
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)\r
7 //\r
8 \r
9 //\r
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)\r
11 //\r
12 // Permission is hereby granted, free of charge, to any person obtaining\r
13 // a copy of this software and associated documentation files (the\r
14 // "Software"), to deal in the Software without restriction, including\r
15 // without limitation the rights to use, copy, modify, merge, publish,\r
16 // distribute, sublicense, and/or sell copies of the Software, and to\r
17 // permit persons to whom the Software is furnished to do so, subject to\r
18 // the following conditions:\r
19 // \r
20 // The above copyright notice and this permission notice shall be\r
21 // included in all copies or substantial portions of the Software.\r
22 // \r
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
30 //\r
31 \r
32 #if NET_2_0\r
33 \r
34 using System.Web.Util;\r
35 \r
36 namespace System.Web {\r
37 \r
38         public static class VirtualPathUtility\r
39         {\r
40                 public static string AppendTrailingSlash (string virtualPath)\r
41                 {\r
42                         if (virtualPath == null)\r
43                                 return virtualPath;\r
44 \r
45                         int length = virtualPath.Length;\r
46                         if (length == 0 || virtualPath [length - 1] == '/')\r
47                                 return virtualPath;\r
48 \r
49                         return virtualPath + "/";\r
50                 }\r
51 \r
52                 public static string Combine (string basePath, string relativePath)\r
53                 {\r
54                         if (basePath == null || basePath == "")\r
55                                 throw new ArgumentNullException ("basePath");\r
56 \r
57                         if (relativePath == null)\r
58                                 // LAME SPEC - MSDN Specifies ArgumentNullException but MS throws ArgumentException\r
59                                 throw new ArgumentException ("relativePath");\r
60 \r
61                         if (relativePath == "")\r
62                                 // MS throw different exception for null or empty string.\r
63                                 throw new ArgumentNullException ("relativePath");\r
64 \r
65                         if (relativePath.Length == 1 && relativePath [0] == '~')\r
66                                 return HttpRuntime.AppDomainAppVirtualPath;\r
67 \r
68                         if (relativePath [0] == '~' && relativePath [1] == '/')\r
69                                 return UrlUtils.RemoveDoubleSlashes ((HttpRuntime.AppDomainAppVirtualPath + relativePath.Substring (1)).Replace ('\\', '/'));\r
70 \r
71                         if (basePath [0] != '/')\r
72                                 throw new ArgumentException ("basePath is not an absolute path", "basePath");\r
73 \r
74                         if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/') {\r
75                                 int lastSlash = basePath.LastIndexOf ('/');\r
76                                 if (lastSlash >= 0)\r
77                                         return UrlUtils.Combine (basePath.Substring (0, lastSlash + 1), relativePath);\r
78                         }\r
79 \r
80                         return UrlUtils.Combine (basePath, relativePath);\r
81                 }\r
82 \r
83                 public static string GetDirectory (string virtualPath)\r
84                 {\r
85                         if (virtualPath == null || virtualPath == "") // Yes, "" throws an ArgumentNullException\r
86                                 throw new ArgumentNullException ("virtualPath");\r
87 \r
88                         if (virtualPath [0] != '/')\r
89                                 throw new ArgumentException ("The virtual path is not rooted", "virtualPath");\r
90 \r
91                         if (virtualPath == "/")\r
92                                 return null; //.net behavior\r
93 \r
94                         //In .Net - will look for one '/' before the last one, and will return it as a directory\r
95                         //therefor we always should remove the last slash.\r
96                         if (virtualPath.EndsWith("/")) \r
97                                 virtualPath = virtualPath.Substring(0, virtualPath.Length - 1);\r
98 \r
99                         string result = UrlUtils.GetDirectory (virtualPath);\r
100                         return AppendTrailingSlash (result);\r
101                 }\r
102 \r
103                 public static string GetExtension (string virtualPath)\r
104                 {\r
105                         if (virtualPath != null && virtualPath != "" && \r
106                                 virtualPath.IndexOf('/') == -1)\r
107                         {\r
108                                 virtualPath = "./" + virtualPath;\r
109                         }\r
110 \r
111                         string filename = GetFileName (virtualPath);\r
112                         int dot = filename.LastIndexOf ('.');\r
113                         if (dot == -1 || dot == filename.Length + 1)\r
114                                 return "";\r
115 \r
116                         return filename.Substring (dot);\r
117                 }\r
118 \r
119                 public static string GetFileName (string virtualPath)\r
120                 {\r
121                         if (virtualPath == null || virtualPath == "") // Yes, "" throws an ArgumentNullException\r
122                                 throw new ArgumentNullException ("virtualPath");\r
123                         \r
124                         return UrlUtils.GetFile (RemoveTrailingSlash (virtualPath));\r
125                 }\r
126 \r
127                 public static bool IsAbsolute (string virtualPath)\r
128                 {\r
129                         if (virtualPath == "" || virtualPath == null)\r
130                                 throw new ArgumentNullException ("virtualPath");\r
131 \r
132                         return (virtualPath [0] == '/');\r
133                 }\r
134 \r
135                 public static bool IsAppRelative (string virtualPath)\r
136                 {\r
137                         if (String.IsNullOrEmpty (virtualPath))\r
138                                 throw new ArgumentNullException ("virtualPath");\r
139 \r
140                         if (virtualPath.Length == 1 && virtualPath [0] == '~')\r
141                                 return true;\r
142 \r
143                         if (virtualPath [0] == '~' && virtualPath [1] == '/')\r
144                                 return true;\r
145 \r
146                         return false;\r
147                 }\r
148 \r
149                 public static string MakeRelative (string fromPath, string toPath)\r
150                 {\r
151                         if (fromPath == null || toPath == null)\r
152                                 throw new NullReferenceException (); // yeah!\r
153 \r
154                         if (toPath == "")\r
155                                 return toPath;\r
156 \r
157                         if (toPath [0] != '/')\r
158                                 throw new ArgumentOutOfRangeException (); // This is what MS does.\r
159 \r
160                         if (fromPath.Length > 0 && fromPath [0] != '/')\r
161                                 throw new ArgumentOutOfRangeException (); // This is what MS does.\r
162 \r
163                         Uri from = new Uri ("http://nothing" + fromPath);\r
164                         return from.MakeRelativeUri (new Uri ("http://nothing" + toPath)).AbsolutePath;\r
165                 }\r
166 \r
167                 public static string RemoveTrailingSlash (string virtualPath)\r
168                 {\r
169                         if (virtualPath == null || virtualPath == "")\r
170                                 return null;\r
171 \r
172                         int last = virtualPath.Length - 1;\r
173                         if (last == 0 || virtualPath [last] != '/')\r
174                                 return virtualPath;\r
175 \r
176                         return virtualPath.Substring (0, last);\r
177                 }\r
178 \r
179                 public static string ToAbsolute (string virtualPath)\r
180                 {\r
181                         string apppath = HttpRuntime.AppDomainAppVirtualPath;\r
182                         if (apppath == null)\r
183                                 throw new HttpException ("The path to the application is not known");\r
184 \r
185                         return ToAbsolute (virtualPath,apppath);\r
186                 }\r
187 \r
188                 // If virtualPath is: \r
189                 // Absolute, the ToAbsolute method returns the virtual path with no changes.\r
190                 // Application relative, the ToAbsolute method adds applicationPath to the beginning of the virtual path.\r
191                 // Not rooted, the ToAbsolute method raises an ArgumentOutOfRangeException exception.\r
192                 public static string ToAbsolute (string virtualPath, string applicationPath)\r
193                 {\r
194                         if (applicationPath == null || applicationPath == "")\r
195                                 throw new ArgumentNullException ("applicationPath");\r
196 \r
197                         if (virtualPath == null || virtualPath == "")\r
198                                 throw new ArgumentNullException ("virtualPath");\r
199 \r
200                         if (IsAppRelative(virtualPath)) {\r
201                                 if (applicationPath [0] != '/')\r
202                                         throw new ArgumentException ("appPath is not rooted", "applicationPath");\r
203                                 return UrlUtils.RemoveDoubleSlashes ((applicationPath + (virtualPath.Length == 1 ? "/" : virtualPath.Substring (1))).Replace ('\\', '/'));\r
204                         }\r
205 \r
206                         if (virtualPath [0] != '/')\r
207                                 throw new ArgumentException (String.Format ("Relative path not allowed: '{0}'", virtualPath));\r
208 \r
209                         return UrlUtils.RemoveDoubleSlashes (virtualPath.Replace ('\\', '/'));\r
210 \r
211                 }\r
212 \r
213                 public static string ToAppRelative (string virtualPath)\r
214                 {\r
215                         string apppath = HttpRuntime.AppDomainAppVirtualPath;\r
216                         if (apppath == null)\r
217                                 throw new HttpException ("The path to the application is not known");\r
218 \r
219                         return ToAppRelative (apppath, virtualPath);\r
220                 }\r
221 \r
222                 public static string ToAppRelative (string virtualPath, string applicationPath)\r
223                 {\r
224                         if (applicationPath == null || applicationPath == "")\r
225                                 throw new ArgumentNullException ("applicationPath");\r
226 \r
227                         if (virtualPath == null || virtualPath == "")\r
228                                 throw new ArgumentNullException ("virtualPath");\r
229 \r
230                         if (virtualPath.StartsWith (".."))\r
231                                 throw new ArgumentException (String.Format ("Relative path not allowed: '{0}'", virtualPath));\r
232 \r
233                         if (applicationPath [0] != '/')\r
234                                 throw new ArgumentOutOfRangeException ("appPath is not rooted", "applicationPath");\r
235 \r
236                         return MakeRelative (applicationPath, virtualPath);\r
237                 }\r
238         }\r
239 }\r
240 \r
241 #endif\r
242 \r
243 \r
244 \r