mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-12 05:25:03 +00:00
Compare commits
5 Commits
0.45.1
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89420d43cf | ||
|
|
0696bf5efc | ||
|
|
3ad39f96da | ||
|
|
649729d520 | ||
|
|
31ed7b822e |
@@ -112,16 +112,149 @@ public class TarFactory
|
||||
#region IArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.OpenArchive(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
readerOptions ??= new ReaderOptions();
|
||||
|
||||
// Try to detect compressed TAR formats
|
||||
// For async-only streams, skip detection and assume uncompressed
|
||||
bool canDoSyncDetection = true;
|
||||
try
|
||||
{
|
||||
// Test if we can do synchronous reads
|
||||
var testBuffer = new byte[1];
|
||||
var pos = stream.Position;
|
||||
stream.Read(testBuffer, 0, 0); // Try a zero-length read
|
||||
stream.Position = pos;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
// Stream doesn't support synchronous reads
|
||||
canDoSyncDetection = false;
|
||||
}
|
||||
|
||||
if (!canDoSyncDetection)
|
||||
{
|
||||
// For async-only streams, we can't do format detection
|
||||
// Assume it's an uncompressed TAR
|
||||
return TarArchive.OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
var sharpCompressStream = new SharpCompressStream(stream);
|
||||
sharpCompressStream.StartRecording();
|
||||
|
||||
foreach (var wrapper in TarWrapper.Wrappers)
|
||||
{
|
||||
sharpCompressStream.Rewind();
|
||||
if (wrapper.IsMatch(sharpCompressStream))
|
||||
{
|
||||
sharpCompressStream.Rewind();
|
||||
var decompressedStream = wrapper.CreateStream(sharpCompressStream);
|
||||
if (TarArchive.IsTarFile(decompressedStream))
|
||||
{
|
||||
sharpCompressStream.StopRecording();
|
||||
|
||||
// For compressed TAR files, we need to decompress to a seekable stream
|
||||
// since Archive API requires seekable streams
|
||||
if (wrapper.CompressionType != CompressionType.None)
|
||||
{
|
||||
// Rewind and create a fresh decompression stream
|
||||
sharpCompressStream.Rewind();
|
||||
decompressedStream = wrapper.CreateStream(sharpCompressStream);
|
||||
|
||||
// Decompress to a MemoryStream to make it seekable
|
||||
var memoryStream = new MemoryStream();
|
||||
decompressedStream.CopyTo(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
// If we shouldn't leave the stream open, close the original
|
||||
if (!readerOptions.LeaveStreamOpen)
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
// Open the decompressed TAR with LeaveStreamOpen = false
|
||||
// so the MemoryStream gets cleaned up with the archive
|
||||
return TarArchive.OpenArchive(
|
||||
memoryStream,
|
||||
readerOptions with
|
||||
{
|
||||
LeaveStreamOpen = false,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// For uncompressed TAR, use the original stream directly
|
||||
sharpCompressStream.Rewind();
|
||||
return TarArchive.OpenArchive(stream, readerOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: try opening as uncompressed TAR
|
||||
sharpCompressStream.StopRecording();
|
||||
return TarArchive.OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.OpenArchive(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
readerOptions ??= new ReaderOptions();
|
||||
|
||||
// Open the file and check if it's compressed
|
||||
using var testStream = fileInfo.OpenRead();
|
||||
var sharpCompressStream = new SharpCompressStream(testStream);
|
||||
sharpCompressStream.StartRecording();
|
||||
|
||||
foreach (var wrapper in TarWrapper.Wrappers)
|
||||
{
|
||||
sharpCompressStream.Rewind();
|
||||
if (wrapper.IsMatch(sharpCompressStream))
|
||||
{
|
||||
sharpCompressStream.Rewind();
|
||||
var decompressedStream = wrapper.CreateStream(sharpCompressStream);
|
||||
if (TarArchive.IsTarFile(decompressedStream))
|
||||
{
|
||||
sharpCompressStream.StopRecording();
|
||||
|
||||
// For compressed TAR files, decompress to memory
|
||||
if (wrapper.CompressionType != CompressionType.None)
|
||||
{
|
||||
// Reopen file and decompress
|
||||
using var fileStream = fileInfo.OpenRead();
|
||||
var compressedStream = new SharpCompressStream(fileStream);
|
||||
compressedStream.StartRecording();
|
||||
var decompStream = wrapper.CreateStream(compressedStream);
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
decompStream.CopyTo(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
// Open with LeaveStreamOpen = false so MemoryStream gets cleaned up
|
||||
return TarArchive.OpenArchive(
|
||||
memoryStream,
|
||||
readerOptions with
|
||||
{
|
||||
LeaveStreamOpen = false,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Uncompressed, can use TarArchive's FileInfo overload directly
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Open as regular TAR file
|
||||
return TarArchive.OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -308,4 +308,39 @@ public class TarArchiveTests : ArchiveTests
|
||||
|
||||
Assert.False(isTar);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Tar.tar.gz")]
|
||||
[InlineData("Tar.tar.bz2")]
|
||||
[InlineData("Tar.tar.xz")]
|
||||
[InlineData("Tar.tar.lz")]
|
||||
[InlineData("Tar.tar.zst")]
|
||||
[InlineData("Tar.tar.Z")]
|
||||
[InlineData("Tar.oldgnu.tar.gz")]
|
||||
[InlineData("TarWithSymlink.tar.gz")]
|
||||
public void Tar_Compressed_Archive_Factory(string filename)
|
||||
{
|
||||
var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, filename);
|
||||
using Stream stream = File.OpenRead(archiveFullPath);
|
||||
using var archive = ArchiveFactory.OpenArchive(stream);
|
||||
Assert.True(archive.Type == ArchiveType.Tar);
|
||||
Assert.True(archive.Entries.Any());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Tar.tar.gz")]
|
||||
[InlineData("Tar.tar.bz2")]
|
||||
[InlineData("Tar.tar.xz")]
|
||||
[InlineData("Tar.tar.lz")]
|
||||
[InlineData("Tar.tar.zst")]
|
||||
[InlineData("Tar.tar.Z")]
|
||||
[InlineData("Tar.oldgnu.tar.gz")]
|
||||
[InlineData("TarWithSymlink.tar.gz")]
|
||||
public void Tar_Compressed_Archive_Factory_FromFile(string filename)
|
||||
{
|
||||
var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, filename);
|
||||
using var archive = ArchiveFactory.OpenArchive(archiveFullPath);
|
||||
Assert.True(archive.Type == ArchiveType.Tar);
|
||||
Assert.True(archive.Entries.Any());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user