Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ SharpCompress supports multiple archive and compression formats:
- Preserve existing public method signatures and behavior when possible.
- If a breaking change is unavoidable, document it and provide a migration path.
- Add or update tests that cover backward compatibility expectations.
- Avoid exposing public `init` setters, positional records, `required` members, or other metadata that forces consumers onto newer C# language versions; validate older-consumer compatibility with tests when changing exported APIs.

### Stream Ownership and Position Checklist
- Verify `LeaveStreamOpen` behavior for externally owned streams.
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
Include="Microsoft.VisualStudio.Threading.Analyzers"
Version="17.14.15"
/>
<GlobalPackageReference Include="PolySharp" Version="1.15.0" />
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions build/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
"resolved": "17.14.15",
"contentHash": "mXQPJsbuUD2ydq4/ffd8h8tSOFCXec+2xJOVNCvXjuMOq/+5EKHq3D2m2MC2+nUaXeFMSt66VS/J4HdKBixgcw=="
},
"PolySharp": {
"type": "Direct",
"requested": "[1.15.0, )",
"resolved": "1.15.0",
"contentHash": "FbU0El+EEjdpuIX4iDbeS7ki1uzpJPx8vbqOzEtqnl1GZeAGJfq+jCbxeJL2y0EPnUNk8dRnnqR2xnYXg9Tf+g=="
},
"SimpleExec": {
"type": "Direct",
"requested": "[13.0.0, )",
Expand Down
36 changes: 26 additions & 10 deletions src/SharpCompress/Archives/ArchiveInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,29 @@ namespace SharpCompress.Archives;
/// <see cref="ArchiveFactory.GetArchiveInformationAsync(System.IO.Stream,System.Threading.CancellationToken)"/>
/// to obtain an instance of this record.
/// </remarks>
/// <param name="Type">
/// The type of archive detected, or <see langword="null"/> when the format is not a registered well-known type.
/// </param>
/// <param name="SupportsRandomAccess">
/// <see langword="true"/> when this archive format supports random access via the <see cref="IArchive"/> API,
/// meaning the full file listing can be retrieved without decompressing the entire archive.
/// <see langword="false"/> when only the <see cref="SharpCompress.Readers.IReader"/> API is available,
/// which reads entries sequentially and can only report per-entry progress.
/// </param>
public record ArchiveInformation(ArchiveType? Type, bool SupportsRandomAccess);
public record ArchiveInformation
{
/// <summary>
/// The type of archive detected, or <see langword="null"/> when the format is not a registered well-known type.
/// </summary>
public ArchiveType? Type { get; set; }

/// <summary>
/// <see langword="true"/> when this archive format supports random access via the <see cref="IArchive"/> API,
/// meaning the full file listing can be retrieved without decompressing the entire archive.
/// <see langword="false"/> when only the <see cref="SharpCompress.Readers.IReader"/> API is available,
/// which reads entries sequentially and can only report per-entry progress.
/// </summary>
public bool SupportsRandomAccess { get; set; }

/// <summary>
/// Creates a new archive information instance.
/// </summary>
/// <param name="type">The detected archive type.</param>
/// <param name="supportsRandomAccess">Whether the detected format supports random access.</param>
public ArchiveInformation(ArchiveType? type, bool supportsRandomAccess)
{
Type = type;
SupportsRandomAccess = supportsRandomAccess;
}
}
14 changes: 7 additions & 7 deletions src/SharpCompress/Common/ExtractionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace SharpCompress.Common;
/// Options for configuring extraction behavior when extracting archive entries.
/// </summary>
/// <remarks>
/// This class is immutable. Use the <c>with</c> expression to create modified copies:
/// Configure extraction behavior with constructors, property setters, or the <c>with</c> expression:
/// <code>
/// var options = new ExtractionOptions { Overwrite = false };
/// options = options with { PreserveFileTime = true };
Expand All @@ -19,35 +19,35 @@ public sealed record ExtractionOptions : IExtractionOptions
/// Overwrite target if it exists.
/// <para><b>Breaking change:</b> Default changed from false to true in version 0.40.0.</para>
/// </summary>
public bool Overwrite { get; init; } = true;
public bool Overwrite { get; set; } = true;

/// <summary>
/// Extract with internal directory structure.
/// <para><b>Breaking change:</b> Default changed from false to true in version 0.40.0.</para>
/// </summary>
public bool ExtractFullPath { get; init; } = true;
public bool ExtractFullPath { get; set; } = true;

/// <summary>
/// Preserve file time.
/// <para><b>Breaking change:</b> Default changed from false to true in version 0.40.0.</para>
/// </summary>
public bool PreserveFileTime { get; init; } = true;
public bool PreserveFileTime { get; set; } = true;

/// <summary>
/// Preserve windows file attributes.
/// </summary>
public bool PreserveAttributes { get; init; }
public bool PreserveAttributes { get; set; }

/// <summary>
/// Delegate for writing symbolic links to disk.
/// The first parameter is the source path (where the symlink is created).
/// The second parameter is the target path (what the symlink refers to).
/// </summary>
/// <remarks>
/// <b>Breaking change:</b> Changed from field to init-only property in version 0.40.0.
/// <b>Breaking change:</b> Changed from field to property in version 0.40.0.
/// If no handler is provided, symbolic links are silently skipped during extraction.
/// </remarks>
public Action<string, string>? SymbolicLinkHandler { get; init; }
public Action<string, string>? SymbolicLinkHandler { get; set; }

/// <summary>
/// Creates a new ExtractionOptions instance with default values.
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Common/Options/IEncodingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace SharpCompress.Common.Options;

public interface IEncodingOptions
{
IArchiveEncoding ArchiveEncoding { get; init; }
IArchiveEncoding ArchiveEncoding { get; set; }
}
10 changes: 5 additions & 5 deletions src/SharpCompress/Common/Options/IExtractionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ public interface IExtractionOptions
/// Overwrite target if it exists.
/// <para><b>Breaking change:</b> Default changed from false to true in version 0.40.0.</para>
/// </summary>
bool Overwrite { get; init; }
bool Overwrite { get; set; }

/// <summary>
/// Extract with internal directory structure.
/// <para><b>Breaking change:</b> Default changed from false to true in version 0.40.0.</para>
/// </summary>
bool ExtractFullPath { get; init; }
bool ExtractFullPath { get; set; }

/// <summary>
/// Preserve file time.
/// <para><b>Breaking change:</b> Default changed from false to true in version 0.40.0.</para>
/// </summary>
bool PreserveFileTime { get; init; }
bool PreserveFileTime { get; set; }

/// <summary>
/// Preserve windows file attributes.
/// </summary>
bool PreserveAttributes { get; init; }
bool PreserveAttributes { get; set; }

/// <summary>
/// Delegate for writing symbolic links to disk.
/// The first parameter is the source path (where the symlink is created).
/// The second parameter is the target path (what the symlink refers to).
/// </summary>
Action<string, string>? SymbolicLinkHandler { get; init; }
Action<string, string>? SymbolicLinkHandler { get; set; }
}
2 changes: 1 addition & 1 deletion src/SharpCompress/Common/Options/IProgressOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ namespace SharpCompress.Common.Options;

public interface IProgressOptions
{
IProgress<ProgressReport>? Progress { get; init; }
IProgress<ProgressReport>? Progress { get; set; }
}
14 changes: 7 additions & 7 deletions src/SharpCompress/Common/Options/IReaderOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,37 @@ public interface IReaderOptions : IStreamOptions, IEncodingOptions, IProgressOpt
/// <summary>
/// Look for RarArchive (Check for self-extracting archives or cases where RarArchive isn't at the start of the file)
/// </summary>
bool LookForHeader { get; init; }
bool LookForHeader { get; set; }

/// <summary>
/// Password for encrypted archives.
/// </summary>
string? Password { get; init; }
string? Password { get; set; }

/// <summary>
/// Disable checking for incomplete archives.
/// </summary>
bool DisableCheckIncomplete { get; init; }
bool DisableCheckIncomplete { get; set; }

/// <summary>
/// Buffer size for stream operations.
/// </summary>
int BufferSize { get; init; }
int BufferSize { get; set; }

/// <summary>
/// Provide a hint for the extension of the archive being read, can speed up finding the correct decoder.
/// </summary>
string? ExtensionHint { get; init; }
string? ExtensionHint { get; set; }

/// <summary>
/// Size of the rewindable buffer for non-seekable streams.
/// </summary>
int? RewindableBufferSize { get; init; }
int? RewindableBufferSize { get; set; }

/// <summary>
/// Registry of compression providers.
/// Defaults to <see cref="CompressionProviderRegistry.Default" /> but can be replaced with custom providers.
/// Use this to provide alternative decompression implementations.
/// </summary>
CompressionProviderRegistry Providers { get; init; }
CompressionProviderRegistry Providers { get; set; }
}
2 changes: 1 addition & 1 deletion src/SharpCompress/Common/Options/IStreamOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace SharpCompress.Common.Options;

public interface IStreamOptions
{
bool LeaveStreamOpen { get; init; }
bool LeaveStreamOpen { get; set; }
}
6 changes: 3 additions & 3 deletions src/SharpCompress/Common/Options/IWriterOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ public interface IWriterOptions : IStreamOptions, IEncodingOptions, IProgressOpt
/// <summary>
/// The compression type to use for the archive.
/// </summary>
CompressionType CompressionType { get; init; }
CompressionType CompressionType { get; set; }

/// <summary>
/// The compression level to be used when the compression type supports variable levels.
/// </summary>
int CompressionLevel { get; init; }
int CompressionLevel { get; set; }

/// <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; }
CompressionProviderRegistry Providers { get; set; }
}
12 changes: 6 additions & 6 deletions src/SharpCompress/Providers/CompressionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ public sealed record CompressionContext
/// <summary>
/// The size of the input data, or -1 if unknown.
/// </summary>
public long InputSize { get; init; } = -1;
public long InputSize { get; set; } = -1;

/// <summary>
/// The expected output size, or -1 if unknown.
/// </summary>
public long OutputSize { get; init; } = -1;
public long OutputSize { get; set; } = -1;

/// <summary>
/// Properties bytes for the compression format (e.g., LZMA properties).
/// </summary>
public byte[]? Properties { get; init; }
public byte[]? Properties { get; set; }

/// <summary>
/// Whether the underlying stream supports seeking.
/// </summary>
public bool CanSeek { get; init; }
public bool CanSeek { get; set; }

/// <summary>
/// Additional format-specific options.
Expand All @@ -38,7 +38,7 @@ public sealed record CompressionContext
/// Examples of valid FormatOptions values include compression properties (e.g., LZMA properties),
/// format flags, or algorithm-specific configuration.
/// </remarks>
public object? FormatOptions { get; init; }
public object? FormatOptions { get; set; }

/// <summary>
/// Creates a CompressionContext from a stream.
Expand All @@ -51,7 +51,7 @@ public static CompressionContext FromStream(Stream stream) =>
/// <summary>
/// Reader options for accessing archive metadata such as header encoding.
/// </summary>
public IReaderOptions? ReaderOptions { get; init; }
public IReaderOptions? ReaderOptions { get; set; }

/// <summary>
/// Returns a new <see cref="CompressionContext"/> with the specified reader options.
Expand Down
22 changes: 11 additions & 11 deletions src/SharpCompress/Readers/ReaderOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace SharpCompress.Readers;
/// Options for configuring reader behavior when opening archives.
/// </summary>
/// <remarks>
/// This class is immutable. Use preset properties and fluent helpers for common configurations:
/// Use preset properties, setters, and fluent helpers for common configurations:
/// <code>
/// var options = ReaderOptions.ForExternalStream
/// .WithPassword("secret")
Expand Down Expand Up @@ -53,43 +53,43 @@ public sealed record ReaderOptions : IReaderOptions
/// </code>
/// </para>
/// </remarks>
public bool LeaveStreamOpen { get; init; } = false;
public bool LeaveStreamOpen { get; set; } = false;

/// <summary>
/// Encoding to use for archive entry names.
/// </summary>
public IArchiveEncoding ArchiveEncoding { get; init; } = new ArchiveEncoding();
public IArchiveEncoding ArchiveEncoding { get; set; } = new ArchiveEncoding();

/// <summary>
/// Look for RarArchive (Check for self-extracting archives or cases where RarArchive isn't at the start of the file)
/// </summary>
public bool LookForHeader { get; init; }
public bool LookForHeader { get; set; }

/// <summary>
/// Password for encrypted archives.
/// </summary>
public string? Password { get; init; }
public string? Password { get; set; }

/// <summary>
/// Disable checking for incomplete archives.
/// </summary>
public bool DisableCheckIncomplete { get; init; }
public bool DisableCheckIncomplete { get; set; }

/// <summary>
/// Buffer size for stream operations.
/// </summary>
public int BufferSize { get; init; } = Constants.BufferSize;
public int BufferSize { get; set; } = Constants.BufferSize;

/// <summary>
/// Provide a hint for the extension of the archive being read, can speed up finding the correct decoder. Should be without the leading period in the form like: tar.gz or zip
/// </summary>
public string? ExtensionHint { get; init; }
public string? ExtensionHint { get; set; }

/// <summary>
/// An optional progress reporter for tracking extraction operations.
/// When set, progress updates will be reported as entries are extracted.
/// </summary>
public IProgress<ProgressReport>? Progress { get; init; }
public IProgress<ProgressReport>? Progress { get; set; }

/// <summary>
/// Size of the rewindable buffer for non-seekable streams.
Expand Down Expand Up @@ -133,14 +133,14 @@ public sealed record ReaderOptions : IReaderOptions
/// using var reader = ReaderFactory.OpenReader(networkStream, options);
/// </code>
/// </example>
public int? RewindableBufferSize { get; init; }
public int? RewindableBufferSize { get; set; }

/// <summary>
/// Registry of compression providers.
/// Defaults to <see cref="CompressionProviderRegistry.Default" /> but can be replaced with custom implementations, such as
/// System.IO.Compression for Deflate/GZip on modern .NET.
/// </summary>
public CompressionProviderRegistry Providers { get; init; } =
public CompressionProviderRegistry Providers { get; set; } =
CompressionProviderRegistry.Default;

/// <summary>
Expand Down
Loading
Loading