diff --git a/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs b/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs
index 3c3caa3f..53f8527a 100644
--- a/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs
+++ b/src/SharpCompress/Archives/Tar/TarArchive.Factory.cs
@@ -58,7 +58,7 @@ public partial class TarArchive
);
var compressionType = TarFactory.GetCompressionType(
sourceStream,
- sourceStream.ReaderOptions.Providers
+ sourceStream.ReaderOptions
);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -78,7 +78,7 @@ public partial class TarArchive
);
var compressionType = TarFactory.GetCompressionType(
sourceStream,
- sourceStream.ReaderOptions.Providers
+ sourceStream.ReaderOptions
);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -112,11 +112,7 @@ public partial class TarArchive
readerOptions ?? new ReaderOptions()
);
var compressionType = await TarFactory
- .GetCompressionTypeAsync(
- sourceStream,
- sourceStream.ReaderOptions.Providers,
- cancellationToken
- )
+ .GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -144,11 +140,7 @@ public partial class TarArchive
readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false };
var sourceStream = new SourceStream(fileInfo, i => null, readerOptions);
var compressionType = await TarFactory
- .GetCompressionTypeAsync(
- sourceStream,
- sourceStream.ReaderOptions.Providers,
- cancellationToken
- )
+ .GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -169,11 +161,7 @@ public partial class TarArchive
readerOptions ?? new ReaderOptions()
);
var compressionType = await TarFactory
- .GetCompressionTypeAsync(
- sourceStream,
- sourceStream.ReaderOptions.Providers,
- cancellationToken
- )
+ .GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -194,11 +182,7 @@ public partial class TarArchive
readerOptions ?? new ReaderOptions() { LeaveStreamOpen = false }
);
var compressionType = await TarFactory
- .GetCompressionTypeAsync(
- sourceStream,
- sourceStream.ReaderOptions.Providers,
- cancellationToken
- )
+ .GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
diff --git a/src/SharpCompress/Factories/TarFactory.cs b/src/SharpCompress/Factories/TarFactory.cs
index 5e506696..719a1b31 100644
--- a/src/SharpCompress/Factories/TarFactory.cs
+++ b/src/SharpCompress/Factories/TarFactory.cs
@@ -50,7 +50,6 @@ public class TarFactory
///
public override bool IsArchive(Stream stream, string? password = null)
{
- var providers = CompressionProviderRegistry.Default;
var sharpCompressStream = new SharpCompressStream(stream);
sharpCompressStream.StartRecording(TarWrapper.MaximumRewindBufferSize);
foreach (var wrapper in TarWrapper.Wrappers)
@@ -61,8 +60,7 @@ public class TarFactory
sharpCompressStream.Rewind();
var decompressedStream = CreateProbeDecompressionStream(
sharpCompressStream,
- wrapper.CompressionType,
- providers
+ wrapper.CompressionType
);
if (TarArchive.IsTarFile(decompressedStream))
{
@@ -82,7 +80,6 @@ public class TarFactory
CancellationToken cancellationToken = default
)
{
- var providers = CompressionProviderRegistry.Default;
var sharpCompressStream = new SharpCompressStream(stream);
sharpCompressStream.StartRecording(TarWrapper.MaximumRewindBufferSize);
foreach (var wrapper in TarWrapper.Wrappers)
@@ -98,7 +95,6 @@ public class TarFactory
var decompressedStream = await CreateProbeDecompressionStreamAsync(
sharpCompressStream,
wrapper.CompressionType,
- providers,
cancellationToken: cancellationToken
)
.ConfigureAwait(false);
@@ -122,10 +118,10 @@ public class TarFactory
private static Stream CreateProbeDecompressionStream(
Stream stream,
CompressionType compressionType,
- CompressionProviderRegistry providers,
IReaderOptions? readerOptions = null
)
{
+ var providers = readerOptions?.Providers ?? CompressionProviderRegistry.Default;
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(stream);
if (compressionType == CompressionType.None)
{
@@ -147,7 +143,6 @@ public class TarFactory
private static async ValueTask CreateProbeDecompressionStreamAsync(
Stream stream,
CompressionType compressionType,
- CompressionProviderRegistry providers,
IReaderOptions? readerOptions = null,
CancellationToken cancellationToken = default
)
@@ -157,6 +152,7 @@ public class TarFactory
{
return nonDisposingStream;
}
+ var providers = readerOptions?.Providers ?? CompressionProviderRegistry.Default;
if (compressionType == CompressionType.GZip && readerOptions is not null)
{
@@ -179,10 +175,9 @@ public class TarFactory
public static CompressionType GetCompressionType(
Stream stream,
- CompressionProviderRegistry? providers = null
+ IReaderOptions? readerOptions = null
)
{
- providers ??= CompressionProviderRegistry.Default;
stream.Seek(0, SeekOrigin.Begin);
foreach (var wrapper in TarWrapper.Wrappers)
{
@@ -193,7 +188,7 @@ public class TarFactory
var decompressedStream = CreateProbeDecompressionStream(
stream,
wrapper.CompressionType,
- providers
+ readerOptions
);
if (TarArchive.IsTarFile(decompressedStream))
{
@@ -206,11 +201,10 @@ public class TarFactory
public static async ValueTask GetCompressionTypeAsync(
Stream stream,
- CompressionProviderRegistry? providers = null,
+ IReaderOptions? readerOptions = null,
CancellationToken cancellationToken = default
)
{
- providers ??= CompressionProviderRegistry.Default;
stream.Seek(0, SeekOrigin.Begin);
foreach (var wrapper in TarWrapper.Wrappers)
{
@@ -221,7 +215,7 @@ public class TarFactory
var decompressedStream = await CreateProbeDecompressionStreamAsync(
stream,
wrapper.CompressionType,
- providers,
+ readerOptions,
cancellationToken: cancellationToken
)
.ConfigureAwait(false);
@@ -329,7 +323,6 @@ public class TarFactory
var decompressedStream = CreateProbeDecompressionStream(
sharpCompressStream,
wrapper.CompressionType,
- options.Providers,
options
);
if (TarArchive.IsTarFile(decompressedStream))
@@ -366,7 +359,6 @@ public class TarFactory
var decompressedStream = await CreateProbeDecompressionStreamAsync(
sharpCompressStream,
wrapper.CompressionType,
- options.Providers,
options,
cancellationToken
)
@@ -409,35 +401,6 @@ public class TarFactory
{
throw new ArgumentException("Tars require writable streams.");
}
- if (writerOptions.LeaveStreamOpen)
- {
- stream = SharpCompressStream.CreateNonDisposing(stream);
- }
-
- var providers = writerOptions.Providers;
-
- stream = writerOptions.CompressionType switch
- {
- CompressionType.None => stream,
- CompressionType.BZip2 => providers.CreateCompressStream(
- CompressionType.BZip2,
- stream,
- writerOptions.CompressionLevel
- ),
- CompressionType.GZip => providers.CreateCompressStream(
- CompressionType.GZip,
- stream,
- writerOptions.CompressionLevel
- ),
- CompressionType.LZip => providers.CreateCompressStream(
- CompressionType.LZip,
- stream,
- writerOptions.CompressionLevel
- ),
- _ => throw new InvalidFormatException(
- "Tar does not support compression: " + writerOptions.CompressionType
- ),
- };
return new TarWriter(stream, tarOptions);
}
@@ -501,7 +464,7 @@ public class TarFactory
"Tar does not support compression: " + writerOptions.CompressionType
),
};
- return new TarWriter(stream, tarOptions);
+ return new TarWriter(stream, tarOptions, streamIsPrepared: true);
}
#endregion
diff --git a/src/SharpCompress/Writers/Tar/TarWriter.Async.cs b/src/SharpCompress/Writers/Tar/TarWriter.Async.cs
index ca220ca1..f66ad7ac 100644
--- a/src/SharpCompress/Writers/Tar/TarWriter.Async.cs
+++ b/src/SharpCompress/Writers/Tar/TarWriter.Async.cs
@@ -31,7 +31,14 @@ public partial class TarWriter
{
await finishable.FinishAsync().ConfigureAwait(false);
}
- OutputStream?.Dispose();
+ if (OutputStream is IAsyncDisposable asyncDisposableOutputStream)
+ {
+ await asyncDisposableOutputStream.DisposeAsync().ConfigureAwait(false);
+ }
+ else
+ {
+ OutputStream?.Dispose();
+ }
// base.DisposeAsync() is a no-op since _isDisposed is already set
await base.DisposeAsync().ConfigureAwait(false);
}
diff --git a/src/SharpCompress/Writers/Tar/TarWriter.cs b/src/SharpCompress/Writers/Tar/TarWriter.cs
index d456ef2b..00cdc14a 100644
--- a/src/SharpCompress/Writers/Tar/TarWriter.cs
+++ b/src/SharpCompress/Writers/Tar/TarWriter.cs
@@ -2,6 +2,8 @@ using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Common.Tar.Headers;
+using SharpCompress.Compressors;
+using SharpCompress.IO;
using SharpCompress.Providers;
namespace SharpCompress.Writers.Tar;
@@ -12,12 +14,60 @@ public partial class TarWriter : AbstractWriter
private readonly TarHeaderWriteFormat _headerFormat;
public TarWriter(Stream destination, TarWriterOptions options)
- : base(ArchiveType.Tar, options)
+ : base(ArchiveType.Tar, GetEffectiveOptions(options))
{
_finalizeArchiveOnClose = options.FinalizeArchiveOnClose;
_headerFormat = options.HeaderFormat;
- InitializeStream(destination);
+ InitializeStream(CreateOutputStream(destination, options));
+ }
+
+ internal TarWriter(Stream destination, TarWriterOptions options, bool streamIsPrepared)
+ : base(ArchiveType.Tar, GetEffectiveOptions(options))
+ {
+ _finalizeArchiveOnClose = options.FinalizeArchiveOnClose;
+ _headerFormat = options.HeaderFormat;
+
+ InitializeStream(streamIsPrepared ? destination : CreateOutputStream(destination, options));
+ }
+
+ private static TarWriterOptions GetEffectiveOptions(TarWriterOptions options) =>
+ options with
+ {
+ CompressionType = CompressionType.None,
+ LeaveStreamOpen = false,
+ };
+
+ private static Stream CreateOutputStream(Stream destination, TarWriterOptions options)
+ {
+ if (options.LeaveStreamOpen)
+ {
+ destination = SharpCompressStream.CreateNonDisposing(destination);
+ }
+
+ var providers = options.Providers;
+ return options.CompressionType switch
+ {
+ CompressionType.None => destination,
+ CompressionType.BZip2 => providers.CreateCompressStream(
+ CompressionType.BZip2,
+ destination,
+ options.CompressionLevel
+ ),
+ CompressionType.GZip => providers.CreateCompressStream(
+ CompressionType.GZip,
+ destination,
+ options.CompressionLevel
+ ),
+ CompressionType.LZip => providers.CreateCompressStream(
+ CompressionType.LZip,
+ destination,
+ options.CompressionLevel
+ ),
+ _ => throw new InvalidFormatException(
+ "Tar does not support compression: " + options.CompressionType
+ ),
+ };
}
public override void Write(string filename, Stream source, DateTime? modificationTime) =>