diff --git a/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.Async.cs new file mode 100644 index 00000000..321535aa --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.Async.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Compressors.Filters; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class ArmFilter +{ + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var bytesRead = await BaseStream + .ReadAsync(buffer, offset, count, cancellationToken) + .ConfigureAwait(false); + BranchExecFilter.ARMConverter(buffer, _ip); + _ip += (uint)bytesRead; + return bytesRead; + } + +#if !LEGACY_DOTNET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var bytesRead = await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); + var arrayBuffer = buffer.Slice(0, bytesRead).ToArray(); + BranchExecFilter.ARMConverter(arrayBuffer, _ip); + arrayBuffer.AsSpan(0, bytesRead).CopyTo(buffer.Span); + _ip += (uint)bytesRead; + return bytesRead; + } +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.cs b/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.cs index cff95778..30590408 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/ArmFilter.cs @@ -10,7 +10,7 @@ using SharpCompress.Compressors.Filters; namespace SharpCompress.Compressors.Xz.Filters; -public class ArmFilter : BlockFilter +public partial class ArmFilter : BlockFilter { public override bool AllowAsLast => false; diff --git a/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.Async.cs new file mode 100644 index 00000000..3632716b --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.Async.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Compressors.Filters; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class ArmThumbFilter +{ + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var bytesRead = await BaseStream + .ReadAsync(buffer, offset, count, cancellationToken) + .ConfigureAwait(false); + BranchExecFilter.ARMTConverter(buffer, _ip); + _ip += (uint)bytesRead; + return bytesRead; + } + +#if !LEGACY_DOTNET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var bytesRead = await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); + var arrayBuffer = buffer.Slice(0, bytesRead).ToArray(); + BranchExecFilter.ARMTConverter(arrayBuffer, _ip); + arrayBuffer.AsSpan(0, bytesRead).CopyTo(buffer.Span); + _ip += (uint)bytesRead; + return bytesRead; + } +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.cs b/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.cs index 1bcfcdc9..97d20867 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/ArmThumbFilter.cs @@ -10,7 +10,7 @@ using SharpCompress.Compressors.Filters; namespace SharpCompress.Compressors.Xz.Filters; -public class ArmThumbFilter : BlockFilter +public partial class ArmThumbFilter : BlockFilter { public override bool AllowAsLast => false; diff --git a/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.Async.cs new file mode 100644 index 00000000..cb1b4535 --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.Async.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Compressors.Filters; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class IA64Filter +{ + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var bytesRead = await BaseStream + .ReadAsync(buffer, offset, count, cancellationToken) + .ConfigureAwait(false); + BranchExecFilter.IA64Converter(buffer, _ip); + _ip += (uint)bytesRead; + return bytesRead; + } + +#if !LEGACY_DOTNET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var bytesRead = await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); + var arrayBuffer = buffer.Slice(0, bytesRead).ToArray(); + BranchExecFilter.IA64Converter(arrayBuffer, _ip); + arrayBuffer.AsSpan(0, bytesRead).CopyTo(buffer.Span); + _ip += (uint)bytesRead; + return bytesRead; + } +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.cs b/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.cs index 14f8cdad..b514f64e 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/IA64Filter.cs @@ -10,7 +10,7 @@ using SharpCompress.Compressors.Filters; namespace SharpCompress.Compressors.Xz.Filters; -public class IA64Filter : BlockFilter +public partial class IA64Filter : BlockFilter { public override bool AllowAsLast => false; diff --git a/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.Async.cs new file mode 100644 index 00000000..f8d04250 --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.Async.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class Lzma2Filter +{ + public override Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) => BaseStream.ReadAsync(buffer, offset, count, cancellationToken); + +#if !LEGACY_DOTNET + public override ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) => BaseStream.ReadAsync(buffer, cancellationToken); +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs b/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs index c4169ebb..ab8904b0 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/Lzma2Filter.cs @@ -6,7 +6,7 @@ using SharpCompress.Compressors.LZMA; namespace SharpCompress.Compressors.Xz.Filters; [CLSCompliant(false)] -public class Lzma2Filter : BlockFilter +public partial class Lzma2Filter : BlockFilter { public override bool AllowAsLast => true; public override bool AllowAsNonLast => false; diff --git a/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.Async.cs new file mode 100644 index 00000000..95c04b0b --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.Async.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Compressors.Filters; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class PowerPCFilter +{ + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var bytesRead = await BaseStream + .ReadAsync(buffer, offset, count, cancellationToken) + .ConfigureAwait(false); + BranchExecFilter.PowerPCConverter(buffer, _ip); + _ip += (uint)bytesRead; + return bytesRead; + } + +#if !LEGACY_DOTNET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var bytesRead = await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); + var arrayBuffer = buffer.Slice(0, bytesRead).ToArray(); + BranchExecFilter.PowerPCConverter(arrayBuffer, _ip); + arrayBuffer.AsSpan(0, bytesRead).CopyTo(buffer.Span); + _ip += (uint)bytesRead; + return bytesRead; + } +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.cs b/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.cs index b171fa6c..d0c6e5f5 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/PowerPCFilter.cs @@ -10,7 +10,7 @@ using SharpCompress.Compressors.Filters; namespace SharpCompress.Compressors.Xz.Filters; -public class PowerPCFilter : BlockFilter +public partial class PowerPCFilter : BlockFilter { public override bool AllowAsLast => false; diff --git a/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.Async.cs new file mode 100644 index 00000000..d4b06191 --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.Async.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Compressors.Filters; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class SparcFilter +{ + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var bytesRead = await BaseStream + .ReadAsync(buffer, offset, count, cancellationToken) + .ConfigureAwait(false); + BranchExecFilter.SPARCConverter(buffer, _ip); + _ip += (uint)bytesRead; + return bytesRead; + } + +#if !LEGACY_DOTNET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var bytesRead = await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); + var arrayBuffer = buffer.Slice(0, bytesRead).ToArray(); + BranchExecFilter.SPARCConverter(arrayBuffer, _ip); + arrayBuffer.AsSpan(0, bytesRead).CopyTo(buffer.Span); + _ip += (uint)bytesRead; + return bytesRead; + } +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.cs b/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.cs index 8b3a4532..01c1cf36 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/SparcFilter.cs @@ -10,7 +10,7 @@ using SharpCompress.Compressors.Filters; namespace SharpCompress.Compressors.Xz.Filters; -public class SparcFilter : BlockFilter +public partial class SparcFilter : BlockFilter { public override bool AllowAsLast => false; diff --git a/src/SharpCompress/Compressors/Xz/Filters/X86Filter.Async.cs b/src/SharpCompress/Compressors/Xz/Filters/X86Filter.Async.cs new file mode 100644 index 00000000..6a8ff6f4 --- /dev/null +++ b/src/SharpCompress/Compressors/Xz/Filters/X86Filter.Async.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Compressors.Filters; + +namespace SharpCompress.Compressors.Xz.Filters; + +public partial class X86Filter +{ + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var bytesRead = await BaseStream + .ReadAsync(buffer, offset, count, cancellationToken) + .ConfigureAwait(false); + BranchExecFilter.X86Converter(buffer, _ip, ref _state); + _ip += (uint)bytesRead; + return bytesRead; + } + +#if !LEGACY_DOTNET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var bytesRead = await BaseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); + // X86Converter requires byte[], so we need to copy to an array + var arrayBuffer = buffer.Slice(0, bytesRead).ToArray(); + BranchExecFilter.X86Converter(arrayBuffer, _ip, ref _state); + arrayBuffer.AsSpan(0, bytesRead).CopyTo(buffer.Span); + _ip += (uint)bytesRead; + return bytesRead; + } +#endif +} diff --git a/src/SharpCompress/Compressors/Xz/Filters/X86Filter.cs b/src/SharpCompress/Compressors/Xz/Filters/X86Filter.cs index fd8ef42a..37d959bc 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/X86Filter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/X86Filter.cs @@ -10,7 +10,7 @@ using SharpCompress.Compressors.Filters; namespace SharpCompress.Compressors.Xz.Filters; -public class X86Filter : BlockFilter +public partial class X86Filter : BlockFilter { public override bool AllowAsLast => false; diff --git a/src/SharpCompress/Factories/TarFactory.cs b/src/SharpCompress/Factories/TarFactory.cs index 189ad3b4..53286880 100644 --- a/src/SharpCompress/Factories/TarFactory.cs +++ b/src/SharpCompress/Factories/TarFactory.cs @@ -84,7 +84,10 @@ public class TarFactory if (await wrapper.IsMatchAsync(rewindableStream, cancellationToken)) { rewindableStream.Rewind(); - var decompressedStream = wrapper.CreateStream(rewindableStream); + var decompressedStream = await wrapper.CreateStreamAsync( + rewindableStream, + cancellationToken + ); if (await TarArchive.IsTarFileAsync(decompressedStream, cancellationToken)) { rewindableStream.Rewind(); diff --git a/src/SharpCompress/Factories/TarWrapper.cs b/src/SharpCompress/Factories/TarWrapper.cs index 640a34d5..2f3ff64a 100644 --- a/src/SharpCompress/Factories/TarWrapper.cs +++ b/src/SharpCompress/Factories/TarWrapper.cs @@ -20,6 +20,7 @@ public class TarWrapper( Func canHandle, Func> canHandleAsync, Func createStream, + Func> createStreamAsync, IEnumerable knownExtensions, bool wrapInSharpCompressStream = true ) @@ -30,6 +31,8 @@ public class TarWrapper( public bool WrapInSharpCompressStream { get; } = wrapInSharpCompressStream; public Func CreateStream { get; } = createStream; + public Func> CreateStreamAsync { get; } = + createStreamAsync; public IEnumerable KnownExtensions { get; } = knownExtensions; @@ -41,6 +44,7 @@ public class TarWrapper( (_) => true, (_, _) => new ValueTask(true), (stream) => stream, + (stream, _) => new ValueTask(stream), ["tar"], false ), // We always do a test for IsTarFile later @@ -49,6 +53,8 @@ public class TarWrapper( BZip2Stream.IsBZip2, BZip2Stream.IsBZip2Async, (stream) => BZip2Stream.Create(stream, CompressionMode.Decompress, false), + async (stream, _) => + await BZip2Stream.CreateAsync(stream, CompressionMode.Decompress, false), ["tar.bz2", "tb2", "tbz", "tbz2", "tz2"] ), new( @@ -56,6 +62,8 @@ public class TarWrapper( GZipArchive.IsGZipFile, GZipArchive.IsGZipFileAsync, (stream) => new GZipStream(stream, CompressionMode.Decompress), + (stream, _) => + new ValueTask(new GZipStream(stream, CompressionMode.Decompress)), ["tar.gz", "taz", "tgz"] ), new( @@ -63,6 +71,7 @@ public class TarWrapper( ZStandardStream.IsZStandard, ZStandardStream.IsZStandardAsync, (stream) => new ZStandardStream(stream), + (stream, _) => new ValueTask(new ZStandardStream(stream)), ["tar.zst", "tar.zstd", "tzst", "tzstd"] ), new( @@ -70,6 +79,8 @@ public class TarWrapper( LZipStream.IsLZipFile, LZipStream.IsLZipFileAsync, (stream) => new LZipStream(stream, CompressionMode.Decompress), + (stream, _) => + new ValueTask(new LZipStream(stream, CompressionMode.Decompress)), ["tar.lz"] ), new( @@ -77,6 +88,7 @@ public class TarWrapper( XZStream.IsXZStream, XZStream.IsXZStreamAsync, (stream) => new XZStream(stream), + (stream, _) => new ValueTask(new XZStream(stream)), ["tar.xz", "txz"], false ), @@ -85,6 +97,7 @@ public class TarWrapper( LzwStream.IsLzwStream, LzwStream.IsLzwStreamAsync, (stream) => new LzwStream(stream), + (stream, _) => new ValueTask(new LzwStream(stream)), ["tar.Z", "tZ", "taZ"], false ),