Files
sharpcompress/tests/SharpCompress.Test/CompressionProviderTests.cs
2026-02-13 11:00:53 +00:00

887 lines
32 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AwesomeAssertions;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;
using SharpCompress.Common.Options;
using SharpCompress.Compressors;
using SharpCompress.IO;
using SharpCompress.Providers;
using SharpCompress.Providers.Default;
using SharpCompress.Providers.System;
using SharpCompress.Readers;
using SharpCompress.Readers.Tar;
using SharpCompress.Writers;
using SharpCompress.Writers.Tar;
using Xunit;
namespace SharpCompress.Test;
public class CompressionProviderTests
{
private sealed class TrackingCompressionProvider : ICompressionProvider
{
private readonly ICompressionProvider _inner;
public TrackingCompressionProvider(ICompressionProvider inner)
{
_inner = inner;
}
public int CompressionCalls { get; private set; }
public int DecompressionCalls { get; private set; }
public int AsyncCompressionCalls { get; private set; }
public int AsyncDecompressionCalls { get; private set; }
public CompressionType CompressionType => _inner.CompressionType;
public bool SupportsCompression => _inner.SupportsCompression;
public bool SupportsDecompression => _inner.SupportsDecompression;
public Stream CreateCompressStream(Stream destination, int compressionLevel)
{
CompressionCalls++;
return _inner.CreateCompressStream(destination, compressionLevel);
}
public Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
)
{
CompressionCalls++;
return _inner.CreateCompressStream(destination, compressionLevel, context);
}
public Stream CreateDecompressStream(Stream source)
{
DecompressionCalls++;
return _inner.CreateDecompressStream(source);
}
public Stream CreateDecompressStream(Stream source, CompressionContext context)
{
DecompressionCalls++;
return _inner.CreateDecompressStream(source, context);
}
public ValueTask<Stream> CreateCompressStreamAsync(
Stream destination,
int compressionLevel,
CancellationToken cancellationToken = default
)
{
AsyncCompressionCalls++;
return _inner.CreateCompressStreamAsync(
destination,
compressionLevel,
cancellationToken
);
}
public ValueTask<Stream> CreateCompressStreamAsync(
Stream destination,
int compressionLevel,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
AsyncCompressionCalls++;
return _inner.CreateCompressStreamAsync(
destination,
compressionLevel,
context,
cancellationToken
);
}
public ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
)
{
AsyncDecompressionCalls++;
return _inner.CreateDecompressStreamAsync(source, cancellationToken);
}
public ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
AsyncDecompressionCalls++;
return _inner.CreateDecompressStreamAsync(source, context, cancellationToken);
}
}
private sealed class TrackingLzmaHooksProvider : ICompressionProviderHooks
{
public int PreCalls { get; private set; }
public int PropertiesCalls { get; private set; }
public int PostCalls { get; private set; }
public CompressionType CompressionType => CompressionType.LZMA;
public bool SupportsCompression => true;
public bool SupportsDecompression => false;
public Stream CreateCompressStream(Stream destination, int compressionLevel)
{
CompressionContext context = new() { CanSeek = destination.CanSeek };
return CreateCompressStream(destination, compressionLevel, context);
}
public Stream CreateCompressStream(
Stream destination,
int compressionLevel,
CompressionContext context
) => SharpCompressStream.CreateNonDisposing(destination);
public Stream CreateDecompressStream(Stream source) => throw new NotSupportedException();
public Stream CreateDecompressStream(Stream source, CompressionContext context) =>
throw new NotSupportedException();
public ValueTask<Stream> CreateCompressStreamAsync(
Stream destination,
int compressionLevel,
CancellationToken cancellationToken = default
)
{
CompressionContext context = new() { CanSeek = destination.CanSeek };
return CreateCompressStreamAsync(
destination,
compressionLevel,
context,
cancellationToken
);
}
public ValueTask<Stream> CreateCompressStreamAsync(
Stream destination,
int compressionLevel,
CompressionContext context,
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
return new ValueTask<Stream>(SharpCompressStream.CreateNonDisposing(destination));
}
public ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CancellationToken cancellationToken = default
) => throw new NotSupportedException();
public ValueTask<Stream> CreateDecompressStreamAsync(
Stream source,
CompressionContext context,
CancellationToken cancellationToken = default
) => throw new NotSupportedException();
public byte[]? GetPreCompressionData(CompressionContext context)
{
PreCalls++;
return [];
}
public byte[]? GetCompressionProperties(Stream stream, CompressionContext context)
{
PropertiesCalls++;
return [];
}
public byte[]? GetPostCompressionData(Stream stream, CompressionContext context)
{
PostCalls++;
return [1, 2, 3];
}
}
private sealed class ContextRequiredGZipProvider : CompressionProviderBase
{
private readonly GZipCompressionProvider _inner = new();
public override CompressionType CompressionType => CompressionType.GZip;
public override bool SupportsCompression => true;
public override bool SupportsDecompression => true;
public override Stream CreateCompressStream(Stream destination, int compressionLevel) =>
_inner.CreateCompressStream(destination, compressionLevel);
public override Stream CreateDecompressStream(Stream source) =>
throw new InvalidOperationException("Context is required for GZip decompression.");
public override Stream CreateDecompressStream(Stream source, CompressionContext context)
{
context.ReaderOptions.Should().NotBeNull();
return _inner.CreateDecompressStream(source, context);
}
}
[Fact]
public void CompressionProviderRegistry_Default_ReturnsInternalProviders()
{
var registry = CompressionProviderRegistry.Default;
registry.GetProvider(CompressionType.Deflate).Should().NotBeNull();
registry.GetProvider(CompressionType.GZip).Should().NotBeNull();
registry.GetProvider(CompressionType.BZip2).Should().NotBeNull();
registry.GetProvider(CompressionType.ZStandard).Should().NotBeNull();
registry.GetProvider(CompressionType.LZip).Should().NotBeNull();
registry.GetProvider(CompressionType.Xz).Should().NotBeNull();
registry.GetProvider(CompressionType.Lzw).Should().NotBeNull();
}
[Fact]
public void CompressionProviderRegistry_With_ReplacesProvider()
{
var customProvider = new DeflateCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
// Should return the new provider
var retrieved = registry.GetProvider(CompressionType.Deflate);
retrieved.Should().BeSameAs(customProvider);
}
[Fact]
public void CompressionProviderRegistry_With_DoesNotModifyOriginal()
{
var original = CompressionProviderRegistry.Default;
var customProvider = new DeflateCompressionProvider();
var modified = original.With(customProvider);
// Original should still have the default provider
var originalProvider = original.GetProvider(CompressionType.Deflate);
var modifiedProvider = modified.GetProvider(CompressionType.Deflate);
originalProvider.Should().NotBeSameAs(modifiedProvider);
originalProvider.Should().NotBeSameAs(customProvider);
}
[Fact]
public void DeflateProvider_RoundTrip_Works()
{
var provider = new DeflateCompressionProvider();
var original = Encoding.UTF8.GetBytes("Hello, World! This is a test of compression.");
using var compressedStream = new MemoryStream();
// Wrap in NonDisposingStream so the compression stream doesn't close it
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = provider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
compressedStream.Position = 0;
using var decompressStream = provider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Fact]
public void GZipProvider_RoundTrip_Works()
{
var provider = new GZipCompressionProvider();
var original = Encoding.UTF8.GetBytes("Hello, World! This is a test of compression.");
using var compressedStream = new MemoryStream();
// Wrap in NonDisposingStream so the compression stream doesn't close it
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = provider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
compressedStream.Position = 0;
using var decompressStream = provider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Fact]
public void GZipProvider_Decompress_WithReaderOptionsContext_UsesArchiveEncoding()
{
var provider = new GZipCompressionProvider();
var data = Encoding.UTF8.GetBytes("gzip filename encoding");
var expectedFileName = "café.txt";
var archiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding("iso-8859-1") };
using var compressedStream = CreateGZipWithFileName(
data,
expectedFileName,
archiveEncoding.Default
);
compressedStream.Position = 0;
var readerOptions = new ReaderOptions { ArchiveEncoding = archiveEncoding };
var context = CompressionContext.FromStream(compressedStream) with
{
ReaderOptions = readerOptions,
};
using var decompressStream = provider.CreateDecompressStream(compressedStream, context);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
resultStream.ToArray().Should().Equal(data);
decompressStream.Should().BeOfType<SharpCompress.Compressors.Deflate.GZipStream>();
var gzipStream = (SharpCompress.Compressors.Deflate.GZipStream)decompressStream;
gzipStream.FileName.Should().Be(expectedFileName);
}
[Fact]
public void GZipProvider_Decompress_WithNullReaderOptions_FallsBackToUtf8()
{
var provider = new GZipCompressionProvider();
var data = Encoding.UTF8.GetBytes("gzip filename encoding");
var expectedFileName = "café.txt";
using var compressedStream = CreateGZipWithFileName(data, expectedFileName, Encoding.UTF8);
compressedStream.Position = 0;
var context = CompressionContext.FromStream(compressedStream);
// ReaderOptions is null by default
using var decompressStream = provider.CreateDecompressStream(compressedStream, context);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
resultStream.ToArray().Should().Equal(data);
var gzipStream = (SharpCompress.Compressors.Deflate.GZipStream)decompressStream;
gzipStream.FileName.Should().Be(expectedFileName);
}
[Fact]
public void BZip2Provider_SupportsCompressionAndDecompression()
{
var provider = new BZip2CompressionProvider();
// Verify the provider reports correct capabilities
provider.CompressionType.Should().Be(CompressionType.BZip2);
provider.SupportsCompression.Should().BeTrue();
provider.SupportsDecompression.Should().BeTrue();
}
[Fact]
public void TarWriter_WithCustomProvider_UsesProvider()
{
var customProvider = new GZipCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
using var stream = new MemoryStream();
var options = new TarWriterOptions(CompressionType.GZip, true) { Providers = registry };
using (var writer = new TarWriter(stream, options))
{
var data = Encoding.UTF8.GetBytes("Test content");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
// Should have written compressed data
stream.Position = 0;
stream.Length.Should().BeGreaterThan(0);
}
[Fact]
public void TarWriter_WithoutCustomProvider_UsesDefault()
{
using var stream = new MemoryStream();
var options = new TarWriterOptions(CompressionType.GZip, true);
using (var writer = new TarWriter(stream, options))
{
var data = Encoding.UTF8.GetBytes("Test content");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
stream.Position = 0;
stream.Length.Should().BeGreaterThan(0);
}
[Fact]
public void TarReader_WithCustomProvider_UsesProvider()
{
// First, create a tar.gz file
using var archiveStream = new MemoryStream();
var writeOptions = new TarWriterOptions(CompressionType.GZip, true);
using (var writer = new TarWriter(archiveStream, writeOptions))
{
var data = Encoding.UTF8.GetBytes("Test content for reading");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
// Now read it back with a custom provider
archiveStream.Position = 0;
var customProvider = new GZipCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
var readOptions = new ReaderOptions { Providers = registry };
using var reader = TarReader.OpenReader(archiveStream, readOptions);
reader.MoveToNextEntry().Should().BeTrue();
using var entryStream = reader.OpenEntryStream();
using var resultStream = new MemoryStream();
entryStream.CopyTo(resultStream);
var result = Encoding.UTF8.GetString(resultStream.ToArray());
result.Should().Be("Test content for reading");
}
[Fact]
public void TarReader_OpenReader_WithContextRequiredGZipProvider_Succeeds()
{
using var archiveStream = new MemoryStream();
using (
var writer = new TarWriter(
archiveStream,
new TarWriterOptions(CompressionType.GZip, true)
)
)
{
var data = Encoding.UTF8.GetBytes("Test content for context-required provider");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
archiveStream.Position = 0;
var registry = CompressionProviderRegistry.Default.With(new ContextRequiredGZipProvider());
var readOptions = new ReaderOptions { Providers = registry };
using var reader = TarReader.OpenReader(archiveStream, readOptions);
reader.MoveToNextEntry().Should().BeTrue();
using var entryStream = reader.OpenEntryStream();
using var resultStream = new MemoryStream();
entryStream.CopyTo(resultStream);
var result = Encoding.UTF8.GetString(resultStream.ToArray());
result.Should().Be("Test content for context-required provider");
}
[Fact]
public void WriterOptions_WithProviders_CanBeCloned()
{
var customProvider = new DeflateCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
var original = new WriterOptions(CompressionType.GZip)
{
Providers = registry,
LeaveStreamOpen = false,
};
// Clone using 'with' expression
var clone = original with
{
LeaveStreamOpen = true,
};
clone.CompressionType.Should().Be(original.CompressionType);
clone.CompressionLevel.Should().Be(original.CompressionLevel);
clone.Providers.Should().BeSameAs(original.Providers);
clone.LeaveStreamOpen.Should().BeTrue();
}
[Fact]
public void ReaderOptions_WithProviders_CanBeCloned()
{
var customProvider = new DeflateCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
var original = new ReaderOptions { Providers = registry, LeaveStreamOpen = false };
// Clone using 'with' expression
var clone = original with
{
LeaveStreamOpen = true,
};
clone.Providers.Should().BeSameAs(original.Providers);
clone.LeaveStreamOpen.Should().BeTrue();
}
[Fact]
public void TarArchive_OpenArchive_UsesCustomGZipProvider()
{
using var archiveStream = new MemoryStream();
using (
var writer = new TarWriter(
archiveStream,
new TarWriterOptions(CompressionType.GZip, true)
)
)
{
var data = Encoding.UTF8.GetBytes("tar archive provider usage");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
var trackingProvider = new TrackingCompressionProvider(new GZipCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var readOptions = new ReaderOptions { Providers = registry };
archiveStream.Position = 0;
using var archive = TarArchive.OpenArchive(archiveStream, readOptions);
var entry = archive.Entries.First(x => !x.IsDirectory);
using var entryStream = entry.OpenEntryStream();
using var resultStream = new MemoryStream();
entryStream.CopyTo(resultStream);
trackingProvider.DecompressionCalls.Should().BeGreaterThan(0);
}
[Fact]
public async Task TarArchive_OpenAsyncArchive_UsesCustomGZipProvider()
{
using var archiveStream = new MemoryStream();
using (
var writer = new TarWriter(
archiveStream,
new TarWriterOptions(CompressionType.GZip, true)
)
)
{
var data = Encoding.UTF8.GetBytes("tar async archive provider usage");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
var trackingProvider = new TrackingCompressionProvider(new GZipCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var readOptions = new ReaderOptions { Providers = registry };
archiveStream.Position = 0;
await using var archive = await TarArchive.OpenAsyncArchive(archiveStream, readOptions);
await foreach (var entry in archive.EntriesAsync)
{
if (entry.IsDirectory)
{
continue;
}
using var entryStream = await entry.OpenEntryStreamAsync();
using var resultStream = new MemoryStream();
await entryStream.CopyToAsync(resultStream);
break;
}
trackingProvider.AsyncDecompressionCalls.Should().BeGreaterThan(0);
}
[Fact]
public async Task ZipReader_OpenEntryStreamAsync_UsesCustomDeflateProvider()
{
using var zipStream = new MemoryStream();
using (
var writer = WriterFactory.OpenWriter(
zipStream,
ArchiveType.Zip,
new WriterOptions(CompressionType.Deflate) { LeaveStreamOpen = true }
)
)
{
var data = Encoding.UTF8.GetBytes("zip async provider usage");
writer.Write("test.txt", new MemoryStream(data));
}
var trackingProvider = new TrackingCompressionProvider(new DeflateCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var options = new ReaderOptions { Providers = registry };
zipStream.Position = 0;
await using var reader = await ReaderFactory.OpenAsyncReader(zipStream, options);
(await reader.MoveToNextEntryAsync()).Should().BeTrue();
using var entryStream = await reader.OpenEntryStreamAsync();
using var resultStream = new MemoryStream();
await entryStream.CopyToAsync(resultStream);
trackingProvider.AsyncDecompressionCalls.Should().BeGreaterThan(0);
}
[Fact]
public void LzwReader_OpenReader_UsesCustomLzwProvider()
{
var archivePath = Path.Combine(TestBase.TEST_ARCHIVES_PATH, "Tar.tar.Z");
var trackingProvider = new TrackingCompressionProvider(new LzwCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var options = new ReaderOptions { Providers = registry };
using var stream = File.OpenRead(archivePath);
using var reader = ReaderFactory.OpenReader(stream, options);
reader.MoveToNextEntry().Should().BeTrue();
reader.WriteEntryTo(Stream.Null);
trackingProvider.DecompressionCalls.Should().BeGreaterThan(0);
}
[Fact]
public void ZipWriter_LzmaProviderHook_WritesPostCompressionData()
{
var trackingProvider = new TrackingLzmaHooksProvider();
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
using var zipStream = new MemoryStream();
using (
var writer = WriterFactory.OpenWriter(
zipStream,
ArchiveType.Zip,
new WriterOptions(CompressionType.LZMA)
{
LeaveStreamOpen = true,
Providers = registry,
}
)
)
{
var data = Encoding.UTF8.GetBytes("hook provider");
writer.Write("test.txt", new MemoryStream(data));
}
trackingProvider.PreCalls.Should().BeGreaterThan(0);
trackingProvider.PropertiesCalls.Should().BeGreaterThan(0);
trackingProvider.PostCalls.Should().BeGreaterThan(0);
}
#region System.IO.Compression Tests
private static MemoryStream CreateGZipWithFileName(
byte[] data,
string fileName,
Encoding encoding
)
{
var compressedStream = new MemoryStream();
using (
var compressStream = new SharpCompress.Compressors.Deflate.GZipStream(
SharpCompressStream.CreateNonDisposing(compressedStream),
CompressionMode.Compress,
SharpCompress.Compressors.Deflate.CompressionLevel.Default,
encoding
)
)
{
compressStream.FileName = fileName;
compressStream.Write(data, 0, data.Length);
}
compressedStream.Position = 0;
return compressedStream;
}
[Fact]
public void SystemGZipProvider_RoundTrip_Works()
{
var provider = new SystemGZipCompressionProvider();
var original = Encoding.UTF8.GetBytes(
"Hello, World! This is a test of System.IO.Compression.GZipStream."
);
using var compressedStream = new MemoryStream();
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = provider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
compressedStream.Position = 0;
using var decompressStream = provider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Theory]
[InlineData(0)] // No compression
[InlineData(3)] // Fast
[InlineData(6)] // Default
[InlineData(9)] // Best compression
public void SystemGZipProvider_DifferentCompressionLevels_Work(int level)
{
var provider = new SystemGZipCompressionProvider();
var original = Encoding.UTF8.GetBytes(
"Test data for compression level testing with System.IO.Compression."
);
using var compressedStream = new MemoryStream();
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = provider.CreateCompressStream(nonDisposingStream, level))
{
compressStream.Write(original, 0, original.Length);
}
compressedStream.Position = 0;
using var decompressStream = provider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Fact]
public void SystemGZipProvider_Compress_InternalProvider_Decompress_CrossCompatibility()
{
// Compress with System.IO.Compression
var systemProvider = new SystemGZipCompressionProvider();
var original = Encoding.UTF8.GetBytes(
"Cross-compatibility test between System.IO.Compression and internal GZip."
);
using var compressedStream = new MemoryStream();
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = systemProvider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
// Decompress with internal provider
compressedStream.Position = 0;
var internalProvider = new GZipCompressionProvider();
using var decompressStream = internalProvider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Fact]
public void InternalProvider_Compress_SystemGZipProvider_Decompress_CrossCompatibility()
{
// Compress with internal provider
var internalProvider = new GZipCompressionProvider();
var original = Encoding.UTF8.GetBytes(
"Cross-compatibility test between internal GZip and System.IO.Compression."
);
using var compressedStream = new MemoryStream();
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = internalProvider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
// Decompress with System.IO.Compression
compressedStream.Position = 0;
var systemProvider = new SystemGZipCompressionProvider();
using var decompressStream = systemProvider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Fact]
public void TarWriter_WithSystemGZipProvider_CreatesReadableArchive()
{
// Create tar.gz using System.IO.Compression provider
var systemProvider = new SystemGZipCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(systemProvider);
using var archiveStream = new MemoryStream();
var writeOptions = new TarWriterOptions(CompressionType.GZip, true)
{
Providers = registry,
};
using (var writer = new TarWriter(archiveStream, writeOptions))
{
var data = Encoding.UTF8.GetBytes("Content written with System.IO.Compression");
writer.Write("test.txt", new MemoryStream(data), DateTime.Now);
}
// Read back using internal provider (should be compatible)
archiveStream.Position = 0;
var readOptions = new ReaderOptions();
using var reader = TarReader.OpenReader(archiveStream, readOptions);
reader.MoveToNextEntry().Should().BeTrue();
using var entryStream = reader.OpenEntryStream();
using var resultStream = new MemoryStream();
entryStream.CopyTo(resultStream);
var result = Encoding.UTF8.GetString(resultStream.ToArray());
result.Should().Be("Content written with System.IO.Compression");
}
[Fact]
public void SystemGZipProvider_SupportsCompressionAndDecompression()
{
var provider = new SystemGZipCompressionProvider();
// Verify the provider reports correct capabilities
provider.CompressionType.Should().Be(CompressionType.GZip);
provider.SupportsCompression.Should().BeTrue();
provider.SupportsDecompression.Should().BeTrue();
}
[Fact]
public void SystemDeflateProvider_RoundTrip_Works()
{
var provider = new SystemDeflateCompressionProvider();
var original = Encoding.UTF8.GetBytes(
"Hello, World! This is a test of System.IO.Compression.DeflateStream."
);
using var compressedStream = new MemoryStream();
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = provider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
compressedStream.Position = 0;
using var decompressStream = provider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
[Fact]
public void SystemDeflateProvider_Compress_InternalProvider_Decompress_CrossCompatibility()
{
// Compress with System.IO.Compression Deflate
var systemProvider = new SystemDeflateCompressionProvider();
var original = Encoding.UTF8.GetBytes(
"Cross-compatibility test between System.IO.Compression and internal Deflate."
);
using var compressedStream = new MemoryStream();
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(compressedStream);
using (var compressStream = systemProvider.CreateCompressStream(nonDisposingStream, 6))
{
compressStream.Write(original, 0, original.Length);
}
// Decompress with internal provider
compressedStream.Position = 0;
var internalProvider = new DeflateCompressionProvider();
using var decompressStream = internalProvider.CreateDecompressStream(compressedStream);
using var resultStream = new MemoryStream();
decompressStream.CopyTo(resultStream);
var result = resultStream.ToArray();
result.Should().Equal(original);
}
#endregion
}