diff --git a/src/SharpCompress/Archives/ArchiveFactory.Async.cs b/src/SharpCompress/Archives/ArchiveFactory.Async.cs index 82a40a16..0ae6c910 100644 --- a/src/SharpCompress/Archives/ArchiveFactory.Async.cs +++ b/src/SharpCompress/Archives/ArchiveFactory.Async.cs @@ -53,20 +53,20 @@ public static partial class ArchiveFactory } public static async ValueTask OpenAsyncArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? options = null, CancellationToken cancellationToken = default ) { fileInfos.NotNull(nameof(fileInfos)); - var filesArray = fileInfos.ToArray(); - if (filesArray.Length == 0) + var filesArray = fileInfos; + if (filesArray.Count == 0) { throw new ArchiveOperationException("No files to open"); } var fileInfo = filesArray[0]; - if (filesArray.Length == 1) + if (filesArray.Count == 1) { return await OpenAsyncArchive(fileInfo, options, cancellationToken) .ConfigureAwait(false); @@ -83,21 +83,21 @@ public static partial class ArchiveFactory } public static async ValueTask OpenAsyncArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? options = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); streams.NotNull(nameof(streams)); - var streamsArray = streams.ToArray(); - if (streamsArray.Length == 0) + var streamsArray = streams; + if (streamsArray.Count == 0) { throw new ArchiveOperationException("No streams"); } var firstStream = streamsArray[0]; - if (streamsArray.Length == 1) + if (streamsArray.Count == 1) { return await OpenAsyncArchive(firstStream, options, cancellationToken) .ConfigureAwait(false); @@ -114,18 +114,18 @@ public static partial class ArchiveFactory } public static ValueTask FindFactoryAsync( - string path, + string filePath, CancellationToken cancellationToken = default ) where T : IFactory { - path.NotNullOrEmpty(nameof(path)); - return FindFactoryAsync(new FileInfo(path), cancellationToken); + filePath.NotNullOrEmpty(nameof(filePath)); + return FindFactoryAsync(new FileInfo(filePath), cancellationToken); } - private static async ValueTask FindFactoryAsync( + public static async ValueTask FindFactoryAsync( FileInfo finfo, - CancellationToken cancellationToken + CancellationToken cancellationToken = default ) where T : IFactory { @@ -134,9 +134,9 @@ public static partial class ArchiveFactory return await FindFactoryAsync(stream, cancellationToken).ConfigureAwait(false); } - private static async ValueTask FindFactoryAsync( + public static async ValueTask FindFactoryAsync( Stream stream, - CancellationToken cancellationToken + CancellationToken cancellationToken = default ) where T : IFactory { diff --git a/src/SharpCompress/Archives/ArchiveFactory.cs b/src/SharpCompress/Archives/ArchiveFactory.cs index 85cf0058..879cb999 100644 --- a/src/SharpCompress/Archives/ArchiveFactory.cs +++ b/src/SharpCompress/Archives/ArchiveFactory.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common; using SharpCompress.Common.Options; using SharpCompress.Factories; @@ -21,7 +23,7 @@ public static partial class ArchiveFactory where TOptions : IWriterOptions { var factory = Factory - .Factories.OfType>() + .Factories.OfType>() .FirstOrDefault(); if (factory != null) @@ -32,6 +34,24 @@ public static partial class ArchiveFactory throw new NotSupportedException("Cannot create Archives of type: " + typeof(TOptions)); } + public static ValueTask> CreateAsyncArchive( + CancellationToken cancellationToken = default + ) + where TOptions : IWriterOptions + { + cancellationToken.ThrowIfCancellationRequested(); + var factory = Factory + .Factories.OfType>() + .FirstOrDefault(); + + if (factory is not null) + { + return factory.CreateAsyncArchive(cancellationToken); + } + + throw new NotSupportedException("Cannot create Archives of type: " + typeof(TOptions)); + } + public static IArchive OpenArchive(string filePath, ReaderOptions? options = null) { filePath.NotNullOrEmpty(nameof(filePath)); @@ -46,19 +66,19 @@ public static partial class ArchiveFactory } public static IArchive OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? options = null ) { fileInfos.NotNull(nameof(fileInfos)); - var filesArray = fileInfos.ToArray(); - if (filesArray.Length == 0) + var filesArray = fileInfos; + if (filesArray.Count == 0) { throw new ArchiveOperationException("No files to open"); } var fileInfo = filesArray[0]; - if (filesArray.Length == 1) + if (filesArray.Count == 1) { return OpenArchive(fileInfo, options); } @@ -69,17 +89,17 @@ public static partial class ArchiveFactory return FindFactory(fileInfo).OpenArchive(filesArray, options); } - public static IArchive OpenArchive(IEnumerable streams, ReaderOptions? options = null) + public static IArchive OpenArchive(IReadOnlyList streams, ReaderOptions? options = null) { streams.NotNull(nameof(streams)); - var streamsArray = streams.ToArray(); - if (streamsArray.Length == 0) + var streamsArray = streams; + if (streamsArray.Count == 0) { throw new ArchiveOperationException("No streams"); } var firstStream = streamsArray[0]; - if (streamsArray.Length == 1) + if (streamsArray.Count == 1) { return OpenArchive(firstStream, options); } @@ -100,11 +120,11 @@ public static partial class ArchiveFactory archive.WriteToDirectory(destinationDirectory, options); } - public static T FindFactory(string path) + public static T FindFactory(string filePath) where T : IFactory { - path.NotNullOrEmpty(nameof(path)); - using Stream stream = File.OpenRead(path); + filePath.NotNullOrEmpty(nameof(filePath)); + using Stream stream = File.OpenRead(filePath); return FindFactory(stream); } @@ -182,6 +202,46 @@ public static partial class ArchiveFactory return false; } + public static ValueTask<(bool IsArchive, ArchiveType? Type)> IsArchiveAsync( + string filePath, + CancellationToken cancellationToken = default + ) + { + filePath.NotNullOrEmpty(nameof(filePath)); + using Stream stream = File.OpenRead(filePath); + return IsArchiveAsync(stream, cancellationToken); + } + + public static async ValueTask<(bool IsArchive, ArchiveType? Type)> IsArchiveAsync( + Stream stream, + CancellationToken cancellationToken = default + ) + { + stream.NotNull(nameof(stream)); + + if (!stream.CanRead || !stream.CanSeek) + { + throw new ArgumentException("Stream should be readable and seekable"); + } + + var startPosition = stream.Position; + + foreach (var factory in Factory.Factories) + { + var isArchive = await factory + .IsArchiveAsync(stream, cancellationToken: cancellationToken) + .ConfigureAwait(false); + stream.Position = startPosition; + + if (isArchive) + { + return (true, factory.KnownArchiveType); + } + } + + return (false, null); + } + public static IEnumerable GetFileParts(string part1) { part1.NotNullOrEmpty(nameof(part1)); diff --git a/src/SharpCompress/Archives/GZip/GZipArchive.Factory.cs b/src/SharpCompress/Archives/GZip/GZipArchive.Factory.cs index 6fe3fe60..9dad1ae8 100644 --- a/src/SharpCompress/Archives/GZip/GZipArchive.Factory.cs +++ b/src/SharpCompress/Archives/GZip/GZipArchive.Factory.cs @@ -21,14 +21,14 @@ public partial class GZipArchive #endif { public static ValueTask> OpenAsyncArchive( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return OpenAsyncArchive(new FileInfo(path), readerOptions, cancellationToken); + filePath.NotNullOrEmpty(nameof(filePath)); + return OpenAsyncArchive(new FileInfo(filePath), readerOptions, cancellationToken); } public static IWritableArchive OpenArchive( @@ -37,7 +37,7 @@ public partial class GZipArchive ) { filePath.NotNullOrEmpty(nameof(filePath)); - return OpenArchive(new FileInfo(filePath), readerOptions ?? new ReaderOptions()); + return OpenArchive(new FileInfo(filePath), readerOptions ?? ReaderOptions.ForFilePath); } public static IWritableArchive OpenArchive( @@ -50,39 +50,39 @@ public partial class GZipArchive new SourceStream( fileInfo, i => ArchiveVolumeFactory.GetFilePart(i, fileInfo), - readerOptions ?? new ReaderOptions() + readerOptions ?? ReaderOptions.ForFilePath ) ); } public static IWritableArchive OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? readerOptions = null ) { fileInfos.NotNull(nameof(fileInfos)); - var files = fileInfos.ToArray(); + var files = fileInfos; return new GZipArchive( new SourceStream( files[0], - i => i < files.Length ? files[i] : null, - readerOptions ?? new ReaderOptions() + i => i < files.Count ? files[i] : null, + readerOptions ?? ReaderOptions.ForFilePath ) ); } public static IWritableArchive OpenArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? readerOptions = null ) { streams.NotNull(nameof(streams)); - var strms = streams.ToArray(); + var strms = streams; return new GZipArchive( new SourceStream( strms[0], - i => i < strms.Length ? strms[i] : null, - readerOptions ?? new ReaderOptions() + i => i < strms.Count ? strms[i] : null, + readerOptions ?? ReaderOptions.ForExternalStream ) ); } @@ -100,7 +100,7 @@ public partial class GZipArchive } return new GZipArchive( - new SourceStream(stream, _ => null, readerOptions ?? new ReaderOptions()) + new SourceStream(stream, _ => null, readerOptions ?? ReaderOptions.ForExternalStream) ); } diff --git a/src/SharpCompress/Archives/IArchiveOpenable.cs b/src/SharpCompress/Archives/IArchiveOpenable.cs index 5539e16e..22c0ed34 100644 --- a/src/SharpCompress/Archives/IArchiveOpenable.cs +++ b/src/SharpCompress/Archives/IArchiveOpenable.cs @@ -20,7 +20,7 @@ public interface IArchiveOpenable public static abstract TSync OpenArchive(Stream stream, ReaderOptions? readerOptions = null); public static abstract ValueTask OpenAsyncArchive( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ); diff --git a/src/SharpCompress/Archives/IMultiArchiveOpenable.cs b/src/SharpCompress/Archives/IMultiArchiveOpenable.cs index 6a927297..4c208ec1 100644 --- a/src/SharpCompress/Archives/IMultiArchiveOpenable.cs +++ b/src/SharpCompress/Archives/IMultiArchiveOpenable.cs @@ -12,12 +12,12 @@ public interface IMultiArchiveOpenable where TASync : IAsyncArchive { public static abstract TSync OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? readerOptions = null ); public static abstract TSync OpenArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? readerOptions = null ); diff --git a/src/SharpCompress/Archives/IWritableArchiveExtensions.cs b/src/SharpCompress/Archives/IWritableArchiveExtensions.cs index 6012dda5..f6ce3ff2 100644 --- a/src/SharpCompress/Archives/IWritableArchiveExtensions.cs +++ b/src/SharpCompress/Archives/IWritableArchiveExtensions.cs @@ -22,7 +22,7 @@ public static class IWritableArchiveExtensions var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption) ) { - var fileInfo = new FileInfo(path); + var fileInfo = new FileInfo(filePath); writableArchive.AddEntry( path.Substring(filePath.Length), fileInfo.OpenRead(), diff --git a/src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs b/src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs index 4bdc792f..6e848b21 100644 --- a/src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs +++ b/src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs @@ -24,7 +24,7 @@ public static class IWritableAsyncArchiveExtensions var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption) ) { - var fileInfo = new FileInfo(path); + var fileInfo = new FileInfo(filePath); await writableArchive .AddEntryAsync( path.Substring(filePath.Length), diff --git a/src/SharpCompress/Archives/IWritableAsyncArchiveFactory.cs b/src/SharpCompress/Archives/IWritableAsyncArchiveFactory.cs new file mode 100644 index 00000000..0de3a7da --- /dev/null +++ b/src/SharpCompress/Archives/IWritableAsyncArchiveFactory.cs @@ -0,0 +1,19 @@ +using System.Threading; +using System.Threading.Tasks; +using SharpCompress.Common.Options; + +namespace SharpCompress.Archives; + +/// +/// Decorator for used to declare an archive format as able to create async writable archives. +/// +public interface IWritableAsyncArchiveFactory : Factories.IFactory + where TOptions : IWriterOptions +{ + /// + /// Creates a new, empty async archive, ready to be written. + /// + ValueTask> CreateAsyncArchive( + CancellationToken cancellationToken = default + ); +} diff --git a/src/SharpCompress/Archives/IWriteableArchiveFactory.cs b/src/SharpCompress/Archives/IWriteableArchiveFactory.cs index 40a01fac..7c7ace2c 100644 --- a/src/SharpCompress/Archives/IWriteableArchiveFactory.cs +++ b/src/SharpCompress/Archives/IWriteableArchiveFactory.cs @@ -3,7 +3,7 @@ using SharpCompress.Common.Options; namespace SharpCompress.Archives; /// -/// Decorator for used to declare an archive format as able to create writeable archives +/// Decorator for used to declare an archive format as able to create writable archives. /// /// /// Implemented by:
@@ -12,7 +12,8 @@ namespace SharpCompress.Archives; /// /// /// -public interface IWriteableArchiveFactory : Factories.IFactory +///
+public interface IWritableArchiveFactory : Factories.IFactory where TOptions : IWriterOptions { /// diff --git a/src/SharpCompress/Archives/Rar/RarArchive.Factory.cs b/src/SharpCompress/Archives/Rar/RarArchive.Factory.cs index 707049d3..432bf54f 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.Factory.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.Factory.cs @@ -21,14 +21,14 @@ public partial class RarArchive #endif { public static ValueTask OpenAsyncArchive( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IRarAsyncArchive)OpenArchive(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IRarAsyncArchive)OpenArchive(new FileInfo(filePath), readerOptions)); } public static IRarArchive OpenArchive(string filePath, ReaderOptions? readerOptions = null) @@ -39,7 +39,7 @@ public partial class RarArchive new SourceStream( fileInfo, i => RarArchiveVolumeFactory.GetFilePart(i, fileInfo), - readerOptions ?? new ReaderOptions() + readerOptions ?? ReaderOptions.ForFilePath ) ); } @@ -71,33 +71,33 @@ public partial class RarArchive } public static IRarArchive OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? readerOptions = null ) { fileInfos.NotNull(nameof(fileInfos)); - var files = fileInfos.ToArray(); + var files = fileInfos; return new RarArchive( new SourceStream( files[0], - i => i < files.Length ? files[i] : null, - readerOptions ?? new ReaderOptions() + i => i < files.Count ? files[i] : null, + readerOptions ?? ReaderOptions.ForFilePath ) ); } public static IRarArchive OpenArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? readerOptions = null ) { streams.NotNull(nameof(streams)); - var strms = streams.ToArray(); + var strms = streams; return new RarArchive( new SourceStream( strms[0], - i => i < strms.Length ? strms[i] : null, - readerOptions ?? new ReaderOptions() + i => i < strms.Count ? strms[i] : null, + readerOptions ?? ReaderOptions.ForExternalStream ) ); } diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Factory.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Factory.cs index 30adbaf9..df7fa8c4 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Factory.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.Factory.cs @@ -17,22 +17,25 @@ public partial class SevenZipArchive #endif { public static ValueTask OpenAsyncArchive( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty("path"); + filePath.NotNullOrEmpty(nameof(filePath)); return new( - (IAsyncArchive)OpenArchive(new FileInfo(path), readerOptions ?? new ReaderOptions()) + (IAsyncArchive)OpenArchive( + new FileInfo(filePath), + readerOptions ?? ReaderOptions.ForFilePath + ) ); } public static IArchive OpenArchive(string filePath, ReaderOptions? readerOptions = null) { - filePath.NotNullOrEmpty("filePath"); - return OpenArchive(new FileInfo(filePath), readerOptions ?? new ReaderOptions()); + filePath.NotNullOrEmpty(nameof(filePath)); + return OpenArchive(new FileInfo(filePath), readerOptions ?? ReaderOptions.ForFilePath); } public static IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) @@ -42,39 +45,39 @@ public partial class SevenZipArchive new SourceStream( fileInfo, i => ArchiveVolumeFactory.GetFilePart(i, fileInfo), - readerOptions ?? new ReaderOptions() + readerOptions ?? ReaderOptions.ForFilePath ) ); } public static IArchive OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? readerOptions = null ) { fileInfos.NotNull(nameof(fileInfos)); - var files = fileInfos.ToArray(); + var files = fileInfos; return new SevenZipArchive( new SourceStream( files[0], - i => i < files.Length ? files[i] : null, - readerOptions ?? new ReaderOptions() + i => i < files.Count ? files[i] : null, + readerOptions ?? ReaderOptions.ForFilePath ) ); } public static IArchive OpenArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? readerOptions = null ) { streams.NotNull(nameof(streams)); - var strms = streams.ToArray(); + var strms = streams; return new SevenZipArchive( new SourceStream( strms[0], - i => i < strms.Length ? strms[i] : null, - readerOptions ?? new ReaderOptions() + i => i < strms.Count ? strms[i] : null, + readerOptions ?? ReaderOptions.ForExternalStream ) ); } @@ -89,7 +92,7 @@ public partial class SevenZipArchive } return new SevenZipArchive( - new SourceStream(stream, _ => null, readerOptions ?? new ReaderOptions()) + new SourceStream(stream, _ => null, readerOptions ?? ReaderOptions.ForExternalStream) ); } diff --git a/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs b/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs index 3c3caa3f..e1464dbf 100644 --- a/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs +++ b/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs @@ -38,23 +38,20 @@ public partial class TarArchive ) { fileInfo.NotNull(nameof(fileInfo)); - return OpenArchive( - [fileInfo], - readerOptions ?? new ReaderOptions() { LeaveStreamOpen = false } - ); + return OpenArchive([fileInfo], readerOptions ?? ReaderOptions.ForFilePath); } public static IWritableArchive OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? readerOptions = null ) { fileInfos.NotNull(nameof(fileInfos)); - var files = fileInfos.ToArray(); + var files = fileInfos; var sourceStream = new SourceStream( files[0], - i => i < files.Length ? files[i] : null, - readerOptions ?? new ReaderOptions() { LeaveStreamOpen = false } + i => i < files.Count ? files[i] : null, + readerOptions ?? ReaderOptions.ForFilePath ); var compressionType = TarFactory.GetCompressionType( sourceStream, @@ -65,16 +62,16 @@ public partial class TarArchive } public static IWritableArchive OpenArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? readerOptions = null ) { streams.NotNull(nameof(streams)); - var strms = streams.ToArray(); + var strms = streams; var sourceStream = new SourceStream( strms[0], - i => i < strms.Length ? strms[i] : null, - readerOptions ?? new ReaderOptions() + i => i < strms.Count ? strms[i] : null, + readerOptions ?? ReaderOptions.ForExternalStream ); var compressionType = TarFactory.GetCompressionType( sourceStream, @@ -109,7 +106,7 @@ public partial class TarArchive var sourceStream = new SourceStream( stream, i => null, - readerOptions ?? new ReaderOptions() + readerOptions ?? ReaderOptions.ForExternalStream ); var compressionType = await TarFactory .GetCompressionTypeAsync( @@ -123,14 +120,14 @@ public partial class TarArchive } public static ValueTask> OpenAsyncArchive( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return OpenAsyncArchive(new FileInfo(path), readerOptions, cancellationToken); + filePath.NotNullOrEmpty(nameof(filePath)); + return OpenAsyncArchive(new FileInfo(filePath), readerOptions, cancellationToken); } public static async ValueTask> OpenAsyncArchive( @@ -141,7 +138,7 @@ public partial class TarArchive { cancellationToken.ThrowIfCancellationRequested(); fileInfo.NotNull(nameof(fileInfo)); - readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false }; + readerOptions ??= ReaderOptions.ForFilePath; var sourceStream = new SourceStream(fileInfo, i => null, readerOptions); var compressionType = await TarFactory .GetCompressionTypeAsync( @@ -162,11 +159,11 @@ public partial class TarArchive { cancellationToken.ThrowIfCancellationRequested(); streams.NotNull(nameof(streams)); - var strms = streams.ToArray(); + var strms = streams; var sourceStream = new SourceStream( strms[0], - i => i < strms.Length ? strms[i] : null, - readerOptions ?? new ReaderOptions() + i => i < strms.Count ? strms[i] : null, + readerOptions ?? ReaderOptions.ForExternalStream ); var compressionType = await TarFactory .GetCompressionTypeAsync( @@ -187,11 +184,11 @@ public partial class TarArchive { cancellationToken.ThrowIfCancellationRequested(); fileInfos.NotNull(nameof(fileInfos)); - var files = fileInfos.ToArray(); + var files = fileInfos; var sourceStream = new SourceStream( files[0], - i => i < files.Length ? files[i] : null, - readerOptions ?? new ReaderOptions() { LeaveStreamOpen = false } + i => i < files.Count ? files[i] : null, + readerOptions ?? ReaderOptions.ForFilePath ); var compressionType = await TarFactory .GetCompressionTypeAsync( diff --git a/src/SharpCompress/Archives/Zip/ZipArchive.Factory.cs b/src/SharpCompress/Archives/Zip/ZipArchive.Factory.cs index dc4aad38..db0b8489 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchive.Factory.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchive.Factory.cs @@ -47,33 +47,33 @@ public partial class ZipArchive } public static IWritableArchive OpenArchive( - IEnumerable fileInfos, + IReadOnlyList fileInfos, ReaderOptions? readerOptions = null ) { fileInfos.NotNull(nameof(fileInfos)); - var files = fileInfos.ToArray(); + var files = fileInfos; return new ZipArchive( new SourceStream( files[0], - i => i < files.Length ? files[i] : null, + i => i < files.Count ? files[i] : null, readerOptions ?? new ReaderOptions() { LeaveStreamOpen = false } ) ); } public static IWritableArchive OpenArchive( - IEnumerable streams, + IReadOnlyList streams, ReaderOptions? readerOptions = null ) { streams.NotNull(nameof(streams)); - var strms = streams.ToArray(); + var strms = streams; return new ZipArchive( new SourceStream( strms[0], - i => i < strms.Length ? strms[i] : null, - readerOptions ?? new ReaderOptions() + i => i < strms.Count ? strms[i] : null, + readerOptions ?? ReaderOptions.ForExternalStream ) ); } @@ -91,18 +91,18 @@ public partial class ZipArchive } return new ZipArchive( - new SourceStream(stream, i => null, readerOptions ?? new ReaderOptions()) + new SourceStream(stream, i => null, readerOptions ?? ReaderOptions.ForExternalStream) ); } public static ValueTask> OpenAsyncArchive( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - return new((IWritableAsyncArchive)OpenArchive(path, readerOptions)); + return new((IWritableAsyncArchive)OpenArchive(filePath, readerOptions)); } public static ValueTask> OpenAsyncArchive( diff --git a/src/SharpCompress/Factories/GZipFactory.cs b/src/SharpCompress/Factories/GZipFactory.cs index 70a2ad85..5278871e 100644 --- a/src/SharpCompress/Factories/GZipFactory.cs +++ b/src/SharpCompress/Factories/GZipFactory.cs @@ -27,7 +27,8 @@ public class GZipFactory IMultiArchiveFactory, IReaderFactory, IWriterFactory, - IWriteableArchiveFactory + IWritableArchiveFactory, + IWritableAsyncArchiveFactory { #region IFactory @@ -218,10 +219,19 @@ public class GZipFactory #endregion - #region IWriteableArchiveFactory + #region IWritableArchiveFactory /// public IWritableArchive CreateArchive() => GZipArchive.CreateArchive(); + /// + public ValueTask> CreateAsyncArchive( + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return GZipArchive.CreateAsyncArchive(); + } + #endregion } diff --git a/src/SharpCompress/Factories/TarFactory.cs b/src/SharpCompress/Factories/TarFactory.cs index c92501ba..fda80346 100644 --- a/src/SharpCompress/Factories/TarFactory.cs +++ b/src/SharpCompress/Factories/TarFactory.cs @@ -25,7 +25,8 @@ public class TarFactory IMultiArchiveFactory, IReaderFactory, IWriterFactory, - IWriteableArchiveFactory + IWritableArchiveFactory, + IWritableAsyncArchiveFactory { #region IFactory @@ -421,10 +422,19 @@ public class TarFactory #endregion - #region IWriteableArchiveFactory + #region IWritableArchiveFactory /// public IWritableArchive CreateArchive() => TarArchive.CreateArchive(); + /// + public ValueTask> CreateAsyncArchive( + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return TarArchive.CreateAsyncArchive(); + } + #endregion } diff --git a/src/SharpCompress/Factories/ZipFactory.cs b/src/SharpCompress/Factories/ZipFactory.cs index 057bfb65..67c1100a 100644 --- a/src/SharpCompress/Factories/ZipFactory.cs +++ b/src/SharpCompress/Factories/ZipFactory.cs @@ -24,7 +24,8 @@ public class ZipFactory IMultiArchiveFactory, IReaderFactory, IWriterFactory, - IWriteableArchiveFactory + IWritableArchiveFactory, + IWritableAsyncArchiveFactory { #region IFactory @@ -246,10 +247,19 @@ public class ZipFactory #endregion - #region IWriteableArchiveFactory + #region IWritableArchiveFactory /// public IWritableArchive CreateArchive() => ZipArchive.CreateArchive(); + /// + public ValueTask> CreateAsyncArchive( + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return ZipArchive.CreateAsyncArchive(); + } + #endregion } diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index e6d0966d..52410e14 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -22,20 +22,16 @@ public abstract partial class AbstractReader : IReader, IAsyncR private bool _wroteCurrentEntry; private readonly bool _disposeVolume; - internal AbstractReader( - ReaderOptions options, - ArchiveType archiveType, - bool disposeVolume = true - ) + internal AbstractReader(ReaderOptions options, ArchiveType type, bool disposeVolume = true) { - ArchiveType = archiveType; + Type = type; _disposeVolume = disposeVolume; Options = options; } internal ReaderOptions Options { get; } - public ArchiveType ArchiveType { get; } + public ArchiveType Type { get; } /// /// Current volume that the current entry resides in diff --git a/src/SharpCompress/Readers/Ace/AceReader.Factory.cs b/src/SharpCompress/Readers/Ace/AceReader.Factory.cs index d3adddd0..a4ae43bb 100644 --- a/src/SharpCompress/Readers/Ace/AceReader.Factory.cs +++ b/src/SharpCompress/Readers/Ace/AceReader.Factory.cs @@ -36,14 +36,14 @@ public partial class AceReader } public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( @@ -84,6 +84,7 @@ public partial class AceReader public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } } diff --git a/src/SharpCompress/Readers/Arc/ArcReader.Factory.cs b/src/SharpCompress/Readers/Arc/ArcReader.Factory.cs index 0ca8478c..e6bbfe9e 100644 --- a/src/SharpCompress/Readers/Arc/ArcReader.Factory.cs +++ b/src/SharpCompress/Readers/Arc/ArcReader.Factory.cs @@ -9,14 +9,14 @@ namespace SharpCompress.Readers.Arc; public partial class ArcReader : IReaderOpenable { public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( @@ -48,6 +48,7 @@ public partial class ArcReader : IReaderOpenable public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } } diff --git a/src/SharpCompress/Readers/Arj/ArjReader.Factory.cs b/src/SharpCompress/Readers/Arj/ArjReader.Factory.cs index 6072045d..1e5689d3 100644 --- a/src/SharpCompress/Readers/Arj/ArjReader.Factory.cs +++ b/src/SharpCompress/Readers/Arj/ArjReader.Factory.cs @@ -9,14 +9,14 @@ namespace SharpCompress.Readers.Arj; public partial class ArjReader : IReaderOpenable { public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( @@ -48,6 +48,7 @@ public partial class ArjReader : IReaderOpenable public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } } diff --git a/src/SharpCompress/Readers/GZip/GZipReader.Factory.cs b/src/SharpCompress/Readers/GZip/GZipReader.Factory.cs index 2a05e323..8baf715d 100644 --- a/src/SharpCompress/Readers/GZip/GZipReader.Factory.cs +++ b/src/SharpCompress/Readers/GZip/GZipReader.Factory.cs @@ -10,14 +10,14 @@ public partial class GZipReader #endif { public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( @@ -49,6 +49,7 @@ public partial class GZipReader public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } diff --git a/src/SharpCompress/Readers/IAsyncReader.cs b/src/SharpCompress/Readers/IAsyncReader.cs index bd82ee48..c3cc8de0 100644 --- a/src/SharpCompress/Readers/IAsyncReader.cs +++ b/src/SharpCompress/Readers/IAsyncReader.cs @@ -8,7 +8,7 @@ namespace SharpCompress.Readers; public interface IAsyncReader : IAsyncDisposable { - ArchiveType ArchiveType { get; } + ArchiveType Type { get; } IEntry Entry { get; } diff --git a/src/SharpCompress/Readers/IReader.cs b/src/SharpCompress/Readers/IReader.cs index a38d61d6..f7642ffc 100644 --- a/src/SharpCompress/Readers/IReader.cs +++ b/src/SharpCompress/Readers/IReader.cs @@ -6,7 +6,7 @@ namespace SharpCompress.Readers; public interface IReader : IDisposable { - ArchiveType ArchiveType { get; } + ArchiveType Type { get; } IEntry Entry { get; } diff --git a/src/SharpCompress/Readers/IReaderFactory.cs b/src/SharpCompress/Readers/IReaderFactory.cs index 538dacfb..9b3c533c 100644 --- a/src/SharpCompress/Readers/IReaderFactory.cs +++ b/src/SharpCompress/Readers/IReaderFactory.cs @@ -24,6 +24,6 @@ public interface IReaderFactory : Factories.IFactory ValueTask OpenAsyncReader( Stream stream, ReaderOptions? options, - CancellationToken cancellationToken + CancellationToken cancellationToken = default ); } diff --git a/src/SharpCompress/Readers/IReaderOpenable.cs b/src/SharpCompress/Readers/IReaderOpenable.cs index 32c7bdf3..58604211 100644 --- a/src/SharpCompress/Readers/IReaderOpenable.cs +++ b/src/SharpCompress/Readers/IReaderOpenable.cs @@ -17,7 +17,7 @@ public interface IReaderOpenable public static abstract IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null); public static abstract ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ); diff --git a/src/SharpCompress/Readers/Lzw/LzwReader.Factory.cs b/src/SharpCompress/Readers/Lzw/LzwReader.Factory.cs index 6e17e222..b62e7b5f 100644 --- a/src/SharpCompress/Readers/Lzw/LzwReader.Factory.cs +++ b/src/SharpCompress/Readers/Lzw/LzwReader.Factory.cs @@ -10,14 +10,14 @@ public partial class LzwReader #endif { public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( @@ -49,6 +49,7 @@ public partial class LzwReader public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } diff --git a/src/SharpCompress/Readers/Rar/RarReader.Factory.cs b/src/SharpCompress/Readers/Rar/RarReader.Factory.cs index b18fd3c7..20ec829a 100644 --- a/src/SharpCompress/Readers/Rar/RarReader.Factory.cs +++ b/src/SharpCompress/Readers/Rar/RarReader.Factory.cs @@ -9,14 +9,14 @@ namespace SharpCompress.Readers.Rar; public partial class RarReader : IReaderOpenable { public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( diff --git a/src/SharpCompress/Readers/Rar/RarReader.cs b/src/SharpCompress/Readers/Rar/RarReader.cs index 24235308..a6a8ede7 100644 --- a/src/SharpCompress/Readers/Rar/RarReader.cs +++ b/src/SharpCompress/Readers/Rar/RarReader.cs @@ -48,7 +48,7 @@ public abstract partial class RarReader : AbstractReader fileInfos, ReaderOptions? options = null) { - options ??= new ReaderOptions { LeaveStreamOpen = false }; + options ??= ReaderOptions.ForFilePath; return OpenReader(fileInfos.Select(x => x.OpenRead()), options); } diff --git a/src/SharpCompress/Readers/Tar/TarReader.Factory.cs b/src/SharpCompress/Readers/Tar/TarReader.Factory.cs index 13c8453c..f94a89dc 100644 --- a/src/SharpCompress/Readers/Tar/TarReader.Factory.cs +++ b/src/SharpCompress/Readers/Tar/TarReader.Factory.cs @@ -71,13 +71,13 @@ public partial class TarReader } public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { - path.NotNullOrEmpty(nameof(path)); - return OpenAsyncReader(new FileInfo(path), readerOptions, cancellationToken); + filePath.NotNullOrEmpty(nameof(filePath)); + return OpenAsyncReader(new FileInfo(filePath), readerOptions, cancellationToken); } public static async ValueTask OpenAsyncReader( @@ -139,7 +139,7 @@ public partial class TarReader CancellationToken cancellationToken = default ) { - readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false }; + readerOptions ??= ReaderOptions.ForFilePath; var stream = fileInfo.OpenAsyncReadStream(cancellationToken); return await OpenAsyncReader(stream, readerOptions, cancellationToken) .ConfigureAwait(false); @@ -154,7 +154,7 @@ public partial class TarReader public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); - readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false }; + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } diff --git a/src/SharpCompress/Readers/Zip/ZipReader.Factory.cs b/src/SharpCompress/Readers/Zip/ZipReader.Factory.cs index 65f179cf..7058937d 100644 --- a/src/SharpCompress/Readers/Zip/ZipReader.Factory.cs +++ b/src/SharpCompress/Readers/Zip/ZipReader.Factory.cs @@ -9,14 +9,14 @@ namespace SharpCompress.Readers.Zip; public partial class ZipReader : IReaderOpenable { public static ValueTask OpenAsyncReader( - string path, + string filePath, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - path.NotNullOrEmpty(nameof(path)); - return new((IAsyncReader)OpenReader(new FileInfo(path), readerOptions)); + filePath.NotNullOrEmpty(nameof(filePath)); + return new((IAsyncReader)OpenReader(new FileInfo(filePath), readerOptions)); } public static ValueTask OpenAsyncReader( @@ -48,6 +48,7 @@ public partial class ZipReader : IReaderOpenable public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null) { fileInfo.NotNull(nameof(fileInfo)); + readerOptions ??= ReaderOptions.ForFilePath; return OpenReader(fileInfo.OpenRead(), readerOptions); } } diff --git a/src/SharpCompress/Writers/AbstractWriter.cs b/src/SharpCompress/Writers/AbstractWriter.cs index 60ddb1b1..6cd32c7f 100644 --- a/src/SharpCompress/Writers/AbstractWriter.cs +++ b/src/SharpCompress/Writers/AbstractWriter.cs @@ -20,7 +20,7 @@ public abstract partial class AbstractWriter(ArchiveType type, IWriterOptions wr protected Stream? OutputStream { get; private set; } - public ArchiveType WriterType { get; } = type; + public ArchiveType Type { get; } = type; protected IWriterOptions WriterOptions { get; } = writerOptions; diff --git a/src/SharpCompress/Writers/GZip/GZipWriter.Factory.cs b/src/SharpCompress/Writers/GZip/GZipWriter.Factory.cs index 01e6edb5..f4f2b902 100644 --- a/src/SharpCompress/Writers/GZip/GZipWriter.Factory.cs +++ b/src/SharpCompress/Writers/GZip/GZipWriter.Factory.cs @@ -1,5 +1,7 @@ #if NET8_0_OR_GREATER using System.IO; +using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common; namespace SharpCompress.Writers.GZip; @@ -15,7 +17,7 @@ public partial class GZipWriter : IWriterOpenable public static IWriter OpenWriter(FileInfo fileInfo, GZipWriterOptions writerOptions) { fileInfo.NotNull(nameof(fileInfo)); - return new GZipWriter(fileInfo.OpenWrite(), writerOptions); + return new GZipWriter(fileInfo.OpenWrite(), writerOptions with { LeaveStreamOpen = false }); } public static IWriter OpenWriter(Stream stream, GZipWriterOptions writerOptions) @@ -24,19 +26,34 @@ public partial class GZipWriter : IWriterOpenable return new GZipWriter(stream, writerOptions); } - public static IAsyncWriter OpenAsyncWriter(string stream, GZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + string filePath, + GZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(filePath, writerOptions)); } - public static IAsyncWriter OpenAsyncWriter(Stream stream, GZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + Stream stream, + GZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(stream, writerOptions)); } - public static IAsyncWriter OpenAsyncWriter(FileInfo fileInfo, GZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + FileInfo fileInfo, + GZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(fileInfo, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(fileInfo, writerOptions)); } } #endif diff --git a/src/SharpCompress/Writers/IWriter.cs b/src/SharpCompress/Writers/IWriter.cs index 648c0fe0..c64166df 100644 --- a/src/SharpCompress/Writers/IWriter.cs +++ b/src/SharpCompress/Writers/IWriter.cs @@ -8,14 +8,14 @@ namespace SharpCompress.Writers; public interface IWriter : IDisposable { - ArchiveType WriterType { get; } + ArchiveType Type { get; } void Write(string filename, Stream source, DateTime? modificationTime); void WriteDirectory(string directoryName, DateTime? modificationTime); } public interface IAsyncWriter : IDisposable, IAsyncDisposable { - ArchiveType WriterType { get; } + ArchiveType Type { get; } ValueTask WriteAsync( string filename, Stream source, diff --git a/src/SharpCompress/Writers/IWriterOpenable.cs b/src/SharpCompress/Writers/IWriterOpenable.cs index 828b0b7c..1c584f2f 100644 --- a/src/SharpCompress/Writers/IWriterOpenable.cs +++ b/src/SharpCompress/Writers/IWriterOpenable.cs @@ -1,6 +1,7 @@ #if NET8_0_OR_GREATER using System.IO; using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common.Options; namespace SharpCompress.Writers; @@ -17,22 +18,25 @@ public interface IWriterOpenable /// Opens a Writer asynchronously. /// /// The stream to write to. - /// The archive type. /// Writer options. - /// A task that returns an IWriter. - public static abstract IAsyncWriter OpenAsyncWriter( + /// Cancellation token. + /// A task that returns an async writer. + public static abstract ValueTask OpenAsyncWriter( Stream stream, - TWriterOptions writerOptions + TWriterOptions writerOptions, + CancellationToken cancellationToken = default ); - public static abstract IAsyncWriter OpenAsyncWriter( + public static abstract ValueTask OpenAsyncWriter( string filePath, - TWriterOptions writerOptions + TWriterOptions writerOptions, + CancellationToken cancellationToken = default ); - public static abstract IAsyncWriter OpenAsyncWriter( + public static abstract ValueTask OpenAsyncWriter( FileInfo fileInfo, - TWriterOptions writerOptions + TWriterOptions writerOptions, + CancellationToken cancellationToken = default ); } #endif diff --git a/src/SharpCompress/Writers/SevenZip/SevenZipWriter.Factory.cs b/src/SharpCompress/Writers/SevenZip/SevenZipWriter.Factory.cs index 89e80414..e84d7401 100644 --- a/src/SharpCompress/Writers/SevenZip/SevenZipWriter.Factory.cs +++ b/src/SharpCompress/Writers/SevenZip/SevenZipWriter.Factory.cs @@ -1,5 +1,7 @@ #if NET8_0_OR_GREATER using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace SharpCompress.Writers.SevenZip; @@ -20,7 +22,13 @@ public partial class SevenZipWriter : IWriterOpenable public static IWriter OpenWriter(FileInfo fileInfo, SevenZipWriterOptions writerOptions) { fileInfo.NotNull(nameof(fileInfo)); - return new SevenZipWriter(fileInfo.OpenWrite(), writerOptions); + return new SevenZipWriter( + fileInfo.OpenWrite(), + writerOptions with + { + LeaveStreamOpen = false, + } + ); } /// @@ -35,28 +43,40 @@ public partial class SevenZipWriter : IWriterOpenable /// /// Opens a new async SevenZipWriter for the specified file path. /// - public static IAsyncWriter OpenAsyncWriter(string filePath, SevenZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + string filePath, + SevenZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(filePath, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(filePath, writerOptions)); } /// /// Opens a new async SevenZipWriter for the specified stream. /// - public static IAsyncWriter OpenAsyncWriter(Stream stream, SevenZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + Stream stream, + SevenZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(stream, writerOptions)); } /// /// Opens a new async SevenZipWriter for the specified file. /// - public static IAsyncWriter OpenAsyncWriter( + public static ValueTask OpenAsyncWriter( FileInfo fileInfo, - SevenZipWriterOptions writerOptions + SevenZipWriterOptions writerOptions, + CancellationToken cancellationToken = default ) { - return (IAsyncWriter)OpenWriter(fileInfo, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(fileInfo, writerOptions)); } } #endif diff --git a/src/SharpCompress/Writers/Tar/TarWriter.Factory.cs b/src/SharpCompress/Writers/Tar/TarWriter.Factory.cs index a3c6bf6f..b00ed13e 100644 --- a/src/SharpCompress/Writers/Tar/TarWriter.Factory.cs +++ b/src/SharpCompress/Writers/Tar/TarWriter.Factory.cs @@ -1,5 +1,7 @@ #if NET8_0_OR_GREATER using System.IO; +using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common; namespace SharpCompress.Writers.Tar; @@ -15,7 +17,7 @@ public partial class TarWriter : IWriterOpenable public static IWriter OpenWriter(FileInfo fileInfo, TarWriterOptions writerOptions) { fileInfo.NotNull(nameof(fileInfo)); - return new TarWriter(fileInfo.OpenWrite(), writerOptions); + return new TarWriter(fileInfo.OpenWrite(), writerOptions with { LeaveStreamOpen = false }); } public static IWriter OpenWriter(Stream stream, TarWriterOptions writerOptions) @@ -24,19 +26,34 @@ public partial class TarWriter : IWriterOpenable return new TarWriter(stream, writerOptions); } - public static IAsyncWriter OpenAsyncWriter(string stream, TarWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + string filePath, + TarWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(filePath, writerOptions)); } - public static IAsyncWriter OpenAsyncWriter(Stream stream, TarWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + Stream stream, + TarWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(stream, writerOptions)); } - public static IAsyncWriter OpenAsyncWriter(FileInfo fileInfo, TarWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + FileInfo fileInfo, + TarWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(fileInfo, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(fileInfo, writerOptions)); } } #endif diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.Factory.cs b/src/SharpCompress/Writers/Zip/ZipWriter.Factory.cs index d21ab7e2..b6667842 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.Factory.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.Factory.cs @@ -1,5 +1,7 @@ #if NET8_0_OR_GREATER using System.IO; +using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common; namespace SharpCompress.Writers.Zip; @@ -15,7 +17,7 @@ public partial class ZipWriter : IWriterOpenable public static IWriter OpenWriter(FileInfo fileInfo, ZipWriterOptions writerOptions) { fileInfo.NotNull(nameof(fileInfo)); - return new ZipWriter(fileInfo.OpenWrite(), writerOptions); + return new ZipWriter(fileInfo.OpenWrite(), writerOptions with { LeaveStreamOpen = false }); } public static IWriter OpenWriter(Stream stream, ZipWriterOptions writerOptions) @@ -24,19 +26,34 @@ public partial class ZipWriter : IWriterOpenable return new ZipWriter(stream, writerOptions); } - public static IAsyncWriter OpenAsyncWriter(string stream, ZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + string filePath, + ZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(filePath, writerOptions)); } - public static IAsyncWriter OpenAsyncWriter(Stream stream, ZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + Stream stream, + ZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(stream, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(stream, writerOptions)); } - public static IAsyncWriter OpenAsyncWriter(FileInfo fileInfo, ZipWriterOptions writerOptions) + public static ValueTask OpenAsyncWriter( + FileInfo fileInfo, + ZipWriterOptions writerOptions, + CancellationToken cancellationToken = default + ) { - return (IAsyncWriter)OpenWriter(fileInfo, writerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return new((IAsyncWriter)OpenWriter(fileInfo, writerOptions)); } } #endif diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 270900b9..492cc85e 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -179,7 +179,7 @@ public class ArchiveTests : ReaderTests { using ( var archive = ArchiveFactory.OpenArchive( - testArchives.Select(a => new FileInfo(a)), + testArchives.Select(a => new FileInfo(a)).ToArray(), readerOptions ) ) @@ -208,7 +208,7 @@ public class ArchiveTests : ReaderTests { using ( var archive = ArchiveFactory.OpenArchive( - testArchives.Select(f => new FileInfo(f)), + testArchives.Select(f => new FileInfo(f)).ToArray(), readerOptions ) ) @@ -240,7 +240,7 @@ public class ArchiveTests : ReaderTests { var src = testArchives.ToArray(); using var archive = ArchiveFactory.OpenArchive( - src.Select(f => new FileInfo(f)), + src.Select(f => new FileInfo(f)).ToArray(), readerOptions ); var idx = 0; diff --git a/tests/SharpCompress.Test/Lzw/LzwReaderAsyncTests.cs b/tests/SharpCompress.Test/Lzw/LzwReaderAsyncTests.cs index 6ecc6047..0b09298b 100644 --- a/tests/SharpCompress.Test/Lzw/LzwReaderAsyncTests.cs +++ b/tests/SharpCompress.Test/Lzw/LzwReaderAsyncTests.cs @@ -23,7 +23,7 @@ public class LzwReaderAsyncTests : ReaderTests using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "large_test.txt.Z")); using var reader = LzwReader.OpenReader(stream); - Assert.Equal(ArchiveType.Lzw, reader.ArchiveType); + Assert.Equal(ArchiveType.Lzw, reader.Type); Assert.True(reader.MoveToNextEntry()); var entry = reader.Entry; diff --git a/tests/SharpCompress.Test/Lzw/LzwReaderTests.cs b/tests/SharpCompress.Test/Lzw/LzwReaderTests.cs index f75fd666..8e94481f 100644 --- a/tests/SharpCompress.Test/Lzw/LzwReaderTests.cs +++ b/tests/SharpCompress.Test/Lzw/LzwReaderTests.cs @@ -41,7 +41,7 @@ public class LzwReaderTests : ReaderTests ); // Should detect as Tar archive with Lzw compression - Assert.Equal(ArchiveType.Tar, reader.ArchiveType); + Assert.Equal(ArchiveType.Tar, reader.Type); Assert.True(reader.MoveToNextEntry()); Assert.NotNull(reader.Entry); Assert.Equal(CompressionType.Lzw, reader.Entry.CompressionType); @@ -80,7 +80,7 @@ public class LzwReaderTests : ReaderTests using var reader = ReaderFactory.OpenReader(stream); // Should detect as Lzw archive (not Tar) - Assert.Equal(ArchiveType.Lzw, reader.ArchiveType); + Assert.Equal(ArchiveType.Lzw, reader.Type); Assert.True(reader.MoveToNextEntry()); Assert.NotNull(reader.Entry); Assert.Equal(CompressionType.Lzw, reader.Entry.CompressionType); diff --git a/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs index bba174d6..3f48b976 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs @@ -253,7 +253,10 @@ public class RarArchiveAsyncTests : ArchiveTests private async ValueTask DoRar_Multi_ArchiveStreamReadAsync(string[] archives, bool isSolid) { using var archive = RarArchive.OpenArchive( - archives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)).Select(File.OpenRead) + archives + .Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) + .Select(File.OpenRead) + .ToArray() ); Assert.Equal(archive.IsSolid, isSolid); foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) @@ -672,7 +675,7 @@ public class RarArchiveAsyncTests : ArchiveTests { var paths = testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x)); using var archive = ArchiveFactory.OpenArchive( - paths.Select(a => new FileInfo(a)), + paths.Select(a => new FileInfo(a)).ToArray(), readerOptions ); foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) @@ -730,7 +733,7 @@ public class RarArchiveAsyncTests : ArchiveTests { var paths = testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x)); using var archive = ArchiveFactory.OpenArchive( - paths.Select(f => new FileInfo(f)), + paths.Select(f => new FileInfo(f)).ToArray(), readerOptions ); foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) diff --git a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs index e4fef73f..fdb8d56b 100644 --- a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs +++ b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs @@ -242,7 +242,10 @@ public class RarArchiveTests : ArchiveTests private void DoRar_Multi_ArchiveStreamRead(string[] archives, bool isSolid) { using var archive = RarArchive.OpenArchive( - archives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)).Select(File.OpenRead) + archives + .Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)) + .Select(File.OpenRead) + .ToArray() ); Assert.Equal(archive.IsSolid, isSolid); foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory)) diff --git a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs index 008bb145..086ca02c 100644 --- a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs +++ b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs @@ -336,7 +336,7 @@ public class TarArchiveTests : ArchiveTests using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz")); using var reader = ReaderFactory.OpenReader(stream); - Assert.Equal(ArchiveType.Tar, reader.ArchiveType); + Assert.Equal(ArchiveType.Tar, reader.Type); Assert.True(reader.MoveToNextEntry()); } } diff --git a/tests/SharpCompress.Test/Tar/TarReaderAsyncTests.cs b/tests/SharpCompress.Test/Tar/TarReaderAsyncTests.cs index 34ceac02..07c0b15b 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderAsyncTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderAsyncTests.cs @@ -156,7 +156,7 @@ public class TarReaderAsyncTests : ReaderTests var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsRar.tar"); using Stream stream = File.OpenRead(archiveFullPath); using var reader = ReaderFactory.OpenReader(stream); - Assert.True(reader.ArchiveType == ArchiveType.Tar); + Assert.True(reader.Type == ArchiveType.Tar); } [Fact] diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index d76792cf..21c62f83 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -147,7 +147,7 @@ public class TarReaderTests : ReaderTests var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsRar.tar"); using Stream stream = File.OpenRead(archiveFullPath); using var reader = ReaderFactory.OpenReader(stream); - Assert.True(reader.ArchiveType == ArchiveType.Tar); + Assert.True(reader.Type == ArchiveType.Tar); } [Fact]