Author: jonpryor
Date: 2005-03-28 12:28:54 -0500 (Mon, 28 Mar 2005)
New Revision: 42310

Added:
   trunk/mcs/class/Mono.Posix/Test/Mono.Unix/StdioFileStreamTest.cs
Modified:
   trunk/mcs/class/Mono.Posix/ChangeLog
   trunk/mcs/class/Mono.Posix/Mono.Posix_test.dll.sources
   trunk/mcs/class/Mono.Posix/Mono.Unix/ChangeLog
   trunk/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs
   trunk/mcs/class/Mono.Posix/Mono.Unix/UnixConvert.cs
   trunk/mcs/class/Mono.Posix/Test/Mono.Unix/ChangeLog
Log:
  * Mono.Posix_test.dll.sources: Added Test/Mono.Unix/StdioFileStreamTest.cs.
  * Mono.Unix/UnixConvert.cs: Add ToFopenMode() methods, which convert 
    FileMode/FileAccess into an fopen(3) mode string.  ToOpenFlags() should 
    throw ArgumentOutOfRangeException for argument violations.
  * Mono.Unix/StdioFileStream.cs: Add constructor overloads accepting filename 
    and FileMode/FileAccess overloads; Compatibility fixes with regression 
tests;
    remove IDisposable implementation since System.IO.Stream already
    implements it (which calls Close() for us).
  * Test/Mono.Unix/StdioFileStreamTest.cs: Added; based on 
    MonoTests.System.IO.FileStreamTest.


Modified: trunk/mcs/class/Mono.Posix/ChangeLog
===================================================================
--- trunk/mcs/class/Mono.Posix/ChangeLog        2005-03-28 16:46:23 UTC (rev 
42309)
+++ trunk/mcs/class/Mono.Posix/ChangeLog        2005-03-28 17:28:54 UTC (rev 
42310)
@@ -1,3 +1,7 @@
+2005-02-28  Jonathan Pryor  <[EMAIL PROTECTED]>
+
+       * Mono.Posix_test.dll.sources: Added 
Test/Mono.Unix/StdioFileStreamTest.cs.
+
 2005-01-13  Jonathan Pryor  <[EMAIL PROTECTED]>
 
        * Mono.Posix_test.dll.sources: Added Test/Mono.Unix/StdlibTest.cs.

Modified: trunk/mcs/class/Mono.Posix/Mono.Posix_test.dll.sources
===================================================================
--- trunk/mcs/class/Mono.Posix/Mono.Posix_test.dll.sources      2005-03-28 
16:46:23 UTC (rev 42309)
+++ trunk/mcs/class/Mono.Posix/Mono.Posix_test.dll.sources      2005-03-28 
17:28:54 UTC (rev 42310)
@@ -1,3 +1,4 @@
+Mono.Unix/StdioFileStreamTest.cs
 Mono.Unix/StdlibTest.cs
 Mono.Unix/UnixUserTest.cs
 Mono.Unix/UnixGroupTest.cs

Modified: trunk/mcs/class/Mono.Posix/Mono.Unix/ChangeLog
===================================================================
--- trunk/mcs/class/Mono.Posix/Mono.Unix/ChangeLog      2005-03-28 16:46:23 UTC 
(rev 42309)
+++ trunk/mcs/class/Mono.Posix/Mono.Unix/ChangeLog      2005-03-28 17:28:54 UTC 
(rev 42310)
@@ -1,3 +1,13 @@
+2005-03-28  Jonathan Pryor <[EMAIL PROTECTED]>
+
+       * UnixConvert.cs: Add ToFopenMode() methods, which convert 
FileMode/FileAccess
+         into an fopen(3) mode string.  ToOpenFlags() should throw
+         ArgumentOutOfRangeException for argument violations.
+       * StdioFileStream.cs: Add constructor overloads accepting filename and
+         FileMode/FileAccess overloads; Compatibility fixes with regression 
tests;
+         remove IDisposable implementation since System.IO.Stream already
+         implements it (which calls Close() for us).
+
 2005-03-17  Jonathan Pryor <[EMAIL PROTECTED]>
 
        * Stdlib.cs: Move Errno-related functionality into Stdlib from Syscall,

Modified: trunk/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs
===================================================================
--- trunk/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs     2005-03-28 
16:46:23 UTC (rev 42309)
+++ trunk/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs     2005-03-28 
17:28:54 UTC (rev 42310)
@@ -34,7 +34,7 @@
 
 namespace Mono.Unix {
 
-       public class StdioFileStream : Stream, IDisposable
+       public class StdioFileStream : Stream
        {
                public static readonly IntPtr InvalidFileStream  = IntPtr.Zero;
                public static readonly IntPtr StandardInput  = Stdlib.stdin;
@@ -46,24 +46,137 @@
 
                public StdioFileStream (IntPtr fileStream, bool ownsHandle)
                {
+                       InitStream (fileStream, ownsHandle);
+               }
+
+               public StdioFileStream (IntPtr fileStream, FileAccess access)
+                       : this (fileStream, access, true) {}
+
+               public StdioFileStream (IntPtr fileStream, FileAccess access, 
bool ownsHandle)
+               {
+                       InitStream (fileStream, ownsHandle);
+                       InitCanReadWrite (access);
+               }
+
+               public StdioFileStream (string path)
+               {
+                       InitStream (Fopen (path, "r"), true);
+               }
+
+               public StdioFileStream (string path, string mode)
+               {
+                       InitStream (Fopen (path, mode), true);
+               }
+
+               public StdioFileStream (string path, FileMode mode)
+               {
+                       InitStream (Fopen (path, ToFopenMode (path, mode)), 
true);
+               }
+
+               public StdioFileStream (string path, FileAccess access)
+               {
+                       InitStream (Fopen (path, ToFopenMode (path, access)), 
true);
+                       InitCanReadWrite (access);
+               }
+
+               public StdioFileStream (string path, FileMode mode, FileAccess 
access)
+               {
+                       InitStream (Fopen (path, ToFopenMode (path, mode, 
access)), true);
+                       InitCanReadWrite (access);
+               }
+
+               private static IntPtr Fopen (string path, string mode)
+               {
+                       if (path == null)
+                               throw new ArgumentNullException ("path");
+                       if (path.Length == 0)
+                               throw new ArgumentException ("path");
+                       if (mode == null)
+                               throw new ArgumentNullException ("path");
+                       IntPtr f = Stdlib.fopen (path, mode);
+                       if (f == IntPtr.Zero)
+                               throw new DirectoryNotFoundException ("path", 
+                                               
UnixMarshal.CreateExceptionForLastError ());
+                       return f;
+               }
+
+               private void InitStream (IntPtr fileStream, bool ownsHandle)
+               {
                        if (InvalidFileStream == fileStream)
                                throw new ArgumentException (Locale.GetText 
("Invalid file stream"), "fileStream");
                        
                        this.file = fileStream;
                        this.owner = ownsHandle;
                        
-                       long offset = Stdlib.fseek (file, 0, 
SeekFlags.SEEK_CUR);
-                       if (offset != -1)
-                               canSeek = true;
-                       Stdlib.fread (IntPtr.Zero, 0, 0, file);
-                       if (Stdlib.ferror (file) == 0)
-                               canRead = true;
-                       Stdlib.fwrite (IntPtr.Zero, 0, 0, file);
-                       if (Stdlib.ferror (file) == 0)
-                               canWrite = true;  
-                       Stdlib.clearerr (file);
+                       try {
+                               long offset = Stdlib.fseek (file, 0, 
SeekFlags.SEEK_CUR);
+                               if (offset != -1)
+                                       canSeek = true;
+                               Stdlib.fread (IntPtr.Zero, 0, 0, file);
+                               if (Stdlib.ferror (file) == 0)
+                                       canRead = true;
+                               Stdlib.fwrite (IntPtr.Zero, 0, 0, file);
+                               if (Stdlib.ferror (file) == 0)
+                                       canWrite = true;  
+                               Stdlib.clearerr (file);
+                       }
+                       catch (Exception e) {
+                               throw new ArgumentException (Locale.GetText 
("Invalid file stream"), "fileStream");
+                       }
                }
 
+               private void InitCanReadWrite (FileAccess access)
+               {
+                       canRead = canRead && 
+                               (access == FileAccess.Read || access == 
FileAccess.ReadWrite);
+                       canWrite = canWrite &&
+                               (access == FileAccess.Write || access == 
FileAccess.ReadWrite);
+               }
+
+               private static string ToFopenMode (string file, FileMode mode)
+               {
+                       string cmode = UnixConvert.ToFopenMode (mode);
+                       AssertFileMode (file, mode);
+                       return cmode;
+               }
+
+               private static string ToFopenMode (string file, FileAccess 
access)
+               {
+                       return UnixConvert.ToFopenMode (access);
+               }
+
+               private static string ToFopenMode (string file, FileMode mode, 
FileAccess access)
+               {
+                       string cmode = UnixConvert.ToFopenMode (mode, access);
+                       bool exists = AssertFileMode (file, mode);
+                       // HACK: for open-or-create & read, mode is "rb", which 
doesn't create
+                       // files.  If the file doesn't exist, we need to use 
"w+b" to ensure
+                       // file creation.
+                       if (mode == FileMode.OpenOrCreate && access == 
FileAccess.Read && !exists)
+                               cmode = "w+b";
+                       return cmode;
+               }
+
+               private static bool AssertFileMode (string file, FileMode mode)
+               {
+                       bool exists = FileExists (file);
+                       if (mode == FileMode.CreateNew && exists)
+                               throw new IOException ("File exists and 
FileMode.CreateNew specified");
+                       if ((mode == FileMode.Open || mode == 
FileMode.Truncate) && !exists)
+                               throw new FileNotFoundException ("File doesn't 
exist and FileMode.Open specified", file);
+                       return exists;
+               }
+
+               private static bool FileExists (string file)
+               {
+                       bool found = false;
+                       IntPtr f = Stdlib.fopen (file, "r");
+                       found = f != IntPtr.Zero;
+                       if (f != IntPtr.Zero)
+                               Stdlib.fclose (f);
+                       return found;
+               }
+
                private void AssertNotDisposed ()
                {
                        if (file == InvalidFileStream)
@@ -71,7 +184,7 @@
                }
 
                public IntPtr Handle {
-                       get {return file;}
+                       get {AssertNotDisposed (); return file;}
                }
 
                public override bool CanRead {
@@ -119,18 +232,21 @@
                                return (long) pos;
                        }
                        set {
+                               AssertNotDisposed ();
                                Seek (value, SeekOrigin.Begin);
                        }
                }
 
                public FilePosition FilePosition {
                        get {
+                               AssertNotDisposed ();
                                FilePosition pos = new FilePosition ();
                                int r = Stdlib.fgetpos (file, pos);
                                UnixMarshal.ThrowExceptionForLastErrorIf (r);
                                return pos;
                        }
                        set {
+                               AssertNotDisposed ();
                                if (value == null)
                                        throw new ArgumentNullException 
("value");
                                int r = Stdlib.fsetpos (file, value);
@@ -140,6 +256,7 @@
 
                public override void Flush ()
                {
+                       AssertNotDisposed ();
                        int r = Stdlib.fflush (file);
                        if (r != 0)
                                UnixMarshal.ThrowExceptionForLastError ();
@@ -157,8 +274,6 @@
                                r = Stdlib.fread (buf, 1, (ulong) count, file);
                        }
                        if (r != (ulong) count) {
-                               if (Stdlib.feof (file) != 0)
-                                       throw new EndOfStreamException ();
                                if (Stdlib.ferror (file) != 0)
                                        throw new IOException ();
                        }
@@ -181,6 +296,7 @@
 
                public void Rewind ()
                {
+                       AssertNotDisposed ();
                        Stdlib.rewind (file);
                }
 
@@ -195,15 +311,18 @@
                                case SeekOrigin.Begin:   sf = 
SeekFlags.SEEK_SET; break;
                                case SeekOrigin.Current: sf = 
SeekFlags.SEEK_CUR; break;
                                case SeekOrigin.End:     sf = 
SeekFlags.SEEK_END; break;
+                               default: throw new ArgumentException ("origin");
                        }
 
                        int r = Stdlib.fseek (file, offset, sf);
                        if (r != 0)
-                               UnixMarshal.ThrowExceptionForLastError ();
+                               throw new IOException ("Unable to seek",
+                                               
UnixMarshal.CreateExceptionForLastError ());
 
                        long pos = Stdlib.ftell (file);
                        if (pos == -1)
-                               UnixMarshal.ThrowExceptionForLastError ();
+                               throw new IOException ("Unable to get current 
file position",
+                                               
UnixMarshal.CreateExceptionForLastError ());
 
                        return pos;
                }
@@ -237,23 +356,21 @@
                {
                        if (file == InvalidFileStream)
                                return;
+
+                       GC.SuppressFinalize (this);
                                
                        Flush ();
-                       int r = Stdlib.fclose (file);
-                       if (r != 0)
-                               UnixMarshal.ThrowExceptionForLastError ();
+                       if (owner) {
+                               int r = Stdlib.fclose (file);
+                               if (r != 0)
+                                       UnixMarshal.ThrowExceptionForLastError 
();
+                       }
                        file = InvalidFileStream;
+                       canRead = false;
+                       canSeek = false;
+                       canWrite = false;
                }
                
-               void IDisposable.Dispose ()
-               {
-                       AssertNotDisposed ();
-                       GC.SuppressFinalize (this);
-                       if (owner) {
-                               Close ();
-                       }
-               }
-
                private bool canSeek  = false;
                private bool canRead  = false;
                private bool canWrite = false;

Modified: trunk/mcs/class/Mono.Posix/Mono.Unix/UnixConvert.cs
===================================================================
--- trunk/mcs/class/Mono.Posix/Mono.Unix/UnixConvert.cs 2005-03-28 16:46:23 UTC 
(rev 42309)
+++ trunk/mcs/class/Mono.Posix/Mono.Unix/UnixConvert.cs 2005-03-28 17:28:54 UTC 
(rev 42310)
@@ -745,11 +745,70 @@
                                flags |= OpenFlags.O_RDWR;
                                break;
                        default:
-                               throw new ArgumentException (Locale.GetText 
("Unsupported access value"), "access");
+                               throw new ArgumentOutOfRangeException 
(Locale.GetText ("Unsupported access value"), "access");
                        }
 
                        return flags;
                }
+
+               public static string ToFopenMode (FileAccess access)
+               {
+                       switch (access) {
+                               case FileAccess.Read:       return "rb";
+                               case FileAccess.Write:      return "wb";
+                               case FileAccess.ReadWrite:  return "r+b";
+                               default:                    throw new 
ArgumentOutOfRangeException ("access");
+                       }
+               }
+
+               public static string ToFopenMode (FileMode mode)
+               {
+                       switch (mode) {
+                               case FileMode.CreateNew: case FileMode.Create:  
      return "w+b";
+                               case FileMode.Open:      case 
FileMode.OpenOrCreate:  return "r+b";
+                               case FileMode.Truncate: return "w+b";
+                               case FileMode.Append:   return "a+b";
+                               default:                throw new 
ArgumentOutOfRangeException ("mode");
+                       }
+               }
+
+               private static readonly string[][] fopen_modes = new string[][]{
+                       //                                         Read         
              Write ReadWrite
+                       /*    FileMode.CreateNew: */  new string[]{"Can't 
Read+Create",       "wb", "w+b"},
+                       /*       FileMode.Create: */  new string[]{"Can't 
Read+Create",       "wb", "w+b"},
+                       /*         FileMode.Open: */  new string[]{"rb",        
              "wb", "r+b"},
+                       /* FileMode.OpenOrCreate: */  new string[]{"rb",        
              "wb", "r+b"},
+                       /*     FileMode.Truncate: */  new string[]{"Cannot 
Truncate and Read","wb", "w+b"},
+                       /*       FileMode.Append: */  new string[]{"Cannot 
Append and Read",  "ab", "a+b"},
+               };
+
+               public static string ToFopenMode (FileMode mode, FileAccess 
access)
+               {
+                       int fm = -1, fa = -1;
+                       switch (mode) {
+                               case FileMode.CreateNew:    fm = 0; break;
+                               case FileMode.Create:       fm = 1; break;
+                               case FileMode.Open:         fm = 2; break;
+                               case FileMode.OpenOrCreate: fm = 3; break;
+                               case FileMode.Truncate:     fm = 4; break;
+                               case FileMode.Append:       fm = 5; break;
+                       }
+                       switch (access) {
+                               case FileAccess.Read:       fa = 0; break;
+                               case FileAccess.Write:      fa = 1; break;
+                               case FileAccess.ReadWrite:  fa = 2; break;
+                       }
+
+                       if (fm == -1)
+                               throw new ArgumentOutOfRangeException ("mode");
+                       if (fa == -1)
+                               throw new ArgumentOutOfRangeException 
("access");
+
+                       string fopen_mode = fopen_modes [fm][fa];
+                       if (fopen_mode [0] != 'r' && fopen_mode [0] != 'w' && 
fopen_mode [0] != 'a')
+                               throw new ArgumentException (fopen_mode);
+                       return fopen_mode;
+               }
        }
 }
 

Modified: trunk/mcs/class/Mono.Posix/Test/Mono.Unix/ChangeLog
===================================================================
--- trunk/mcs/class/Mono.Posix/Test/Mono.Unix/ChangeLog 2005-03-28 16:46:23 UTC 
(rev 42309)
+++ trunk/mcs/class/Mono.Posix/Test/Mono.Unix/ChangeLog 2005-03-28 17:28:54 UTC 
(rev 42310)
@@ -1,3 +1,7 @@
+2005-03-28  Jonathan Pryor  <[EMAIL PROTECTED]>
+
+       * StdioFileStreamTest.cs: Added; based on 
MonoTests.System.IO.FileStreamTest.
+
 2005-02-09  Jonathan Pryor  <[EMAIL PROTECTED]>
 
        * StdlibTest.cs: Signal is currently ignored, but add 
Category(NotDotNet) so

Added: trunk/mcs/class/Mono.Posix/Test/Mono.Unix/StdioFileStreamTest.cs
===================================================================
--- trunk/mcs/class/Mono.Posix/Test/Mono.Unix/StdioFileStreamTest.cs    
2005-03-28 16:46:23 UTC (rev 42309)
+++ trunk/mcs/class/Mono.Posix/Test/Mono.Unix/StdioFileStreamTest.cs    
2005-03-28 17:28:54 UTC (rev 42310)
@@ -0,0 +1,813 @@
+// StdioFileStreamTest.cs - NUnit2 Test Cases for Mono.Unix.StdioFileStream 
class
+//
+// Authors:
+//     Ville Palo ([EMAIL PROTECTED])
+//     Gert Driesen ([EMAIL PROTECTED])
+//     Gonzalo Paniagua Javier ([EMAIL PROTECTED])
+// 
+// (C) Ville Palo
+// (c) 2003 Ximian, Inc. (http://www.ximian.com)
+// 
+
+
+using NUnit.Framework;
+using System;
+using System.IO;
+using System.Text;
+using Mono.Unix;
+
+namespace MonoTests.System.IO
+{
+       [TestFixture]
+       public class StdioFileStreamTest {
+
+               string TempFolder = Path.Combine (Path.GetTempPath (), 
"MonoTests.Mono.Unix.Tests");
+               static readonly char DSC = Path.DirectorySeparatorChar;
+
+               [TearDown]
+               public void TearDown()
+               {
+                       if (Directory.Exists (TempFolder))
+                               Directory.Delete (TempFolder, true);
+               }
+
+               [SetUp]
+               public void SetUp ()
+               {
+                       if (Directory.Exists (TempFolder))
+                               Directory.Delete (TempFolder, true);
+
+                       Directory.CreateDirectory (TempFolder);
+               }
+
+               public void TestCtr ()
+               {
+                       string path = TempFolder + DSC + "testfilestream.tmp.1";
+                       DeleteFile (path);
+                       StdioFileStream stream = null;
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.Create);
+                       } finally {
+
+                               if (stream != null)
+                                       stream.Close ();
+                               DeleteFile (path);                      
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void CtorArgumentException1 ()
+               {
+                       StdioFileStream stream;
+                       stream = new StdioFileStream ("", FileMode.Create);
+                       stream.Close ();
+               }                       
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void CtorArgumentNullException ()
+               {
+                       StdioFileStream stream = new StdioFileStream (null, 
FileMode.Create);
+                       stream.Close ();
+               }
+
+               [Test]
+               [ExpectedException (typeof (FileNotFoundException))]
+               public void CtorFileNotFoundException1 ()
+               {
+                       string path = TempFolder + DSC + 
"thisfileshouldnotexists.test";
+                       DeleteFile (path);
+                       StdioFileStream stream = null;
+                       try {                           
+                               stream = new StdioFileStream (path, 
FileMode.Open);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                               DeleteFile (path);
+                       }
+               }                       
+
+               [Test]
+               [ExpectedException (typeof (FileNotFoundException))]
+               public void CtorFileNotFoundException2 ()
+               {
+                       string path = TempFolder + DSC + 
"thisfileshouldNOTexists.test";
+                       DeleteFile (path);
+                       StdioFileStream stream = null;
+
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.Truncate);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+
+                               DeleteFile (path);
+                       }
+               } 
+
+               [Test]
+               [ExpectedException (typeof (IOException))]
+               public void CtorIOException1 ()
+               {
+                       string path = TempFolder + DSC + 
"thisfileshouldexists.test";
+                       StdioFileStream stream = null;
+                       DeleteFile (path);
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.CreateNew);
+                               stream.Close ();
+                               stream = null;
+                               stream = new StdioFileStream (path, 
FileMode.CreateNew);
+                       } finally {
+
+                               if (stream != null)
+                                       stream.Close ();
+                               DeleteFile (path);
+                       } 
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void CtorArgumentOutOfRangeException1 ()
+               {
+                       StdioFileStream stream = null;
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.Append | FileMode.CreateNew);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                               DeleteFile (path);
+                       }                       
+               }                       
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void CtorArgumentOutOfRangeException2 ()
+               {
+                       StdioFileStream stream = null;
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+                       try {
+                               stream = new StdioFileStream ("test.test.test", 
FileMode.Append | FileMode.Open);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                               DeleteFile (path);
+                       }                       
+               }
+
+               [Test]
+               [ExpectedException (typeof (DirectoryNotFoundException))]
+               public void CtorDirectoryNotFoundException ()
+               {
+                       string path = TempFolder + DSC + 
"thisDirectoryShouldNotExists";
+                       if (Directory.Exists (path))
+                               Directory.Delete (path, true);
+
+                       StdioFileStream stream = null;                          
+                       try {
+                               stream = new StdioFileStream (path + DSC + 
"eitherthisfile.test", FileMode.CreateNew);
+                       } finally {
+
+                               if (stream != null)
+                                       stream.Close ();
+
+                               if (Directory.Exists (path))
+                                       Directory.Delete (path, true);
+                       }                               
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void CtorArgumentException3 ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       StdioFileStream stream = null;
+
+                       DeleteFile (path);
+
+                       try {
+                               stream = new StdioFileStream 
(".test.test.test.2", FileMode.Truncate, FileAccess.Read);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+
+                               DeleteFile (path);
+                       }                       
+               }
+
+               // StdioFileStream doesn't mimic the "no writing by another 
object" rule
+               [/* Test, */ ExpectedException(typeof(IOException))]
+               public void CtorIOException ()
+               {                       
+                       string path = TempFolder + DSC + "CTorIOException.Test";
+                       StdioFileStream stream = null;
+                       StdioFileStream stream2 = null;
+                       DeleteFile (path);
+
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.CreateNew);
+
+                               // used by an another process
+                               stream2 = new StdioFileStream (path, 
FileMode.OpenOrCreate);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                               if (stream2 != null)
+                                       stream2.Close ();
+                               DeleteFile (path);
+                       }
+               }
+
+               [Test]
+               public void CtorAccess1Read2Read ()
+               {
+                       StdioFileStream fs = null;
+                       StdioFileStream fs2 = null;
+                       try {
+                               if (!File.Exists ("temp")) {
+                                       TextWriter tw = File.CreateText 
("temp");
+                                       tw.Write ("FOO");
+                                       tw.Close ();
+                               }
+                               fs = new StdioFileStream ("temp", 
FileMode.Open, FileAccess.Read);
+                               fs2 = new StdioFileStream ("temp", 
FileMode.Open, FileAccess.Read);
+                       } finally {
+                               if (fs != null)
+                                       fs.Close ();
+                               if (fs2 != null)
+                                       fs2.Close ();
+                               if (File.Exists ("temp"))
+                                       File.Delete ("temp");
+                       }
+               }
+
+               [Test]
+               public void Write ()
+               {
+                       string path = TempFolder + DSC + 
"StdioFileStreamTest.Write";
+
+                       DeleteFile (path);
+
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.CreateNew, FileAccess.ReadWrite);
+
+                       byte[] outbytes = new byte [] {1, 2, 3, 4, 5, 6, 7, 8, 
9, 10, 11, 12, 13, 14, 15, 16};
+                       byte[] bytes = new byte [15];
+
+                       // Check that the data is flushed when we overflow the 
buffer
+                       // with a large amount of data
+                       stream.Write (outbytes, 0, 5);
+                       stream.Write (outbytes, 5, 10);
+                       stream.Seek (0, SeekOrigin.Begin);
+
+                       stream.Read (bytes, 0, 15);
+                       for (int i = 0; i < 15; ++i)
+                               Assert.AreEqual (i + 1, bytes [i]);
+
+                       // Check that the data is flushed when we overflow the 
buffer
+                       // with a small amount of data
+                       stream.Write (outbytes, 0, 7);
+                       stream.Write (outbytes, 7, 7);
+                       stream.Write (outbytes, 14, 1);
+
+                       stream.Read (bytes, 0, 15);
+                       stream.Seek (15, SeekOrigin.Begin);
+                       for (int i = 0; i < 15; ++i)
+                               Assert.AreEqual (i + 1, bytes [i]);
+                       stream.Close ();
+               }
+
+               [Test]
+               public void Length ()
+               {
+                       // Test that the Length property takes into account the 
data
+                       // in the buffer
+                       string path = TempFolder + DSC + 
"StdioFileStreamTest.Length";
+
+                       DeleteFile (path);
+
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.CreateNew);
+
+                       byte[] outbytes = new byte [] {1, 2, 3, 4};
+
+                       stream.Write (outbytes, 0, 4);
+                       Assert.AreEqual (stream.Length, 4);
+                       stream.Close ();
+               }
+
+               [Test]
+               public void Flush ()
+               {
+                       string path = TempFolder + DSC + 
"StdioFileStreamTest.Flush";
+                       StdioFileStream stream = null;
+                       StdioFileStream stream2 = null;
+
+                       DeleteFile (path);
+
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.CreateNew, FileAccess.ReadWrite);
+                               stream2 = new StdioFileStream (path, 
FileMode.Open, FileAccess.ReadWrite);
+
+                               stream.Write (new byte [] {1, 2, 3, 4, 5}, 0, 
5);
+
+                               byte [] bytes = new byte [5];
+                               stream2.Read (bytes, 0, 5);
+
+                               Assert.AreEqual (0, bytes [0], "test#01");
+                               Assert.AreEqual (0, bytes [1], "test#02");
+                               Assert.AreEqual (0, bytes [2], "test#03");
+                               Assert.AreEqual (0, bytes [3], "test#04");
+
+                               stream.Flush ();
+                               stream2.Read (bytes, 0, 5);                     
+                               Assert.AreEqual (1, bytes [0], "test#05");
+                               Assert.AreEqual (2, bytes [1], "test#06");
+                               Assert.AreEqual (3, bytes [2], "test#07");
+                               Assert.AreEqual (4, bytes [3], "test#08");
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                               if (stream2 != null)
+                                       stream2.Close ();
+
+                               DeleteFile (path);
+                       }
+               }
+
+               [Test]
+               public void TestDefaultProperties ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "testStdioFileStream.tmp.2";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.Create);
+
+                       Assert.AreEqual (true, stream.CanRead, "test#01");
+                       Assert.AreEqual (true, stream.CanSeek, "test#02");
+                       Assert.AreEqual (true, stream.CanWrite, "test#03");
+                       Assert.AreEqual (0, stream.Position, "test#06");
+                       Assert.AreEqual ("Mono.Unix.StdioFileStream", 
stream.ToString(), "test#07");
+                       stream.Close ();
+                       DeleteFile (path);
+
+                       stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Read);
+                       Assert.AreEqual (true, stream.CanRead, "test#08");
+                       Assert.AreEqual (true, stream.CanSeek, "test#09");
+                       Assert.AreEqual (false, stream.CanWrite, "test#10");
+                       Assert.AreEqual (0, stream.Position, "test#13");
+                       Assert.AreEqual ("Mono.Unix.StdioFileStream", 
stream.ToString(), "test#14");                    
+                       stream.Close ();
+
+                       stream = new StdioFileStream (path, FileMode.Truncate, 
FileAccess.Write);
+                       Assert.AreEqual (false, stream.CanRead, "test#15");
+                       Assert.AreEqual (true, stream.CanSeek, "test#16");
+                       Assert.AreEqual (true, stream.CanWrite, "test#17");
+                       Assert.AreEqual (0, stream.Position, "test#20");
+                       Assert.AreEqual ("Mono.Unix.StdioFileStream", 
stream.ToString(), "test#21");                    
+                       stream.Close ();
+                       DeleteFile (path);
+               }
+
+               [Test]
+               public void Seek ()
+               {
+                       string path = TempFolder + DSC + "FST.Seek.Test";
+                       DeleteFile (path);                      
+
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.CreateNew, FileAccess.ReadWrite);
+                       StdioFileStream stream2 = new StdioFileStream (path, 
FileMode.Open, FileAccess.ReadWrite);
+
+                       stream.Write (new byte [] {1, 2, 3, 4, 5, 6, 7, 8, 10}, 
0, 9);
+                       Assert.AreEqual (5, stream2.Seek (5, SeekOrigin.Begin), 
"test#01");
+                       Assert.AreEqual (-1, stream2.ReadByte (), "test#02");
+
+                       Assert.AreEqual (2, stream2.Seek (-3, 
SeekOrigin.Current), "test#03");
+                       Assert.AreEqual (-1, stream2.ReadByte (), "test#04");
+
+                       Assert.AreEqual (12, stream.Seek (3, 
SeekOrigin.Current), "test#05");
+                       Assert.AreEqual (-1, stream.ReadByte (), "test#06");
+
+                       Assert.AreEqual (5, stream.Seek (-7, 
SeekOrigin.Current), "test#07");
+                       Assert.AreEqual (6, stream.ReadByte (), "test#08");
+
+                       Assert.AreEqual (5, stream2.Seek (5, SeekOrigin.Begin), 
"test#09");
+                       Assert.AreEqual (6, stream2.ReadByte (), "test#10");
+
+                       stream.Close ();
+                       stream2.Close ();
+
+                       DeleteFile (path);
+               }
+
+               [Test]
+               public void TestSeek ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "TestSeek";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.CreateNew, FileAccess.ReadWrite);
+                       stream.Write (new byte[] {1, 2, 3, 4, 5, 6, 7, 8 , 9, 
10}, 0, 10);
+
+                       stream.Seek (5, SeekOrigin.End);
+                       Assert.AreEqual (-1, stream.ReadByte (), "test#01");
+
+                       stream.Seek (-5, SeekOrigin.End);
+                       Assert.AreEqual (6, stream.ReadByte (), "test#02");
+
+                       try {
+                               stream.Seek (-11, SeekOrigin.End);
+                               Assert.Fail ();
+                       } catch (Exception e) {
+                               Assert.AreEqual (typeof (IOException), 
e.GetType (), "test#03");
+                       }
+
+                       stream.Seek (19, SeekOrigin.Begin);
+                       Assert.AreEqual (-1, stream.ReadByte (), "test#04");
+
+                       stream.Seek (1, SeekOrigin.Begin);
+                       Assert.AreEqual (2, stream.ReadByte (), "test#05");
+
+                       stream.Seek (3, SeekOrigin.Current);
+                       Assert.AreEqual (6, stream.ReadByte (), "test#06");
+
+                       stream.Seek (-2, SeekOrigin.Current);
+                       Assert.AreEqual (5, stream.ReadByte (), "test#07");
+
+                       stream.Flush ();
+
+                       // Test that seeks work correctly when seeking inside 
the buffer
+                       stream.Seek (0, SeekOrigin.Begin);
+                       stream.WriteByte (0);
+                       stream.WriteByte (1);
+                       stream.Seek (0, SeekOrigin.Begin);
+                       byte[] buf = new byte [1];
+                       buf [0] = 2;
+                       stream.Write (buf, 0, 1);
+                       stream.Write (buf, 0, 1);
+                       stream.Flush ();
+                       stream.Seek (0, SeekOrigin.Begin);
+                       Assert.AreEqual (2, stream.ReadByte (), "test#08");
+                       Assert.AreEqual (2, stream.ReadByte (), "test#09");
+
+                       stream.Close ();
+
+                       DeleteFile (path);
+               }
+
+               [Test]
+               public void TestClose ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "TestClose";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.CreateNew, FileAccess.ReadWrite);
+
+                       stream.Write (new byte [] {1, 2, 3, 4}, 0, 4);
+                       stream.ReadByte ();                     
+                       stream.Close ();
+
+                       try {                   
+                               stream.ReadByte ();
+                               Assert.Fail ();
+                       } catch (Exception e) {
+                               Assert.AreEqual (typeof 
(ObjectDisposedException), e.GetType (), "test#01");
+                       }
+
+                       try {                   
+                               stream.WriteByte (64);
+                               Assert.Fail ();
+                       } catch (Exception e) {
+                               Assert.AreEqual (typeof 
(ObjectDisposedException), e.GetType (), "test#02");
+                       }
+
+                       try {                   
+                               stream.Flush ();
+                               Assert.Fail ();
+                       } catch (Exception e) {
+                               Assert.AreEqual (typeof 
(ObjectDisposedException), e.GetType (), "test#03");
+                       }
+
+                       try { 
+                               long l = stream.Length;
+                               l = l;
+                               Assert.Fail ();
+                       } catch (Exception e) {
+                               Assert.AreEqual (typeof 
(ObjectDisposedException), e.GetType (), "test#04");
+                       }
+
+                       try { 
+                               long l = stream.Position;
+                               l = l;
+                               Assert.Fail ();
+                       } catch (Exception e) {
+                               Assert.AreEqual (typeof 
(ObjectDisposedException), e.GetType (), "test#05");
+                       }
+
+                       Assert.AreEqual (false, stream.CanRead, "test#06");
+                       Assert.AreEqual (false, stream.CanSeek, "test#07");
+                       Assert.AreEqual (false, stream.CanWrite, "test#08");    
                
+
+                       DeleteFile (path);                      
+               }
+
+
+               /// <summary>
+               /// Checks whether the <see cref="StdioFileStream" /> throws a 
<see cref="NotSupportedException" />
+               /// when the stream is opened with access mode <see 
cref="FileAccess.Read" /> and the
+               /// <see cref="StdioFileStream.Write(byte[], int, int)" /> 
method is called.
+               /// </summary>
+               [Test]
+               [ExpectedException (typeof(NotSupportedException))]
+               public void TestWriteVerifyAccessMode ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = null;
+                       byte[] buffer;
+
+                       try {
+                               buffer = Encoding.ASCII.GetBytes ("test");
+                               stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Read);
+                               stream.Write (buffer, 0, buffer.Length);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close();
+                               DeleteFile (path);
+                       }
+               }
+
+               /// <summary>
+               /// Checks whether the <see cref="StdioFileStream" /> throws a 
<see cref="NotSupportedException" />
+               /// when the stream is opened with access mode <see 
cref="FileAccess.Read" /> and the
+               /// <see cref="StdioFileStream.WriteByte(byte)" /> method is 
called.
+               /// </summary>
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void TestWriteByteVerifyAccessMode ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = null;
+
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Read);
+                               stream.WriteByte (Byte.MinValue);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                               DeleteFile (path);
+                       }
+               }
+
+               /// <summary>
+               /// Checks whether the <see cref="StdioFileStream" /> throws a 
<see cref="NotSupportedException" />
+               /// when the stream is opened with access mode <see 
cref="FileAccess.Write" /> and the
+               /// <see cref="StdioFileStream.Read(byte[], int, int)" /> 
method is called.
+               /// </summary>
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void TestReadVerifyAccessMode ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = null;
+                       byte[] buffer = new byte [100];
+
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Write);
+                               stream.Read (buffer, 0, buffer.Length);
+                       } finally {
+                               if (stream != null)
+                                       stream.Close ();
+                       }
+               }
+
+               /// <summary>
+               /// Checks whether the <see cref="StdioFileStream" /> throws a 
<see cref="NotSupportedException" />
+               /// when the stream is opened with access mode <see 
cref="FileAccess.Write" /> and the
+               /// <see cref="StdioFileStream.ReadByte()" /> method is called.
+               /// </summary>
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void TestReadByteVerifyAccessMode ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       StdioFileStream stream = null;
+
+                       try {
+                               stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Write);
+                               int readByte = stream.ReadByte ();
+                               readByte = readByte;
+                       } finally {
+                               if (stream != null)
+                                       stream.Close();
+                               DeleteFile (path);
+                       }
+               }
+
+               // Check that the stream is flushed even when it doesn't own the
+               // handle
+               [Test]
+               public void TestFlushNotOwningHandle ()
+               {
+                       string path = Path.Combine (TempFolder, 
"TestFlushNotOwningHandle");
+                       DeleteFile (path);
+
+                       StdioFileStream s = new StdioFileStream (path, 
FileMode.Create);
+                       using (StdioFileStream s2 = new StdioFileStream 
(s.Handle, FileAccess.Write, false)) {
+                               byte[] buf = new byte [2];
+                               buf [0] = (int)'1';
+                               s2.Write (buf, 0, 1);
+                       }
+
+                       s.Position = 0;
+                       Assert.AreEqual (s.ReadByte (), (int)'1');
+                       s.Close ();
+               }
+
+               private void DeleteFile (string path) 
+               {
+                       if (File.Exists (path))
+                               File.Delete (path);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Read_OffsetNegative ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Read)) {
+                               stream.Read (new byte[0], -1, 1);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void Read_OffsetOverflow ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Read)) {
+                               stream.Read (new byte[0], Int32.MaxValue, 1);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Read_CountNegative ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Read)) {
+                               stream.Read (new byte[0], 1, -1);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void Read_CountOverflow ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Read)) {
+                               stream.Read (new byte[0], 1, Int32.MaxValue);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Write_OffsetNegative ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Write)) {
+                               stream.Write (new byte[0], -1, 1);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void Write_OffsetOverflow ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Write)) {
+                               stream.Write (new byte[0], Int32.MaxValue, 1);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Write_CountNegative ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Write)) {
+                               stream.Write (new byte[0], 1, -1);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void Write_CountOverflow ()
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Write)) {
+                               stream.Write (new byte[0], 1, Int32.MaxValue);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void Seek_InvalidSeekOrigin () 
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Read)) {
+                               stream.Seek (0, (SeekOrigin) (-1));
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void Constructor_InvalidFileHandle () 
+               {
+                       new StdioFileStream ((IntPtr)(-1), FileAccess.Read);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void Position_Disposed () 
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Read);
+                       stream.Close ();
+                       stream.Position = 0;
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void Flush_Disposed () 
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Write);
+                       stream.Close ();
+                       stream.Flush ();
+               }
+
+               [Test]
+               [ExpectedException (typeof (ObjectDisposedException))]
+               public void Seek_Disposed () 
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+                       StdioFileStream stream = new StdioFileStream (path, 
FileMode.OpenOrCreate, FileAccess.Write);
+                       stream.Close ();
+                       stream.Seek (0, SeekOrigin.Begin);
+               }
+
+               [Test]
+               public void ReadBytePastEndOfStream () 
+               {
+                       string path = TempFolder + Path.DirectorySeparatorChar 
+ "temp";
+                       DeleteFile (path);
+                       using (StdioFileStream stream = new StdioFileStream 
(path, FileMode.OpenOrCreate, FileAccess.Read)) {
+                               stream.Seek (0, SeekOrigin.End);
+                               Assert.AreEqual (-1, stream.ReadByte (), 
"ReadByte");
+                               stream.Close ();
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void SetLengthWithClosedBaseStream ()
+               {
+                       StdioFileStream fs = new StdioFileStream ("temp", 
FileMode.Create);
+                       BufferedStream bs = new BufferedStream (fs);
+                       fs.Close ();
+
+                       bs.SetLength (1000);
+               }
+       }
+}
+

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to