diff --git a/src/SharpCompress/Archives/AbstractArchive.cs b/src/SharpCompress/Archives/AbstractArchive.cs index 18a60f84..14bf9caa 100644 --- a/src/SharpCompress/Archives/AbstractArchive.cs +++ b/src/SharpCompress/Archives/AbstractArchive.cs @@ -25,8 +25,12 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync _sourceStream = sourceStream; _lazyVolumes = new LazyReadOnlyCollection(LoadVolumes(_sourceStream)); _lazyEntries = new LazyReadOnlyCollection(LoadEntries(Volumes)); - _lazyVolumesAsync = new LazyAsyncReadOnlyCollection(LoadVolumesAsync(_sourceStream)); - _lazyEntriesAsync = new LazyAsyncReadOnlyCollection(LoadEntriesAsync(_lazyVolumesAsync)); + _lazyVolumesAsync = new LazyAsyncReadOnlyCollection( + LoadVolumesAsync(_sourceStream) + ); + _lazyEntriesAsync = new LazyAsyncReadOnlyCollection( + LoadEntriesAsync(_lazyVolumesAsync) + ); } internal AbstractArchive(ArchiveType type) @@ -35,8 +39,12 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync ReaderOptions = new(); _lazyVolumes = new LazyReadOnlyCollection(Enumerable.Empty()); _lazyEntries = new LazyReadOnlyCollection(Enumerable.Empty()); - _lazyVolumesAsync = new LazyAsyncReadOnlyCollection(AsyncEnumerableEx.Empty()); - _lazyEntriesAsync = new LazyAsyncReadOnlyCollection(AsyncEnumerableEx.Empty()); + _lazyVolumesAsync = new LazyAsyncReadOnlyCollection( + AsyncEnumerableEx.Empty() + ); + _lazyEntriesAsync = new LazyAsyncReadOnlyCollection( + AsyncEnumerableEx.Empty() + ); } public ArchiveType Type { get; } @@ -45,6 +53,7 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync /// Returns an ReadOnlyCollection of all the RarArchiveEntries across the one or many parts of the RarArchive. /// public virtual ICollection Entries => _lazyEntries; + /// /// Returns an ReadOnlyCollection of all the RarArchiveVolumes across the one or many parts of the RarArchive. /// @@ -65,16 +74,19 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync protected abstract IEnumerable LoadVolumes(SourceStream sourceStream); protected abstract IEnumerable LoadEntries(IEnumerable volumes); + protected virtual IAsyncEnumerable LoadVolumesAsync(SourceStream sourceStream) => + LoadVolumes(sourceStream).ToAsyncEnumerable(); - protected virtual IAsyncEnumerable LoadVolumesAsync(SourceStream sourceStream) => LoadVolumes(sourceStream).ToAsyncEnumerable(); - - protected virtual async IAsyncEnumerable LoadEntriesAsync(IAsyncEnumerable volumes) + protected virtual async IAsyncEnumerable LoadEntriesAsync( + IAsyncEnumerable volumes + ) { - foreach (var item in LoadEntries(await volumes.ToListAsync()) ) + foreach (var item in LoadEntries(await volumes.ToListAsync())) { yield return item; } } + IEnumerable IArchive.Entries => Entries.Cast(); IEnumerable IArchive.Volumes => _lazyVolumes.Cast(); @@ -149,14 +161,13 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync private readonly LazyAsyncReadOnlyCollection _lazyVolumesAsync; private readonly LazyAsyncReadOnlyCollection _lazyEntriesAsync; - public virtual async ValueTask DisposeAsync() { if (!_disposed) { await foreach (var v in _lazyVolumesAsync) { - v.Dispose(); + v.Dispose(); } foreach (var v in _lazyEntriesAsync.GetLoaded().Cast()) { @@ -175,9 +186,11 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync } public virtual IAsyncEnumerable EntriesAsync => _lazyEntriesAsync; - IAsyncEnumerable IArchiveAsync.EntriesAsync => EntriesAsync.Cast(); + IAsyncEnumerable IArchiveAsync.EntriesAsync => + EntriesAsync.Cast(); public IAsyncEnumerable VolumesAsync => _lazyVolumesAsync.Cast(); + public async ValueTask ExtractAllEntriesAsync() { if (!IsSolid && Type != ArchiveType.SevenZip) @@ -190,11 +203,10 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync return await CreateReaderForSolidExtractionAsync(); } - protected virtual ValueTask CreateReaderForSolidExtractionAsync() => - new (CreateReaderForSolidExtraction()); + new(CreateReaderForSolidExtraction()); - public virtual ValueTask IsSolidAsync() => new (false); + public virtual ValueTask IsSolidAsync() => new(false); public async ValueTask IsCompleteAsync() { @@ -202,9 +214,11 @@ public abstract class AbstractArchive : IArchive, IArchiveAsync return await EntriesAsync.All(x => x.IsComplete); } - public async ValueTask TotalSizeAsync() => await EntriesAsync.Aggregate(0L, (total, cf) => total + cf.CompressedSize); + public async ValueTask TotalSizeAsync() => + await EntriesAsync.Aggregate(0L, (total, cf) => total + cf.CompressedSize); - public async ValueTask TotalUncompressSizeAsync() => await EntriesAsync.Aggregate(0L, (total, cf) => total + cf.Size); + public async ValueTask TotalUncompressSizeAsync() => + await EntriesAsync.Aggregate(0L, (total, cf) => total + cf.Size); #endregion } diff --git a/src/SharpCompress/Archives/IArchive.cs b/src/SharpCompress/Archives/IArchive.cs index dacb5907..f123d984 100644 --- a/src/SharpCompress/Archives/IArchive.cs +++ b/src/SharpCompress/Archives/IArchive.cs @@ -42,7 +42,6 @@ public interface IArchiveAsync : IAsyncDisposable ValueTask TotalUncompressSizeAsync(); } - public interface IArchive : IDisposable { IEnumerable Entries { get; } diff --git a/src/SharpCompress/LazyAsyncReadOnlyCollection.cs b/src/SharpCompress/LazyAsyncReadOnlyCollection.cs index 499edfb9..85caf611 100644 --- a/src/SharpCompress/LazyAsyncReadOnlyCollection.cs +++ b/src/SharpCompress/LazyAsyncReadOnlyCollection.cs @@ -7,13 +7,17 @@ using System.Threading.Tasks; namespace SharpCompress; -internal sealed class LazyAsyncReadOnlyCollection(IAsyncEnumerable source) : IAsyncEnumerable +internal sealed class LazyAsyncReadOnlyCollection(IAsyncEnumerable source) + : IAsyncEnumerable { private readonly List backing = new(); private readonly IAsyncEnumerator source = source.GetAsyncEnumerator(); private bool fullyLoaded; - private class LazyLoader(LazyAsyncReadOnlyCollection lazyReadOnlyCollection, CancellationToken cancellationToken) : IAsyncEnumerator + private class LazyLoader( + LazyAsyncReadOnlyCollection lazyReadOnlyCollection, + CancellationToken cancellationToken + ) : IAsyncEnumerator { private bool disposed; private int index = -1; @@ -35,7 +39,10 @@ internal sealed class LazyAsyncReadOnlyCollection(IAsyncEnumerable source) index++; return true; } - if (!lazyReadOnlyCollection.fullyLoaded && await lazyReadOnlyCollection.source.MoveNextAsync()) + if ( + !lazyReadOnlyCollection.fullyLoaded + && await lazyReadOnlyCollection.source.MoveNextAsync() + ) { lazyReadOnlyCollection.backing.Add(lazyReadOnlyCollection.source.Current); index++; @@ -62,7 +69,6 @@ internal sealed class LazyAsyncReadOnlyCollection(IAsyncEnumerable source) } #endregion - } internal async ValueTask EnsureFullyLoaded() @@ -92,5 +98,6 @@ internal sealed class LazyAsyncReadOnlyCollection(IAsyncEnumerable source) #endregion - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => new LazyLoader(this, cancellationToken); + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => + new LazyLoader(this, cancellationToken); } diff --git a/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs b/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs index f4c07df5..785d4c32 100644 --- a/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs +++ b/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs @@ -10,8 +10,8 @@ public static class AsyncEnumerableEx public static async IAsyncEnumerable Empty() where T : notnull { - await Task.CompletedTask; - yield break; + await Task.CompletedTask; + yield break; } } @@ -41,6 +41,7 @@ public static class AsyncEnumerableExtensions } return list; } + public async IAsyncEnumerable Cast() where TResult : class { @@ -49,6 +50,7 @@ public static class AsyncEnumerableExtensions yield return (item as TResult).NotNull(); } } + public async ValueTask All(Func predicate) { await foreach (var item in source) @@ -61,6 +63,7 @@ public static class AsyncEnumerableExtensions return true; } + public async IAsyncEnumerable Where(Func predicate) { await foreach (var item in source) @@ -82,10 +85,13 @@ public static class AsyncEnumerableExtensions return default; // Returns null/default if the stream is empty } - public async ValueTask Aggregate(TAccumulate seed, Func func) + public async ValueTask Aggregate( + TAccumulate seed, + Func func + ) { TAccumulate result = seed; - await foreach (var element in source) + await foreach (var element in source) { result = func(result, element); } diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index c3ff9d6d..3001b4bd 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -609,7 +609,9 @@ public class ArchiveTests : ReaderTests { try { - await foreach (var entry in archive.EntriesAsync.Where(entry => !entry.IsDirectory)) + await foreach ( + var entry in archive.EntriesAsync.Where(entry => !entry.IsDirectory) + ) { await entry.WriteToDirectoryAsync( SCRATCH_FILES_PATH,