mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-11-15 17:02:03 +00:00
Use shared archive entry views for completeness checks
This commit is contained in:
@@ -47,7 +47,7 @@ public abstract partial class AbstractArchive<TEntry, TVolume>
|
||||
|
||||
private async ValueTask EnsureEntriesLoadedAsync()
|
||||
{
|
||||
await _lazyEntriesAsync.EnsureFullyLoaded().ConfigureAwait(false);
|
||||
await foreach (var entry in EntriesAsync.ConfigureAwait(false)) { }
|
||||
await _lazyVolumesAsync.EnsureFullyLoaded().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,8 @@ public abstract partial class AbstractArchive<TEntry, TVolume> : IArchive, IAsyn
|
||||
|
||||
private void EnsureEntriesLoaded()
|
||||
{
|
||||
_lazyEntries.EnsureFullyLoaded();
|
||||
// Writable archives expose a shared view rather than this base cache.
|
||||
Entries.ForEach(_ => { });
|
||||
_lazyVolumes.EnsureFullyLoaded();
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,56 @@ public class GZipArchiveCacheTests : TestBase
|
||||
Assert.True(input.CanRead);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(true, false)]
|
||||
[InlineData(true, true)]
|
||||
public async Task Completeness_Uses_The_Current_Entry_Cache(bool useAsync, bool partial)
|
||||
{
|
||||
using var input = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
|
||||
using var archive = GZipArchive.OpenArchive(input, ReaderOptions.ForExternalStream);
|
||||
var asyncArchive = (IAsyncArchive)archive;
|
||||
if (partial)
|
||||
{
|
||||
if (useAsync)
|
||||
{
|
||||
await asyncArchive.EntriesAsync.FirstAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = archive.Entries.First();
|
||||
}
|
||||
}
|
||||
Assert.True(useAsync ? await asyncArchive.IsCompleteAsync() : archive.IsComplete);
|
||||
var entry = Assert.Single(archive.Entries);
|
||||
Assert.Same(entry, Assert.Single(await asyncArchive.EntriesAsync.ToListAsync()));
|
||||
Assert.True(archive.IsComplete);
|
||||
Assert.True(await asyncArchive.IsCompleteAsync());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public async Task Completeness_Does_Not_Reparse_Already_Cached_Entries(bool useAsync)
|
||||
{
|
||||
using var input = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
|
||||
using var archive = GZipArchive.OpenArchive(input, ReaderOptions.ForExternalStream);
|
||||
var asyncArchive = (IAsyncArchive)archive;
|
||||
if (useAsync)
|
||||
{
|
||||
Assert.Single(await asyncArchive.EntriesAsync.ToListAsync());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Single(archive.Entries);
|
||||
}
|
||||
// Completeness needs only cached metadata and must not move the source.
|
||||
input.Position = input.Length;
|
||||
Assert.True(useAsync ? await asyncArchive.IsCompleteAsync() : archive.IsComplete);
|
||||
Assert.Equal(input.Length, input.Position);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
@@ -77,4 +127,26 @@ public class GZipArchiveCacheTests : TestBase
|
||||
: await asyncArchive.EntriesAsync.ToListAsync();
|
||||
Assert.Same(first, Assert.Single(entries));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Resuming_And_Checking_Completeness_Do_Not_Use_Synchronous_Io()
|
||||
{
|
||||
using var input = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
|
||||
using var asyncOnly = new AsyncOnlyStream(input, disposeStream: false);
|
||||
await using (
|
||||
var archive = await GZipArchive.OpenAsyncArchive(
|
||||
asyncOnly,
|
||||
ReaderOptions.ForExternalStream,
|
||||
CancellationToken.None
|
||||
)
|
||||
)
|
||||
{
|
||||
var entry = await archive.EntriesAsync.FirstAsync();
|
||||
Assert.True(await archive.IsCompleteAsync());
|
||||
Assert.Same(entry, Assert.Single(await archive.EntriesAsync.ToListAsync()));
|
||||
using var payload = await entry.OpenEntryStreamAsync(CancellationToken.None);
|
||||
await payload.CopyToAsync(Stream.Null, 81920, CancellationToken.None);
|
||||
}
|
||||
Assert.True(input.CanRead);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user