2002-01-23 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / class / corlib / System.IO / Path.cs
1 //------------------------------------------------------------------------------
2 // 
3 // System.IO.Path.cs 
4 //
5 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
6 // 
7 // Author:         Jim Richardson, develop@wtfo-guru.com
8 // Created:        Saturday, August 11, 2001 
9 //
10 //------------------------------------------------------------------------------
11
12 using System;
13 using System.PAL;
14
15 namespace System.IO
16 {
17         public class Path
18         {
19                 private static OpSys _os = Platform.OS;
20
21                 public static readonly char AltDirectorySeparatorChar = _os.AltDirectorySeparator;
22                 public static readonly char DirectorySeparatorChar = _os.DirectorySeparator;
23                 public static readonly char[] InvalidPathChars = _os.InvalidPathChars;
24                 public static readonly char PathSeparator = _os.PathSeparator;
25                 public static readonly char VolumeSeparatorChar = _os.VolumeSeparator;
26
27                 private static readonly char[] PathSeparatorChars = {   DirectorySeparatorChar, 
28                                                                         AltDirectorySeparatorChar,
29                                                                         VolumeSeparatorChar };
30
31                 // class methods
32                 public static string ChangeExtension (string path, string extension)
33                 {
34                         if (path == null)
35                         {
36                                 return null;
37                         }
38
39                         int iExt = findExtension (path);
40                         
41                         if (iExt < 0)
42                         {
43                                 return extension == null ? path : path + extension;
44                         }
45                         else if (iExt > 0)
46                         {
47                                 string temp = path.Substring (0, iExt);
48                                 if (extension != null)
49                                 {
50                                         return temp + extension;
51                                 }
52                                 return  temp;
53                         }
54
55                         return extension;
56                 }
57
58                 [MonoTODO]
59                 public static string Combine (string path1, string path2)
60                 {
61                         if (path1 == null || path2 == null)
62                         {
63                                 return null;
64                         }
65
66                         CheckArgument.Empty (path2);
67
68                         // TODO: Check for invalid DirectoryInfo characters
69                         //       although I don't think it is necesary for linux
70
71                         // TODO: Verify functionality further after NUnit tests written
72                         //               since the documentation was rather sketchy
73
74                         if (IsPathRooted (path2))
75                         {
76                                 if (path1.Equals (string.Empty))
77                                 {
78                                         return path2;
79                                 }
80                                 throw new ArgumentException ("Rooted path");
81                         }
82                         
83                         string dirSep = new string (DirectorySeparatorChar, 1);
84                         string altSep = new string (AltDirectorySeparatorChar, 1);
85                         
86                         bool b1 = path1.EndsWith (dirSep) || path1.EndsWith (dirSep);
87                         bool b2 = path2.StartsWith (dirSep) || path2.StartsWith (altSep);
88                         if (b1 && b2)
89                         {
90                                 throw new ArgumentException ("Invalid combination");
91                         }
92                         
93                         if (!b1 && !b2)
94                         {
95                                 return path1 + dirSep + path2;
96                         }
97
98                         return path1 + path2;
99                 }
100
101                 public static string GetDirectoryName (string path)
102                 {
103                         if (path != null)
104                         {
105                                 CheckArgument.Empty (path);
106                                 CheckArgument.WhitespaceOnly (path);
107                                 CheckArgument.PathChars (path);
108
109                                 if (path.Length > 2)
110                                 {
111                                         int nLast = path.LastIndexOfAny (PathSeparatorChars, path.Length - 2);
112
113                                         if (nLast > 0)
114                                         {
115                                                 return path.Substring (0, nLast);
116                                         }
117                                 }
118                         }
119                         return path;
120                 }
121
122                 public static string GetExtension (string path)
123                 {
124                         if (path == null)
125                         {
126                                 return string.Empty;
127                         }
128
129                         CheckArgument.Empty (path);
130                         CheckArgument.WhitespaceOnly (path);
131                         
132                         int iExt = findExtension (path);
133                         int iLastSep = path.LastIndexOfAny ( PathSeparatorChars );
134
135                         if (iExt > -1)
136                         {       // okay it has an extension
137                                 return path.Substring (iExt);
138                         }
139                         return string.Empty;
140                 }
141
142                 public static string GetFileName (string path)
143                 {
144                         if (path == null)
145                         {
146                                 return string.Empty;
147                         }
148
149                         CheckArgument.Empty (path);
150                         CheckArgument.WhitespaceOnly (path);
151
152                         int nLast = path.LastIndexOfAny (PathSeparatorChars);
153
154                         if (nLast > 0)
155                         {
156                                 return path.Substring (nLast + 1);
157                         }
158
159                         return nLast == 0 ? null : path;
160                 }
161
162                 public static string GetFileNameWithoutExtension (string path)
163                 {
164                         return ChangeExtension (GetFileName (path), null);
165                 }
166
167                 public static string GetFullPath (string path)
168                 {
169                         if (path == null)
170                                 throw (new ArgumentNullException (
171                                         "path",
172                                         "You must specify a path when calling System.IO.Path.GetFullPath"));
173
174                         if (path.StartsWith (new string (DirectorySeparatorChar, 1)) ||
175                                                 path.StartsWith (new string (AltDirectorySeparatorChar, 1)))
176                                 return path;
177
178                         return _os.GetCurrentDirectory () + new string (DirectorySeparatorChar, 1) + path;
179                 }
180
181                 public static string GetPathRoot (string path)
182                 {
183                         if (path != null || 
184                                 (path.StartsWith (new string (DirectorySeparatorChar, 1)) ||
185                                         path.StartsWith (new string (AltDirectorySeparatorChar, 1))))
186                         {
187                                 return path.Substring (0, 1);
188                         }
189                         return null;
190                 }
191
192                 [MonoTODO]
193                 public static string GetTempFileName ()
194                 {
195                         //TODO: Implement method
196                         return string.Empty;
197                 }
198
199                 /// <summary>
200                 /// Returns the path of the current systems temp directory
201                 /// </summary>
202                 [MonoTODO]
203                 public static string GetTempPath ()
204                 {       // TODO: This might vary with distribution and there
205                         //       might be an api to provide it. Research is needed
206                         return "/tmp";
207                 }
208
209                 public static bool HasExtension (string path)
210                 {  
211                         CheckArgument.Null (path);
212                         CheckArgument.Empty (path);
213                         CheckArgument.WhitespaceOnly (path);
214                         
215                         return findExtension (path) > -1;
216                 }
217
218                 public static bool IsPathRooted (string path)
219                 {
220                         return path.StartsWith (new string (VolumeSeparatorChar,1));
221                 }
222
223                 // private class methods
224
225                 private static int findExtension (string path)
226                 {
227                         // method should return the index of the path extension
228                         // start or -1 if no valid extension
229                         if (path != null){
230                                 int iLastDot = path.LastIndexOf (".");
231                                 int iLastSep = path.LastIndexOfAny ( PathSeparatorChars );
232
233                                 if (iLastDot > iLastSep)
234                                         return iLastDot;
235                         }
236                         return -1;
237                 }
238         }
239 }