2002-08-01 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / class / corlib / System.IO / Directory.cs
index 855254f24cc7935d03d515b0ace50abca1960b66..a31b74adbd82e687f03bbe1ed2553526a93dae30 100644 (file)
@@ -4,6 +4,7 @@
 // Authors:\r
 //   Jim Richardson  (develop@wtfo-guru.com)\r
 //   Miguel de Icaza (miguel@ximian.com)\r
+//   Dan Lewis       (dihlewis@yahoo.co.uk)\r
 //\r
 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved\r
 // Copyright (C) 2002 Ximian, Inc.\r
 using System;\r
 using System.Security.Permissions;\r
 using System.Collections;\r
-using System.Private;\r
 \r
 namespace System.IO\r
 {\r
        public sealed class Directory : Object\r
        {\r
-\r
+               private Directory () {}
+
                public static DirectoryInfo CreateDirectory (string path)\r
-               {       \r
-                       DirectoryInfo dInfo = getInfo (path);\r
-                       if (!dInfo.Exists)\r
-                       {\r
-                               dInfo.Create ();\r
-                       }\r
-                       return dInfo;\r
+               {\r
+                       if (path == null)\r
+                               throw new ArgumentNullException ();\r
+                       if (path == "" || path.IndexOfAny (Path.InvalidPathChars) != -1)\r
+                               throw new ArgumentException ();\r
+\r
+                       if (!MonoIO.CreateDirectory (path))\r
+                               throw MonoIO.GetException ();\r
+\r
+                       return new DirectoryInfo (path);\r
                }\r
-               \r
+\r
                public static void Delete (string path)\r
-               {       \r
-                       DirectoryInfo dInfo = getInfo (path);\r
-                       if (dInfo.Exists)\r
-                               dInfo.Delete ();\r
+               {\r
+                       if (path == null)\r
+                               throw new ArgumentNullException ();\r
+                       if (path == "" || path.IndexOfAny (Path.InvalidPathChars) != -1)\r
+                               throw new ArgumentException ();\r
+\r
+                       if (!MonoIO.RemoveDirectory (path))\r
+                               throw MonoIO.GetException ();\r
+               }\r
+\r
+               static void RecursiveDelete (string path)\r
+               {\r
+                       foreach (string dir in GetDirectories (path))\r
+                               RecursiveDelete (dir);\r
+\r
+                       foreach (string file in GetFiles (path))\r
+                               File.Delete (file);\r
+\r
+                       Directory.Delete (path);\r
                }\r
                \r
-               public static void Delete (string path, bool bRecurse)\r
-               {       \r
-                       DirectoryInfo dInfo = getInfo (path);\r
-                       if (dInfo.Exists)\r
-                       {\r
-                               dInfo.Delete (bRecurse);\r
+               public static void Delete (string path, bool recurse)\r
+               {\r
+                       if (path == null)\r
+                               throw new ArgumentNullException ();\r
+                       if (path.IndexOfAny (Path.InvalidPathChars) != -1)\r
+                               throw new ArgumentException ("Path contains invalid characters");\r
+\r
+                       if (recurse == false){\r
+                               Delete (path);\r
+                               return;\r
                        }\r
+\r
+                       RecursiveDelete (path);\r
                }\r
                \r
                public static bool Exists (string path)\r
                {\r
-                       return getInfo (path).Exists;\r
+                       return MonoIO.ExistsDirectory (path);\r
+               }\r
+\r
+               public static DateTime GetLastAccessTime (string path)\r
+               {\r
+                       return File.GetLastAccessTime (path);\r
+               }\r
+               \r
+               public static DateTime GetLastWriteTime (string path)\r
+               {\r
+                       return File.GetLastWriteTime (path);\r
                }\r
                \r
                public static DateTime GetCreationTime (string path)\r
                {\r
-                       return getInfo (path).CreationTime;\r
+                       return File.GetLastWriteTime (path);\r
                }\r
                \r
                public static string GetCurrentDirectory ()\r
-               {       // Implementation complete 08/25/2001 14:24 except for\r
+               {\r
+                       /*\r
+                       // Implementation complete 08/25/2001 14:24 except for\r
                        // LAMESPEC: documentation specifies invalid exceptions (i think)\r
                        //           also shouldn't need Write to getcurrrent should we?\r
                        string str = Environment.CurrentDirectory;\r
                        CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, str);\r
-                       return str;     \r
-               }\r
-\r
-               static bool Matches (string name, string pattern)\r
-               {\r
-                       return true;\r
-               }\r
-               \r
-               internal static ArrayList GetListing (string path, string pattern)\r
-               {\r
-                       IntPtr handle = Wrapper.opendir (path);\r
-                       ArrayList list;\r
-                       string name;\r
-                       \r
-                       if (path == null)\r
-                               return null;\r
-\r
-                       list = new ArrayList ();\r
-                       while ((name = Wrapper.readdir (handle)) != null){\r
-                               if (pattern == null){\r
-                                       list.Add (name);\r
-                                       continue;\r
-                               }\r
-                               if (Matches (name, pattern))\r
-                                       list.Add (name);\r
-                       }\r
-                       Wrapper.closedir (handle);\r
-\r
-                       return list;\r
+                       */\r
+                       return Environment.CurrentDirectory;\r
                }\r
                \r
-               public static string[] GetDirectories (string path)\r
+               public static string [] GetDirectories (string path)\r
                {\r
                        return GetDirectories (path, "*");\r
                }\r
-\r
-               enum Kind {\r
-                       Files = 1,\r
-                       Dirs  = 2,\r
-                       All   = Files | Dirs\r
-               }\r
                \r
-               static string [] GetFileListing (ArrayList list, string path, Kind kind)\r
+               public static string [] GetDirectories (string path, string pattern)\r
                {\r
-                       ArrayList result_list = new ArrayList ();\r
-                       foreach (string name in list){\r
-                               string full = path + Path.DirectorySeparatorChar + name;\r
-\r
-                               unsafe {\r
-                                       stat s;\r
-                                       \r
-                                       if (Wrapper.stat (full, &s) != 0)\r
-                                               continue;\r
-\r
-                                       if ((s.st_mode & Wrapper.S_IFDIR) != 0){\r
-                                               if ((kind & Kind.Dirs) != 0)\r
-                                                       result_list.Add (full);\r
-                                       } else {\r
-                                               if ((kind & Kind.Files) != 0)\r
-                                                       result_list.Add (full);\r
-                                       }\r
-                               }\r
-                       }\r
-                       string [] names = new string [result_list.Count];\r
-                       result_list.CopyTo (names);\r
-                       return names;\r
-               }\r
-               \r
-               public static string[] GetDirectories (string path, string mask)\r
-               {\r
-                       if (path == null || mask == null)\r
-                               throw new ArgumentNullException ();\r
-                       \r
-                       ArrayList list = GetListing (path, mask);\r
-                       if (list == null)\r
-                               throw new DirectoryNotFoundException ();\r
-                       if (path.IndexOfAny (Path.InvalidPathChars) != -1)\r
-                               throw new ArgumentException ("Path contains invalid characters");\r
-\r
-                       return GetFileListing (list, path, Kind.Dirs);\r
+                       return GetFileSystemEntries (path, pattern, FileAttributes.Directory, FileAttributes.Directory);\r
                }\r
                \r
                public static string GetDirectoryRoot (string path)\r
                {\r
-                       return getInfo (path).Root.FullName;\r
+                       return "" + Path.DirectorySeparatorChar;\r
                }\r
                \r
-               public static string[] GetFiles (string path)\r
+               public static string [] GetFiles (string path)\r
                {\r
                        return GetFiles (path, "*");\r
                }\r
                \r
-               public static string[] GetFiles (string path, string mask)\r
+               public static string [] GetFiles (string path, string pattern)\r
                {\r
-                       if (path == null || mask == null)\r
-                               throw new ArgumentNullException ();\r
-                       \r
-                       ArrayList list = GetListing (path, mask);\r
-                       if (list == null)\r
-                               throw new DirectoryNotFoundException ();\r
-                       if (path.IndexOfAny (Path.InvalidPathChars) != -1)\r
-                               throw new ArgumentException ("Path contains invalid characters");\r
-\r
-                       return GetFileListing (list, path, Kind.Files);\r
+                       return GetFileSystemEntries (path, pattern, FileAttributes.Directory, 0);\r
                }\r
 \r
-               public static string[] GetFileSystemEntries (string path)\r
+               public static string [] GetFileSystemEntries (string path)\r
                {       \r
                        return GetFileSystemEntries (path, "*");\r
                }\r
 \r
-               public static string[] GetFileSystemEntries (string path, string mask)\r
+               public static string [] GetFileSystemEntries (string path, string pattern)\r
                {\r
-                       if (path == null || mask == null)\r
-                               throw new ArgumentNullException ();\r
-                       \r
-                       ArrayList list = GetListing (path, mask);\r
-                       if (list == null)\r
-                               throw new DirectoryNotFoundException ();\r
-                       if (path.IndexOfAny (Path.InvalidPathChars) != -1)\r
-                               throw new ArgumentException ("Path contains invalid characters");\r
-\r
-                       return GetFileListing (list, path, Kind.All);\r
+                       return GetFileSystemEntries (path, pattern, 0, 0);\r
                }\r
                \r
-               public static DateTime GetLastAccessTime (string path)\r
-               {\r
-                       return getInfo (path).LastAccessTime;\r
-               }\r
-               \r
-               public static DateTime GetLastWriteTime (string path)\r
-               {\r
-                       return getInfo (path).LastWriteTime;\r
-               }\r
-               \r
-               [MonoTODO]\r
                public static string[] GetLogicalDrives ()\r
-               {       // TODO: Implement\r
-                       return null;\r
+               {       \r
+                       return new string [] { "A:\\", "C:\\" };\r
                }\r
 \r
-               [MonoTODO]\r
                public static DirectoryInfo GetParent (string path)\r
-               {       // TODO: Implement\r
-                       return null;\r
+               {\r
+                       return new DirectoryInfo (Path.GetDirectoryName (path));\r
                }\r
 \r
-               public static void Move (string src, string dst)\r
+               public static void Move (string src, string dest)\r
                {\r
-                        getInfo (src).MoveTo (dst);\r
+                       File.Move (src, dest);\r
                }\r
-               \r
-               public static void SetCreationTime (string path, DateTime creationTime)\r
+\r
+               public static void SetCreationTime (string path, DateTime creation_time)\r
                {\r
-                       getInfo (path).CreationTime = creationTime;\r
+                       File.SetCreationTime (path, creation_time);\r
                }\r
                \r
                public static void SetCurrentDirectory (string path)\r
-               {       // Implementation complete 08/25/2001 14:24 except for\r
+               {\r
+                       /*\r
+                       // Implementation complete 08/25/2001 14:24 except for\r
                        // LAMESPEC: documentation specifies invalid exceptions IOException (i think)\r
                        CheckArgument.Path (path, true);\r
                        CheckPermission.Demand (FileIOPermissionAccess.Read & FileIOPermissionAccess.Write, path);      \r
+                       */\r
                        if (!Exists (path))\r
                        {\r
                                throw new DirectoryNotFoundException ("Directory \"" + path + "\" not found.");\r
                        }\r
                        Environment.CurrentDirectory = path;\r
                }\r
-               \r
-               public static void SetLastAccessTime (string path, DateTime accessTime)\r
-               {\r
-                       getInfo (path).LastAccessTime = accessTime;\r
-               }\r
-               \r
-               public static void SetLastWriteTime (string path, DateTime modifiedTime)\r
+\r
+               public static void SetLastAccessTime (string path, DateTime last_access_time)\r
                {\r
-                       getInfo (path).LastWriteTime = modifiedTime;\r
+                       File.SetLastAccessTime (path, last_access_time);\r
                }\r
                \r
-               private static DirectoryInfo getInfo (string path)\r
+               public static void SetLastWriteTime (string path, DateTime last_write_time)\r
                {\r
-                       return new DirectoryInfo (path);\r
+                       File.SetLastWriteTime (path, last_write_time);\r
                }\r
                \r
-               private static string[] getNames (FileSystemInfo[] arInfo)\r
+               // private\r
+\r
+               private static string [] GetFileSystemEntries (string path, string pattern, FileAttributes mask, FileAttributes attrs)\r
                {\r
-                       int index = 0;\r
-                       string[] ar = new string[arInfo.Length];\r
-                                               \r
-                       foreach (FileInfo fi in arInfo)\r
-                       {\r
-                               ar[index++] = fi.FullName;\r
+                       SearchPattern search;\r
+                       MonoIOStat stat;\r
+                       IntPtr find;\r
+\r
+                       if (path.IndexOfAny (Path.InvalidPathChars) != -1)\r
+                               throw new ArgumentException ("Path contains invalid characters.");\r
+\r
+                       if (!Directory.Exists (path))
+                               throw new DirectoryNotFoundException ("Directory '" + path + "' not found.");
+
+                       search = new SearchPattern (pattern);\r
+\r
+                       find = MonoIO.FindFirstFile (Path.Combine (path , "*"), out stat);\r
+                       if (find == MonoIO.InvalidHandle) {\r
+                               switch (MonoIO.GetLastError ()) {\r
+                               case MonoIOError.ERROR_FILE_NOT_FOUND:\r
+                               case MonoIOError.ERROR_PATH_NOT_FOUND:\r
+                                       string message = String.Format ("Could not find a part of the path \"{0}\"", path);\r
+                                       throw new DirectoryNotFoundException (message);\r
+                               case MonoIOError.ERROR_NO_MORE_FILES:
+                                       return new string [0];
+\r
+                               default:\r
+                                       throw MonoIO.GetException (path);\r
+                               }\r
                        }\r
-                       return ar;\r
+                       \r
+                       ArrayList entries = new ArrayList ();\r
+\r
+                       while (true) {\r
+                               // Ignore entries of "." and ".." -
+                               // the documentation doesn't mention
+                               // it (surprise!) but empirical
+                               // testing indicates .net never
+                               // returns "." or ".." in a
+                               // GetDirectories() list.
+                               if ((stat.Attributes & mask) == attrs &&
+                                   search.IsMatch (stat.Name) &&
+                                   stat.Name != "." &&
+                                   stat.Name != "..")\r
+                                       entries.Add (Path.Combine (path, stat.Name));\r
+\r
+                               if (!MonoIO.FindNextFile (find, out stat))\r
+                                       break;\r
+                       }\r
+                       MonoIO.FindClose (find);\r
+\r
+                       return (string []) entries.ToArray (typeof (string));\r
                }\r
        }\r
 }\r