+2007-02-13 Boris Kirzner <borisk@mainsoft.com>
+
+ * Directory.cs: small fixes in path handling.
+ * DirectorYInfo.cs: fix CreateSubdirectory and MoveTo.
+ * File.cs: fixed negative flows in Copy
+ * Path.cs: fixed InvalidPathChars order, fixed handling of spaces
+ and wildcards, fixed negative flows in windows environment.
+
+
2007-01-31 Gert Driesen <drieseng@users.sourceforge.net>
* StreamReader.cs: Removed checks for non-existing directory or file,
if (path == null)
throw new ArgumentNullException ("path");
+ path = path.TrimEnd ();
+
if (path == "")
throw new ArgumentException ("Path is empty");
if (path.IndexOfAny (Path.InvalidPathChars) != -1)
throw new ArgumentException ("Path contains invalid chars");
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("Only blank characters in path");
-
#if NET_2_0
if (File.Exists(path))
throw new IOException ("Cannot create " + path + " because a file with the same name already exists.");
if (info.Parent != null && !info.Parent.Exists)
info.Parent.Create ();
+ path = Path.GetFullPath (path);
+
MonoIOError error;
if (!MonoIO.CreateDirectory (path, out error)) {
// LAMESPEC: 1.1 and 1.2alpha allow CreateDirectory on a file path.
public static bool Exists (string path)
{
- if (path == null)
+ if (path == null || path.Trim ().Length == 0)
return false;
MonoIOError error;
public DirectoryInfo CreateSubdirectory (string name) {
CheckPath (name);
+ if (Path.IsPathRooted (name))
+ throw new ArgumentException ();
+
+ if (Environment.IsRunningOnWindows)
+ if (name.IndexOf (':') != -1)
+ throw new NotSupportedException ("The given path's format is not supported.");
+
string path = Path.Combine (FullPath, name);
+
+ string subdirectoryPath = Path.GetFullPath (path);
+
+ if (!subdirectoryPath.StartsWith (FullPath))
+ throw new ArgumentException (String.Format ("The directory specified, '{0}', is not a subdirectory of '{1}'.", name, FullPath));
+
Directory.CreateDirectory (path);
return new DirectoryInfo (path);
public void MoveTo (string dest) {
Directory.Move (FullPath, Path.GetFullPath (dest));
+ this.FullPath = Path.GetFullPath (dest);
}
public override string ToString () {
throw new ArgumentNullException ("src");
if (dest == null)
throw new ArgumentNullException ("dest");
- if (src.Trim () == "" || src.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException (Locale.GetText ("src is null"));
- if (dest.Trim () == "" || dest.IndexOfAny (Path.InvalidPathChars) != -1)
- throw new ArgumentException (Locale.GetText ("dest is empty or contains invalid characters"));
+ if (src.Trim () == "" || src.IndexOfAny (Path.InvalidPathChars) != -1
+ || src.IndexOfAny (Path.WildcardChars) != -1)
+ throw new ArgumentException (Locale.GetText ("Illegal characters in path"));
+ if (dest.Trim () == "" || dest.IndexOfAny (Path.InvalidPathChars) != -1
+ || dest.IndexOfAny (Path.WildcardChars) != -1)
+ throw new ArgumentException (Locale.GetText ("Illegal characters in path"));
if (!Exists (src))
throw new FileNotFoundException (Locale.GetText ("{0} does not exist", src), src);
throw new ArgumentException(Locale.GetText ("{0} is a directory", src));
}
- if (Exists (dest)) {
- if ((GetAttributes(dest) & FileAttributes.Directory) == FileAttributes.Directory){
- throw new ArgumentException (Locale.GetText ("{0} is a directory", dest));
- }
- if (!overwrite)
- throw new IOException (Locale.GetText ("{0} already exists", dest));
- }
+ if (Directory.Exists (dest))
+ //LAMESPEC: MSDN claims ArgumentException, but IOException is actually thrown
+ throw new IOException (Locale.GetText ("The target file \'{0}\' is a directory, not a file.", dest));
+
+ if (!overwrite && File.Exists (dest))
+ throw new IOException (Locale.GetText ("The file \'{0}\' already exists.", dest));
string DirName = Path.GetDirectoryName(dest);
if (DirName != String.Empty && !Directory.Exists (DirName))
private static readonly char[] PathSeparatorChars;
private static readonly bool dirEqualsVolume;
+ internal static char [] WildcardChars;
+ internal static char [] SpaceChars;
// class methods
public static string ChangeExtension (string path, string extension)
{
- if (path == null)
- return null;
+ if (path == null || path == String.Empty)
+ return path;
if (path.IndexOfAny (InvalidPathChars) != -1)
throw new ArgumentException ("Illegal characters in path", "path");
public static string GetExtension (string path)
{
- if (path == null)
- return null;
+ if (path == null || path == String.Empty)
+ return path;
if (path.IndexOfAny (InvalidPathChars) != -1)
throw new ArgumentException ("Illegal characters in path", "path");
public static string GetFullPath (string path)
{
- string fullpath = InsecureGetFullPath (path);
+ if (path == null)
+ throw new ArgumentNullException ("path");
+
+ if (Environment.IsRunningOnWindows)
+ if (path.Length > 256)
+ throw new PathTooLongException (
+ "The specified path, file name, or both are too long.After full qualification,"
+ + " each must be less than 260 characters.");
+
+ if (path.IndexOfAny (WildcardChars) != -1)
+ throw new ArgumentException (Environment.GetResourceString ("Argument_InvalidPathChars"));
+
+ string fullpath = InsecureGetFullPath (path.TrimEnd());
if (SecurityManager.SecurityEnabled) {
new FileIOPermission (FileIOPermissionAccess.PathDiscovery, fullpath).Demand ();
}
throw new ArgumentException (msg, "path");
}
+ if (Environment.IsRunningOnWindows) {
+ if (path.StartsWith (":"))
+ throw new ArgumentException ("The path is not in legal form");
+
+ if (IsPathRooted(path)) {
+ int rootLength = GetPathRoot (path).Length;
+ if ((path.Length > rootLength) && (path.Substring (rootLength).IndexOf (':') != -1))
+ throw new ArgumentException ("The path is not in legal form");
+ }
+ else if (path.IndexOf (':') != -1)
+ throw new NotSupportedException ("The given path's format is not supported.");
+ }
+
// adjust for drives, i.e. a special case for windows
if (Environment.IsRunningOnWindows)
path = WindowsDriveAdjustment (path);
public static bool IsPathRooted (string path)
{
- if (path == null || path.Length == 0)
+ if (path == null)
+ return false;
+
+ path = path.Trim (SpaceChars);
+
+ if (path.Length == 0)
return false;
if (path.IndexOfAny (InvalidPathChars) != -1)
{
// return a new array as we do not want anyone to be able to change the values
if (Environment.IsRunningOnWindows) {
- return new char [36] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
+ return new char [36] { '\x22', '\x3C', '\x3E', '\x7C', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12',
'\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D',
- '\x1E', '\x1F', '\x22', '\x3C', '\x3E', '\x7C' };
+ '\x1E', '\x1F' };
} else {
return new char [1] { '\x00' };
}
}
#endif
// internal fields
+ WildcardChars = new char [] { '*', '?' };
+ SpaceChars = new char [] { ' ' };
DirectorySeparatorStr = DirectorySeparatorChar.ToString ();
PathSeparatorChars = new char [] {
+2007-02-13 Boris Kirzner <borisk@mainsoft.com>
+ * DirectoryInfoTest.cs: added negative flow tests, some are
+ windows-specific.
+ * DirectoryTest.cs: added tests, some are windows-specific.
+ * FileTest.cs: added negative tests.
+ * PathTest.cs: added invalid chars order test, negative tests,
+ windows-specific tests.
+
2007-01-31 Gert Driesen <drieseng@users.sourceforge.net>
* FileStreamTest.cs: Added and improved tests to verify whether the
static readonly char DSC = Path.DirectorySeparatorChar;
string current;
+ static OsType OS;\r
+\r
+ bool Windows
+ {
+ get {
+ return OS == OsType.Windows;
+ }
+ }
[SetUp]
protected void SetUp ()
if (Directory.Exists (TempFolder))
Directory.Delete (TempFolder, true);
Directory.CreateDirectory (TempFolder);
+
+ if ('/' == DSC) {
+ OS = OsType.Unix;
+ } else if ('\\' == DSC) {
+ OS = OsType.Windows;
+ } else {
+ OS = OsType.Mac;
+ //FIXME: For Mac. figure this out when we need it
+ }
}
[TearDown]
public void CreateSubdirectoryEmptyString ()
{
new DirectoryInfo (".").CreateSubdirectory ("");
+ }\r
+\r
+ [Test]\r
+ [ExpectedException (typeof (ArgumentException))]\r
+ public void CreateSubdirectory_ArgumentException1 ()\r
+ {\r
+ string path = TempFolder + DSC + "DIT.CreateSubdirectory.Test";\r
+ string fullsubpath = Path.GetFullPath (path + DSC + "Subdir");\r
+ DirectoryInfo info = new DirectoryInfo (path);\r
+\r
+ info.CreateSubdirectory (fullsubpath);\r
+ }\r
+\r
+ [Test]\r
+ [ExpectedException (typeof (ArgumentException))]\r
+ public void CreateSubdirectory_ArgumentException2 ()\r
+ {\r
+ string path = TempFolder + DSC + "DIT.CreateSubdirectory.Test";\r
+ string subpath = ".." + DSC + "Subdir";\r
+ DirectoryInfo info = new DirectoryInfo (path);\r
+\r
+ info.CreateSubdirectory (subpath);\r
+ }\r
+\r
+ [Test]\r
+ public void CreateSubdirectory_NotSupportedException ()\r
+ {\r
+ if (Windows) {\r
+ string path = TempFolder + DSC + "DIT.CreateSubdirectory.Test";\r
+ string subpath = "Sub:dir";\r
+ DirectoryInfo info = new DirectoryInfo (path);\r
+\r
+ try {\r
+ info.CreateSubdirectory (subpath);\r
+ Fail ("Path containing ':' is not legal on Windows");\r
+ }\r
+ catch (NotSupportedException e) { }\r
+ }\r
}
[Test]
DeleteDir (path1);
DeleteDir (path2);
}
- }
+ }\r
+\r
+ [Test]\r
+ public void MoveTo2 ()\r
+ {\r
+ string path1 = TempFolder + DSC + "DIT.MoveTo.Soucre.Test";\r
+ string path2 = TempFolder + DSC + "DIT.MoveTo.Dest.Test" + DSC;\r
+ DeleteDir (path1);\r
+ DeleteDir (path2);\r
+\r
+ try {\r
+ DirectoryInfo info1 = Directory.CreateDirectory (path1);\r
+\r
+ info1.MoveTo (path2);\r
+ AssertEquals ("#01", path2, info1.FullName);\r
+ }\r
+ finally {\r
+ DeleteDir (path1);\r
+ DeleteDir (path2);\r
+ }\r
+ }
[Test]
[ExpectedException (typeof (ArgumentNullException))]
{\r
string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.IO.Tests");\r
static readonly char DSC = Path.DirectorySeparatorChar;\r
+ static OsType OS;\r
+\r
+ bool Windows\r
+ {\r
+ get {\r
+ return OS == OsType.Windows;\r
+ }\r
+ }\r
\r
[SetUp]\r
public void SetUp ()\r
Directory.CreateDirectory (TempFolder);\r
\r
Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");\r
+\r
+ if ('/' == DSC) {\r
+ OS = OsType.Unix;\r
+ } else if ('\\' == DSC) {\r
+ OS = OsType.Windows;\r
+ } else {\r
+ OS = OsType.Mac;\r
+ //FIXME: For Mac. figure this out when we need it\r
+ }\r
}\r
\r
[TearDown]\r
[Test]\r
public void CreateDirectoryNotSupportedException ()\r
{\r
- DeleteDirectory (":");\r
- try {\r
- DirectoryInfo info = Directory.CreateDirectory (":");\r
- Assert.Fail ();\r
- } catch (ArgumentException) {\r
+ if (Windows) {\r
+ try {\r
+ DirectoryInfo info = Directory.CreateDirectory ("aa:");\r
+ Assert.Fail ("Path containing ':' is not legal on Windows");\r
+ }\r
+ catch (NotSupportedException) { }\r
+ }\r
+ }\r
+\r
+ [Test]\r
+ public void CreateDirectoryPathTooLongException ()\r
+ {\r
+ if (Windows) {\r
+ string path = TempFolder + DSC;\r
+ for (int i = 0; i < 280; i++)\r
+ path = path + "a";\r
+\r
+ try {\r
+ Directory.CreateDirectory (path);\r
+ Assert.Fail ("Path longer than 256 chars is not legal on Windows");\r
+ }\r
+ catch (PathTooLongException e) { }\r
}\r
- DeleteDirectory (":");\r
}\r
\r
[Test]\r
string path = TempFolder + DSC + "DirectoryTest.Test";\r
DeleteDirectory (path);\r
try {\r
- path += Path.InvalidPathChars [0];\r
+ path += '\x00';\r
path += ".2";\r
DirectoryInfo info = Directory.CreateDirectory (path);\r
} finally {\r
}\r
}\r
\r
+ [Test]\r
+ [ExpectedException (typeof (ArgumentException))]\r
+ public void CreateDirectoryArgumentException4 ()\r
+ {\r
+ string path = TempFolder + DSC + "DirectoryTest.Test";\r
+ DirectoryInfo info = Directory.CreateDirectory ("\t\t\t " + path);\r
+ }\r
+\r
+ [Test]\r
+ public void CreateDirectory2 ()\r
+ {\r
+ string path = TempFolder + DSC + "DirectoryTest.Test";\r
+ DeleteDirectory (path);\r
+\r
+ DirectoryInfo info = Directory.CreateDirectory (path + "\t\t\t ");\r
+ Assert.IsTrue (info.Exists, "#1");\r
+ DeleteDirectory (path);\r
+ }\r
+\r
[Test]\r
public void CreateDirectoryAlreadyExists ()\r
{\r
File.Copy ("a", " ");
}
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CopyArgumentException5 ()
+ {
+ File.Copy ("a*", "b");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CopyArgumentException6 ()
+ {
+ File.Copy ("a?", "b");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CopyArgumentException7 ()
+ {
+ File.Copy ("a", "b*");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CopyArgumentException8 ()
+ {
+ File.Copy ("a", "b?");
+ }
+
+ [Test]
+ [ExpectedException (typeof (IOException))]
+ public void CopyIOException2 ()
+ {
+ string dirpath = TempFolder + Path.DirectorySeparatorChar + "dir";
+ string filepath = TempFolder + Path.DirectorySeparatorChar + "file.txt";
+
+ try {
+ Directory.CreateDirectory (dirpath);
+ File.WriteAllText (filepath, "xxx");
+
+ File.Copy (filepath, dirpath);
+ }
+ finally {
+ DeleteFile (filepath);
+ DeleteDirectory (dirpath);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (IOException))]
+ public void CopyIOException3 ()
+ {
+ string filepath1 = TempFolder + Path.DirectorySeparatorChar + "file1.txt";
+ string filepath2 = TempFolder + Path.DirectorySeparatorChar + "file2.txt";
+
+ try {
+ File.WriteAllText (filepath1, "xxx");
+ File.WriteAllText (filepath2, "yyy");
+
+ File.Copy (filepath1, filepath2);
+ }
+ finally {
+ DeleteFile (filepath1);
+ DeleteDirectory (filepath2);
+ }
+ }
+
[Test]
[ExpectedException(typeof(FileNotFoundException))]
public void CopyFileNotFoundException ()
if (File.Exists (path))
File.Delete (path);
}
+
+ private void DeleteDirectory (string path)
+ {
+ if (Directory.Exists (path))
+ Directory.Delete (path);
+ }
}
}
}
}
+ [Test]
+ public void GetInvalidPathChars_Order()
+ {
+ if (Windows) {
+ char [] invalid = Path.GetInvalidPathChars ();
+ char [] expected = new char [36] { '\x22', '\x3C', '\x3E', '\x7C', '\x00', '\x01', '\x02',
+ '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D',
+ '\x0E', '\x0F', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18',
+ '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F' };
+ AssertEquals (expected.Length, invalid.Length);
+ for (int i = 0; i < expected.Length; i++ ) {
+ AssertEquals( "Character at position " + i,expected [i], invalid [i]);
+ }
+ }
+ }
+
[Test]
public void GetInvalidPathChars_Modify ()
{
Assert (i.ToString (), Array.IndexOf (invalid, s[i]) == -1);
}
}
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void GetFullPath_ArgumentException1 ()
+ {
+ Path.GetFullPath ("aa*");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void GetFullPath_ArgumentException2 ()
+ {
+ Path.GetFullPath ("aa?");
+ }
+
+ [Test]
+ public void GetFullPath_ArgumentException3 ()
+ {
+ if (Windows) {
+ try {
+ Path.GetFullPath (":aa");
+ Fail ("Path containing ':' is not legal on Windows");
+ }
+ catch (ArgumentException e) { }
+ }
+ }
+
+ [Test]
+ public void GetFullPath_ArgumentException4 ()
+ {
+ if (Windows) {
+ try {
+ Path.GetFullPath ("C:\\Temp\aa:");
+ Fail ("Path containing ':' is not legal on Windows");
+ }
+ catch (ArgumentException e) { }
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void GetFullPath_ArgumentException5 ()
+ {
+ try {
+ Path.GetFullPath (" aa \t \n");
+ }
+ catch (Exception e) {
+ Fail ("Path should be trimmed from the end.");
+ }
+ Path.GetFullPath (" \t aa ");
+ }
+
+ [Test]
+ public void GetFullPath_NotSupportedException ()
+ {
+ if (Windows) {
+ try {
+ Path.GetFullPath ("aa:");
+ Fail ("Path containing ':' is not legal on Windows");
+ }
+ catch (NotSupportedException e) { }
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentNullException))]
+ public void GetFullPath_ArgumentNullException ()
+ {
+ Path.GetFullPath (null);
+ }
+
+ [Test]
+ public void GetFullPath_PathTooLongException ()
+ {
+ string path = "";
+ for (int i = 0; i < 280; i++)
+ path = path + "a";
+
+ if (Windows) {
+ try {
+ Path.GetFullPath (path);
+ Fail ("Path longer than 256 chars is not legal on Windows");
+ }
+ catch (PathTooLongException e) { }
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void IsPathRooted_ArgumentException1 ()
+ {
+ try {
+ Path.IsPathRooted (" aa ");
+ }
+ catch (Exception e) {
+ Fail ("Spaces in path should be trimmed.");
+ }
+ Path.IsPathRooted (" \t aa ");
+ }
#endif
}
}