Add ability to have alternate compressions#1197
Conversation
…compressions # Conflicts: # src/SharpCompress/Archives/GZip/GZipArchive.Async.cs # src/SharpCompress/Archives/GZip/GZipArchive.cs # src/SharpCompress/Archives/Zip/ZipArchive.Async.cs # src/SharpCompress/Archives/Zip/ZipArchive.cs # src/SharpCompress/Common/GZip/GZipEntry.Async.cs # src/SharpCompress/Common/GZip/GZipEntry.cs # src/SharpCompress/Common/Options/IReaderOptions.cs # src/SharpCompress/Readers/ReaderOptions.cs # src/SharpCompress/Readers/Zip/ZipReader.Async.cs # src/SharpCompress/Readers/Zip/ZipReader.cs # src/SharpCompress/Writers/GZip/GZipWriterOptions.cs
| ); | ||
| internal override Stream GetCompressedStream() | ||
| { | ||
| return _compressionProviders.CreateDecompressStream(CompressionType.Deflate, _stream); |
There was a problem hiding this comment.
WARNING: GZip uses Deflate compression, but this hardcodes CompressionType.Deflate instead of using CompressionType.GZip.
When a custom provider is registered for GZip, this code will still use the Deflate provider for decompression. This breaks the provider abstraction for GZip files.
Consider using CompressionType.GZip here, or ensure the provider registry properly maps GZip to use the correct decompression implementation.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (84 files)
|
There was a problem hiding this comment.
Pull request overview
Adds a configurable CompressionProviderRegistry that flows through SharpCompress reader/writer options so callers can swap compression stream implementations (e.g., use System.IO.Compression for GZip/Deflate) while keeping internal defaults.
Changes:
- Introduces
ICompressionProvider,CompressionProviderRegistry, andCompressionContext(plus hook/finalization interfaces) and internal default provider implementations for manyCompressionTypes. - Threads
ProvidersthroughReaderOptions/WriterOptions(and format-specific options) into ZIP/GZip/Tar read/write pipelines. - Adds docs + tests demonstrating replacing providers and validating round-trips / compatibility.
Reviewed changes
Copilot reviewed 55 out of 55 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/SharpCompress.Test/CompressionProviderTests.cs | New unit tests covering default registry, replacement, cloning, and System.IO.Compression provider scenarios. |
| src/SharpCompress/Writers/Zip/ZipWriterOptions.cs | Adds Providers to zip writer options and copies it from generic options. |
| src/SharpCompress/Writers/Zip/ZipWriter.cs | Uses provider registry for ZIP compression streams; introduces hook-based init for LZMA/PPMd. |
| src/SharpCompress/Writers/WriterOptionsExtensions.cs | Adds WithProviders(...) helper for WriterOptions. |
| src/SharpCompress/Writers/WriterOptions.cs | Adds Providers to generic writer options (defaulting to CompressionProviderRegistry.Default). |
| src/SharpCompress/Writers/Tar/TarWriterOptions.cs | Adds Providers and copies from generic options. |
| src/SharpCompress/Writers/Tar/TarWriter.cs | Uses provider registry to create compression stream; finalizes via IFinishable. |
| src/SharpCompress/Writers/GZip/GZipWriterOptions.cs | Adds Providers and copies from generic options. |
| src/SharpCompress/Writers/GZip/GZipWriter.cs | Creates gzip compression stream via provider registry instead of hard-coded internal stream construction. |
| src/SharpCompress/Readers/Zip/ZipReader.cs | Passes Options.Providers into ZIP file parts for decompression. |
| src/SharpCompress/Readers/Zip/ZipReader.Async.cs | Passes _options.Providers into streaming ZIP file parts for decompression. |
| src/SharpCompress/Readers/Tar/TarReader.cs | Uses provider registry for tar wrapper decompression stream creation. |
| src/SharpCompress/Readers/ReaderOptionsExtensions.cs | Adds WithProviders(...) helper for ReaderOptions. |
| src/SharpCompress/Readers/ReaderOptions.cs | Adds Providers to reader options (defaulting to CompressionProviderRegistry.Default). |
| src/SharpCompress/Compressors/Providers/ZStandardCompressionProvider.cs | Internal ZStandard provider implementation. |
| src/SharpCompress/Compressors/Providers/XzCompressionProvider.cs | Internal XZ provider (decompress-only). |
| src/SharpCompress/Compressors/Providers/SystemGZipCompressionProvider.cs | System.IO.Compression-based GZip provider. |
| src/SharpCompress/Compressors/Providers/SystemDeflateCompressionProvider.cs | System.IO.Compression-based Deflate provider. |
| src/SharpCompress/Compressors/Providers/ShrinkCompressionProvider.cs | Internal Shrink provider (decompress-only, context sizes required). |
| src/SharpCompress/Compressors/Providers/Reduce4CompressionProvider.cs | Internal Reduce4 provider (decompress-only, context sizes required). |
| src/SharpCompress/Compressors/Providers/Reduce3CompressionProvider.cs | Internal Reduce3 provider (decompress-only, context sizes required). |
| src/SharpCompress/Compressors/Providers/Reduce2CompressionProvider.cs | Internal Reduce2 provider (decompress-only, context sizes required). |
| src/SharpCompress/Compressors/Providers/Reduce1CompressionProvider.cs | Internal Reduce1 provider (decompress-only, context sizes required). |
| src/SharpCompress/Compressors/Providers/PpmdCompressingProvider.cs | Internal PPMd provider implementing ICompressionProviderHooks. |
| src/SharpCompress/Compressors/Providers/LzwCompressionProvider.cs | Internal LZW provider (decompress-only). |
| src/SharpCompress/Compressors/Providers/LzmaCompressingProvider.cs | Internal LZMA provider implementing ICompressionProviderHooks. |
| src/SharpCompress/Compressors/Providers/LZipCompressionProvider.cs | Internal LZip provider. |
| src/SharpCompress/Compressors/Providers/GZipCompressionProvider.cs | Internal GZip provider. |
| src/SharpCompress/Compressors/Providers/ExplodeCompressionProvider.cs | Internal Explode provider (decompress-only, context required). |
| src/SharpCompress/Compressors/Providers/DeflateCompressionProvider.cs | Internal Deflate provider. |
| src/SharpCompress/Compressors/Providers/Deflate64CompressionProvider.cs | Internal Deflate64 provider (decompress-only). |
| src/SharpCompress/Compressors/Providers/BZip2CompressionProvider.cs | Internal BZip2 provider. |
| src/SharpCompress/Compressors/LZMA/LZipStream.cs | Implements IFinishable for generic finalization. |
| src/SharpCompress/Compressors/IFinishable.cs | New interface for streams needing explicit finalization. |
| src/SharpCompress/Compressors/ICompressionProviderHooks.cs | Hook interface for pre/properties/post data patterns (e.g., LZMA/PPMd in Zip). |
| src/SharpCompress/Compressors/ICompressionProvider.cs | New provider abstraction for compress/decompress stream creation. |
| src/SharpCompress/Compressors/CompressionProviderRegistry.cs | New immutable registry with default internal providers and helper methods. |
| src/SharpCompress/Compressors/CompressionContext.cs | New context record carrying sizes/properties/format options for providers. |
| src/SharpCompress/Compressors/BZip2/BZip2Stream.cs | Implements IFinishable for generic finalization. |
| src/SharpCompress/Common/Zip/ZipFilePart.cs | Uses provider registry + CompressionContext for ZIP entry decompression. |
| src/SharpCompress/Common/Zip/StreamingZipFilePart.cs | Accepts provider registry and passes through to base ZIP part. |
| src/SharpCompress/Common/Zip/SeekableZipFilePart.cs | Accepts provider registry and passes through to base ZIP part. |
| src/SharpCompress/Common/Options/IWriterOptions.cs | Adds Providers to writer options interface. |
| src/SharpCompress/Common/Options/IReaderOptions.cs | Adds Providers to reader options interface. |
| src/SharpCompress/Common/GZip/GZipFilePart.cs | Accepts provider registry for gzip payload decompression stream creation. |
| src/SharpCompress/Common/GZip/GZipFilePart.Async.cs | Async create path accepts provider registry. |
| src/SharpCompress/Common/GZip/GZipEntry.cs | Threads options.Providers into GZipFilePart.Create. |
| src/SharpCompress/Common/GZip/GZipEntry.Async.cs | Threads options.Providers into GZipFilePart.CreateAsync. |
| src/SharpCompress/Archives/Zip/ZipArchive.cs | Passes ReaderOptions.Providers into seekable ZIP parts. |
| src/SharpCompress/Archives/Zip/ZipArchive.Async.cs | Passes ReaderOptions.Providers into seekable ZIP parts (async). |
| src/SharpCompress/Archives/GZip/GZipArchive.cs | Passes ReaderOptions.Providers into GZipFilePart.Create. |
| src/SharpCompress/Archives/GZip/GZipArchive.Async.cs | Passes ReaderOptions.Providers into GZipFilePart.CreateAsync. |
| docs/USAGE.md | Adds usage guide for custom compression providers. |
| docs/API.md | Documents Providers registry and hook contract. |
| README.md | Adds a high-level overview and links for custom compression providers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Get the compression type and providers | ||
| var compressionType = ToCompressionType(method); | ||
| var providers = GetProviders(); | ||
|
|
||
| // Build context with header information | ||
| var context = new CompressionContext | ||
| { | ||
| InputSize = Header.CompressedSize, | ||
| OutputSize = Header.UncompressedSize, | ||
| CanSeek = stream.CanSeek, |
There was a problem hiding this comment.
ZipFilePart.cs still imports a number of compressor implementation namespaces (BZip2/Deflate/Deflate64/Explode/LZMA/PPMd/Reduce/Shrink/Xz/ZStandard), but the refactored implementation now resolves decompression via CompressionProviderRegistry and no longer references those types. With TreatWarningsAsErrors enabled, the resulting CS8019 warnings will fail the build; remove the unused using directives.
| using SharpCompress.Common.Zip; | ||
| using SharpCompress.Common.Zip.Headers; | ||
| using SharpCompress.Compressors; | ||
|
|
There was a problem hiding this comment.
ZipReader.Async.cs adds using SharpCompress.Compressors;, but this file doesn’t reference any types from that namespace (it only accesses _options.Providers). With TreatWarningsAsErrors enabled, this will trigger CS8019 and fail the build; remove the unused using directive.
| @@ -0,0 +1,44 @@ | |||
| using System; | |||
There was a problem hiding this comment.
CompressionContext.cs includes using System; which is unused in this file. With TreatWarningsAsErrors enabled, this will fail the build (CS8019). Remove the unused using directive.
| using System; |
| // Use the configured compression providers | ||
| var providers = WriterOptions.Providers; | ||
|
|
||
| // Create the GZip stream using the provider | ||
| var compressionStream = providers.CreateCompressStream( | ||
| CompressionType.GZip, | ||
| destination, | ||
| WriterOptions.CompressionLevel | ||
| ); |
There was a problem hiding this comment.
GZipWriter used to pass WriterOptions.ArchiveEncoding.GetEncoding() into the internal SharpCompress.Compressors.Deflate.GZipStream constructor. With the new provider-based creation, internal gzip streams will always use the default UTF-8 encoding, changing the bytes written for the header filename/comment when a non-default ArchiveEncoding is configured. Consider using the provider overload that accepts a CompressionContext (e.g., pass the encoding via context.FormatOptions or a dedicated field) and update GZipCompressionProvider to honor it by calling the 4-arg GZipStream constructor.
| internal override Stream GetCompressedStream() | ||
| { | ||
| //GZip uses Deflate compression, at this point we need a deflate stream | ||
| return _compressionProviders.CreateDecompressStream(CompressionType.Deflate, _stream); |
There was a problem hiding this comment.
GZipFilePart.GetCompressedStream() always resolves CompressionType.Deflate from the provider registry. That means swapping the CompressionType.GZip provider (e.g., to SystemGZipCompressionProvider) will not affect reading .gz archives via GZipArchive/GZipEntry; only replacing the Deflate provider would. If the intent is that .gz reading honors the GZip provider, this needs a different integration point (or the docs should explicitly note that .gz uses the Deflate provider).
| var providers = writer.WriterOptions.Providers; | ||
|
|
||
| switch (zipCompressionMethod) | ||
| { |
There was a problem hiding this comment.
After refactoring to provider-based compression, ZipWriter.cs no longer references several compression-implementation types directly, but the corresponding using SharpCompress.Compressors.* directives at the top of the file remain. With warnings treated as errors, the resulting “unnecessary using directive” warnings (CS8019) will fail the build; remove any now-unused compressor usings (e.g., BZip2/Deflate/LZMA/ZStandard) and keep only the ones still needed (like PPMd if referenced).
| // Use ICompressionProviderHooks for complex initialization | ||
| var compressingProvider = providers.GetCompressingProvider( | ||
| CompressionType.LZMA | ||
| ); | ||
| counting.Write(lzmaStream.Properties, 0, lzmaStream.Properties.Length); | ||
| if (compressingProvider is null) | ||
| { | ||
| throw new InvalidOperationException("LZMA compression provider not found."); | ||
| } | ||
|
|
||
| var context = new CompressionContext { CanSeek = originalStream.CanSeek }; | ||
|
|
||
| // Write pre-compression data (magic bytes) | ||
| var preData = compressingProvider.GetPreCompressionData(context); | ||
| if (preData != null) | ||
| { | ||
| counting.Write(preData, 0, preData.Length); | ||
| } | ||
|
|
||
| // Create compression stream | ||
| var lzmaStream = compressingProvider.CreateCompressStream( | ||
| counting, | ||
| compressionLevel, | ||
| context | ||
| ); | ||
|
|
||
| // Write compression properties | ||
| var props = compressingProvider.GetCompressionProperties(lzmaStream, context); | ||
| if (props != null) | ||
| { | ||
| counting.Write(props, 0, props.Length); | ||
| } | ||
|
|
||
| return lzmaStream; | ||
| } | ||
| case ZipCompressionMethod.PPMd: | ||
| { | ||
| counting.Write(writer.PpmdProperties.Properties, 0, 2); | ||
| return PpmdStream.Create(writer.PpmdProperties, counting, true); | ||
| // Use ICompressionProviderHooks for complex initialization | ||
| var compressingProvider = providers.GetCompressingProvider( | ||
| CompressionType.PPMd | ||
| ); | ||
| if (compressingProvider is null) | ||
| { | ||
| throw new InvalidOperationException("PPMd compression provider not found."); | ||
| } | ||
|
|
||
| var context = new CompressionContext | ||
| { | ||
| CanSeek = originalStream.CanSeek, | ||
| FormatOptions = writer.PpmdProperties, | ||
| }; | ||
|
|
||
| // Write pre-compression data (properties) | ||
| var preData = compressingProvider.GetPreCompressionData(context); | ||
| if (preData != null) | ||
| { | ||
| counting.Write(preData, 0, preData.Length); | ||
| } | ||
|
|
||
| // Create compression stream | ||
| return compressingProvider.CreateCompressStream( | ||
| counting, | ||
| compressionLevel, | ||
| context | ||
| ); |
There was a problem hiding this comment.
ZipWriter uses ICompressionProviderHooks for pre-stream bytes and properties, but never calls GetPostCompressionData(...). That makes it impossible for a custom provider to append required footer bytes after the compression stream completes, and also risks incorrect entry.Compressed sizing when such footers are needed. Consider capturing the selected hooks-provider + context and, in ZipWritingStream.Dispose, after disposing the compression stream but before reading counting.BytesWritten, write any post-compression bytes returned by the provider.
| ); | ||
|
|
||
| // If using internal GZipStream, set the encoding for header filename | ||
| if (compressionStream is GZipStream gzipStream) |
There was a problem hiding this comment.
This assignment to gzipStream is useless, since its value is never read.
| { | ||
| var original = CompressionProviderRegistry.Default; | ||
| var customProvider = new DeflateCompressionProvider(); | ||
| var modified = original.With(customProvider); |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 61 out of 61 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/SharpCompress/Providers/SystemDeflateCompressionProvider.cs
Outdated
Show resolved
Hide resolved
| public Stream CreateCompressStream(Stream destination, int compressionLevel) | ||
| { | ||
| var level = (CompressionLevel)compressionLevel; | ||
| return new GZipStream(destination, CompressionMode.Compress, level); | ||
| } | ||
|
|
||
| public Stream CreateCompressStream( | ||
| Stream destination, | ||
| int compressionLevel, | ||
| CompressionContext context | ||
| ) | ||
| { | ||
| // Context not used for simple GZip compression | ||
| return CreateCompressStream(destination, compressionLevel); | ||
| } |
There was a problem hiding this comment.
The internal GZipCompressionProvider always constructs SharpCompress.Compressors.Deflate.GZipStream with its default encoding (UTF-8). Since GZipWriter previously used WriterOptions.ArchiveEncoding, the provider should accept/consume encoding from CompressionContext (or similar) so callers can preserve non-UTF8 header encoding when needed.
| FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor) || Header.IsZip64; | ||
|
|
||
| /// <summary> | ||
| /// Gets the compression provider registry, falling back to default if not set. |
There was a problem hiding this comment.
The doc comment says GetProviders() “falls back to default if not set”, but _compressionProviders is required by the constructor and the method just returns the field. Either implement an actual fallback (e.g., null/optional ctor param) or adjust the comment to match behavior.
| /// Gets the compression provider registry, falling back to default if not set. | |
| /// Gets the configured compression provider registry. |
| foreach (var entry in archive.Entries.Where(e => !e.IsDirectory)) | ||
| { | ||
| using var entryStream = entry.OpenEntryStream(); | ||
| entryStream.CopyTo(Stream.Null); | ||
| } |
There was a problem hiding this comment.
This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.
| foreach (var entry in archive.Entries.Where(e => !e.IsDirectory)) | ||
| { | ||
| using var entryStream = entry.OpenEntryStream(); | ||
| entryStream.CopyTo(Stream.Null); | ||
| } |
There was a problem hiding this comment.
This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.
c4fb32a to
5fe248e
Compare
5fe248e to
c4fb32a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 61 out of 61 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (1)
tests/SharpCompress.Test/ReaderTests.cs:117
- Second
IsArchiveAsynccall also opens a newFileStreamwithout disposing it. Please ensure the stream is disposed (and ideally avoid opening the file twice).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/SharpCompress/Providers/SystemDeflateCompressionProvider.cs
Outdated
Show resolved
Hide resolved
# Conflicts: # tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs # tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs # tests/SharpCompress.Performance/baseline-results.md
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 81 out of 82 changed files in this pull request and generated 23 comments.
Comments suppressed due to low confidence (1)
tests/SharpCompress.Test/ReaderTests.cs:116
IsArchiveAsyncis called withnew FileInfo(testArchive).OpenRead()but the stream is not disposed. Use ausing/await usingto avoid leaking file handles in tests.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| using System.IO; | ||
| using SharpCompress.Common.Zip.Headers; | ||
| using SharpCompress.Compressors.Deflate; | ||
| using SharpCompress.Compressors; |
There was a problem hiding this comment.
using SharpCompress.Compressors; appears unused in this file and may trigger CS8019 under warnings-as-errors. Remove the unused using directive.
| using SharpCompress.Compressors; |
| using SharpCompress.Common; | ||
| using SharpCompress.Compressors; | ||
| using SharpCompress.Providers; | ||
|
|
||
| namespace SharpCompress.Common.Options; | ||
|
|
||
| /// <summary> | ||
| /// Options for configuring writer behavior when creating archives. | ||
| /// </summary> | ||
| public interface IWriterOptions : IStreamOptions, IEncodingOptions, IProgressOptions | ||
| { | ||
| /// <summary> | ||
| /// The compression type to use for the archive. | ||
| /// </summary> | ||
| CompressionType CompressionType { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// The compression level to be used when the compression type supports variable levels. | ||
| /// </summary> | ||
| int CompressionLevel { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Registry of compression providers. | ||
| /// Defaults to <see cref="CompressionProviderRegistry.Default" /> but can be replaced with custom providers, such as | ||
| /// System.IO.Compression for Deflate/GZip on modern .NET. | ||
| /// </summary> | ||
| CompressionProviderRegistry Providers { get; init; } | ||
| } |
There was a problem hiding this comment.
using SharpCompress.Compressors; appears unused in this file and will trigger CS8019 (unnecessary using directive). Since the repo treats warnings as errors, this can break the build; remove the unused using.
| using SharpCompress.Common; | |
| using SharpCompress.Compressors; | |
| using SharpCompress.Providers; | |
| namespace SharpCompress.Common.Options; | |
| /// <summary> | |
| /// Options for configuring writer behavior when creating archives. | |
| /// </summary> | |
| public interface IWriterOptions : IStreamOptions, IEncodingOptions, IProgressOptions | |
| { | |
| /// <summary> | |
| /// The compression type to use for the archive. | |
| /// </summary> | |
| CompressionType CompressionType { get; init; } | |
| /// <summary> | |
| /// The compression level to be used when the compression type supports variable levels. | |
| /// </summary> | |
| int CompressionLevel { get; init; } | |
| /// <summary> | |
| /// Registry of compression providers. | |
| /// Defaults to <see cref="CompressionProviderRegistry.Default" /> but can be replaced with custom providers, such as | |
| /// System.IO.Compression for Deflate/GZip on modern .NET. | |
| /// </summary> | |
| CompressionProviderRegistry Providers { get; init; } | |
| } | |
| using SharpCompress.Common; | |
| using SharpCompress.Providers; | |
| namespace SharpCompress.Common.Options; | |
| /// <summary> | |
| /// Options for configuring writer behavior when creating archives. | |
| /// </summary> | |
| public interface IWriterOptions : IStreamOptions, IEncodingOptions, IProgressOptions | |
| { | |
| /// <summary> | |
| /// The compression type to use for the archive. | |
| /// </summary> | |
| CompressionType CompressionType { get; init; } | |
| /// <summary> | |
| /// The compression level to be used when the compression type supports variable levels. | |
| /// </summary> | |
| int CompressionLevel { get; init; } | |
| /// <summary> | |
| /// Registry of compression providers. | |
| /// Defaults to <see cref="CompressionProviderRegistry.Default" /> but can be replaced with custom providers, such as | |
| /// System.IO.Compression for Deflate/GZip on modern .NET. | |
| /// </summary> | |
| CompressionProviderRegistry Providers { get; init; } | |
| } |
| CompressionContext context, | ||
| CancellationToken cancellationToken = default | ||
| ) | ||
| { | ||
| return CreateCompressStreamAsync(destination, compressionLevel, cancellationToken); |
There was a problem hiding this comment.
The default CreateCompressStreamAsync(..., CompressionContext, ...) implementation ignores the provided context and delegates to the non-context overload. This breaks providers that require context (e.g., LZMA needs CanSeek, PPMd may need FormatOptions) when used via the async context overload. The default implementation should delegate to the synchronous context overload (or call a context-aware async override) so context is honored.
| /// <summary> | ||
| /// Registry of compression providers. | ||
| /// Defaults to <see cref="CompressionProviderRegistry.Default" /> but can be replaced with custom providers, such as | ||
| /// System.IO.Compression for Deflate/GZip on modern .NET. | ||
| /// </summary> | ||
| CompressionProviderRegistry Providers { get; init; } |
There was a problem hiding this comment.
Adding Providers to this public options interface is a breaking change for any external implementations of IWriterOptions (they now must add a new init property). If preserving binary/source compatibility is important, consider introducing a separate interface (e.g., ICompressionProviderOptions) or providing an adapter/default implementation path that doesn’t require all implementers to update immediately.
| using System; | ||
| using SharpCompress.Common; | ||
| using SharpCompress.Common.Options; | ||
| using SharpCompress.Compressors; |
There was a problem hiding this comment.
using SharpCompress.Compressors; is not referenced in this file and can trigger CS8019 (unnecessary using directive). Given warnings-as-errors, remove the unused using to avoid breaking builds.
| using System; | ||
| using SharpCompress.Common; | ||
| using SharpCompress.Common.Options; | ||
| using SharpCompress.Compressors; |
There was a problem hiding this comment.
using SharpCompress.Compressors; is unused in this file and can trigger CS8019. With warnings-as-errors, remove the unused using to keep builds green.
| using SharpCompress.Common; | ||
| using SharpCompress.Common.Options; | ||
| using SharpCompress.Common.Tar.Headers; | ||
| using SharpCompress.Compressors; |
There was a problem hiding this comment.
using SharpCompress.Compressors; does not appear to be used in this file (CompressionType comes from SharpCompress.Common). This will trigger CS8019 under warnings-as-errors; remove the unused using.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 97 out of 98 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ) | ||
| { | ||
| var data = Encoding.UTF8.GetBytes("zip async provider usage"); | ||
| writer.Write("test.txt", new MemoryStream(data)); |
There was a problem hiding this comment.
Disposable 'MemoryStream' is created but not disposed.
| ) | ||
| { | ||
| var data = Encoding.UTF8.GetBytes("hook provider"); | ||
| writer.Write("test.txt", new MemoryStream(data)); |
There was a problem hiding this comment.
Disposable 'MemoryStream' is created but not disposed.
#1196
This pull request introduces support for custom compression providers throughout the SharpCompress library, allowing users to swap out the built-in compression implementations for alternatives (such as using
System.IO.Compressionfor GZip/Deflate). The changes include updates to the API, documentation, and internal handling of compression streams to make the provider registry configurable and accessible wherever compression or decompression occurs.API and Core Library Updates:
Providersproperty of typeCompressionProviderRegistryto bothReaderOptionsandWriterOptions, allowing users to specify custom compression providers. This property defaults to the built-in registry but can be overridden as needed. [1] [2] [3]GZipFilePart,SeekableZipFilePart,StreamingZipFilePart, andZipFilePartto accept and use theCompressionProviderRegistryfor creating decompression streams, replacing hardcoded usage of built-in codecs. [1] [2] [3] [4] [5] [6] [7]Providersregistry from options to file part constructors, ensuring the custom provider is used throughout. [1] [2] [3] [4] [5] [6]Documentation Improvements:
README.md,docs/API.md, anddocs/USAGE.mdexplaining how to configure and use custom compression providers, with code samples and guidance for replacing or extending built-in codecs. [1] [2] [3]Internal Refactoring:
GZipFilePartandZipFilePartto use the provider registry, removing direct references to specific codec classes and making the implementation more flexible. [1] [2]DeflateStreamin favor of using the provider registry abstraction.These changes make it much easier to integrate alternative or third-party compression libraries, improve testability, and allow for more flexible deployment scenarios.