diff --git a/src/SharpCompress/Common/GZip/GZipFilePart.cs b/src/SharpCompress/Common/GZip/GZipFilePart.cs index 28d0ed51..4bbf7c44 100644 --- a/src/SharpCompress/Common/GZip/GZipFilePart.cs +++ b/src/SharpCompress/Common/GZip/GZipFilePart.cs @@ -32,7 +32,7 @@ namespace SharpCompress.Common.GZip { long position = stream.Position; stream.Position = stream.Length - 8; - ReadTrailer(); + await ReadTrailerAsync(cancellationToken); stream.Position = position; } EntryStartPosition = stream.Position; @@ -56,14 +56,12 @@ namespace SharpCompress.Common.GZip return _stream; } - private void ReadTrailer() + private async ValueTask ReadTrailerAsync(CancellationToken cancellationToken) { // Read and potentially verify the GZIP trailer: CRC32 and size mod 2^32 - Span trailer = stackalloc byte[8]; - int n = _stream.Read(trailer); - Crc = BinaryPrimitives.ReadInt32LittleEndian(trailer); - UncompressedSize = BinaryPrimitives.ReadInt32LittleEndian(trailer.Slice(4)); + Crc = await _stream.ReadInt32(cancellationToken); + UncompressedSize = await _stream.ReadInt32(cancellationToken); } private async ValueTask ReadAndValidateGzipHeaderAsync(CancellationToken cancellationToken) diff --git a/src/SharpCompress/Compressors/Deflate/GZipStream.cs b/src/SharpCompress/Compressors/Deflate/GZipStream.cs index ba29c1b3..991fe3db 100644 --- a/src/SharpCompress/Compressors/Deflate/GZipStream.cs +++ b/src/SharpCompress/Compressors/Deflate/GZipStream.cs @@ -199,21 +199,22 @@ namespace SharpCompress.Compressors.Deflate /// protected override void Dispose(bool disposing) { - try + if (disposing) { - if (!_disposed) - { - if (disposing && (_baseStream != null)) - { - _baseStream.Dispose(); - Crc32 = _baseStream.Crc32; - } - _disposed = true; - } + throw new NotImplementedException(); } - finally + } + + public override async ValueTask DisposeAsync() + { + if (!_disposed) { - base.Dispose(disposing); + if ((_baseStream != null)) + { + await _baseStream.DisposeAsync(); + Crc32 = _baseStream.Crc32; + } + _disposed = true; } } diff --git a/src/SharpCompress/IO/NonDisposingStream.cs b/src/SharpCompress/IO/NonDisposingStream.cs index 9eabcbb9..5339bee5 100644 --- a/src/SharpCompress/IO/NonDisposingStream.cs +++ b/src/SharpCompress/IO/NonDisposingStream.cs @@ -87,7 +87,7 @@ namespace SharpCompress.IO public override void Write(byte[] buffer, int offset, int count) { - throw new NotImplementedException(); + Stream.Write(buffer, offset, count); } public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index dc2fedf2..83caec87 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -25,6 +25,10 @@ namespace SharpCompress { return stream.ReadPrimitive(4, x => BinaryPrimitives.ReadUInt32LittleEndian(x.Span), cancellationToken); } + public static ValueTask ReadInt32(this Stream stream, CancellationToken cancellationToken) + { + return stream.ReadPrimitive(4, x => BinaryPrimitives.ReadInt32LittleEndian(x.Span), cancellationToken); + } public static ValueTask ReadUInt64(this Stream stream, CancellationToken cancellationToken) { @@ -317,6 +321,11 @@ namespace SharpCompress return total; } + public static async ValueTask WriteByte(this Stream stream, byte b, CancellationToken cancellationToken = default) + { + await stream.WriteAsync(new ReadOnlyMemory(new[] {b}), cancellationToken); + } + public static long TransferTo(this Stream source, Stream destination) { byte[] array = GetTransferByteArray(); @@ -339,25 +348,19 @@ namespace SharpCompress public static async ValueTask TransferToAsync(this Stream source, Stream destination, Common.Entry entry, IReaderExtractionListener readerExtractionListener, CancellationToken cancellationToken) { - byte[] array = GetTransferByteArray(); - try + using var buffer = MemoryPool.Shared.Rent(81920); + var iterations = 0; + long total = 0; + var count = 0; + var slice = buffer.Memory.Slice(0, 81920); + while ((count = await source.ReadAsync(slice, cancellationToken)) != 0) { - var iterations = 0; - long total = 0; - var count = 0; - while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken)) != 0) - { - total += count; - await destination.WriteAsync(array, 0, count, cancellationToken); - iterations++; - readerExtractionListener.FireEntryExtractionProgress(entry, total, iterations); - } - return total; - } - finally - { - ArrayPool.Shared.Return(array); + total += count; + await destination.WriteAsync(slice.Slice(0, count), cancellationToken); + iterations++; + readerExtractionListener.FireEntryExtractionProgress(entry, total, iterations); } + return total; } private static byte[] GetTransferByteArray() diff --git a/tests/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs index 64f06a72..779aa46a 100644 --- a/tests/SharpCompress.Test/WriterTests.cs +++ b/tests/SharpCompress.Test/WriterTests.cs @@ -44,7 +44,7 @@ namespace SharpCompress.Test await using (var reader = await ReaderFactory.OpenAsync(new NonDisposingStream(stream), readerOptions)) { - await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH, new ExtractionOptions() + await reader.WriteAllToDirectoryAsync(SCRATCH_FILES_PATH, new ExtractionOptions() { ExtractFullPath = true });