From ea688e1f4cebb8a03672bb4533200e6c90c0aa32 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sat, 13 Feb 2021 17:52:31 +0000 Subject: [PATCH] Writer problems still :( --- .../Compressors/Deflate/DeflateStream.cs | 52 ++-------------- .../Compressors/Deflate/GZipStream.cs | 26 ++------ .../Compressors/Deflate/ZlibStream.cs | 62 +++---------------- .../Compressors/Xz/Filters/Lzma2Filter.cs | 10 +-- .../Compressors/Xz/ReadOnlyStream.cs | 22 +++---- src/SharpCompress/Compressors/Xz/XZStream.cs | 5 ++ src/SharpCompress/IO/AsyncStream.cs | 5 ++ tests/SharpCompress.Test/ADCTest.cs | 7 ++- tests/SharpCompress.Test/Xz/XZBlockTests.cs | 41 ++++++------ 9 files changed, 65 insertions(+), 165 deletions(-) diff --git a/src/SharpCompress/Compressors/Deflate/DeflateStream.cs b/src/SharpCompress/Compressors/Deflate/DeflateStream.cs index a324400d..ceeb0ad4 100644 --- a/src/SharpCompress/Compressors/Deflate/DeflateStream.cs +++ b/src/SharpCompress/Compressors/Deflate/DeflateStream.cs @@ -29,10 +29,11 @@ using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; +using SharpCompress.IO; namespace SharpCompress.Compressors.Deflate { - public class DeflateStream : Stream + public class DeflateStream : AsyncStream { private readonly ZlibBaseStream _baseStream; private bool _disposed; @@ -218,14 +219,6 @@ namespace SharpCompress.Compressors.Deflate /// /// This may or may not result in a Close() call on the captive stream. /// - protected override void Dispose(bool disposing) - { - if (disposing) - { - throw new NotImplementedException(); - } - } - public override async ValueTask DisposeAsync() { if (!_disposed) @@ -238,13 +231,13 @@ namespace SharpCompress.Compressors.Deflate /// /// Flush the stream. /// - public override void Flush() + public override async Task FlushAsync(CancellationToken cancellationToken) { if (_disposed) { throw new ObjectDisposedException("DeflateStream"); } - _baseStream.Flush(); + await _baseStream.FlushAsync(cancellationToken); } /// @@ -273,15 +266,6 @@ namespace SharpCompress.Compressors.Deflate /// the offset within that data array to put the first byte read. /// the number of bytes to read. /// the number of bytes actually read - public override int Read(byte[] buffer, int offset, int count) - { - if (_disposed) - { - throw new ObjectDisposedException("DeflateStream"); - } - return _baseStream.Read(buffer, offset, count); - } - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_disposed) @@ -290,16 +274,6 @@ namespace SharpCompress.Compressors.Deflate } return await _baseStream.ReadAsync(buffer, offset, count, cancellationToken); } - - public override int ReadByte() - { - if (_disposed) - { - throw new ObjectDisposedException("DeflateStream"); - } - return _baseStream.ReadByte(); - } - /// /// Calling this method always throws a . /// @@ -349,15 +323,6 @@ namespace SharpCompress.Compressors.Deflate /// The buffer holding data to write to the stream. /// the offset within that data array to find the first byte to write. /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - if (_disposed) - { - throw new ObjectDisposedException("DeflateStream"); - } - _baseStream.Write(buffer, offset, count); - } - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_disposed) @@ -367,15 +332,6 @@ namespace SharpCompress.Compressors.Deflate await _baseStream.WriteAsync(buffer, offset, count, cancellationToken); } - public override void WriteByte(byte value) - { - if (_disposed) - { - throw new ObjectDisposedException("DeflateStream"); - } - _baseStream.WriteByte(value); - } - #endregion public MemoryStream InputBuffer => new MemoryStream(_baseStream._z.InputBuffer, _baseStream._z.NextIn, diff --git a/src/SharpCompress/Compressors/Deflate/GZipStream.cs b/src/SharpCompress/Compressors/Deflate/GZipStream.cs index 991fe3db..8cf7fcd9 100644 --- a/src/SharpCompress/Compressors/Deflate/GZipStream.cs +++ b/src/SharpCompress/Compressors/Deflate/GZipStream.cs @@ -33,10 +33,11 @@ using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; +using SharpCompress.IO; namespace SharpCompress.Compressors.Deflate { - public class GZipStream : Stream + public class GZipStream : AsyncStream { private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); @@ -197,14 +198,6 @@ namespace SharpCompress.Compressors.Deflate /// /// This may or may not result in a Close() call on the captive stream. /// - protected override void Dispose(bool disposing) - { - if (disposing) - { - throw new NotImplementedException(); - } - } - public override async ValueTask DisposeAsync() { if (!_disposed) @@ -221,13 +214,13 @@ namespace SharpCompress.Compressors.Deflate /// /// Flush the stream. /// - public override void Flush() + public override Task FlushAsync(CancellationToken cancellationToken) { if (_disposed) { throw new ObjectDisposedException("GZipStream"); } - _baseStream.Flush(); + return _baseStream.FlushAsync(cancellationToken); } /// @@ -261,12 +254,7 @@ namespace SharpCompress.Compressors.Deflate /// the offset within that data array to put the first byte read. /// the number of bytes to read. /// the number of bytes actually read - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_disposed) { @@ -329,10 +317,6 @@ namespace SharpCompress.Compressors.Deflate /// The buffer holding data to write to the stream. /// the offset within that data array to find the first byte to write. /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - } - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_disposed) diff --git a/src/SharpCompress/Compressors/Deflate/ZlibStream.cs b/src/SharpCompress/Compressors/Deflate/ZlibStream.cs index 68dbded4..cf4c198f 100644 --- a/src/SharpCompress/Compressors/Deflate/ZlibStream.cs +++ b/src/SharpCompress/Compressors/Deflate/ZlibStream.cs @@ -30,10 +30,11 @@ using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; +using SharpCompress.IO; namespace SharpCompress.Compressors.Deflate { - public class ZlibStream : Stream + public class ZlibStream : AsyncStream { private readonly ZlibBaseStream _baseStream; private bool _disposed; @@ -206,35 +207,25 @@ namespace SharpCompress.Compressors.Deflate /// /// This may or may not result in a Close() call on the captive stream. /// - protected override void Dispose(bool disposing) + public override async ValueTask DisposeAsync() { - try + if (!_disposed) { - if (!_disposed) - { - if (disposing) - { - _baseStream?.Dispose(); - } - _disposed = true; - } - } - finally - { - base.Dispose(disposing); + await _baseStream.DisposeAsync(); + _disposed = true; } } /// /// Flush the stream. /// - public override void Flush() + public override Task FlushAsync(CancellationToken cancellationToken) { if (_disposed) { throw new ObjectDisposedException("ZlibStream"); } - _baseStream.Flush(); + return _baseStream.FlushAsync(cancellationToken); } /// @@ -263,15 +254,6 @@ namespace SharpCompress.Compressors.Deflate /// The buffer into which the read data should be placed. /// the offset within that data array to put the first byte read. /// the number of bytes to read. - public override int Read(byte[] buffer, int offset, int count) - { - if (_disposed) - { - throw new ObjectDisposedException("ZlibStream"); - } - return _baseStream.Read(buffer, offset, count); - } - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_disposed) @@ -281,15 +263,6 @@ namespace SharpCompress.Compressors.Deflate return await _baseStream.ReadAsync(buffer, offset, count, cancellationToken); } - public override int ReadByte() - { - if (_disposed) - { - throw new ObjectDisposedException("ZlibStream"); - } - return _baseStream.ReadByte(); - } - /// /// Calling this method always throws a . /// @@ -332,15 +305,6 @@ namespace SharpCompress.Compressors.Deflate /// The buffer holding data to write to the stream. /// the offset within that data array to find the first byte to write. /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - if (_disposed) - { - throw new ObjectDisposedException("ZlibStream"); - } - _baseStream.Write(buffer, offset, count); - } - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_disposed) @@ -349,16 +313,6 @@ namespace SharpCompress.Compressors.Deflate } await _baseStream.WriteAsync(buffer, offset, count, cancellationToken); } - - public override void WriteByte(byte value) - { - if (_disposed) - { - throw new ObjectDisposedException("ZlibStream"); - } - _baseStream.WriteByte(value); - } - #endregion System.IO.Stream methods } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs b/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs index 9d926fd0..15a96514 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading; using System.Threading.Tasks; using SharpCompress.Compressors.LZMA; @@ -55,14 +56,9 @@ namespace SharpCompress.Compressors.Xz.Filters BaseStream = await LzmaStream.CreateAsync(new[] { _dictionarySize }, stream); } - public override int Read(byte[] buffer, int offset, int count) + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - return BaseStream.Read(buffer, offset, count); - } - - public override int ReadByte() - { - return BaseStream.ReadByte(); + return BaseStream.ReadAsync(buffer, offset, count, cancellationToken); } } } diff --git a/src/SharpCompress/Compressors/Xz/ReadOnlyStream.cs b/src/SharpCompress/Compressors/Xz/ReadOnlyStream.cs index a8324366..cacb402c 100644 --- a/src/SharpCompress/Compressors/Xz/ReadOnlyStream.cs +++ b/src/SharpCompress/Compressors/Xz/ReadOnlyStream.cs @@ -2,10 +2,13 @@ using System; using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.IO; namespace SharpCompress.Compressors.Xz { - public abstract class ReadOnlyStream : Stream + public abstract class ReadOnlyStream : AsyncStream { public Stream BaseStream { get; protected set; } @@ -23,16 +26,6 @@ namespace SharpCompress.Compressors.Xz set => throw new NotSupportedException(); } - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - public override void Flush() - { - throw new NotSupportedException(); - } - public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); @@ -43,7 +36,12 @@ namespace SharpCompress.Compressors.Xz throw new NotSupportedException(); } - public override void Write(byte[] buffer, int offset, int count) + public override ValueTask DisposeAsync() + { + return new(); + } + + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { throw new NotSupportedException(); } diff --git a/src/SharpCompress/Compressors/Xz/XZStream.cs b/src/SharpCompress/Compressors/Xz/XZStream.cs index 41a76ff8..be9e2a38 100644 --- a/src/SharpCompress/Compressors/Xz/XZStream.cs +++ b/src/SharpCompress/Compressors/Xz/XZStream.cs @@ -48,6 +48,11 @@ namespace SharpCompress.Compressors.Xz { } + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return await ReadAsync(new Memory(buffer, offset, count), cancellationToken); + } + public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) { int bytesRead = 0; diff --git a/src/SharpCompress/IO/AsyncStream.cs b/src/SharpCompress/IO/AsyncStream.cs index 6a73d04e..d46ae8ab 100644 --- a/src/SharpCompress/IO/AsyncStream.cs +++ b/src/SharpCompress/IO/AsyncStream.cs @@ -52,6 +52,11 @@ namespace SharpCompress.IO throw new NotSupportedException(); } + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return await ReadAsync(new Memory(buffer, offset, count), cancellationToken); + } + public abstract override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken); #if !NET461 && !NETSTANDARD2_0 diff --git a/tests/SharpCompress.Test/ADCTest.cs b/tests/SharpCompress.Test/ADCTest.cs index 26ea2699..ac9b7b33 100644 --- a/tests/SharpCompress.Test/ADCTest.cs +++ b/tests/SharpCompress.Test/ADCTest.cs @@ -24,6 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System.IO; +using System.Threading.Tasks; using SharpCompress.Compressors; using SharpCompress.Compressors.ADC; using SharpCompress.Compressors.Deflate; @@ -128,16 +129,16 @@ namespace SharpCompress.Test } [Fact] - public void TestCrc32Stream() + public async Task TestCrc32Stream() { - using (FileStream decFs = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar"))) + await using (FileStream decFs = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar"))) { var crc32 = new CRC32().GetCrc32(decFs); decFs.Seek(0, SeekOrigin.Begin); var memory = new MemoryStream(); var crcStream = new Crc32Stream(memory, 0xEDB88320, 0xFFFFFFFF); - decFs.CopyTo(crcStream); + await decFs.CopyToAsync(crcStream); decFs.Seek(0, SeekOrigin.Begin); diff --git a/tests/SharpCompress.Test/Xz/XZBlockTests.cs b/tests/SharpCompress.Test/Xz/XZBlockTests.cs index 50ac0cb1..3142002e 100644 --- a/tests/SharpCompress.Test/Xz/XZBlockTests.cs +++ b/tests/SharpCompress.Test/Xz/XZBlockTests.cs @@ -1,5 +1,6 @@ using System.Text; using System.IO; +using System.Threading.Tasks; using SharpCompress.Compressors.Xz; using Xunit; @@ -17,10 +18,10 @@ namespace SharpCompress.Test.Xz stream.Position = 12; } - private byte[] ReadBytes(XZBlock block, int bytesToRead) + private async ValueTask ReadBytesAsync(XZBlock block, int bytesToRead) { byte[] buffer = new byte[bytesToRead]; - var read = block.Read(buffer, 0, bytesToRead); + var read = await block.ReadAsync(buffer, 0, bytesToRead); if (read != bytesToRead) { throw new EndOfStreamException(); @@ -30,71 +31,71 @@ namespace SharpCompress.Test.Xz } [Fact] - public void OnFindIndexBlockThrow() + public async Task OnFindIndexBlockThrow() { var bytes = new byte[] { 0 }; - using (Stream indexBlockStream = new MemoryStream(bytes)) + await using (Stream indexBlockStream = new MemoryStream(bytes)) { var XZBlock = new XZBlock(indexBlockStream, CheckType.CRC64, 8); - Assert.Throws(() => { ReadBytes(XZBlock, 1); }); + await Assert.ThrowsAsync(async () => { await ReadBytesAsync(XZBlock, 1); }); } } [Fact] - public void CrcIncorrectThrows() + public async Task CrcIncorrectThrows() { var bytes = Compressed.Clone() as byte[]; bytes[20]++; - using (Stream badCrcStream = new MemoryStream(bytes)) + await using (Stream badCrcStream = new MemoryStream(bytes)) { Rewind(badCrcStream); var XZBlock = new XZBlock(badCrcStream, CheckType.CRC64, 8); - var ex = Assert.Throws(() => { ReadBytes(XZBlock, 1); }); + var ex = await Assert.ThrowsAsync(async () => { await ReadBytesAsync(XZBlock, 1); }); Assert.Equal("Block header corrupt", ex.Message); } } [Fact] - public void CanReadM() + public async Task CanReadM() { var XZBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8); - Assert.Equal(Encoding.ASCII.GetBytes("M"), ReadBytes(XZBlock, 1)); + Assert.Equal(Encoding.ASCII.GetBytes("M"), await ReadBytesAsync(XZBlock, 1)); } [Fact] - public void CanReadMary() + public async Task CanReadMary() { var XZBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8); - Assert.Equal(Encoding.ASCII.GetBytes("M"), ReadBytes(XZBlock, 1)); - Assert.Equal(Encoding.ASCII.GetBytes("a"), ReadBytes(XZBlock, 1)); - Assert.Equal(Encoding.ASCII.GetBytes("ry"), ReadBytes(XZBlock, 2)); + Assert.Equal(Encoding.ASCII.GetBytes("M"), await ReadBytesAsync(XZBlock, 1)); + Assert.Equal(Encoding.ASCII.GetBytes("a"), await ReadBytesAsync(XZBlock, 1)); + Assert.Equal(Encoding.ASCII.GetBytes("ry"), await ReadBytesAsync(XZBlock, 2)); } [Fact] - public void CanReadPoemWithStreamReader() + public async Task CanReadPoemWithStreamReader() { var XZBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8); var sr = new StreamReader(XZBlock); - Assert.Equal(sr.ReadToEnd(), Original); + Assert.Equal(await sr.ReadToEndAsync(), Original); } [Fact] - public void NoopWhenNoPadding() + public async Task NoopWhenNoPadding() { // CompressedStream's only block has no padding. var XZBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8); var sr = new StreamReader(XZBlock); - sr.ReadToEnd(); + await sr.ReadToEndAsync(); Assert.Equal(0L, CompressedStream.Position % 4L); } [Fact] - public void SkipsPaddingWhenPresent() + public async Task SkipsPaddingWhenPresent() { // CompressedIndexedStream's first block has 1-byte padding. var XZBlock = new XZBlock(CompressedIndexedStream, CheckType.CRC64, 8); var sr = new StreamReader(XZBlock); - sr.ReadToEnd(); + await sr.ReadToEndAsync(); Assert.Equal(0L, CompressedIndexedStream.Position % 4L); } }