diff --git a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs index 74a3ce4c..b795d1e6 100644 --- a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs +++ b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs @@ -70,26 +70,44 @@ public class RarArchiveEntry : RarEntry, IArchiveEntry public Stream OpenEntryStream() { + RarStream stream; if (IsRarV3) { - return new RarStream( + stream = new RarStream( archive.UnpackV1.Value, FileHeader, new MultiVolumeReadOnlyStream(Parts.Cast(), archive) ); } - return new RarStream( + stream = new RarStream( archive.UnpackV2017.Value, FileHeader, new MultiVolumeReadOnlyStream(Parts.Cast(), archive) ); + stream.Initialize(); + return stream; } - public Task OpenEntryStreamAsync(CancellationToken cancellationToken = default) + public async Task OpenEntryStreamAsync(CancellationToken cancellationToken = default) { - cancellationToken.ThrowIfCancellationRequested(); - return Task.FromResult(OpenEntryStream()); + RarStream stream; + if (IsRarV3) + { + stream = new RarStream( + archive.UnpackV1.Value, + FileHeader, + new MultiVolumeReadOnlyStream(Parts.Cast(), archive) + ); + } + + stream = new RarStream( + archive.UnpackV2017.Value, + FileHeader, + new MultiVolumeReadOnlyStream(Parts.Cast(), archive) + ); + await stream.InitializeAsync(cancellationToken); + return stream; } public bool IsComplete diff --git a/src/SharpCompress/Compressors/Rar/RarCrcStream.cs b/src/SharpCompress/Compressors/Rar/RarCrcStream.cs index 5473370f..28386c0e 100644 --- a/src/SharpCompress/Compressors/Rar/RarCrcStream.cs +++ b/src/SharpCompress/Compressors/Rar/RarCrcStream.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common; using SharpCompress.Common.Rar.Headers; using SharpCompress.IO; @@ -31,7 +33,7 @@ internal class RarCrcStream : RarStream, IStreamStack private uint currentCrc; private readonly bool disableCRC; - public RarCrcStream( + private RarCrcStream( IRarUnpack unpack, FileHeader fileHeader, MultiVolumeReadOnlyStream readStream @@ -46,6 +48,26 @@ internal class RarCrcStream : RarStream, IStreamStack ResetCrc(); } + public static RarCrcStream Create( + IRarUnpack unpack, + FileHeader fileHeader, + MultiVolumeReadOnlyStream readStream) + { + var stream = new RarCrcStream(unpack, fileHeader, readStream); + stream.Initialize(); + return stream; + } + + public static async Task CreateAsync( + IRarUnpack unpack, + FileHeader fileHeader, + MultiVolumeReadOnlyStream readStream, CancellationToken cancellationToken = default) + { + var stream = new RarCrcStream(unpack, fileHeader, readStream); + await stream.InitializeAsync(cancellationToken); + return stream; + } + protected override void Dispose(bool disposing) { #if DEBUG_STREAMS diff --git a/src/SharpCompress/Compressors/Rar/RarStream.cs b/src/SharpCompress/Compressors/Rar/RarStream.cs index 43d6ff4a..2a9facaa 100644 --- a/src/SharpCompress/Compressors/Rar/RarStream.cs +++ b/src/SharpCompress/Compressors/Rar/RarStream.cs @@ -3,6 +3,8 @@ using System; using System.Buffers; using System.IO; +using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common.Rar.Headers; using SharpCompress.IO; @@ -56,13 +58,24 @@ internal class RarStream : Stream, IStreamStack #if DEBUG_STREAMS this.DebugConstruct(typeof(RarStream)); #endif + } + public void Initialize() + { fetch = true; unpack.DoUnpack(fileHeader, readStream, this); fetch = false; _position = 0; } + public async Task InitializeAsync(CancellationToken cancellationToken = default) + { + fetch = true; + await unpack.DoUnpackAsync(fileHeader, readStream, this, cancellationToken); + fetch = false; + _position = 0; + } + protected override void Dispose(bool disposing) { if (!isDisposed) diff --git a/src/SharpCompress/Readers/Rar/RarReader.cs b/src/SharpCompress/Readers/Rar/RarReader.cs index 79842e6a..8238e619 100644 --- a/src/SharpCompress/Readers/Rar/RarReader.cs +++ b/src/SharpCompress/Readers/Rar/RarReader.cs @@ -113,7 +113,7 @@ public abstract class RarReader : AbstractReader ); if (Entry.IsRarV3) { - return CreateEntryStream(new RarCrcStream(UnpackV1.Value, Entry.FileHeader, stream)); + return CreateEntryStream( RarCrcStream.Create(UnpackV1.Value, Entry.FileHeader, stream)); } if (Entry.FileHeader.FileCrc?.Length > 5) @@ -123,6 +123,6 @@ public abstract class RarReader : AbstractReader ); } - return CreateEntryStream(new RarCrcStream(UnpackV2017.Value, Entry.FileHeader, stream)); + return CreateEntryStream(RarCrcStream.Create(UnpackV2017.Value, Entry.FileHeader, stream)); } }