diff --git a/TestResults/ApiBuilderTests-windows-net11.0-report.html b/TestResults/ApiBuilderTests-windows-net11.0-report.html new file mode 100644 index 00000000..0d733a35 --- /dev/null +++ b/TestResults/ApiBuilderTests-windows-net11.0-report.html @@ -0,0 +1,1593 @@ + + + + + +Test Report — ApiBuilderTests + + + + + + +
+
+
+ +
+

ApiBuilderTests

+Test Report +
+
+
+03 Mar 2026, 04:28:56 UTC +DTL-8CC3211MVK +Microsoft Windows 10.0.26200 +.NET 11.0.0-preview.1.26104.118 +TUnit 1.18.9.0 +
+ +
+
+
+
+ + + + +
100%pass rate
+
+
+
+71Total
+
+71Passed
+
+0Failed
+
+0Skipped
+
+0Cancelled
+
+
+33.97s +duration +
+
+
+
+ +
+ + + + + +
+
+ + + +Group: +
+ + + +
+ +Sort: +
+ + + +
+
+ +
+
+
+
+
+
+ + +
+ + diff --git a/TestResults/Tests-windows-net10.0-report.html b/TestResults/Tests-windows-net10.0-report.html new file mode 100644 index 00000000..6fdfcf6b --- /dev/null +++ b/TestResults/Tests-windows-net10.0-report.html @@ -0,0 +1,1593 @@ + + + + + +Test Report — Tests + + + + + + +
+
+
+ +
+

Tests

+Test Report +
+
+
+03 Mar 2026, 04:29:28 UTC +DTL-8CC3211MVK +Microsoft Windows 10.0.26200 +.NET 10.0.3 +TUnit 1.18.9.0 +
+ +
+
+
+
+ + + + +
100%pass rate
+
+
+
+997Total
+
+997Passed
+
+0Failed
+
+0Skipped
+
+0Cancelled
+
+
+380ms +duration +
+
+
+
+ +
+ + + + + +
+
+ + + +Group: +
+ + + +
+ +Sort: +
+ + + +
+
+ +
+
+
+
+
+
+ + +
+ + diff --git a/TestResults/Tests-windows-net48-report.html b/TestResults/Tests-windows-net48-report.html new file mode 100644 index 00000000..88f554b9 --- /dev/null +++ b/TestResults/Tests-windows-net48-report.html @@ -0,0 +1,1593 @@ + + + + + +Test Report — Tests + + + + + + +
+
+
+ +
+

Tests

+Test Report +
+
+
+03 Mar 2026, 04:29:30 UTC +DTL-8CC3211MVK +Microsoft Windows 10.0.26200 +.NET Framework 4.8.9221.0 +TUnit 1.18.9.0 +
+ +
+
+
+
+ + + + +
100%pass rate
+
+
+
+1004Total
+
+1004Passed
+
+0Failed
+
+0Skipped
+
+0Cancelled
+
+
+691ms +duration +
+
+
+
+ +
+ + + + + +
+
+ + + +Group: +
+ + + +
+ +Sort: +
+ + + +
+
+ +
+
+
+
+
+
+ + +
+ + diff --git a/apiCount.include.md b/apiCount.include.md index 72132342..4ee9be43 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1 +1 @@ -**API count: 748** \ No newline at end of file +**API count: 749** \ No newline at end of file diff --git a/api_list.include.md b/api_list.include.md index c8603cae..04ff720c 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -787,6 +787,7 @@ * `void ReadExactly(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readexactly?view=net-11.0#system-io-stream-readexactly(system-span((system-byte)))) * `ValueTask ReadExactlyAsync(byte[], int, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readexactlyasync?view=net-11.0#system-io-stream-readexactlyasync(system-byte()-system-int32-system-int32-system-threading-cancellationtoken)) * `ValueTask ReadExactlyAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readexactlyasync?view=net-11.0#system-io-stream-readexactlyasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.write?view=net-11.0#system-io-stream-write(system-readonlyspan((system-byte)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync?view=net-11.0#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index 07050193..b002d833 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ The package targets `netstandard2.0` and is designed to support the following ru * `uap10` -**API count: 748** +**API count: 749** **See [Milestones](../../milestones?state=closed) for release notes.** @@ -1290,6 +1290,7 @@ The class `Polyfill` includes the following extension methods: * `void ReadExactly(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readexactly?view=net-11.0#system-io-stream-readexactly(system-span((system-byte)))) * `ValueTask ReadExactlyAsync(byte[], int, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readexactlyasync?view=net-11.0#system-io-stream-readexactlyasync(system-byte()-system-int32-system-int32-system-threading-cancellationtoken)) * `ValueTask ReadExactlyAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readexactlyasync?view=net-11.0#system-io-stream-readexactlyasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.write?view=net-11.0#system-io-stream-write(system-readonlyspan((system-byte)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync?view=net-11.0#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 5b8b1608..090ba724 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -648,7 +648,7 @@ void File_Methods() using var nullHandle = File.OpenNullHandle(); #endif - FileSystemInfo hardLink = File.CreateHardLink("hardlink.txt", TestFilePath); + var hardLink = File.CreateHardLink("hardlink.txt", TestFilePath); var fileInfo = new FileInfo("hardlink2.txt"); fileInfo.CreateAsHardLink(TestFilePath); } @@ -1005,6 +1005,9 @@ async Task Stream_Methods() var input = new byte[] {1, 2}; using var stream = new MemoryStream(input); var result = new byte[2]; +#if FeatureMemory + ((Stream)stream).Write((ReadOnlySpan)input); +#endif #if FeatureMemory && FeatureValueTask var memory = new Memory(result); var read = await stream.ReadAsync(memory); diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ad460c86..750eb7a2 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ CS1591;NETSDK1138;NU1901;NU1902;NU1903;CA1822;CA1847;CA1861;NU1510;NU1608;NU1109 - 9.13.0 + 9.14.0 1.0.0 Polyfill true diff --git a/src/Polyfill/Polyfill_Stream.cs b/src/Polyfill/Polyfill_Stream.cs index 0a742f3b..50ccaf46 100644 --- a/src/Polyfill/Polyfill_Stream.cs +++ b/src/Polyfill/Polyfill_Stream.cs @@ -3,54 +3,12 @@ namespace Polyfills; // ReSharper disable once RedundantUsingDirective using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { #if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1_OR_GREATER -#if FeatureMemory && FeatureValueTask - - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - //Link: https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync?view=net-11.0#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken) - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - //Link: https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync?view=net-11.0#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken) - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified diff --git a/src/Polyfill/Polyfill_Stream_Read.cs b/src/Polyfill/Polyfill_Stream_Read.cs index 1e6bf7d7..d26c52ad 100644 --- a/src/Polyfill/Polyfill_Stream_Read.cs +++ b/src/Polyfill/Polyfill_Stream_Read.cs @@ -3,12 +3,37 @@ namespace Polyfills; using System; using System.IO; // ReSharper disable RedundantUsingDirective +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; // ReSharper restore RedundantUsingDirective static partial class Polyfill { +#if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1_OR_GREATER +#if FeatureMemory && FeatureValueTask + + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync?view=net-11.0#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken) + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } + +#endif +#endif #if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1 && FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Polyfill/Polyfill_Stream_Write.cs b/src/Polyfill/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..ff2d9e23 --- /dev/null +++ b/src/Polyfill/Polyfill_Stream_Write.cs @@ -0,0 +1,46 @@ +#if FeatureMemory +namespace Polyfills; + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +static partial class Polyfill +{ +#if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1 + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.write?view=net-11.0#system-io-stream-write(system-readonlyspan((system-byte))) + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#endif + +#if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1_OR_GREATER && FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync?view=net-11.0#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken) + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net461/Polyfill_Stream.cs b/src/Split/net461/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net461/Polyfill_Stream.cs +++ b/src/Split/net461/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net461/Polyfill_Stream_Read.cs b/src/Split/net461/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net461/Polyfill_Stream_Read.cs +++ b/src/Split/net461/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net461/Polyfill_Stream_Write.cs b/src/Split/net461/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net461/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net462/Polyfill_Stream.cs b/src/Split/net462/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net462/Polyfill_Stream.cs +++ b/src/Split/net462/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net462/Polyfill_Stream_Read.cs b/src/Split/net462/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net462/Polyfill_Stream_Read.cs +++ b/src/Split/net462/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net462/Polyfill_Stream_Write.cs b/src/Split/net462/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net462/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net47/Polyfill_Stream.cs b/src/Split/net47/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net47/Polyfill_Stream.cs +++ b/src/Split/net47/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net47/Polyfill_Stream_Read.cs b/src/Split/net47/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net47/Polyfill_Stream_Read.cs +++ b/src/Split/net47/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net47/Polyfill_Stream_Write.cs b/src/Split/net47/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net47/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net471/Polyfill_Stream.cs b/src/Split/net471/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net471/Polyfill_Stream.cs +++ b/src/Split/net471/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net471/Polyfill_Stream_Read.cs b/src/Split/net471/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net471/Polyfill_Stream_Read.cs +++ b/src/Split/net471/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net471/Polyfill_Stream_Write.cs b/src/Split/net471/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net471/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net472/Polyfill_Stream.cs b/src/Split/net472/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net472/Polyfill_Stream.cs +++ b/src/Split/net472/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net472/Polyfill_Stream_Read.cs b/src/Split/net472/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net472/Polyfill_Stream_Read.cs +++ b/src/Split/net472/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net472/Polyfill_Stream_Write.cs b/src/Split/net472/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net472/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net48/Polyfill_Stream.cs b/src/Split/net48/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net48/Polyfill_Stream.cs +++ b/src/Split/net48/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net48/Polyfill_Stream_Read.cs b/src/Split/net48/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net48/Polyfill_Stream_Read.cs +++ b/src/Split/net48/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net48/Polyfill_Stream_Write.cs b/src/Split/net48/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net48/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net481/Polyfill_Stream.cs b/src/Split/net481/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/net481/Polyfill_Stream.cs +++ b/src/Split/net481/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/net481/Polyfill_Stream_Read.cs b/src/Split/net481/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/net481/Polyfill_Stream_Read.cs +++ b/src/Split/net481/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/net481/Polyfill_Stream_Write.cs b/src/Split/net481/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/net481/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/net5.0/Polyfill_Stream_Read.cs b/src/Split/net5.0/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/net5.0/Polyfill_Stream_Read.cs +++ b/src/Split/net5.0/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/net6.0/Polyfill_Stream_Read.cs b/src/Split/net6.0/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/net6.0/Polyfill_Stream_Read.cs +++ b/src/Split/net6.0/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/netcoreapp2.0/Polyfill_Stream.cs b/src/Split/netcoreapp2.0/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/netcoreapp2.0/Polyfill_Stream.cs +++ b/src/Split/netcoreapp2.0/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/netcoreapp2.0/Polyfill_Stream_Read.cs b/src/Split/netcoreapp2.0/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/netcoreapp2.0/Polyfill_Stream_Read.cs +++ b/src/Split/netcoreapp2.0/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/netcoreapp2.0/Polyfill_Stream_Write.cs b/src/Split/netcoreapp2.0/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/netcoreapp2.0/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/netcoreapp2.1/Polyfill_Stream_Read.cs b/src/Split/netcoreapp2.1/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/netcoreapp2.1/Polyfill_Stream_Read.cs +++ b/src/Split/netcoreapp2.1/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/netcoreapp2.2/Polyfill_Stream_Read.cs b/src/Split/netcoreapp2.2/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/netcoreapp2.2/Polyfill_Stream_Read.cs +++ b/src/Split/netcoreapp2.2/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/netcoreapp3.0/Polyfill_Stream_Read.cs b/src/Split/netcoreapp3.0/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/netcoreapp3.0/Polyfill_Stream_Read.cs +++ b/src/Split/netcoreapp3.0/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/netcoreapp3.1/Polyfill_Stream_Read.cs b/src/Split/netcoreapp3.1/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/netcoreapp3.1/Polyfill_Stream_Read.cs +++ b/src/Split/netcoreapp3.1/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/netstandard2.0/Polyfill_Stream.cs b/src/Split/netstandard2.0/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/netstandard2.0/Polyfill_Stream.cs +++ b/src/Split/netstandard2.0/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/netstandard2.0/Polyfill_Stream_Read.cs b/src/Split/netstandard2.0/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/netstandard2.0/Polyfill_Stream_Read.cs +++ b/src/Split/netstandard2.0/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/netstandard2.0/Polyfill_Stream_Write.cs b/src/Split/netstandard2.0/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/netstandard2.0/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Split/netstandard2.1/Polyfill_Stream_Read.cs b/src/Split/netstandard2.1/Polyfill_Stream_Read.cs index bb294d77..a13a6a2a 100644 --- a/src/Split/netstandard2.1/Polyfill_Stream_Read.cs +++ b/src/Split/netstandard2.1/Polyfill_Stream_Read.cs @@ -3,6 +3,7 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill diff --git a/src/Split/uap10.0/Polyfill_Stream.cs b/src/Split/uap10.0/Polyfill_Stream.cs index 18e50360..cb050cc2 100644 --- a/src/Split/uap10.0/Polyfill_Stream.cs +++ b/src/Split/uap10.0/Polyfill_Stream.cs @@ -3,45 +3,10 @@ namespace Polyfills; using System; using System.IO; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { -#if FeatureMemory && FeatureValueTask - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by - /// the number of bytes read, and monitors cancellation requests. - /// - public static ValueTask ReadAsync( - this Stream target, - Memory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current position - /// within this stream by the number of bytes written, and monitors cancellation requests. - /// - public static ValueTask WriteAsync( - this Stream target, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); - return new(task); - } -#endif /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Split/uap10.0/Polyfill_Stream_Read.cs b/src/Split/uap10.0/Polyfill_Stream_Read.cs index 8eefba46..39f4a2b7 100644 --- a/src/Split/uap10.0/Polyfill_Stream_Read.cs +++ b/src/Split/uap10.0/Polyfill_Stream_Read.cs @@ -3,10 +3,29 @@ namespace Polyfills; using System; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; static partial class Polyfill { +#if FeatureMemory && FeatureValueTask + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + public static ValueTask ReadAsync( + this Stream target, + Memory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory) buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif #if FeatureMemory /// /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. diff --git a/src/Split/uap10.0/Polyfill_Stream_Write.cs b/src/Split/uap10.0/Polyfill_Stream_Write.cs new file mode 100644 index 00000000..4d562723 --- /dev/null +++ b/src/Split/uap10.0/Polyfill_Stream_Write.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#if FeatureMemory +namespace Polyfills; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +static partial class Polyfill +{ + /// + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current + /// position within this stream by the number of bytes written. + /// + public static void Write(this Stream target, ReadOnlySpan buffer) + { + var sharedBuffer = buffer.ToArray(); + target.Write(sharedBuffer, 0, sharedBuffer.Length); + } +#if FeatureValueTask + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + public static ValueTask WriteAsync( + this Stream target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + var task = target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken); + return new(task); + } +#endif +} +#endif diff --git a/src/Tests/PolyfillTests_Stream.cs b/src/Tests/PolyfillTests_Stream.cs index 01e87cd2..4d889697 100644 --- a/src/Tests/PolyfillTests_Stream.cs +++ b/src/Tests/PolyfillTests_Stream.cs @@ -155,6 +155,23 @@ await Assert.That(async () => } #if FeatureMemory + [Test] + public async Task StreamWriteSpan() + { + using var stream = new MemoryStream(); + var data = new byte[] {1, 2, 3, 4, 5}; + stream.Write((ReadOnlySpan)data); + await Assert.That(stream.ToArray().SequenceEqual(data)).IsTrue(); + } + + [Test] + public async Task StreamWriteSpan_Empty() + { + using var stream = new MemoryStream(); + stream.Write(ReadOnlySpan.Empty); + await Assert.That(stream.ToArray()).IsEmpty(); + } + [Test] public async Task ReadExactlySpan_ReadsExactBytes() {