Merge branch 'master' into adam/xz-wrapped-often

This commit is contained in:
Adam Hathcock
2025-10-22 10:22:36 +01:00
committed by GitHub
10 changed files with 91 additions and 46 deletions

View File

@@ -144,6 +144,12 @@ public abstract class AbstractArchive<TEntry, TVolume> : IArchive, IArchiveExtra
/// <returns></returns>
public IReader ExtractAllEntries()
{
if (!IsSolid && Type != ArchiveType.SevenZip)
{
throw new InvalidOperationException(
"ExtractAllEntries can only be used on solid archives or 7Zip archives (which require random access)."
);
}
((IArchiveExtractionListener)this).EnsureEntriesLoaded();
return CreateReaderForSolidExtraction();
}

View File

@@ -45,12 +45,10 @@ public static class IArchiveExtensions
var seenDirectories = new HashSet<string>();
// Extract
var entries = archive.ExtractAllEntries();
while (entries.MoveToNextEntry())
foreach (var entry in archive.Entries)
{
cancellationToken.ThrowIfCancellationRequested();
var entry = entries.Entry;
if (entry.IsDirectory)
{
var dirPath = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
@@ -77,7 +75,7 @@ public static class IArchiveExtensions
// Write file
using var fs = File.OpenWrite(path);
entries.WriteEntryTo(fs);
entry.WriteTo(fs);
// Update progress
bytesRead += entry.Size;

View File

@@ -1028,7 +1028,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
vmCode.Add((byte)(GetBits() >> 8));
AddBits(8);
}
return (AddVMCode(FirstByte, vmCode, Length));
return AddVMCode(FirstByte, vmCode);
}
private bool ReadVMCodePPM()
@@ -1073,10 +1073,10 @@ internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
}
vmCode.Add((byte)Ch); // VMCode[I]=Ch;
}
return (AddVMCode(FirstByte, vmCode, Length));
return AddVMCode(FirstByte, vmCode);
}
private bool AddVMCode(int firstByte, List<byte> vmCode, int length)
private bool AddVMCode(int firstByte, List<byte> vmCode)
{
var Inp = new BitInput();
Inp.InitBitInput();
@@ -1199,19 +1199,28 @@ internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
{
return (false);
}
Span<byte> VMCode = stackalloc byte[VMCodeSize];
for (var I = 0; I < VMCodeSize; I++)
{
if (Inp.Overflow(3))
{
return (false);
}
VMCode[I] = (byte)(Inp.GetBits() >> 8);
Inp.AddBits(8);
}
// VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
rarVM.prepare(VMCode, VMCodeSize, Filter.Program);
var VMCode = ArrayPool<byte>.Shared.Rent(VMCodeSize);
try
{
for (var I = 0; I < VMCodeSize; I++)
{
if (Inp.Overflow(3))
{
return (false);
}
VMCode[I] = (byte)(Inp.GetBits() >> 8);
Inp.AddBits(8);
}
// VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
rarVM.prepare(VMCode.AsSpan(0, VMCodeSize), Filter.Program);
}
finally
{
ArrayPool<byte>.Shared.Return(VMCode);
}
}
StackFilter.Program.AltCommands = Filter.Program.Commands; // StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
StackFilter.Program.CommandCount = Filter.Program.CommandCount;

View File

@@ -776,9 +776,10 @@ internal sealed class RarVM : BitInput
}
}
public void prepare(ReadOnlySpan<byte> code, int codeSize, VMPreparedProgram prg)
public void prepare(ReadOnlySpan<byte> code, VMPreparedProgram prg)
{
InitBitInput();
var codeSize = code.Length;
var cpLength = Math.Min(MAX_SIZE, codeSize);
// memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
@@ -795,7 +796,7 @@ internal sealed class RarVM : BitInput
prg.CommandCount = 0;
if (xorSum == code[0])
{
var filterType = IsStandardFilter(code, codeSize);
var filterType = IsStandardFilter(code);
if (filterType != VMStandardFilters.VMSF_NONE)
{
var curCmd = new VMPreparedCommand();
@@ -1105,7 +1106,7 @@ internal sealed class RarVM : BitInput
}
}
private VMStandardFilters IsStandardFilter(ReadOnlySpan<byte> code, int codeSize)
private VMStandardFilters IsStandardFilter(ReadOnlySpan<byte> code)
{
VMStandardFilterSignature[] stdList =
{

View File

@@ -40,6 +40,29 @@ public abstract class RarReader : AbstractReader<RarReaderEntry, RarVolume>
public override RarVolume? Volume => volume;
public static RarReader Open(string filePath, ReaderOptions? options = null)
{
filePath.CheckNotNullOrEmpty(nameof(filePath));
return Open(new FileInfo(filePath), options);
}
public static RarReader Open(FileInfo fileInfo, ReaderOptions? options = null)
{
options ??= new ReaderOptions { LeaveStreamOpen = false };
return Open(fileInfo.OpenRead(), options);
}
public static RarReader Open(IEnumerable<string> filePaths, ReaderOptions? options = null)
{
return Open(filePaths.Select(x => new FileInfo(x)), options);
}
public static RarReader Open(IEnumerable<FileInfo> fileInfos, ReaderOptions? options = null)
{
options ??= new ReaderOptions { LeaveStreamOpen = false };
return Open(fileInfos.Select(x => x.OpenRead()), options);
}
/// <summary>
/// Opens a RarReader for Non-seeking usage with a single volume
/// </summary>

View File

@@ -9,6 +9,18 @@ namespace SharpCompress.Readers;
public static class ReaderFactory
{
public static IReader Open(string filePath, ReaderOptions? options = null)
{
filePath.CheckNotNullOrEmpty(nameof(filePath));
return Open(new FileInfo(filePath), options);
}
public static IReader Open(FileInfo fileInfo, ReaderOptions? options = null)
{
options ??= new ReaderOptions { LeaveStreamOpen = false };
return Open(fileInfo.OpenRead(), options);
}
/// <summary>
/// Opens a Reader for Non-seeking usage
/// </summary>