diff --git a/src/System.Memory.Polyfill/System.Memory.Polyfill.csproj b/src/System.Memory.Polyfill/System.Memory.Polyfill.csproj
index a33d3f88699..c0dd87be855 100644
--- a/src/System.Memory.Polyfill/System.Memory.Polyfill.csproj
+++ b/src/System.Memory.Polyfill/System.Memory.Polyfill.csproj
@@ -9,5 +9,6 @@
+
diff --git a/src/System.Memory.Polyfill/System/Stream.cs b/src/System.Memory.Polyfill/System/Stream.cs
index e1d046326e6..9fce3911d60 100644
--- a/src/System.Memory.Polyfill/System/Stream.cs
+++ b/src/System.Memory.Polyfill/System/Stream.cs
@@ -4,6 +4,9 @@
using System.Buffers;
using System.IO;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
namespace System
{
@@ -26,6 +29,78 @@ public static int Read(this Stream stream, Span buffer)
{
if(pooled != null) ArrayPool.Shared.Return(pooled);
}
+#endif
+ }
+
+ public static async ValueTask ReadAsync(this Stream stream, Memory buffer, CancellationToken cancellationToken = default)
+ {
+#if NETCOREAPP2_1
+ return await stream.ReadAsync(buffer, cancellationToken);
+#else
+ if (MemoryMarshal.TryGetArray(buffer, out ArraySegment array))
+ {
+ return await stream.ReadAsync(array.Array, array.Offset, array.Count, cancellationToken);
+ }
+ else
+ {
+ byte[] pooled = null;
+ try
+ {
+ pooled = ArrayPool.Shared.Rent(buffer.Length);
+ int read = await stream.ReadAsync(pooled, 0, pooled.Length, cancellationToken);
+ pooled.AsSpan(0, read).CopyTo(buffer.Span);
+ return read;
+ }
+ finally
+ {
+ if (pooled != null) ArrayPool.Shared.Return(pooled);
+ }
+ }
+#endif
+ }
+
+ public static void Write(this Stream stream, ReadOnlySpan buffer)
+ {
+#if NETCOREAPP2_1
+ stream.Write(buffer);
+#else
+ byte[] pooled = null;
+ try
+ {
+ pooled = ArrayPool.Shared.Rent(buffer.Length);
+ buffer.CopyTo(pooled);
+ stream.Write(pooled, 0, pooled.Length);
+ }
+ finally
+ {
+ if(pooled != null) ArrayPool.Shared.Return(pooled);
+ }
+#endif
+ }
+
+ public static Task WriteAsync(this Stream stream, ReadOnlyMemory buffer, CancellationToken cancellationToken = default)
+ {
+#if NETCOREAPP2_1
+ return stream.WriteAsync(buffer, cancellationToken).AsTask();
+#else
+ if (MemoryMarshal.TryGetArray(buffer, out ArraySegment array))
+ {
+ return stream.WriteAsync(array.Array, array.Offset, array.Count, cancellationToken);
+ }
+ else
+ {
+ byte[] pooled = null;
+ try
+ {
+ pooled = ArrayPool.Shared.Rent(buffer.Length);
+ buffer.CopyTo(pooled);
+ return stream.WriteAsync(pooled, 0, pooled.Length, cancellationToken);
+ }
+ finally
+ {
+ if (pooled != null) ArrayPool.Shared.Return(pooled);
+ }
+ }
#endif
}
}
diff --git a/tests/System.Memory.Polyfill.Tests/Int32.cs b/tests/System.Memory.Polyfill.Tests/Int32.cs
index 59275764edc..81336866031 100644
--- a/tests/System.Memory.Polyfill.Tests/Int32.cs
+++ b/tests/System.Memory.Polyfill.Tests/Int32.cs
@@ -11,7 +11,7 @@ public class Int32Tests
[Fact]
public void Int32TryParse()
{
- ReadOnlySpan span = int.MaxValue.ToString().ToCharArray().AsSpan();
+ ReadOnlySpan span = int.MaxValue.ToString().AsSpan();
Assert.True(Int32Polyfill.TryParse(span, out int value));
Assert.Equal(int.MaxValue, value);
}
diff --git a/tests/System.Memory.Polyfill.Tests/StreamTests.cs b/tests/System.Memory.Polyfill.Tests/StreamTests.cs
index 67a4f156890..b06faa0f4b9 100644
--- a/tests/System.Memory.Polyfill.Tests/StreamTests.cs
+++ b/tests/System.Memory.Polyfill.Tests/StreamTests.cs
@@ -24,5 +24,56 @@ public void StreamRead()
Assert.Equal(i, span[i]);
}
}
+
+ [Fact]
+ public async void StreamReadAsync()
+ {
+ var buffer = new byte[100];
+ for (int i = 0; i < buffer.Length; i++) buffer[i] = (byte)i;
+ var stream = new MemoryStream(buffer);
+
+ buffer = new byte[100];
+ var memory = new Memory(buffer);
+ int read = await stream.ReadAsync(memory);
+
+ Assert.Equal(buffer.Length, read);
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ Assert.Equal(i, buffer[i]);
+ }
+ }
+
+ [Fact]
+ public void StreamWrite()
+ {
+ var span = new Span(new byte[100]);
+ for (int i = 0; i < span.Length; i++) span[i] = (byte)i;
+
+ var buffer = new byte[1000];
+ var stream = new MemoryStream(buffer);
+
+ stream.Write(span);
+ for (int i = 0; i < span.Length; i++)
+ {
+ Assert.Equal(i, buffer[i]);
+ }
+ }
+
+ [Fact]
+ public async void StreamWriteAsync()
+ {
+ var array = new byte[100];
+ var memory = new Memory(array);
+ for (int i = 0; i < array.Length; i++) array[i] = (byte)i;
+
+ var buffer = new byte[100];
+ var stream = new MemoryStream(buffer);
+ await stream.WriteAsync(memory);
+
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ Assert.Equal(i, buffer[i]);
+ }
+ }
}
}
diff --git a/tests/System.Memory.Polyfill.Tests/System.Memory.Polyfill.Tests.csproj b/tests/System.Memory.Polyfill.Tests/System.Memory.Polyfill.Tests.csproj
index 68de1e22c13..6642f6f0f86 100644
--- a/tests/System.Memory.Polyfill.Tests/System.Memory.Polyfill.Tests.csproj
+++ b/tests/System.Memory.Polyfill.Tests/System.Memory.Polyfill.Tests.csproj
@@ -1,10 +1,7 @@
- netcoreapp2.1
-
-
- net46;netcoreapp2.1
+ netcoreapp2.0;netcoreapp2.1