mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 06:54:40 +00:00
Generate the synchronous archive entry extensions from the async ones
The five synchronous WriteTo/WriteToDirectory/WriteToFile overloads were maintained by hand alongside their async counterparts, which had drifted: the async ones report progress through ExtractionOptions.BufferSize while the sync ones did not, and each fix has had to be made twice. Zomp.SyncMethodGenerator produces the synchronous copy from the async source at compile time. The async methods are the only ones written out; the sync versions are emitted into the same partial class, keeping the public API identical - same names, same overloads, same signatures. The generator is a build-time only dependency (PrivateAssets="all"), so it adds nothing to the shipped package and no runtime reference. Documentation summaries lose the word "asynchronously" because a summary is now shared by both copies of the method.
This commit is contained in:
@@ -19,5 +19,6 @@
|
||||
Version="17.14.15"
|
||||
/>
|
||||
<GlobalPackageReference Include="PolySharp" Version="1.16.0" />
|
||||
<PackageVersion Include="Zomp.SyncMethodGenerator" Version="2.0.40" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -7,7 +7,7 @@ using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
public static class IArchiveEntryExtensions
|
||||
public static partial class IArchiveEntryExtensions
|
||||
{
|
||||
/// <param name="archiveEntry">The archive entry to extract.</param>
|
||||
extension(IArchiveEntry archiveEntry)
|
||||
@@ -16,48 +16,9 @@ public static class IArchiveEntryExtensions
|
||||
/// Extract entry to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
public void WriteTo(Stream streamToWriteTo, IProgress<ProgressReport>? progress = null) =>
|
||||
archiveEntry.WriteTo(streamToWriteTo, bufferSize: null, progress: progress);
|
||||
|
||||
/// <summary>
|
||||
/// Extract entry to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="options">Options for configuring extraction behavior.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
public void WriteTo(
|
||||
Stream streamToWriteTo,
|
||||
ExtractionOptions options,
|
||||
IProgress<ProgressReport>? progress = null
|
||||
) => archiveEntry.WriteTo(streamToWriteTo, options.BufferSize, options, progress);
|
||||
|
||||
private void WriteTo(
|
||||
Stream streamToWriteTo,
|
||||
int? bufferSize,
|
||||
ExtractionOptions? options = null,
|
||||
IProgress<ProgressReport>? progress = null
|
||||
)
|
||||
{
|
||||
if (archiveEntry.IsDirectory)
|
||||
{
|
||||
throw new ExtractionException("Entry is a file directory and cannot be extracted.");
|
||||
}
|
||||
|
||||
using var entryStream = archiveEntry.OpenEntryStream();
|
||||
var checkedStream = options is null
|
||||
? entryStream
|
||||
: IEntryExtensions.WrapWithChecksumValidation(archiveEntry, entryStream, options);
|
||||
var sourceStream = WrapWithProgress(checkedStream, archiveEntry, progress);
|
||||
sourceStream.CopyTo(streamToWriteTo, bufferSize ?? Constants.BufferSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract entry to the specified stream asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
[Zomp.SyncMethodGenerator.CreateSyncVersion(PreserveProgress = true)]
|
||||
public async ValueTask WriteToAsync(
|
||||
Stream streamToWriteTo,
|
||||
IProgress<ProgressReport>? progress = null,
|
||||
@@ -73,12 +34,13 @@ public static class IArchiveEntryExtensions
|
||||
.ConfigureAwait(false);
|
||||
|
||||
/// <summary>
|
||||
/// Extract entry to the specified stream asynchronously.
|
||||
/// Extract entry to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="options">Options for configuring extraction behavior.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
[Zomp.SyncMethodGenerator.CreateSyncVersion(PreserveProgress = true)]
|
||||
public async ValueTask WriteToAsync(
|
||||
Stream streamToWriteTo,
|
||||
ExtractionOptions options,
|
||||
@@ -95,6 +57,7 @@ public static class IArchiveEntryExtensions
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
[Zomp.SyncMethodGenerator.CreateSyncVersion(PreserveProgress = true)]
|
||||
private async ValueTask WriteToAsync(
|
||||
Stream streamToWriteTo,
|
||||
int? bufferSize,
|
||||
@@ -167,19 +130,7 @@ public static class IArchiveEntryExtensions
|
||||
/// <summary>
|
||||
/// Extract to specific directory, retaining filename
|
||||
/// </summary>
|
||||
public void WriteToDirectory(
|
||||
string destinationDirectory,
|
||||
ExtractionOptions? options = null
|
||||
) =>
|
||||
entry.WriteEntryToDirectory(
|
||||
destinationDirectory,
|
||||
options,
|
||||
(path) => entry.WriteToFile(path, options)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Extract to specific directory asynchronously, retaining filename
|
||||
/// </summary>
|
||||
[Zomp.SyncMethodGenerator.CreateSyncVersion]
|
||||
public async ValueTask WriteToDirectoryAsync(
|
||||
string destinationDirectory,
|
||||
ExtractionOptions? options = null,
|
||||
@@ -198,23 +149,7 @@ public static class IArchiveEntryExtensions
|
||||
/// <summary>
|
||||
/// Extract to specific file
|
||||
/// </summary>
|
||||
public void WriteToFile(string destinationFileName, ExtractionOptions? options = null)
|
||||
{
|
||||
options ??= new ExtractionOptions();
|
||||
entry.WriteEntryToFile(
|
||||
destinationFileName,
|
||||
options,
|
||||
(x, fm) =>
|
||||
{
|
||||
using var fs = File.Open(x, fm);
|
||||
entry.WriteTo(fs, options?.BufferSize ?? Constants.BufferSize, options, null);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract to specific file asynchronously
|
||||
/// </summary>
|
||||
[Zomp.SyncMethodGenerator.CreateSyncVersion]
|
||||
public async ValueTask WriteToFileAsync(
|
||||
string destinationFileName,
|
||||
ExtractionOptions? options = null,
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Zomp.SyncMethodGenerator" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Zomp.SyncMethodGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.40, )",
|
||||
"resolved": "2.0.40",
|
||||
"contentHash": "lpU06HVF3AXHHU+qQSmoCCYPf3QfAUD4tePJ6o2PZta0K1Vt2jEyChwEeqTuG1940SB7kT6Wp5BagmL+7ILimw=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.300",
|
||||
@@ -175,6 +181,12 @@
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Zomp.SyncMethodGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.40, )",
|
||||
"resolved": "2.0.40",
|
||||
"contentHash": "lpU06HVF3AXHHU+qQSmoCCYPf3QfAUD4tePJ6o2PZta0K1Vt2jEyChwEeqTuG1940SB7kT6Wp5BagmL+7ILimw=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.300",
|
||||
@@ -289,6 +301,12 @@
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Zomp.SyncMethodGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.40, )",
|
||||
"resolved": "2.0.40",
|
||||
"contentHash": "lpU06HVF3AXHHU+qQSmoCCYPf3QfAUD4tePJ6o2PZta0K1Vt2jEyChwEeqTuG1940SB7kT6Wp5BagmL+7ILimw=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.300",
|
||||
@@ -321,9 +339,9 @@
|
||||
"net10.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.9, )",
|
||||
"resolved": "10.0.9",
|
||||
"contentHash": "4Iw41e2h7I4t70SJcX2GCmbyKJIlA273Cfm9RJMM050/3VBejGAG1KcthP5Z2L6SQcbfbf6BhNWO26+ZG+GzMg=="
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "f5VCIE7AJpd5YvzNTeMGVzQIgyE9tX+AreTYwQF+REbu+DZo/2Ae+jNSwhPEYrVz6RRkd7y8ubXjk6Nn6Ka+Cg=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
@@ -357,6 +375,12 @@
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "3kdIIceBPumwjw279FuiVMfVENT2cGASXJgcigdySsbX2dJB8ofUgG6i47yqF/k1qu6fvNR3csrSekZPviR6kQ=="
|
||||
},
|
||||
"Zomp.SyncMethodGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.40, )",
|
||||
"resolved": "2.0.40",
|
||||
"contentHash": "lpU06HVF3AXHHU+qQSmoCCYPf3QfAUD4tePJ6o2PZta0K1Vt2jEyChwEeqTuG1940SB7kT6Wp5BagmL+7ILimw=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.300",
|
||||
@@ -414,6 +438,12 @@
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "3kdIIceBPumwjw279FuiVMfVENT2cGASXJgcigdySsbX2dJB8ofUgG6i47yqF/k1qu6fvNR3csrSekZPviR6kQ=="
|
||||
},
|
||||
"Zomp.SyncMethodGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.40, )",
|
||||
"resolved": "2.0.40",
|
||||
"contentHash": "lpU06HVF3AXHHU+qQSmoCCYPf3QfAUD4tePJ6o2PZta0K1Vt2jEyChwEeqTuG1940SB7kT6Wp5BagmL+7ILimw=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.300",
|
||||
@@ -441,9 +471,9 @@
|
||||
"net8.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.28, )",
|
||||
"resolved": "8.0.28",
|
||||
"contentHash": "XMqgVjlLxLqWmEh3c49haXLQwsMNtvo6YscUaqfvEGfg1iA8hnYgkUVq3i9Zu9gKeNKMWiiZKVwZExc/qyEAsQ=="
|
||||
"requested": "[8.0.29, )",
|
||||
"resolved": "8.0.29",
|
||||
"contentHash": "HSBTfrkIZijz8z3ybLRKB7E8rHk4QQufFwpHa9fc5CMIgRhRzdn4mBGmlyXZqaueiMPtuJcnjresGvSTfaW8Mg=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
@@ -477,6 +507,12 @@
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "3kdIIceBPumwjw279FuiVMfVENT2cGASXJgcigdySsbX2dJB8ofUgG6i47yqF/k1qu6fvNR3csrSekZPviR6kQ=="
|
||||
},
|
||||
"Zomp.SyncMethodGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.40, )",
|
||||
"resolved": "2.0.40",
|
||||
"contentHash": "lpU06HVF3AXHHU+qQSmoCCYPf3QfAUD4tePJ6o2PZta0K1Vt2jEyChwEeqTuG1940SB7kT6Wp5BagmL+7ILimw=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.300",
|
||||
|
||||
Reference in New Issue
Block a user