Merge remote-tracking branch 'origin/copilot/add-lzwreader-support' into copilot/add-lzwreader-support

This commit is contained in:
Adam Hathcock
2026-02-09 15:05:10 +00:00
5 changed files with 84 additions and 7 deletions

View File

@@ -36,8 +36,15 @@ internal sealed partial class LzwFilePart : FilePart
private static string? DeriveFileName(Stream stream)
{
// Unwrap SharpCompressStream to get to the underlying FileStream
var unwrappedStream = stream;
if (stream is SharpCompress.IO.IStreamStack streamStack)
{
unwrappedStream = streamStack.BaseStream();
}
// Try to derive filename from FileStream
if (stream is FileStream fileStream && !string.IsNullOrEmpty(fileStream.Name))
if (unwrappedStream is FileStream fileStream && !string.IsNullOrEmpty(fileStream.Name))
{
var fileName = Path.GetFileName(fileStream.Name);
// Strip .Z extension if present

View File

@@ -216,9 +216,9 @@
"net10.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[10.0.0, )",
"resolved": "10.0.0",
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "sXdDtMf2qcnbygw9OdE535c2lxSxrZP8gO4UhDJ0xiJbl1wIqXS1OTcTDFTIJPOFd6Mhcm8gPEthqWGUxBsTqw=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
@@ -264,9 +264,9 @@
"net8.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[8.0.22, )",
"resolved": "8.0.22",
"contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ=="
"requested": "[8.0.23, )",
"resolved": "8.0.23",
"contentHash": "GqHiB1HbbODWPbY/lc5xLQH8siEEhNA0ptpJCC6X6adtAYNEzu5ZlqV3YHA3Gh7fuEwgA8XqVwMtH2KNtuQM1Q=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",

View File

@@ -1,4 +1,7 @@
using System.IO;
using SharpCompress.Common;
using SharpCompress.Readers;
using SharpCompress.Readers.Lzw;
using Xunit;
namespace SharpCompress.Test.Lzw;
@@ -12,4 +15,29 @@ public class LzwReaderAsyncTests : ReaderTests
{
await ReadAsync("Tar.tar.Z", CompressionType.Lzw);
}
[Fact]
public async System.Threading.Tasks.Task Lzw_Reader_Plain_Z_File_Async()
{
// Test async reading of a plain .Z file (not tar-wrapped) using LzwReader directly
using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "large_test.txt.Z"));
using var reader = LzwReader.OpenReader(stream);
Assert.Equal(ArchiveType.Lzw, reader.ArchiveType);
Assert.True(reader.MoveToNextEntry());
var entry = reader.Entry;
Assert.NotNull(entry);
Assert.Equal(CompressionType.Lzw, entry.CompressionType);
// When opened as FileStream, key should be derived from filename
Assert.Equal("large_test.txt", entry.Key);
// Decompress asynchronously
using var entryStream = reader.OpenEntryStream();
using var ms = new MemoryStream();
await entryStream.CopyToAsync(ms);
Assert.Equal(22300, ms.Length);
}
}

View File

@@ -46,4 +46,46 @@ public class LzwReaderTests : ReaderTests
Assert.NotNull(reader.Entry);
Assert.Equal(CompressionType.Lzw, reader.Entry.CompressionType);
}
[Fact]
public void Lzw_Reader_Plain_Z_File()
{
// Test with a plain .Z file (not tar-wrapped) using LzwReader directly
using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "large_test.txt.Z"));
using var reader = LzwReader.OpenReader(stream);
Assert.True(reader.MoveToNextEntry());
var entry = reader.Entry;
Assert.NotNull(entry);
Assert.Equal(CompressionType.Lzw, entry.CompressionType);
// Entry key should be "large_test.txt" (stripped .Z extension) when opened via FileStream
Assert.Equal("large_test.txt", entry.Key);
// Decompress and verify content
using var entryStream = reader.OpenEntryStream();
using var ms = new MemoryStream();
entryStream.CopyTo(ms);
var decompressed = System.Text.Encoding.UTF8.GetString(ms.ToArray());
Assert.Equal(22300, ms.Length);
Assert.Contains("This is a test file for LZW compression testing", decompressed);
}
[Fact]
public void Lzw_Reader_Factory_Detects_Plain_Z_File()
{
// Test that ReaderFactory correctly identifies a plain .Z file (not tar-wrapped)
using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "large_test.txt.Z"));
using var reader = ReaderFactory.OpenReader(stream);
// Should detect as Lzw archive (not Tar)
Assert.Equal(ArchiveType.Lzw, reader.ArchiveType);
Assert.True(reader.MoveToNextEntry());
Assert.NotNull(reader.Entry);
Assert.Equal(CompressionType.Lzw, reader.Entry.CompressionType);
// When opened via ReaderFactory with a non-FileStream, key defaults to "data"
Assert.NotNull(reader.Entry.Key);
}
}

Binary file not shown.