diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Async.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Async.cs index 1f44fa2e5..ce00f20d6 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Async.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Async.cs @@ -68,4 +68,13 @@ IAsyncEnumerable volumes protected override ValueTask CreateReaderForSolidExtractionAsync() => new(new SevenZipReader(ReaderOptions, this)); + + public override async ValueTask IsSolidAsync() + { + var entries = await EntriesAsync + .Where(x => !x.IsDirectory) + .ToListAsync() + .ConfigureAwait(false); + return entries.GroupBy(x => x.FilePart.Folder).Any(folder => folder.Skip(1).Any()); + } } diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs index 943547df3..278223136 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs @@ -96,7 +96,7 @@ protected override IReader CreateReaderForSolidExtraction() => Entries .Where(x => !x.IsDirectory) .GroupBy(x => x.FilePart.Folder) - .Any(folder => folder.Count() > 1); + .Any(folder => folder.Skip(1).Any()); public override bool IsEncrypted => Entries.First(x => !x.IsDirectory).IsEncrypted; diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs index 228b0111d..b4f3c8551 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs @@ -227,6 +227,25 @@ public async Task SevenZipArchive_PPMd_AsyncStreamExtraction() VerifyFiles(); } + [Fact] + public async Task SevenZipArchive_TestSolidDetectionAsync() + { + await using var oneBlockSolidArchive = await SevenZipArchive.OpenAsyncArchive( + Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.1block.7z") + ); + Assert.True(await oneBlockSolidArchive.IsSolidAsync()); + + await using var solidArchive = await SevenZipArchive.OpenAsyncArchive( + Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.7z") + ); + Assert.True(await solidArchive.IsSolidAsync()); + + await using var nonSolidArchive = await SevenZipArchive.OpenAsyncArchive( + Path.Combine(TEST_ARCHIVES_PATH, "7Zip.nonsolid.7z") + ); + Assert.False(await nonSolidArchive.IsSolidAsync()); + } + [Fact] public async Task SevenZipArchive_Solid_ExtractAllEntries_Contiguous_Async() { @@ -234,7 +253,7 @@ public async Task SevenZipArchive_Solid_ExtractAllEntries_Contiguous_Async() // rather than recreating the decompression stream for each entry var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.7z"); await using var archive = await SevenZipArchive.OpenAsyncArchive(testArchive); - Assert.True(((SevenZipArchive)archive).IsSolid); + Assert.True(await archive.IsSolidAsync()); await using var reader = await archive.ExtractAllEntriesAsync(); while (await reader.MoveToNextEntryAsync()) @@ -255,7 +274,7 @@ public async Task SevenZipArchive_Solid_VerifyStreamReuse() // and not recreated for each entry in solid archives var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.7z"); await using var archive = await SevenZipArchive.OpenAsyncArchive(testArchive); - Assert.True(((SevenZipArchive)archive).IsSolid); + Assert.True(await archive.IsSolidAsync()); await using var reader = await archive.ExtractAllEntriesAsync();