From 8aa3dd159e12d922221ac3ede329e77416ede2cb Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 3 Mar 2026 15:41:34 +1100 Subject: [PATCH 1/3] Add Stream.Write(ReadOnlySpan) --- ...piBuilderTests-windows-net11.0-report.html | 1593 +++++++++++++++++ TestResults/Tests-windows-net10.0-report.html | 1593 +++++++++++++++++ TestResults/Tests-windows-net48-report.html | 1593 +++++++++++++++++ apiCount.include.md | 2 +- api_list.include.md | 1 + assemblySize.include.md | 38 +- readme.md | 41 +- src/Consume/Consume.cs | 5 +- src/Polyfill/Polyfill_Stream.cs | 42 - src/Polyfill/Polyfill_Stream_Read.cs | 25 + src/Polyfill/Polyfill_Stream_Write.cs | 46 + src/Split/net461/Polyfill_Stream.cs | 35 - src/Split/net461/Polyfill_Stream_Read.cs | 19 + src/Split/net461/Polyfill_Stream_Write.cs | 40 + src/Split/net462/Polyfill_Stream.cs | 35 - src/Split/net462/Polyfill_Stream_Read.cs | 19 + src/Split/net462/Polyfill_Stream_Write.cs | 40 + src/Split/net47/Polyfill_Stream.cs | 35 - src/Split/net47/Polyfill_Stream_Read.cs | 19 + src/Split/net47/Polyfill_Stream_Write.cs | 40 + src/Split/net471/Polyfill_Stream.cs | 35 - src/Split/net471/Polyfill_Stream_Read.cs | 19 + src/Split/net471/Polyfill_Stream_Write.cs | 40 + src/Split/net472/Polyfill_Stream.cs | 35 - src/Split/net472/Polyfill_Stream_Read.cs | 19 + src/Split/net472/Polyfill_Stream_Write.cs | 40 + src/Split/net48/Polyfill_Stream.cs | 35 - src/Split/net48/Polyfill_Stream_Read.cs | 19 + src/Split/net48/Polyfill_Stream_Write.cs | 40 + src/Split/net481/Polyfill_Stream.cs | 35 - src/Split/net481/Polyfill_Stream_Read.cs | 19 + src/Split/net481/Polyfill_Stream_Write.cs | 40 + src/Split/net5.0/Polyfill_Stream_Read.cs | 1 + src/Split/net6.0/Polyfill_Stream_Read.cs | 1 + src/Split/netcoreapp2.0/Polyfill_Stream.cs | 35 - .../netcoreapp2.0/Polyfill_Stream_Read.cs | 19 + .../netcoreapp2.0/Polyfill_Stream_Write.cs | 40 + .../netcoreapp2.1/Polyfill_Stream_Read.cs | 1 + .../netcoreapp2.2/Polyfill_Stream_Read.cs | 1 + .../netcoreapp3.0/Polyfill_Stream_Read.cs | 1 + .../netcoreapp3.1/Polyfill_Stream_Read.cs | 1 + src/Split/netstandard2.0/Polyfill_Stream.cs | 35 - .../netstandard2.0/Polyfill_Stream_Read.cs | 19 + .../netstandard2.0/Polyfill_Stream_Write.cs | 40 + .../netstandard2.1/Polyfill_Stream_Read.cs | 1 + src/Split/uap10.0/Polyfill_Stream.cs | 35 - src/Split/uap10.0/Polyfill_Stream_Read.cs | 19 + src/Split/uap10.0/Polyfill_Stream_Write.cs | 40 + 48 files changed, 5493 insertions(+), 433 deletions(-) create mode 100644 TestResults/ApiBuilderTests-windows-net11.0-report.html create mode 100644 TestResults/Tests-windows-net10.0-report.html create mode 100644 TestResults/Tests-windows-net48-report.html create mode 100644 src/Polyfill/Polyfill_Stream_Write.cs create mode 100644 src/Split/net461/Polyfill_Stream_Write.cs create mode 100644 src/Split/net462/Polyfill_Stream_Write.cs create mode 100644 src/Split/net47/Polyfill_Stream_Write.cs create mode 100644 src/Split/net471/Polyfill_Stream_Write.cs create mode 100644 src/Split/net472/Polyfill_Stream_Write.cs create mode 100644 src/Split/net48/Polyfill_Stream_Write.cs create mode 100644 src/Split/net481/Polyfill_Stream_Write.cs create mode 100644 src/Split/netcoreapp2.0/Polyfill_Stream_Write.cs create mode 100644 src/Split/netstandard2.0/Polyfill_Stream_Write.cs create mode 100644 src/Split/uap10.0/Polyfill_Stream_Write.cs diff --git a/TestResults/ApiBuilderTests-windows-net11.0-report.html b/TestResults/ApiBuilderTests-windows-net11.0-report.html new file mode 100644 index 000000000..0d733a350 --- /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 000000000..6fdfcf6bc --- /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 000000000..88f554b9e --- /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 721323422..4ee9be436 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 c8603caea..04ff720c7 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/assemblySize.include.md b/assemblySize.include.md index f9edb81bc..8a1fd8a5c 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -2,16 +2,16 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 238.0KB | +230.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | +| netstandard2.0 | 8.0KB | 238.5KB | +230.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | | netstandard2.1 | 8.5KB | 190.0KB | +181.5KB | +12.0KB | +9.5KB | +12.0KB | +17.0KB | -| net461 | 8.5KB | 244.5KB | +236.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net462 | 7.0KB | 243.5KB | +236.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 243.0KB | +236.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | -| net471 | 8.5KB | 243.0KB | +234.5KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | -| net472 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net461 | 8.5KB | 244.5KB | +236.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | +| net462 | 7.0KB | 243.5KB | +236.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net47 | 7.0KB | 243.5KB | +236.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net471 | 8.5KB | 243.5KB | +235.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net472 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | | net48 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net481 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.0 | 9.0KB | 218.5KB | +209.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net481 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp2.0 | 9.0KB | 218.5KB | +209.5KB | +9.0KB | +7.0KB | +9.0KB | +14.0KB | | netcoreapp2.1 | 9.0KB | 200.5KB | +191.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | | netcoreapp2.2 | 9.0KB | 200.5KB | +191.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | | netcoreapp3.0 | 9.5KB | 188.0KB | +178.5KB | +12.5KB | +10.0KB | +12.5KB | +17.0KB | @@ -20,7 +20,7 @@ | net6.0 | 10.0KB | 115.0KB | +105.0KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | | net7.0 | 10.0KB | 86.0KB | +76.0KB | +9.5KB | +6.0KB | +512bytes | +3.5KB | | net8.0 | 9.5KB | 69.5KB | +60.0KB | +8.5KB | | +512bytes | +3.5KB | -| net9.0 | 9.5KB | 35.5KB | +26.0KB | +9.0KB | | +1.0KB | +3.5KB | +| net9.0 | 10.0KB | 35.5KB | +25.5KB | +9.0KB | | +1.0KB | +3.5KB | | net10.0 | 10.0KB | 22.5KB | +12.5KB | +9.0KB | | +512bytes | +3.5KB | | net11.0 | 10.0KB | 19.0KB | +9.0KB | +9.0KB | | +1.0KB | +4.0KB | @@ -29,16 +29,16 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 353.3KB | +345.3KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | +| netstandard2.0 | 8.0KB | 354.3KB | +346.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | | netstandard2.1 | 8.5KB | 281.2KB | +272.7KB | +19.7KB | +11.2KB | +16.9KB | +22.4KB | -| net461 | 8.5KB | 360.3KB | +351.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net462 | 7.0KB | 359.3KB | +352.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 358.5KB | +351.5KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | -| net471 | 8.5KB | 358.5KB | +350.0KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | -| net472 | 8.5KB | 356.5KB | +348.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net48 | 8.5KB | 356.5KB | +348.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net481 | 8.5KB | 356.5KB | +348.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.0 | 9.0KB | 324.0KB | +315.0KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 360.8KB | +352.3KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | +| net462 | 7.0KB | 359.8KB | +352.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net47 | 7.0KB | 359.5KB | +352.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net471 | 8.5KB | 359.5KB | +351.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net472 | 8.5KB | 357.0KB | +348.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net48 | 8.5KB | 357.0KB | +348.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 357.0KB | +348.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.0 | 9.0KB | 324.5KB | +315.5KB | +16.7KB | +8.7KB | +13.9KB | +19.4KB | | netcoreapp2.1 | 9.0KB | 295.9KB | +286.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | | netcoreapp2.2 | 9.0KB | 295.9KB | +286.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | | netcoreapp3.0 | 9.5KB | 274.2KB | +264.7KB | +20.2KB | +11.7KB | +17.4KB | +22.4KB | @@ -47,6 +47,6 @@ | net6.0 | 10.0KB | 170.0KB | +160.0KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | | net7.0 | 10.0KB | 124.6KB | +114.6KB | +17.1KB | +7.4KB | +1.1KB | +4.2KB | | net8.0 | 9.5KB | 99.1KB | +89.6KB | +16.0KB | +299bytes | +1.1KB | +4.2KB | -| net9.0 | 9.5KB | 51.6KB | +42.1KB | +16.5KB | | +1.6KB | +4.2KB | +| net9.0 | 10.0KB | 51.6KB | +41.6KB | +16.5KB | | +1.6KB | +4.2KB | | net10.0 | 10.0KB | 33.9KB | +23.9KB | +16.5KB | | +1.1KB | +4.2KB | | net11.0 | 10.0KB | 28.5KB | +18.5KB | +16.5KB | | +1.6KB | +4.7KB | diff --git a/readme.md b/readme.md index 2f09cd7b0..4eef3763f 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.** @@ -68,16 +68,16 @@ This project uses features from the current stable SDK and C# language. As such | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 238.0KB | +230.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | +| netstandard2.0 | 8.0KB | 238.5KB | +230.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | | netstandard2.1 | 8.5KB | 190.0KB | +181.5KB | +12.0KB | +9.5KB | +12.0KB | +17.0KB | -| net461 | 8.5KB | 244.5KB | +236.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net462 | 7.0KB | 243.5KB | +236.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 243.0KB | +236.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | -| net471 | 8.5KB | 243.0KB | +234.5KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | -| net472 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net461 | 8.5KB | 244.5KB | +236.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | +| net462 | 7.0KB | 243.5KB | +236.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net47 | 7.0KB | 243.5KB | +236.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net471 | 8.5KB | 243.5KB | +235.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net472 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | | net48 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net481 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.0 | 9.0KB | 218.5KB | +209.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net481 | 8.5KB | 242.0KB | +233.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp2.0 | 9.0KB | 218.5KB | +209.5KB | +9.0KB | +7.0KB | +9.0KB | +14.0KB | | netcoreapp2.1 | 9.0KB | 200.5KB | +191.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | | netcoreapp2.2 | 9.0KB | 200.5KB | +191.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | | netcoreapp3.0 | 9.5KB | 188.0KB | +178.5KB | +12.5KB | +10.0KB | +12.5KB | +17.0KB | @@ -86,7 +86,7 @@ This project uses features from the current stable SDK and C# language. As such | net6.0 | 10.0KB | 115.0KB | +105.0KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | | net7.0 | 10.0KB | 86.0KB | +76.0KB | +9.5KB | +6.0KB | +512bytes | +3.5KB | | net8.0 | 9.5KB | 69.5KB | +60.0KB | +8.5KB | | +512bytes | +3.5KB | -| net9.0 | 9.5KB | 35.5KB | +26.0KB | +9.0KB | | +1.0KB | +3.5KB | +| net9.0 | 10.0KB | 35.5KB | +25.5KB | +9.0KB | | +1.0KB | +3.5KB | | net10.0 | 10.0KB | 22.5KB | +12.5KB | +9.0KB | | +512bytes | +3.5KB | | net11.0 | 10.0KB | 19.0KB | +9.0KB | +9.0KB | | +1.0KB | +4.0KB | @@ -95,16 +95,16 @@ This project uses features from the current stable SDK and C# language. As such | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 353.3KB | +345.3KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | +| netstandard2.0 | 8.0KB | 354.1KB | +346.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | | netstandard2.1 | 8.5KB | 281.2KB | +272.7KB | +19.7KB | +11.2KB | +16.9KB | +22.4KB | -| net461 | 8.5KB | 360.3KB | +351.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net462 | 7.0KB | 359.3KB | +352.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 358.5KB | +351.5KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | -| net471 | 8.5KB | 358.5KB | +350.0KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | -| net472 | 8.5KB | 356.5KB | +348.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net48 | 8.5KB | 356.5KB | +348.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net481 | 8.5KB | 356.5KB | +348.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.0 | 9.0KB | 324.0KB | +315.0KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 360.6KB | +352.1KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | +| net462 | 7.0KB | 359.6KB | +352.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net47 | 7.0KB | 359.4KB | +352.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net471 | 8.5KB | 359.4KB | +350.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net472 | 8.5KB | 356.8KB | +348.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net48 | 8.5KB | 356.8KB | +348.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 356.8KB | +348.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.0 | 9.0KB | 324.3KB | +315.3KB | +16.7KB | +8.7KB | +13.9KB | +19.4KB | | netcoreapp2.1 | 9.0KB | 295.9KB | +286.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | | netcoreapp2.2 | 9.0KB | 295.9KB | +286.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | | netcoreapp3.0 | 9.5KB | 274.2KB | +264.7KB | +20.2KB | +11.7KB | +17.4KB | +22.4KB | @@ -113,7 +113,7 @@ This project uses features from the current stable SDK and C# language. As such | net6.0 | 10.0KB | 170.0KB | +160.0KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | | net7.0 | 10.0KB | 124.6KB | +114.6KB | +17.1KB | +7.4KB | +1.1KB | +4.2KB | | net8.0 | 9.5KB | 99.1KB | +89.6KB | +16.0KB | +299bytes | +1.1KB | +4.2KB | -| net9.0 | 9.5KB | 51.6KB | +42.1KB | +16.5KB | | +1.6KB | +4.2KB | +| net9.0 | 10.0KB | 51.6KB | +41.6KB | +16.5KB | | +1.6KB | +4.2KB | | net10.0 | 10.0KB | 33.9KB | +23.9KB | +16.5KB | | +1.1KB | +4.2KB | | net11.0 | 10.0KB | 28.5KB | +18.5KB | +16.5KB | | +1.6KB | +4.7KB | @@ -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 c6844327d..8c2c539d4 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/Polyfill/Polyfill_Stream.cs b/src/Polyfill/Polyfill_Stream.cs index 0a742f3bb..50ccaf46c 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 1e6bf7d70..d26c52ad1 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 000000000..ff2d9e23e --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 bb294d779..a13a6a2aa 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 bb294d779..a13a6a2aa 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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 bb294d779..a13a6a2aa 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 bb294d779..a13a6a2aa 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 bb294d779..a13a6a2aa 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 bb294d779..a13a6a2aa 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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 bb294d779..a13a6a2aa 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 18e503600..cb050cc28 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 8eefba465..39f4a2b7d 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 000000000..4d562723c --- /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 From cddb82007d24159c698c2816a96251f4caac2e6b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 3 Mar 2026 15:41:40 +1100 Subject: [PATCH 2/3] Update PolyfillTests_Stream.cs --- src/Tests/PolyfillTests_Stream.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Tests/PolyfillTests_Stream.cs b/src/Tests/PolyfillTests_Stream.cs index 01e87cd28..4d889697e 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() { From f5814e795d83f5f1d27f03f29d4d3351a6b4680c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 3 Mar 2026 15:42:36 +1100 Subject: [PATCH 3/3] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ad460c865..750eb7a20 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