diff --git a/src/SharpCompress/Archives/AbstractArchive.cs b/src/SharpCompress/Archives/AbstractArchive.cs index 11ccb114..a4ee6278 100644 --- a/src/SharpCompress/Archives/AbstractArchive.cs +++ b/src/SharpCompress/Archives/AbstractArchive.cs @@ -101,8 +101,8 @@ namespace SharpCompress.Archives { if (!disposed) { - await lazyVolumes.ForEachAsync(v => v.Dispose()); - lazyEntries.GetLoaded().Cast().ForEach(x => x.Close()); + await lazyVolumes.ForEachAsync(async v => await v.DisposeAsync()); + await lazyEntries.GetLoaded().Cast().ForEachAsync(async x => await x.CloseAsync()); disposed = true; } } diff --git a/src/SharpCompress/Archives/AbstractWritableArchive.cs b/src/SharpCompress/Archives/AbstractWritableArchive.cs index 6c8d7da2..f82204af 100644 --- a/src/SharpCompress/Archives/AbstractWritableArchive.cs +++ b/src/SharpCompress/Archives/AbstractWritableArchive.cs @@ -168,9 +168,9 @@ namespace SharpCompress.Archives public override async ValueTask DisposeAsync() { await base.DisposeAsync(); - newEntries.Cast().ForEach(x => x.Close()); - removedEntries.Cast().ForEach(x => x.Close()); - modifiedEntries.Cast().ForEach(x => x.Close()); + await newEntries.Cast().ForEachAsync(async x => await x.CloseAsync()); + await removedEntries.Cast().ForEachAsync(async x => await x.CloseAsync()); + await modifiedEntries.Cast().ForEachAsync(async x => await x.CloseAsync()); } } } diff --git a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs index da6994ad..8f9a6e45 100644 --- a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs @@ -59,11 +59,11 @@ namespace SharpCompress.Archives.GZip return new(new NonDisposingStream(stream)); } - internal override void Close() + internal override async ValueTask CloseAsync() { if (closeStream) { - stream.Dispose(); + await stream.DisposeAsync(); } } } diff --git a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs index 608b2128..5a1b89eb 100644 --- a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs @@ -58,11 +58,11 @@ namespace SharpCompress.Archives.Tar return new(new NonDisposingStream(stream)); } - internal override void Close() + internal override async ValueTask CloseAsync() { if (closeStream) { - stream.Dispose(); + await stream.DisposeAsync(); } } } diff --git a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs index fbbebade..8d6cb93d 100644 --- a/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs +++ b/src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs @@ -58,11 +58,11 @@ namespace SharpCompress.Archives.Zip return new(new NonDisposingStream(stream)); } - internal override void Close() + internal override async ValueTask CloseAsync() { if (closeStream && !isDisposed) { - stream.Dispose(); + await stream.DisposeAsync(); isDisposed = true; } } diff --git a/src/SharpCompress/Common/Entry.cs b/src/SharpCompress/Common/Entry.cs index 7a1047d1..9beeff68 100644 --- a/src/SharpCompress/Common/Entry.cs +++ b/src/SharpCompress/Common/Entry.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace SharpCompress.Common { @@ -77,8 +78,9 @@ namespace SharpCompress.Common internal bool IsSolid { get; set; } - internal virtual void Close() + internal virtual ValueTask CloseAsync() { + return new (); } /// diff --git a/src/SharpCompress/Common/EntryStream.cs b/src/SharpCompress/Common/EntryStream.cs index 414f5a06..5b055ec2 100644 --- a/src/SharpCompress/Common/EntryStream.cs +++ b/src/SharpCompress/Common/EntryStream.cs @@ -2,11 +2,12 @@ using System.IO; using System.Threading; using System.Threading.Tasks; +using SharpCompress.IO; using SharpCompress.Readers; namespace SharpCompress.Common { - public class EntryStream : Stream + public class EntryStream : AsyncStream { private readonly IReader _reader; private readonly Stream _stream; @@ -42,21 +43,11 @@ namespace SharpCompress.Common await _stream.DisposeAsync(); } - protected override void Dispose(bool disposing) - { - throw new NotImplementedException(); - } - public override bool CanRead => true; public override bool CanSeek => false; public override bool CanWrite => false; - - public override void Flush() - { - } - public override long Length => _stream.Length; public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } @@ -71,14 +62,14 @@ namespace SharpCompress.Common return read; } - public override int Read(byte[] buffer, int offset, int count) + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + throw new NotSupportedException(); } - public override int ReadByte() + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public override long Seek(long offset, SeekOrigin origin) @@ -90,10 +81,5 @@ namespace SharpCompress.Common { throw new NotSupportedException(); } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } } } \ No newline at end of file diff --git a/src/SharpCompress/Common/IVolume.cs b/src/SharpCompress/Common/IVolume.cs index f19971fe..3b948f5d 100644 --- a/src/SharpCompress/Common/IVolume.cs +++ b/src/SharpCompress/Common/IVolume.cs @@ -2,7 +2,7 @@ namespace SharpCompress.Common { - public interface IVolume : IDisposable + public interface IVolume : IAsyncDisposable { } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs b/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs index be31c9b3..88b28a22 100644 --- a/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs +++ b/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs @@ -38,11 +38,6 @@ namespace SharpCompress.Common.Tar } } - protected override void Dispose(bool disposing) - { - throw new NotImplementedException(); - } - private long BytesLeftToRead { get; set; } public override bool CanRead => true; @@ -51,11 +46,6 @@ namespace SharpCompress.Common.Tar public override bool CanWrite => false; - public override void Flush() - { - throw new NotSupportedException(); - } - public override long Length => throw new NotSupportedException(); public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } @@ -76,17 +66,6 @@ namespace SharpCompress.Common.Tar return read; } - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - public override int ReadByte() - { - throw new NotImplementedException(); - - } - public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); @@ -96,10 +75,5 @@ namespace SharpCompress.Common.Tar { throw new NotSupportedException(); } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } } } \ No newline at end of file diff --git a/src/SharpCompress/Common/Volume.cs b/src/SharpCompress/Common/Volume.cs index b937b281..65fa37c6 100644 --- a/src/SharpCompress/Common/Volume.cs +++ b/src/SharpCompress/Common/Volume.cs @@ -1,5 +1,5 @@ -using System; -using System.IO; +using System.IO; +using System.Threading.Tasks; using SharpCompress.IO; using SharpCompress.Readers; @@ -33,19 +33,10 @@ namespace SharpCompress.Common /// RarArchive is part of a multi-part archive. /// public virtual bool IsMultiVolume => true; - - protected virtual void Dispose(bool disposing) + + public ValueTask DisposeAsync() { - if (disposing) - { - _actualStream.Dispose(); - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); + return _actualStream.DisposeAsync(); } } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/LZMA/LZipStream.cs b/src/SharpCompress/Compressors/LZMA/LZipStream.cs index 42f28664..10bca9a9 100644 --- a/src/SharpCompress/Compressors/LZMA/LZipStream.cs +++ b/src/SharpCompress/Compressors/LZMA/LZipStream.cs @@ -2,6 +2,7 @@ using System; using System.Buffers; using System.Buffers.Binary; using System.IO; +using System.Threading; using System.Threading.Tasks; using SharpCompress.Crypto; using SharpCompress.IO; @@ -59,15 +60,15 @@ namespace SharpCompress.Compressors.LZMA return lzip; } - public void Finish() + public async ValueTask FinishAsync() { if (!_finished) { if (Mode == CompressionMode.Compress) { var crc32Stream = (Crc32Stream)_stream; - crc32Stream.WrappedStream.Dispose(); - crc32Stream.Dispose(); + await crc32Stream.WrappedStream.DisposeAsync(); + await crc32Stream.DisposeAsync(); var compressedCount = _countingWritableSubStream!.Count; byte[] intBuf = new byte[8]; @@ -87,17 +88,22 @@ namespace SharpCompress.Compressors.LZMA #region Stream methods - protected override void Dispose(bool disposing) + public override async ValueTask DisposeAsync() { if (_disposed) { return; } _disposed = true; + await FinishAsync(); + await _stream.DisposeAsync(); + } + + protected override void Dispose(bool disposing) + { if (disposing) { - Finish(); - _stream.Dispose(); + throw new NotSupportedException(); } } @@ -120,41 +126,40 @@ namespace SharpCompress.Compressors.LZMA public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count); + public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException(); - public override int ReadByte() => _stream.ReadByte(); + public override int ReadByte() => throw new NotSupportedException(); + + public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = new CancellationToken()) + { + return _stream.ReadAsync(buffer, cancellationToken); + } public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); public override void SetLength(long value) => throw new NotImplementedException(); - - -#if !NET461 && !NETSTANDARD2_0 - - public override int Read(Span buffer) - { - return _stream.Read(buffer); - } - - public override void Write(ReadOnlySpan buffer) - { - _stream.Write(buffer); - - _writeCount += buffer.Length; - } - -#endif + public override void Write(byte[] buffer, int offset, int count) { - _stream.Write(buffer, offset, count); + throw new NotSupportedException(); + } + + public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = new CancellationToken()) + { + await _stream.WriteAsync(buffer, cancellationToken); + _writeCount += buffer.Length; + } + + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + await _stream.WriteAsync(buffer, offset, count, cancellationToken); _writeCount += count; } public override void WriteByte(byte value) { - _stream.WriteByte(value); - ++_writeCount; + throw new NotSupportedException(); } #endregion diff --git a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs index 9bea4b82..8e611ad6 100644 --- a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs +++ b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs @@ -224,7 +224,7 @@ namespace SharpCompress.Compressors.LZMA _highCoder.Init(); } - public virtual async ValueTask EncodeAsync(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) + public async ValueTask EncodeAsync(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) { if (symbol < Base.K_NUM_LOW_LEN_SYMBOLS) { @@ -310,7 +310,7 @@ namespace SharpCompress.Compressors.LZMA } } - public override async ValueTask EncodeAsync(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) + public new async ValueTask EncodeAsync(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) { await base.EncodeAsync(rangeEncoder, symbol, posState); if (--_counters[posState] == 0) diff --git a/src/SharpCompress/Compressors/LZMA/LzmaStream.cs b/src/SharpCompress/Compressors/LZMA/LzmaStream.cs index 47336c1f..2af4959a 100644 --- a/src/SharpCompress/Compressors/LZMA/LzmaStream.cs +++ b/src/SharpCompress/Compressors/LZMA/LzmaStream.cs @@ -7,10 +7,11 @@ using System.IO; using System.Threading; using System.Threading.Tasks; using SharpCompress.Compressors.LZMA.LZ; +using SharpCompress.IO; namespace SharpCompress.Compressors.LZMA { - public class LzmaStream : Stream + public class LzmaStream : AsyncStream { private Stream _inputStream; private long _inputSize; @@ -119,11 +120,6 @@ namespace SharpCompress.Compressors.LZMA public override bool CanWrite => _encoder != null; - public override void Flush() - { - throw new NotSupportedException(); - } - public override async ValueTask DisposeAsync() { if (_isDisposed) @@ -138,20 +134,10 @@ namespace SharpCompress.Compressors.LZMA _inputStream?.DisposeAsync(); } - protected override void Dispose(bool disposing) - { - throw new NotSupportedException(); - } - public override long Length => _position + _availableBytes; public override long Position { get => _position; set => throw new NotSupportedException(); } - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (_endReached) @@ -307,22 +293,25 @@ namespace SharpCompress.Compressors.LZMA throw new NotSupportedException(); } + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (_encoder != null) + { + _position = await _encoder.CodeAsync(new MemoryStream(buffer, offset, count), false); + } + } + public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = new CancellationToken()) { if (_encoder != null) { var m = ArrayPool.Shared.Rent(buffer.Length); - buffer.CopyTo(m.AsMemory()); - _position = await _encoder.CodeAsync(new MemoryStream(m), false); + buffer.CopyTo(m.AsMemory().Slice(0, buffer.Length)); + _position = await _encoder.CodeAsync(new MemoryStream(m, 0, buffer.Length), false); ArrayPool.Shared.Return(m); } } - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - public byte[] Properties { get; private set; } } } diff --git a/src/SharpCompress/Crypto/Crc32Stream.cs b/src/SharpCompress/Crypto/Crc32Stream.cs index fe3cd00c..da209821 100644 --- a/src/SharpCompress/Crypto/Crc32Stream.cs +++ b/src/SharpCompress/Crypto/Crc32Stream.cs @@ -2,6 +2,8 @@ using System; using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace SharpCompress.Crypto { @@ -52,16 +54,20 @@ namespace SharpCompress.Crypto } #endif + public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = new CancellationToken()) + { + await stream.WriteAsync(buffer, cancellationToken); + hash = CalculateCrc(table, hash, buffer.Span); + } + public override void Write(byte[] buffer, int offset, int count) { - stream.Write(buffer, offset, count); - hash = CalculateCrc(table, hash, buffer.AsSpan(offset, count)); + throw new NotSupportedException(); } public override void WriteByte(byte value) { - stream.WriteByte(value); - hash = CalculateCrc(table, hash, value); + throw new NotSupportedException(); } public override bool CanRead => stream.CanRead; diff --git a/src/SharpCompress/IO/AsyncStream.cs b/src/SharpCompress/IO/AsyncStream.cs new file mode 100644 index 00000000..3d0a2a96 --- /dev/null +++ b/src/SharpCompress/IO/AsyncStream.cs @@ -0,0 +1,73 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace SharpCompress.IO +{ + public abstract class AsyncStream : Stream + { + protected sealed override void Dispose(bool disposing) + { + if (disposing) + { + throw new NotSupportedException(); + } + } + + public sealed override void Flush() + { + throw new NotSupportedException(); + } + + public abstract override ValueTask DisposeAsync(); + + public sealed override int Read(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + + public sealed override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + + public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) + { + throw new NotSupportedException(); + } + + public sealed override int EndRead(IAsyncResult asyncResult) + { + throw new NotSupportedException(); + } + + public sealed override int ReadByte() + { + throw new NotSupportedException(); + } + + public sealed override void WriteByte(byte b) + { + throw new NotSupportedException(); + } + + public abstract override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken); + + public abstract override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default); + +#if !NET461 && !NETSTANDARD2_0 + + public sealed override int Read(Span buffer) + { + throw new NotSupportedException(); + } + + public sealed override void Write(ReadOnlySpan buffer) + { + throw new NotSupportedException(); + } + +#endif + } +} \ No newline at end of file diff --git a/src/SharpCompress/IO/BufferedSubStream.cs b/src/SharpCompress/IO/BufferedSubStream.cs index 9b6ae6cd..5a44a5cc 100644 --- a/src/SharpCompress/IO/BufferedSubStream.cs +++ b/src/SharpCompress/IO/BufferedSubStream.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace SharpCompress.IO { @@ -25,16 +27,11 @@ namespace SharpCompress.IO public override bool CanWrite => false; - public override void Flush() - { - throw new NotSupportedException(); - } - public override long Length => BytesLeftToRead; public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } - public override int Read(byte[] buffer, int offset, int count) + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (count > BytesLeftToRead) { @@ -47,7 +44,7 @@ namespace SharpCompress.IO { cacheOffset = 0; Stream.Position = position; - cacheLength = Stream.Read(cache, 0, cache.Length); + cacheLength = await Stream.ReadAsync(cache, 0, cache.Length, cancellationToken); position += cacheLength; } @@ -74,10 +71,5 @@ namespace SharpCompress.IO { throw new NotSupportedException(); } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } } } \ No newline at end of file diff --git a/src/SharpCompress/IO/CountingWritableSubStream.cs b/src/SharpCompress/IO/CountingWritableSubStream.cs index 02f175a2..35e2e5f3 100644 --- a/src/SharpCompress/IO/CountingWritableSubStream.cs +++ b/src/SharpCompress/IO/CountingWritableSubStream.cs @@ -19,20 +19,15 @@ namespace SharpCompress.IO public override bool CanWrite => true; - public override void Flush() + public override Task FlushAsync(CancellationToken cancellationToken) { - Stream.Flush(); + return Stream.FlushAsync(cancellationToken); } public override long Length => throw new NotSupportedException(); public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); @@ -54,17 +49,5 @@ namespace SharpCompress.IO await Stream.WriteAsync(buffer, cancellationToken); Count += (uint)buffer.Length; } - - public override void Write(byte[] buffer, int offset, int count) - { - Stream.Write(buffer, offset, count); - Count += (uint)count; - } - - public override void WriteByte(byte value) - { - Stream.WriteByte(value); - ++Count; - } } } \ No newline at end of file diff --git a/src/SharpCompress/IO/NonDisposingStream.cs b/src/SharpCompress/IO/NonDisposingStream.cs index 5339bee5..0c851c1c 100644 --- a/src/SharpCompress/IO/NonDisposingStream.cs +++ b/src/SharpCompress/IO/NonDisposingStream.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; namespace SharpCompress.IO { - public class NonDisposingStream : Stream + public class NonDisposingStream : AsyncStream { public NonDisposingStream(Stream stream, bool throwOnDispose = false) { @@ -22,15 +22,7 @@ namespace SharpCompress.IO throw new InvalidOperationException($"Attempt to dispose of a {nameof(NonDisposingStream)} when {nameof(ThrowOnDispose)} is {ThrowOnDispose}"); } - return base.DisposeAsync(); - } - - protected override void Dispose(bool disposing) - { - if (ThrowOnDispose) - { - throw new InvalidOperationException($"Attempt to dispose of a {nameof(NonDisposingStream)} when {nameof(ThrowOnDispose)} is {ThrowOnDispose}"); - } + return new ValueTask(); } protected Stream Stream { get; } @@ -41,35 +33,20 @@ namespace SharpCompress.IO public override bool CanWrite => Stream.CanWrite; - public override void Flush() + public override Task FlushAsync(CancellationToken cancellationToken) { - Stream.Flush(); + return Stream.FlushAsync(cancellationToken); } public override long Length => Stream.Length; public override long Position { get => Stream.Position; set => Stream.Position = value; } - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) { return Stream.ReadAsync(buffer, cancellationToken); } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) - { - throw new NotImplementedException(); - } - - public override int EndRead(IAsyncResult asyncResult) - { - throw new NotImplementedException(); - } - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { return Stream.ReadAsync(buffer, offset, count, cancellationToken); @@ -85,11 +62,6 @@ namespace SharpCompress.IO Stream.SetLength(value); } - public override void Write(byte[] buffer, int offset, int count) - { - Stream.Write(buffer, offset, count); - } - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { return Stream.WriteAsync(buffer, offset, count, cancellationToken); @@ -99,19 +71,5 @@ namespace SharpCompress.IO { return Stream.WriteAsync(buffer, cancellationToken); } - -#if !NET461 && !NETSTANDARD2_0 - - public override int Read(Span buffer) - { - return Stream.Read(buffer); - } - - public override void Write(ReadOnlySpan buffer) - { - Stream.Write(buffer); - } - -#endif } } \ No newline at end of file diff --git a/src/SharpCompress/IO/ReadOnlySubStream.cs b/src/SharpCompress/IO/ReadOnlySubStream.cs index e05921ca..7b39a45b 100644 --- a/src/SharpCompress/IO/ReadOnlySubStream.cs +++ b/src/SharpCompress/IO/ReadOnlySubStream.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace SharpCompress.IO { @@ -28,22 +30,17 @@ namespace SharpCompress.IO public override bool CanWrite => false; - public override void Flush() - { - throw new NotSupportedException(); - } - public override long Length => throw new NotSupportedException(); public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } - public override int Read(byte[] buffer, int offset, int count) + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (BytesLeftToRead < count) { count = (int)BytesLeftToRead; } - int read = Stream.Read(buffer, offset, count); + int read = await Stream.ReadAsync(buffer, offset, count, cancellationToken); if (read > 0) { BytesLeftToRead -= read; @@ -51,20 +48,6 @@ namespace SharpCompress.IO return read; } - public override int ReadByte() - { - if (BytesLeftToRead <= 0) - { - return -1; - } - int value = Stream.ReadByte(); - if (value != -1) - { - --BytesLeftToRead; - } - return value; - } - public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); @@ -74,10 +57,5 @@ namespace SharpCompress.IO { throw new NotSupportedException(); } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index 9af95659..f83af94d 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -48,8 +48,8 @@ namespace SharpCompress.Readers public async ValueTask DisposeAsync() { - await (entriesForCurrentReadStream?.DisposeAsync() ?? new ValueTask(Task.CompletedTask)); - Volume?.Dispose(); + await (entriesForCurrentReadStream?.DisposeAsync() ?? new ValueTask()); + await Volume.DisposeAsync(); } #endregion diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index c1e318e7..37028284 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -11,6 +11,13 @@ namespace SharpCompress { internal static class Utility { + public static async ValueTask ForEachAsync(this IEnumerable collection, Func action) + { + foreach (T item in collection) + { + await action(item); + } + } public static async ValueTask ReadPrimitive(this Stream stream, int bytes, Func, T> func, CancellationToken cancellationToken) { using var buffer = MemoryPool.Shared.Rent(bytes); diff --git a/src/SharpCompress/Writers/Tar/TarWriter.cs b/src/SharpCompress/Writers/Tar/TarWriter.cs index 0cbb26b6..df94b83a 100644 --- a/src/SharpCompress/Writers/Tar/TarWriter.cs +++ b/src/SharpCompress/Writers/Tar/TarWriter.cs @@ -130,7 +130,7 @@ namespace SharpCompress.Writers.Tar } */ case LZipStream l: { - l.Finish(); + await l.FinishAsync(); break; } } diff --git a/tests/SharpCompress.Test/Mocks/TestStream.cs b/tests/SharpCompress.Test/Mocks/TestStream.cs index 64bee443..401707e2 100644 --- a/tests/SharpCompress.Test/Mocks/TestStream.cs +++ b/tests/SharpCompress.Test/Mocks/TestStream.cs @@ -1,4 +1,7 @@ -using System.IO; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace SharpCompress.Test.Mocks { @@ -22,8 +25,12 @@ namespace SharpCompress.Test.Mocks protected override void Dispose(bool disposing) { - base.Dispose(disposing); - stream.Dispose(); + throw new NotSupportedException(); + } + + public override async ValueTask DisposeAsync() + { + await stream.DisposeAsync(); IsDisposed = true; } @@ -46,10 +53,17 @@ namespace SharpCompress.Test.Mocks set => stream.Position = value; } + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return stream.ReadAsync(buffer, offset, count, cancellationToken); + } + public override int Read(byte[] buffer, int offset, int count) { return stream.Read(buffer, offset, count); } + + public override long Seek(long offset, SeekOrigin origin) { @@ -65,5 +79,10 @@ namespace SharpCompress.Test.Mocks { stream.Write(buffer, offset, count); } + + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return stream.WriteAsync(buffer, offset, count, cancellationToken); + } } } diff --git a/tests/SharpCompress.Test/ReaderTests.cs b/tests/SharpCompress.Test/ReaderTests.cs index a16d1270..a30a5c50 100644 --- a/tests/SharpCompress.Test/ReaderTests.cs +++ b/tests/SharpCompress.Test/ReaderTests.cs @@ -26,11 +26,11 @@ namespace SharpCompress.Test private async ValueTask ReadImplAsync(string testArchive, CompressionType expectedCompression, ReaderOptions options) { - using (var file = File.OpenRead(testArchive)) + await using (var file = File.OpenRead(testArchive)) { - using (var protectedStream = new NonDisposingStream(new ForwardOnlyStream(file), throwOnDispose: true)) + await using (var protectedStream = new NonDisposingStream(new ForwardOnlyStream(file), throwOnDispose: true)) { - using (var testStream = new TestStream(protectedStream)) + await using (var testStream = new TestStream(protectedStream)) { await using (var reader = await ReaderFactory.OpenAsync(testStream, options)) {