reducing duplication in providers

This commit is contained in:
Adam Hathcock
2026-02-12 17:02:03 +00:00
parent d667288a87
commit 6c2e27870d
20 changed files with 156 additions and 632 deletions

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -31,17 +32,18 @@ public abstract class CompressionProviderBase : ICompressionProvider
public abstract Stream CreateCompressStream(Stream destination, int compressionLevel);
/// <inheritdoc />
public abstract Stream CreateCompressStream(
public virtual Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
);
) => CreateCompressStream(destination, compressionLevel);
/// <inheritdoc />
public abstract Stream CreateDecompressStream(Stream source);
/// <inheritdoc />
public abstract Stream CreateDecompressStream(Stream source, CompressionContext context);
public virtual Stream CreateDecompressStream(Stream source, CompressionContext context) =>
CreateDecompressStream(source);
/// <summary>
/// Asynchronously creates a compression stream.
@@ -68,8 +70,7 @@ public abstract class CompressionProviderBase : ICompressionProvider
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
return new ValueTask<Stream>(CreateCompressStream(destination, compressionLevel, context));
return CreateCompressStreamAsync(destination, compressionLevel, cancellationToken);
}
/// <summary>
@@ -95,7 +96,34 @@ public abstract class CompressionProviderBase : ICompressionProvider
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
return new ValueTask<Stream>(CreateDecompressStream(source, context));
return CreateDecompressStreamAsync(source, cancellationToken);
}
protected static void ValidateRequiredSizes(CompressionContext context, string algorithmName)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
$"{algorithmName} decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
}
protected static T RequireFormatOption<T>(
CompressionContext context,
string algorithmName,
string optionName
)
{
if (context.FormatOptions is not T options)
{
throw new ArgumentException(
$"{algorithmName} decompression requires {optionName} in CompressionContext.FormatOptions.",
nameof(context)
);
}
return options;
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace SharpCompress.Providers;
public abstract class ContextRequiredDecompressionProviderBase : DecompressionOnlyProviderBase
{
protected abstract string DecompressionContextRequirementDescription { get; }
protected virtual string DecompressionContextRequirementSuffix => string.Empty;
public sealed override Stream CreateDecompressStream(Stream source) =>
throw new InvalidOperationException(
$"{DecompressionContextRequirementDescription}. "
+ $"Use CreateDecompressStream(Stream, CompressionContext) overload{DecompressionContextRequirementSuffix}."
);
public sealed override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
$"{DecompressionContextRequirementDescription}. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) "
+ $"overload{DecompressionContextRequirementSuffix}."
);
}

View File

@@ -0,0 +1,22 @@
using System;
using System.IO;
using SharpCompress.Common;
namespace SharpCompress.Providers;
public abstract class DecompressionOnlyProviderBase : CompressionProviderBase
{
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
protected abstract string CompressionNotSupportedMessage { get; }
public sealed override Stream CreateCompressStream(Stream destination, int compressionLevel) =>
throw new NotSupportedException(CompressionNotSupportedMessage);
public sealed override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
) => throw new NotSupportedException(CompressionNotSupportedMessage);
}

View File

@@ -22,27 +22,11 @@ public sealed class BZip2CompressionProvider : CompressionProviderBase
return BZip2Stream.Create(destination, CompressionMode.Compress, false);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for BZip2 compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return BZip2Stream.Create(source, CompressionMode.Decompress, false);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for BZip2 decompression
return CreateDecompressStream(source);
}
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
@@ -52,14 +36,4 @@ public sealed class BZip2CompressionProvider : CompressionProviderBase
.CreateAsync(source, CompressionMode.Decompress, false, false, cancellationToken)
.ConfigureAwait(false);
}
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
// Context not used for BZip2 decompression
return await CreateDecompressStreamAsync(source, cancellationToken).ConfigureAwait(false);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Compressors;
@@ -10,38 +9,14 @@ namespace SharpCompress.Providers.Default;
/// Provides Deflate64 decompression using SharpCompress's internal implementation.
/// Note: Deflate64 compression is not supported; this provider is decompression-only.
/// </summary>
public sealed class Deflate64CompressionProvider : CompressionProviderBase
public sealed class Deflate64CompressionProvider : DecompressionOnlyProviderBase
{
public override CompressionType CompressionType => CompressionType.Deflate64;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Deflate64 compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Deflate64 compression is not supported by SharpCompress's internal implementation."
);
}
protected override string CompressionNotSupportedMessage =>
"Deflate64 compression is not supported by SharpCompress's internal implementation.";
public override Stream CreateDecompressStream(Stream source)
{
return new Deflate64Stream(source, CompressionMode.Decompress);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for Deflate64 decompression
return CreateDecompressStream(source);
}
}

View File

@@ -20,24 +20,8 @@ public sealed class DeflateCompressionProvider : CompressionProviderBase
return new DeflateStream(destination, CompressionMode.Compress, level);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for simple Deflate compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return new DeflateStream(source, CompressionMode.Decompress);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for simple Deflate decompression
return CreateDecompressStream(source);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -15,89 +14,33 @@ namespace SharpCompress.Providers.Default;
/// <remarks>
/// Explode requires compressed size, uncompressed size, and flags which must be provided via CompressionContext.
/// </remarks>
public sealed class ExplodeCompressionProvider : CompressionProviderBase
public sealed class ExplodeCompressionProvider : ContextRequiredDecompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.Explode;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
protected override string CompressionNotSupportedMessage =>
"Explode compression is not supported by SharpCompress's internal implementation.";
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Explode compression is not supported by SharpCompress's internal implementation."
);
}
protected override string DecompressionContextRequirementDescription =>
"Explode decompression requires compressed size, uncompressed size, and flags";
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Explode compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateDecompressStream(Stream source)
{
throw new InvalidOperationException(
"Explode decompression requires compressed size, uncompressed size, and flags. "
+ "Use CreateDecompressStream(Stream, CompressionContext) overload with FormatOptions."
);
}
protected override string DecompressionContextRequirementSuffix => " with FormatOptions";
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Explode decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
if (context.FormatOptions is not HeaderFlags flags)
{
throw new ArgumentException(
"Explode decompression requires HeaderFlags in CompressionContext.FormatOptions.",
nameof(context)
);
}
ValidateRequiredSizes(context, "Explode");
var flags = RequireFormatOption<HeaderFlags>(context, "Explode", "HeaderFlags");
return ExplodeStream.Create(source, context.InputSize, context.OutputSize, flags);
}
public override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
"Explode decompression requires compressed size, uncompressed size, and flags. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) overload with FormatOptions."
);
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Explode decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
if (context.FormatOptions is not HeaderFlags flags)
{
throw new ArgumentException(
"Explode decompression requires HeaderFlags in CompressionContext.FormatOptions.",
nameof(context)
);
}
ValidateRequiredSizes(context, "Explode");
var flags = RequireFormatOption<HeaderFlags>(context, "Explode", "HeaderFlags");
return await ExplodeStream
.CreateAsync(source, context.InputSize, context.OutputSize, flags, cancellationToken)

View File

@@ -20,24 +20,8 @@ public sealed class GZipCompressionProvider : CompressionProviderBase
return new GZipStream(destination, CompressionMode.Compress, level);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for simple GZip compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return new GZipStream(source, CompressionMode.Decompress);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for simple GZip decompression
return CreateDecompressStream(source);
}
}

View File

@@ -19,24 +19,8 @@ public sealed class LZipCompressionProvider : CompressionProviderBase
return new LZipStream(destination, CompressionMode.Compress);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for LZip compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return new LZipStream(source, CompressionMode.Decompress);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for LZip decompression
return CreateDecompressStream(source);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Compressors.Lzw;
@@ -9,38 +8,14 @@ namespace SharpCompress.Providers.Default;
/// Provides LZW compression decompression using SharpCompress's internal implementation.
/// Note: Compression is not supported by this provider.
/// </summary>
public sealed class LzwCompressionProvider : CompressionProviderBase
public sealed class LzwCompressionProvider : DecompressionOnlyProviderBase
{
public override CompressionType CompressionType => CompressionType.Lzw;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"LZW compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"LZW compression is not supported by SharpCompress's internal implementation."
);
}
protected override string CompressionNotSupportedMessage =>
"LZW compression is not supported by SharpCompress's internal implementation.";
public override Stream CreateDecompressStream(Stream source)
{
return new LzwStream(source);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for LZW decompression
return CreateDecompressStream(source);
}
}

View File

@@ -1,9 +1,4 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Compressors.Reduce;
namespace SharpCompress.Providers.Default;
@@ -11,76 +6,8 @@ namespace SharpCompress.Providers.Default;
/// Provides Reduce1 decompression using SharpCompress's internal implementation.
/// Note: Reduce compression is not supported; this provider is decompression-only.
/// </summary>
public sealed class Reduce1CompressionProvider : CompressionProviderBase
public sealed class Reduce1CompressionProvider : ReduceCompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.Reduce1;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateDecompressStream(Stream source)
{
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStream(Stream, CompressionContext) overload."
);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return ReduceStream.Create(source, context.InputSize, context.OutputSize, 1);
}
public override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) overload."
);
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return await ReduceStream
.CreateAsync(source, context.InputSize, context.OutputSize, 1, cancellationToken)
.ConfigureAwait(false);
}
protected override int Factor => 1;
}

View File

@@ -1,9 +1,4 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Compressors.Reduce;
namespace SharpCompress.Providers.Default;
@@ -11,76 +6,8 @@ namespace SharpCompress.Providers.Default;
/// Provides Reduce2 decompression using SharpCompress's internal implementation.
/// Note: Reduce compression is not supported; this provider is decompression-only.
/// </summary>
public sealed class Reduce2CompressionProvider : CompressionProviderBase
public sealed class Reduce2CompressionProvider : ReduceCompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.Reduce2;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateDecompressStream(Stream source)
{
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStream(Stream, CompressionContext) overload."
);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return ReduceStream.Create(source, context.InputSize, context.OutputSize, 2);
}
public override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) overload."
);
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return await ReduceStream
.CreateAsync(source, context.InputSize, context.OutputSize, 2, cancellationToken)
.ConfigureAwait(false);
}
protected override int Factor => 2;
}

View File

@@ -1,9 +1,4 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Compressors.Reduce;
namespace SharpCompress.Providers.Default;
@@ -11,76 +6,8 @@ namespace SharpCompress.Providers.Default;
/// Provides Reduce3 decompression using SharpCompress's internal implementation.
/// Note: Reduce compression is not supported; this provider is decompression-only.
/// </summary>
public sealed class Reduce3CompressionProvider : CompressionProviderBase
public sealed class Reduce3CompressionProvider : ReduceCompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.Reduce3;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateDecompressStream(Stream source)
{
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStream(Stream, CompressionContext) overload."
);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return ReduceStream.Create(source, context.InputSize, context.OutputSize, 3);
}
public override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) overload."
);
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return await ReduceStream
.CreateAsync(source, context.InputSize, context.OutputSize, 3, cancellationToken)
.ConfigureAwait(false);
}
protected override int Factor => 3;
}

View File

@@ -1,9 +1,4 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Compressors.Reduce;
namespace SharpCompress.Providers.Default;
@@ -11,76 +6,8 @@ namespace SharpCompress.Providers.Default;
/// Provides Reduce4 decompression using SharpCompress's internal implementation.
/// Note: Reduce compression is not supported; this provider is decompression-only.
/// </summary>
public sealed class Reduce4CompressionProvider : CompressionProviderBase
public sealed class Reduce4CompressionProvider : ReduceCompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.Reduce4;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Reduce compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateDecompressStream(Stream source)
{
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStream(Stream, CompressionContext) overload."
);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return ReduceStream.Create(source, context.InputSize, context.OutputSize, 4);
}
public override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
"Reduce decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) overload."
);
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Reduce decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
return await ReduceStream
.CreateAsync(source, context.InputSize, context.OutputSize, 4, cancellationToken)
.ConfigureAwait(false);
}
protected override int Factor => 4;
}

View File

@@ -0,0 +1,36 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Compressors.Reduce;
namespace SharpCompress.Providers.Default;
public abstract class ReduceCompressionProviderBase : ContextRequiredDecompressionProviderBase
{
protected abstract int Factor { get; }
protected override string DecompressionContextRequirementDescription =>
"Reduce decompression requires compressed and uncompressed sizes";
protected override string CompressionNotSupportedMessage =>
"Reduce compression is not supported by SharpCompress's internal implementation.";
public sealed override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
ValidateRequiredSizes(context, "Reduce");
return ReduceStream.Create(source, context.InputSize, context.OutputSize, Factor);
}
public sealed override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
ValidateRequiredSizes(context, "Reduce");
return await ReduceStream
.CreateAsync(source, context.InputSize, context.OutputSize, Factor, cancellationToken)
.ConfigureAwait(false);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -15,47 +14,18 @@ namespace SharpCompress.Providers.Default;
/// <remarks>
/// Shrink requires compressed and uncompressed sizes which must be provided via CompressionContext.
/// </remarks>
public sealed class ShrinkCompressionProvider : CompressionProviderBase
public sealed class ShrinkCompressionProvider : ContextRequiredDecompressionProviderBase
{
public override CompressionType CompressionType => CompressionType.Shrink;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
protected override string CompressionNotSupportedMessage =>
"Shrink compression is not supported by SharpCompress's internal implementation.";
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"Shrink compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"Shrink compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateDecompressStream(Stream source)
{
throw new InvalidOperationException(
"Shrink decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStream(Stream, CompressionContext) overload."
);
}
protected override string DecompressionContextRequirementDescription =>
"Shrink decompression requires compressed and uncompressed sizes";
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Shrink decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
ValidateRequiredSizes(context, "Shrink");
return new ShrinkStream(
source,
@@ -65,28 +35,13 @@ public sealed class ShrinkCompressionProvider : CompressionProviderBase
);
}
public override ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) =>
throw new InvalidOperationException(
"Shrink decompression requires compressed and uncompressed sizes. "
+ "Use CreateDecompressStreamAsync(Stream, CompressionContext, CancellationToken) overload."
);
public override async ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
if (context.InputSize < 0 || context.OutputSize < 0)
{
throw new ArgumentException(
"Shrink decompression requires InputSize and OutputSize in CompressionContext.",
nameof(context)
);
}
ValidateRequiredSizes(context, "Shrink");
return await ShrinkStream
.CreateAsync(

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Compressors.Xz;
@@ -9,38 +8,14 @@ namespace SharpCompress.Providers.Default;
/// Provides XZ compression decompression using SharpCompress's internal implementation.
/// Note: Compression is not supported by this provider.
/// </summary>
public sealed class XzCompressionProvider : CompressionProviderBase
public sealed class XzCompressionProvider : DecompressionOnlyProviderBase
{
public override CompressionType CompressionType => CompressionType.Xz;
public override bool SupportsCompression => false;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel)
{
throw new NotSupportedException(
"XZ compression is not supported by SharpCompress's internal implementation."
);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
throw new NotSupportedException(
"XZ compression is not supported by SharpCompress's internal implementation."
);
}
protected override string CompressionNotSupportedMessage =>
"XZ compression is not supported by SharpCompress's internal implementation.";
public override Stream CreateDecompressStream(Stream source)
{
return new XZStream(source);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for XZ decompression
return CreateDecompressStream(source);
}
}

View File

@@ -18,24 +18,8 @@ public sealed class ZStandardCompressionProvider : CompressionProviderBase
return new ZStd.CompressionStream(destination, compressionLevel);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for ZStandard compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return new ZStd.DecompressionStream(source);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for ZStandard decompression
return CreateDecompressStream(source);
}
}

View File

@@ -23,16 +23,6 @@ public sealed class SystemDeflateCompressionProvider : CompressionProviderBase
return new DeflateStream(destination, bclLevel, leaveOpen: false);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for simple Deflate compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return new DeflateStream(
@@ -42,12 +32,6 @@ public sealed class SystemDeflateCompressionProvider : CompressionProviderBase
);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for simple Deflate decompression
return CreateDecompressStream(source);
}
/// <summary>
/// Maps SharpCompress compression level (0-9) to BCL CompressionLevel.
/// </summary>

View File

@@ -23,16 +23,6 @@ public sealed class SystemGZipCompressionProvider : CompressionProviderBase
return new GZipStream(destination, bclLevel, leaveOpen: false);
}
public override Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
// Context not used for simple GZip compression
return CreateCompressStream(destination, compressionLevel);
}
public override Stream CreateDecompressStream(Stream source)
{
return new GZipStream(
@@ -42,12 +32,6 @@ public sealed class SystemGZipCompressionProvider : CompressionProviderBase
);
}
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
// Context not used for simple GZip decompression
return CreateDecompressStream(source);
}
/// <summary>
/// Maps SharpCompress compression level (0-9) to BCL CompressionLevel.
/// </summary>