2006-11-16 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / corlib / System.IO / DirectoryInfo.cs
index 25be8be02915cda5d8116e9258e1a89453ffe6a1..4bb1cf8e9e53dff77e114b11e2509f40fe1f7e1c 100644 (file)
@@ -1,17 +1,15 @@
-// \r
-// System.IO.DirectoryInfo.cs \r
-//\r
-// Author:\r
-//   Miguel de Icaza, miguel@ximian.com\r
-//   Jim Richardson, develop@wtfo-guru.com\r
-//   Dan Lewis, dihlewis@yahoo.co.uk\r
-//\r
-// Copyright (C) 2002 Ximian, Inc.\r
-// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved\r
-// \r
-
+// 
+// System.IO.DirectoryInfo.cs 
 //
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Authors:
+//   Miguel de Icaza, miguel@ximian.com
+//   Jim Richardson, develop@wtfo-guru.com
+//   Dan Lewis, dihlewis@yahoo.co.uk
+//   Sebastien Pouliot  <sebastien@ximian.com>
+//
+// Copyright (C) 2002 Ximian, Inc.
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-\r
-using System;\r
-using System.Collections;\r
-\r
-namespace System.IO {\r
-       \r
-       [Serializable]\r
-       public sealed class DirectoryInfo : FileSystemInfo {\r
-       \r
-               public DirectoryInfo (string path) {\r
-                       CheckPath (path);\r
-               \r
-                       OriginalPath = path;\r
-                       FullPath = Path.GetFullPath (path);\r
-               }\r
-\r
-               // properties\r
-\r
-               public override bool Exists {\r
-                       get {\r
-                               Refresh (false);\r
-\r
-                               if (stat.Attributes == MonoIO.InvalidFileAttributes)\r
-                                       return false;\r
-\r
-                               if ((stat.Attributes & FileAttributes.Directory) == 0)\r
-                                       return false;\r
-\r
-                               return true;\r
-                       }\r
-               }\r
-\r
-               public override string Name {\r
-                       get {\r
-                               string result = Path.GetFileName (FullPath);\r
-                               if (result == null || result == "")\r
-                                       return FullPath;\r
-                               return result;\r
-                       }\r
-               }\r
-\r
-               public DirectoryInfo Parent {\r
-                       get {\r
-                               string dirname = Path.GetDirectoryName (FullPath);\r
-                               if (dirname == null)\r
-                                       return null;\r
-\r
-                               return new DirectoryInfo (dirname);\r
-                       }\r
-               }\r
-\r
-               public DirectoryInfo Root {\r
-                       get {\r
-                               string root = Path.GetPathRoot (FullPath);\r
-                               if (root == null)\r
-                                       return null;\r
-\r
-                               return new DirectoryInfo (root);\r
-                       }\r
-               }\r
-\r
-               // creational methods\r
-\r
-               public void Create () {\r
-                       Directory.CreateDirectory (FullPath);\r
-               }\r
-\r
+
+using System.Collections;
+using System.Runtime.InteropServices;
+using System.Text;
+#if NET_2_0
+using System.Security.AccessControl;
+#endif
+
+namespace System.IO {
+       
+       [Serializable]
+#if NET_2_0
+       [ComVisible (true)]
+#endif
+       public sealed class DirectoryInfo : FileSystemInfo {
+
+               private string current;
+               private string parent;
+       
+               public DirectoryInfo (string path)
+               {
+                       CheckPath (path);
+
+                       FullPath = Path.GetFullPath (path);
+                       OriginalPath = path;
+
+                       int len = FullPath.Length - 1;
+                       if ((len > 1) && (FullPath [len] == Path.DirectorySeparatorChar))
+                               len--;
+                       int last = FullPath.LastIndexOf (Path.DirectorySeparatorChar, len);
+                       if ((last == -1) || ((last == 0) && (len == 0))) {
+                               current = FullPath;
+                               parent = null;
+                       } else {
+                               current = FullPath.Substring (last + 1, len - last);
+                               if (last == 0 && !Environment.IsRunningOnWindows)
+                                       parent = Path.DirectorySeparatorStr;
+                               else
+                                       parent = FullPath.Substring (0, last);
+                               // adjust for drives, i.e. a special case for windows
+                               if (Environment.IsRunningOnWindows) {
+                                       if ((parent.Length == 2) && (parent [1] == ':') && Char.IsLetter (parent [0]))
+                                               parent += Path.DirectorySeparatorChar;
+                               }
+                       }
+               }
+
+               // properties
+
+               public override bool Exists {
+                       get {
+                               Refresh (false);
+
+                               if (stat.Attributes == MonoIO.InvalidFileAttributes)
+                                       return false;
+
+                               if ((stat.Attributes & FileAttributes.Directory) == 0)
+                                       return false;
+
+                               return true;
+                       }
+               }
+
+               public override string Name {
+                       get { return current; }
+               }
+
+               public DirectoryInfo Parent {
+                       get {
+                               if ((parent == null) || (parent.Length == 0))
+                                       return null;
+                               return new DirectoryInfo (parent);
+                       }
+               }
+
+               public DirectoryInfo Root {
+                       get {
+                               string root = Path.GetPathRoot (FullPath);
+                               if (root == null)
+                                       return null;
+
+                               return new DirectoryInfo (root);
+                       }
+               }
+
+               // creational methods
+
+               public void Create () {
+                       Directory.CreateDirectory (FullPath);
+               }
+
                public DirectoryInfo CreateSubdirectory (string name) {
                        CheckPath (name);
-                       \r
-                       string path = Path.Combine (FullPath, name);\r
-                       Directory.CreateDirectory (path);\r
-\r
-                       return new DirectoryInfo (path);\r
-               }\r
-\r
-               // directory listing methods\r
-\r
-               public FileInfo [] GetFiles () {\r
-                       return GetFiles ("*");\r
-               }\r
-\r
-               public FileInfo [] GetFiles (string pattern) {\r
-                       string [] names = Directory.GetFiles (FullPath, pattern);\r
-\r
-                       ArrayList infos = new ArrayList ();\r
-                       foreach (string name in names)\r
-                               infos.Add (new FileInfo (name));\r
-\r
-                       return (FileInfo []) infos.ToArray (typeof (FileInfo));\r
-               }\r
-\r
-               public DirectoryInfo [] GetDirectories () {\r
-                       return GetDirectories ("*");\r
-               }\r
-\r
-               public DirectoryInfo [] GetDirectories (string pattern) {\r
-                       string [] names = Directory.GetDirectories (FullPath, pattern);\r
-\r
-                       ArrayList infos = new ArrayList ();\r
-                       foreach (string name in names)\r
-                               infos.Add (new DirectoryInfo (name));\r
-\r
-                       return (DirectoryInfo []) infos.ToArray (typeof (DirectoryInfo));\r
-               }\r
-\r
-               public FileSystemInfo [] GetFileSystemInfos () {\r
-                       return GetFileSystemInfos ("*");\r
-               }\r
-\r
-               public FileSystemInfo [] GetFileSystemInfos (string pattern) {\r
-                       ArrayList infos = new ArrayList ();\r
-                       infos.AddRange (GetDirectories (pattern));\r
-                       infos.AddRange (GetFiles (pattern));\r
-\r
-                       return (FileSystemInfo []) infos.ToArray (typeof (FileSystemInfo));\r
-               }\r
-\r
-               // directory management methods\r
-\r
-               public override void Delete () {\r
-                       Delete (false);\r
-               }\r
-\r
-               public void Delete (bool recurse) {\r
-                       Directory.Delete (FullPath, recurse);\r
-               }\r
-\r
-               public void MoveTo (string dest) {\r
-                       Directory.Move (FullPath, Path.GetFullPath (dest));\r
-               }\r
-\r
-               public override string ToString () {\r
-                       return OriginalPath;\r
-               }\r
-       }\r
-}\r
+                       
+                       string path = Path.Combine (FullPath, name);
+                       Directory.CreateDirectory (path);
+
+                       return new DirectoryInfo (path);
+               }
+
+               // directory listing methods
+
+               public FileInfo [] GetFiles () {
+                       return GetFiles ("*");
+               }
+
+               public FileInfo [] GetFiles (string pattern)
+               {
+                       string [] names = Directory.GetFiles (FullPath, pattern);
+
+                       FileInfo[] infos = new FileInfo [names.Length];
+                       int i = 0;
+                       foreach (string name in names)
+                               infos [i++] = new FileInfo (name);
+
+                       return infos;
+               }
+
+               public DirectoryInfo [] GetDirectories () {
+                       return GetDirectories ("*");
+               }
+
+               public DirectoryInfo [] GetDirectories (string pattern)
+               {
+                       string [] names = Directory.GetDirectories (FullPath, pattern);
+
+                       DirectoryInfo[] infos = new DirectoryInfo [names.Length];
+                       int i = 0;
+                       foreach (string name in names)
+                               infos [i++] = new DirectoryInfo (name);
+
+                       return infos;
+               }
+
+               public FileSystemInfo [] GetFileSystemInfos () {
+                       return GetFileSystemInfos ("*");
+               }
+
+               public FileSystemInfo [] GetFileSystemInfos (string pattern)
+               {
+                       string[] dirs = Directory.GetDirectories (FullPath, pattern);
+                       string[] files = Directory.GetFiles (FullPath, pattern);
+
+                       FileSystemInfo[] infos = new FileSystemInfo [dirs.Length + files.Length];
+                       int i = 0;
+                       foreach (string dir in dirs)
+                               infos [i++] = new DirectoryInfo (dir);
+                       foreach (string file in files)
+                               infos [i++] = new FileInfo (file);
+
+                       return infos;
+               }
+
+               // directory management methods
+
+               public override void Delete () {
+                       Delete (false);
+               }
+
+               public void Delete (bool recurse) {
+                       Directory.Delete (FullPath, recurse);
+               }
+
+               public void MoveTo (string dest) {
+                       Directory.Move (FullPath, Path.GetFullPath (dest));
+               }
+
+               public override string ToString () {
+                       return OriginalPath;
+               }
+#if NET_2_0
+               // additional search methods
+
+               public DirectoryInfo[] GetDirectories (string pattern, SearchOption searchOption)
+               {
+                       switch (searchOption) {
+                       case SearchOption.TopDirectoryOnly:
+                               return GetDirectories (pattern);
+                       case SearchOption.AllDirectories:
+                               Queue workq = new Queue(GetDirectories(pattern));
+                               Queue doneq = new Queue();
+                               while (workq.Count > 0)
+                                       {
+                                               DirectoryInfo cinfo = (DirectoryInfo) workq.Dequeue();
+                                               DirectoryInfo[] cinfoDirs = cinfo.GetDirectories(pattern);
+                                               foreach (DirectoryInfo i in cinfoDirs) workq.Enqueue(i);
+                                               doneq.Enqueue(cinfo);
+                                       }
+
+                               DirectoryInfo[] infos = new DirectoryInfo[doneq.Count];
+                               doneq.CopyTo(infos, 0);
+                               return infos;
+                       default:
+                               string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
+                               throw new ArgumentOutOfRangeException ("searchOption", msg);
+                       }
+               }       
+
+               internal int GetFilesSubdirs (ArrayList l, string pattern)
+               {
+                       int count;
+                       FileInfo [] thisdir = null;
+
+                       try {
+                               thisdir = GetFiles (pattern);
+                       } catch (System.UnauthorizedAccessException){
+                               return 0;
+                       }
+                       
+                       count = thisdir.Length;
+                       l.Add (thisdir);
+
+                       foreach (DirectoryInfo subdir in GetDirectories ()){
+                               count += subdir.GetFilesSubdirs (l, pattern);
+                       }
+                       return count;
+               }
+               
+               public FileInfo[] GetFiles (string pattern, SearchOption searchOption)
+               {
+                       switch (searchOption) {
+                       case SearchOption.TopDirectoryOnly:
+                               return GetFiles (pattern);
+                       case SearchOption.AllDirectories: {
+                               ArrayList groups = new ArrayList ();
+                               int count = GetFilesSubdirs (groups, pattern);
+                               int current = 0;
+                               
+                               FileInfo [] all = new FileInfo [count];
+                               foreach (FileInfo [] p in groups){
+                                       p.CopyTo (all, current);
+                                       current += p.Length;
+                               }
+                               return all;
+                       }
+                       default:
+                               string msg = Locale.GetText ("Invalid enum value '{0}' for '{1}'.", searchOption, "SearchOption");
+                               throw new ArgumentOutOfRangeException ("searchOption", msg);
+                       }
+               }
+
+               // access control methods
+
+               [MonoTODO ("DirectorySecurity isn't implemented")]
+               public void Create (DirectorySecurity directorySecurity)
+               {
+                       if (directorySecurity != null)
+                               throw new NotImplementedException ();
+                       Create ();
+               }
+
+               [MonoTODO ("DirectorySecurity isn't implemented")]
+               public DirectoryInfo CreateSubdirectory (string name, DirectorySecurity directorySecurity)
+               {
+                       if (directorySecurity != null)
+                               throw new NotImplementedException ();
+                       return CreateSubdirectory (name);
+               }
+
+               [MonoTODO ("DirectorySecurity isn't implemented")]
+               public DirectorySecurity GetAccessControl ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO ("DirectorySecurity isn't implemented")]
+               public DirectorySecurity GetAccessControl (AccessControlSections includeSections)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO ("DirectorySecurity isn't implemented")]
+               public void SetAccessControl (DirectorySecurity directorySecurity)
+               {
+                       if (directorySecurity != null)
+                               throw new ArgumentNullException ("directorySecurity");
+                       throw new NotImplementedException ();
+               }
+#endif
+       }
+}