**
===========================================================*/
using System;
+#if FEATURE_CORECLR
+using System.Buffers;
+#endif
using System.Threading;
using System.Threading.Tasks;
Contract.Requires(CanRead);
Contract.Requires(destination.CanWrite);
+#if FEATURE_CORECLR
+ byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ bufferSize = 0; // reuse same field for high water mark to avoid needing another field in the state machine
+ try
+ {
+ while (true)
+ {
+ int bytesRead = await ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
+ if (bytesRead == 0) break;
+ if (bytesRead > bufferSize) bufferSize = bytesRead;
+ await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
+ }
+ }
+ finally
+ {
+ Array.Clear(buffer, 0, bufferSize); // clear only the most we used
+ ArrayPool<byte>.Shared.Return(buffer, clearArray: false);
+ }
+#else
byte[] buffer = new byte[bufferSize];
while (true)
{
if (bytesRead == 0) break;
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
}
+#endif
}
// Reads the bytes from the current stream and writes the bytes to
public virtual void CopyTo(Stream destination, int bufferSize)
{
StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
-
+
+#if FEATURE_CORECLR
+ byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ int highwaterMark = 0;
+ try
+ {
+ int read;
+ while ((read = Read(buffer, 0, buffer.Length)) != 0)
+ {
+ if (read > highwaterMark) highwaterMark = read;
+ destination.Write(buffer, 0, read);
+ }
+ }
+ finally
+ {
+ Array.Clear(buffer, 0, highwaterMark); // clear only the most we used
+ ArrayPool<byte>.Shared.Return(buffer, clearArray: false);
+ }
+#else
byte[] buffer = new byte[bufferSize];
int read;
while ((read = Read(buffer, 0, buffer.Length)) != 0)
+ {
destination.Write(buffer, 0, read);
+ }
+#endif
}
// Stream used to require that all cleanup logic went into Close(),