Merge pull request #1201 from crisdut/fix-win-mono-dependencies
[mono.git] / mcs / class / corlib / System.IO / MemoryStream.cs
index cac3d70f9dfda8c0af89ab175bc25b3af2d5bb3e..4ce86df30b616f0b9ff96498f8d7fa783d76a698 100644 (file)
@@ -56,6 +56,7 @@ namespace System.IO
                int position;
                int dirty_bytes;
 #if NET_4_5
+               [NonSerialized]
                Task<int> read_task;
 #endif
 
@@ -375,9 +376,6 @@ namespace System.IO
 
                public override void Write (byte [] buffer, int offset, int count)
                {
-                       if (!canWrite)
-                               throw new NotSupportedException ("Cannot write to this stream.");
-
                        if (buffer == null)
                                throw new ArgumentNullException ("buffer");
                        
@@ -390,6 +388,9 @@ namespace System.IO
 
                        CheckIfClosedThrowDisposed ();
 
+                       if (!CanWrite)
+                               throw new NotSupportedException ("Cannot write to this stream.");
+
                        // reordered to avoid possible integer overflow
                        if (position > length - count)
                                Expand (position + count);
@@ -426,36 +427,73 @@ namespace System.IO
 
 #if NET_4_5
 
+               public override Task CopyToAsync (Stream destination, int bufferSize, CancellationToken cancellationToken)
+               {
+                       // TODO: Specialization but what for?
+                       return base.CopyToAsync (destination, bufferSize, cancellationToken);
+               }
+
                public override Task FlushAsync (CancellationToken cancellationToken)
                {
                        if (cancellationToken.IsCancellationRequested)
-                               return Task<int>.Canceled;
+                               return TaskConstants.Canceled;
 
-                       Flush ();
-                       return Task.Finished;
+                       try {
+                               Flush ();
+                               return TaskConstants.Finished;
+                       } catch (Exception ex) {
+                               return Task<object>.FromException (ex);
+                       }
                }
 
                public override Task<int> ReadAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken)
                {
+                       if (buffer == null)
+                               throw new ArgumentNullException ("buffer");
+
+                       if (offset < 0 || count < 0)
+                               throw new ArgumentOutOfRangeException ("offset or count less than zero.");
+
+                       if (buffer.Length - offset < count )
+                               throw new ArgumentException ("offset+count",
+                                                            "The size of the buffer is less than offset + count.");
                        if (cancellationToken.IsCancellationRequested)
-                               return Task<int>.Canceled;
+                               return TaskConstants<int>.Canceled;
 
-                       count = Read (buffer, offset, count);
+                       try {
+                               count = Read (buffer, offset, count);
 
-                       // Try not to allocate a new task for every buffer read
-                       if (read_task == null || read_task.Result != count)
-                               read_task = Task<int>.FromResult (count);
+                               // Try not to allocate a new task for every buffer read
+                               if (read_task == null || read_task.Result != count)
+                                       read_task = Task<int>.FromResult (count);
 
-                       return read_task;
+                               return read_task;
+                       } catch (Exception ex) {
+                               return Task<int>.FromException (ex);
+                       }
                }
 
                public override Task WriteAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken)
                {
+                       if (buffer == null)
+                               throw new ArgumentNullException ("buffer");
+                       
+                       if (offset < 0 || count < 0)
+                               throw new ArgumentOutOfRangeException ();
+
+                       if (buffer.Length - offset < count)
+                               throw new ArgumentException ("offset+count",
+                                                            "The size of the buffer is less than offset + count.");
+
                        if (cancellationToken.IsCancellationRequested)
-                               return Task<int>.Canceled;
+                               return TaskConstants.Canceled;
 
-                       Write (buffer, offset, count);
-                       return Task.Finished;
+                       try {
+                               Write (buffer, offset, count);
+                               return TaskConstants.Finished;
+                       } catch (Exception ex) {
+                               return Task<object>.FromException (ex);
+                       }
                }
 #endif
        }