[Test] Avoid MethodInfoTest.GetMethodBody failure when executed on a release (IL...
[mono.git] / mcs / class / corlib / System.IO / Stream.cs
index 08f30b7a09e67f67e46e0e60f4d8e56b426a3da6..17119e612bea968cb5881223f93d3386f3bd22f2 100644 (file)
@@ -50,8 +50,11 @@ namespace System.IO
        {
                public static readonly Stream Null = new NullStream ();
 
+               [NonSerialized]
                Func<byte[], int, int, int> async_read;
+               [NonSerialized]
                Action<byte[], int, int> async_write;
+               [NonSerialized]
                AutoResetEvent async_event;
 
                protected Stream ()
@@ -150,7 +153,7 @@ namespace System.IO
                {
                        byte[] buffer = new byte [1];
 
-                       if (Read (buffer, 0, 1) == 1)
+                       if (Read (buffer, 0, 1) > 0)
                                return buffer [0];
                        
                        return -1;
@@ -237,7 +240,7 @@ namespace System.IO
                        }
                }
 
-#if MOONLIGHT || NET_4_0 || MOBILE
+#if NET_4_0
                public void CopyTo (Stream destination)
                {
                        CopyTo (destination, 16*1024);
@@ -269,6 +272,41 @@ namespace System.IO
 #endif
                
 #if NET_4_5
+
+               public Task CopyToAsync (Stream destination)
+               {
+                       return CopyToAsync (destination, 16 * 1024, CancellationToken.None);
+               }
+
+               public Task CopyToAsync (Stream destination, int bufferSize)
+               {
+                       return CopyToAsync (destination, bufferSize, CancellationToken.None);
+               }
+
+               public virtual Task CopyToAsync (Stream destination, int bufferSize, CancellationToken cancellationToken)
+               {
+                       if (destination == null)
+                               throw new ArgumentNullException ("destination");
+                       if (!CanRead)
+                               throw new NotSupportedException ("This stream does not support reading");
+                       if (!destination.CanWrite)
+                               throw new NotSupportedException ("This destination stream does not support writing");
+                       if (bufferSize <= 0)
+                               throw new ArgumentOutOfRangeException ("bufferSize");
+
+                       if (cancellationToken.IsCancellationRequested)
+                               return TaskConstants.Canceled;
+
+                       return CopyToAsync (destination, new byte[bufferSize], cancellationToken);
+               }
+
+               async Task CopyToAsync (Stream destination, byte[] buffer, CancellationToken cancellationToken)
+               {
+                       int nread;
+                       while ((nread = await ReadAsync (buffer, 0, buffer.Length, cancellationToken).ConfigureAwait (false)) != 0)
+                               await destination.WriteAsync (buffer, 0, nread, cancellationToken).ConfigureAwait (false);
+               }
+
                public Task FlushAsync ()
                {
                        return FlushAsync (CancellationToken.None);
@@ -277,11 +315,9 @@ namespace System.IO
                public virtual Task FlushAsync (CancellationToken cancellationToken)
                {
                        if (cancellationToken.IsCancellationRequested)
-                               return Task.Canceled;
+                               return TaskConstants.Canceled;
 
-                       var t = new Task (() => Flush (), cancellationToken);
-                       t.Start ();
-                       return t;
+                       return Task.Factory.StartNew (l => ((Stream) l).Flush (), this, cancellationToken);
                }
 
                public Task<int> ReadAsync (byte[] buffer, int offset, int count)
@@ -292,7 +328,7 @@ namespace System.IO
                public virtual Task<int> ReadAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken)
                {
                        if (cancellationToken.IsCancellationRequested)
-                               return Task<int>.Canceled;
+                               return TaskConstants<int>.Canceled;
 
                        return Task<int>.Factory.FromAsync (BeginRead, EndRead, buffer, offset, count, null);
                }