diff --git a/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs b/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs index 40175713e69b3f..80b7286baa5416 100644 --- a/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs +++ b/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs @@ -49,6 +49,7 @@ public override void Flush() { } public override void SetLength(long value) { } public override void Write(byte[] buffer, int offset, int count) { } public override void Write(System.ReadOnlySpan buffer) { } + public override void WriteByte(byte value) { } public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } @@ -83,6 +84,7 @@ public override void Flush() { } public override void SetLength(long value) { } public override void Write(byte[] buffer, int offset, int count) { } public override void Write(System.ReadOnlySpan buffer) { } + public override void WriteByte(byte value) { } public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs index 84b7ad0e5acade..8d818b2fe3ebc7 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs @@ -457,6 +457,21 @@ public override void Write(byte[] buffer, int offset, int count) WriteCore(new ReadOnlySpan(buffer, offset, count)); } + public override void WriteByte(byte value) + { + if (GetType() != typeof(DeflateStream)) + { + // DeflateStream is not sealed, and a derived type may have overridden Write(byte[], int, int) prior + // to this WriteByte override being introduced. In that case, this WriteByte override + // should use the behavior of the Write(byte[],int,int) overload. + base.WriteByte(value); + } + else + { + WriteCore(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); + } + } + public override void Write(ReadOnlySpan buffer) { if (GetType() != typeof(DeflateStream)) diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/GZipStream.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/GZipStream.cs index 8e674d13b97a82..0d184387d3e82d 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/GZipStream.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/GZipStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -111,6 +112,22 @@ public override void Write(byte[] buffer, int offset, int count) _deflateStream.Write(buffer, offset, count); } + public override void WriteByte(byte value) + { + if (GetType() != typeof(GZipStream)) + { + // GZipStream is not sealed, and a derived type may have overridden Write(byte[], int, int) prior + // to this WriteByte override being introduced. In that case, this WriteByte override + // should use the behavior of the Write(byte[],int,int) overload. + base.WriteByte(value); + } + else + { + CheckDeflateStream(); + _deflateStream.WriteCore(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); + } + } + public override void Write(ReadOnlySpan buffer) { if (GetType() != typeof(GZipStream)) diff --git a/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs b/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs index be0b43d4200f37..0d4e4997cc4894 100644 --- a/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs +++ b/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs @@ -102,6 +102,7 @@ public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public override int Read(byte[] buffer, int offset, int count) { throw null; } public override int Read(System.Span buffer) { throw null; } + public override int ReadByte() { throw null; } public override System.Threading.Tasks.Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override int ReadTimeout { get { throw null; } set { } } @@ -112,6 +113,7 @@ public void Shutdown() { } public System.Threading.Tasks.ValueTask WaitForWriteCompletionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override void Write(byte[] buffer, int offset, int count) { } public override void Write(System.ReadOnlySpan buffer) { } + public override void WriteByte(byte value) { } public System.Threading.Tasks.ValueTask WriteAsync(System.Buffers.ReadOnlySequence buffers, bool endStream, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.Threading.Tasks.ValueTask WriteAsync(System.Buffers.ReadOnlySequence buffers, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs index 912d32c9ad889c..98fdd51fb36330 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.IO; using System.Net.Quic.Implementations; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -46,6 +47,12 @@ public override int Read(byte[] buffer, int offset, int count) return Read(buffer.AsSpan(offset, count)); } + public override int ReadByte() + { + byte b = 0; + return Read(MemoryMarshal.CreateSpan(ref b, 1)) != 0 ? b : -1; + } + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { ValidateBufferArguments(buffer, offset, count); @@ -58,6 +65,11 @@ public override void Write(byte[] buffer, int offset, int count) Write(buffer.AsSpan(offset, count)); } + public override void WriteByte(byte value) + { + Write(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); + } + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { ValidateBufferArguments(buffer, offset, count);