merged Sys.Web.Services 2.0 support in my branch:
[mono.git] / mcs / class / corlib / System.IO / DirectoryInfo.cs
1 // 
2 // System.IO.DirectoryInfo.cs 
3 //
4 // Authors:
5 //   Miguel de Icaza, miguel@ximian.com
6 //   Jim Richardson, develop@wtfo-guru.com
7 //   Dan Lewis, dihlewis@yahoo.co.uk
8 //   Sebastien Pouliot  <sebastien@ximian.com>
9 //
10 // Copyright (C) 2002 Ximian, Inc.
11 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
12 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Collections;
35 using System.Runtime.InteropServices;
36 using System.Text;
37 #if NET_2_0
38 using System.Security.AccessControl;
39 #endif
40
41 namespace System.IO {
42         
43         [Serializable]
44 #if NET_2_0
45         [ComVisible (true)]
46 #endif
47         public sealed class DirectoryInfo : FileSystemInfo {
48
49                 private string current;
50                 private string parent;
51         
52                 public DirectoryInfo (string path)
53                 {
54                         CheckPath (path);
55
56                         FullPath = Path.GetFullPath (path);
57                         OriginalPath = path;
58
59                         int len = FullPath.Length - 1;
60                         if ((len > 1) && (FullPath [len] == Path.DirectorySeparatorChar))
61                                 len--;
62                         int last = FullPath.LastIndexOf (Path.DirectorySeparatorChar, len);
63                         if ((last == -1) || ((last == 0) && (len == 0))) {
64                                 current = FullPath;
65                                 parent = null;
66                         } else {
67                                 current = FullPath.Substring (last + 1, len - last);
68                                 if (last == 0 && !Environment.IsRunningOnWindows)
69                                         parent = Path.DirectorySeparatorStr;
70                                 else
71                                         parent = FullPath.Substring (0, last);
72                                 // adjust for drives, i.e. a special case for windows
73                                 if (Environment.IsRunningOnWindows) {
74                                         if ((parent.Length == 2) && (parent [1] == ':') && Char.IsLetter (parent [0]))
75                                                 parent += Path.DirectorySeparatorChar;
76                                 }
77                         }
78                 }
79
80                 // properties
81
82                 public override bool Exists {
83                         get {
84                                 Refresh (false);
85
86                                 if (stat.Attributes == MonoIO.InvalidFileAttributes)
87                                         return false;
88
89                                 if ((stat.Attributes & FileAttributes.Directory) == 0)
90                                         return false;
91
92                                 return true;
93                         }
94                 }
95
96                 public override string Name {
97                         get { return current; }
98                 }
99
100                 public DirectoryInfo Parent {
101                         get {
102                                 if ((parent == null) || (parent.Length == 0))
103                                         return null;
104                                 return new DirectoryInfo (parent);
105                         }
106                 }
107
108                 public DirectoryInfo Root {
109                         get {
110                                 string root = Path.GetPathRoot (FullPath);
111                                 if (root == null)
112                                         return null;
113
114                                 return new DirectoryInfo (root);
115                         }
116                 }
117
118                 // creational methods
119
120                 public void Create () {
121                         Directory.CreateDirectory (FullPath);
122                 }
123
124                 public DirectoryInfo CreateSubdirectory (string name) {
125                         CheckPath (name);
126                         
127                         string path = Path.Combine (FullPath, name);
128                         Directory.CreateDirectory (path);
129
130                         return new DirectoryInfo (path);
131                 }
132
133                 // directory listing methods
134
135                 public FileInfo [] GetFiles () {
136                         return GetFiles ("*");
137                 }
138
139                 public FileInfo [] GetFiles (string pattern)
140                 {
141                         string [] names = Directory.GetFiles (FullPath, pattern);
142
143                         FileInfo[] infos = new FileInfo [names.Length];
144                         int i = 0;
145                         foreach (string name in names)
146                                 infos [i++] = new FileInfo (name);
147
148                         return infos;
149                 }
150
151                 public DirectoryInfo [] GetDirectories () {
152                         return GetDirectories ("*");
153                 }
154
155                 public DirectoryInfo [] GetDirectories (string pattern)
156                 {
157                         string [] names = Directory.GetDirectories (FullPath, pattern);
158
159                         DirectoryInfo[] infos = new DirectoryInfo [names.Length];
160                         int i = 0;
161                         foreach (string name in names)
162                                 infos [i++] = new DirectoryInfo (name);
163
164                         return infos;
165                 }
166
167                 public FileSystemInfo [] GetFileSystemInfos () {
168                         return GetFileSystemInfos ("*");
169                 }
170
171                 public FileSystemInfo [] GetFileSystemInfos (string pattern)
172                 {
173                         string[] dirs = Directory.GetDirectories (FullPath, pattern);
174                         string[] files = Directory.GetFiles (FullPath, pattern);
175
176                         FileSystemInfo[] infos = new FileSystemInfo [dirs.Length + files.Length];
177                         int i = 0;
178                         foreach (string dir in dirs)
179                                 infos [i++] = new DirectoryInfo (dir);
180                         foreach (string file in files)
181                                 infos [i++] = new FileInfo (file);
182
183                         return infos;
184                 }
185
186                 // directory management methods
187
188                 public override void Delete () {
189                         Delete (false);
190                 }
191
192                 public void Delete (bool recurse) {
193                         Directory.Delete (FullPath, recurse);
194                 }
195
196                 public void MoveTo (string dest) {
197                         Directory.Move (FullPath, Path.GetFullPath (dest));
198                 }
199
200                 public override string ToString () {
201                         return OriginalPath;
202                 }
203 #if NET_2_0
204                 // additional search methods
205
206                 public DirectoryInfo[] GetDirectories (string pattern, SearchOption searchOption)
207                 {
208                         switch (searchOption) {
209                         case SearchOption.TopDirectoryOnly:
210                                 return GetDirectories (pattern);
211                         case SearchOption.AllDirectories:
212                                 Queue workq = new Queue(GetDirectories(pattern));
213                                 Queue doneq = new Queue();
214                                 while (workq.Count > 0)
215                                         {
216                                                 DirectoryInfo cinfo = (DirectoryInfo) workq.Dequeue();
217                                                 DirectoryInfo[] cinfoDirs = cinfo.GetDirectories(pattern);
218                                                 foreach (DirectoryInfo i in cinfoDirs) workq.Enqueue(i);
219                                                 doneq.Enqueue(cinfo);
220                                         }
221
222                                 DirectoryInfo[] infos = new DirectoryInfo[doneq.Count];
223                                 doneq.CopyTo(infos, 0);
224                                 return infos;
225                         default:
226                                 string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
227                                 throw new ArgumentOutOfRangeException ("searchOption", msg);
228                         }
229                 }       
230
231                 internal int GetFilesSubdirs (ArrayList l, string pattern)
232                 {
233                         int count;
234                         FileInfo [] thisdir = null;
235
236                         try {
237                                 thisdir = GetFiles (pattern);
238                         } catch (System.UnauthorizedAccessException){
239                                 return 0;
240                         }
241                         
242                         count = thisdir.Length;
243                         l.Add (thisdir);
244
245                         foreach (DirectoryInfo subdir in GetDirectories ()){
246                                 count += subdir.GetFilesSubdirs (l, pattern);
247                         }
248                         return count;
249                 }
250                 
251                 public FileInfo[] GetFiles (string pattern, SearchOption searchOption)
252                 {
253                         switch (searchOption) {
254                         case SearchOption.TopDirectoryOnly:
255                                 return GetFiles (pattern);
256                         case SearchOption.AllDirectories: {
257                                 ArrayList groups = new ArrayList ();
258                                 int count = GetFilesSubdirs (groups, pattern);
259                                 int current = 0;
260                                 
261                                 FileInfo [] all = new FileInfo [count];
262                                 foreach (FileInfo [] p in groups){
263                                         p.CopyTo (all, current);
264                                         current += p.Length;
265                                 }
266                                 return all;
267                         }
268                         default:
269                                 string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
270                                 throw new ArgumentOutOfRangeException ("searchOption", msg);
271                         }
272                 }
273
274                 // access control methods
275
276                 [MonoTODO ("DirectorySecurity isn't implemented")]
277                 public void Create (DirectorySecurity directorySecurity)
278                 {
279                         if (directorySecurity != null)
280                                 throw new NotImplementedException ();
281                         Create ();
282                 }
283
284                 [MonoTODO ("DirectorySecurity isn't implemented")]
285                 public DirectoryInfo CreateSubdirectory (string name, DirectorySecurity directorySecurity)
286                 {
287                         if (directorySecurity != null)
288                                 throw new NotImplementedException ();
289                         return CreateSubdirectory (name);
290                 }
291
292                 [MonoTODO ("DirectorySecurity isn't implemented")]
293                 public DirectorySecurity GetAccessControl ()
294                 {
295                         throw new NotImplementedException ();
296                 }
297
298                 [MonoTODO ("DirectorySecurity isn't implemented")]
299                 public DirectorySecurity GetAccessControl (AccessControlSections includeSections)
300                 {
301                         throw new NotImplementedException ();
302                 }
303
304                 [MonoTODO ("DirectorySecurity isn't implemented")]
305                 public void SetAccessControl (DirectorySecurity directorySecurity)
306                 {
307                         if (directorySecurity != null)
308                                 throw new ArgumentNullException ("directorySecurity");
309                         throw new NotImplementedException ();
310                 }
311 #endif
312         }
313 }