mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-09 02:26:47 +00:00
Let dotnet format do it’s thing
This commit is contained in:
@@ -13,7 +13,7 @@ class Program
|
||||
private const string Build = "build";
|
||||
private const string Test = "test";
|
||||
private const string Publish = "publish";
|
||||
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Target(Clean,
|
||||
@@ -46,17 +46,17 @@ class Program
|
||||
Run("dotnet", "format --check");
|
||||
});
|
||||
|
||||
Target(Build, DependsOn(Format), ForEach("net46", "netstandard2.0", "netstandard2.1"),
|
||||
Target(Build, DependsOn(Format), ForEach("net46", "netstandard2.0", "netstandard2.1"),
|
||||
framework =>
|
||||
{
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && framework == "net46")
|
||||
{
|
||||
return;
|
||||
}
|
||||
Run("dotnet", "build src/SharpCompress/SharpCompress.csproj -c Release");
|
||||
});
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && framework == "net46")
|
||||
{
|
||||
return;
|
||||
}
|
||||
Run("dotnet", "build src/SharpCompress/SharpCompress.csproj -c Release");
|
||||
});
|
||||
|
||||
Target(Test, DependsOn(Build), ForEach("netcoreapp3.1"),
|
||||
Target(Test, DependsOn(Build), ForEach("netcoreapp3.1"),
|
||||
framework =>
|
||||
{
|
||||
IEnumerable<string> GetFiles(string d)
|
||||
@@ -69,7 +69,7 @@ class Program
|
||||
Run("dotnet", $"test {file} -c Release -f {framework}");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Target(Publish, DependsOn(Test),
|
||||
() =>
|
||||
{
|
||||
@@ -77,7 +77,7 @@ class Program
|
||||
});
|
||||
|
||||
Target("default", DependsOn(Publish), () => Console.WriteLine("Done!"));
|
||||
|
||||
|
||||
RunTargetsAndExit(args);
|
||||
}
|
||||
}
|
||||
@@ -132,9 +132,9 @@ namespace SharpCompress.Archives
|
||||
void IExtractionListener.FireFilePartExtractionBegin(string name, long size, long compressedSize)
|
||||
{
|
||||
FilePartExtractionBegin?.Invoke(this, new FilePartExtractionBeginEventArgs(
|
||||
compressedSize : compressedSize,
|
||||
size : size,
|
||||
name : name
|
||||
compressedSize: compressedSize,
|
||||
size: size,
|
||||
name: name
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SharpCompress.Archives
|
||||
where TEntry : IArchiveEntry
|
||||
where TVolume : IVolume
|
||||
{
|
||||
private class RebuildPauseDisposable: IDisposable
|
||||
private class RebuildPauseDisposable : IDisposable
|
||||
{
|
||||
private readonly AbstractWritableArchive<TEntry, TVolume> archive;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace SharpCompress.Archives
|
||||
}
|
||||
streamListener.FireEntryExtractionEnd(archiveEntry);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Extract to specific directory, retaining filename
|
||||
/// </summary>
|
||||
@@ -45,11 +45,11 @@ namespace SharpCompress.Archives
|
||||
/// <summary>
|
||||
/// Extract to specific file
|
||||
/// </summary>
|
||||
public static void WriteToFile(this IArchiveEntry entry,
|
||||
public static void WriteToFile(this IArchiveEntry entry,
|
||||
string destinationFileName,
|
||||
ExtractionOptions? options = null)
|
||||
{
|
||||
|
||||
|
||||
ExtractionMethods.WriteEntryToFile(entry, destinationFileName, options,
|
||||
(x, fm) =>
|
||||
{
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace SharpCompress.Archives.Rar
|
||||
return IsRarFile(stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool IsRarFile(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -61,16 +61,16 @@ namespace SharpCompress.Archives.Rar
|
||||
{
|
||||
return new RarStream(archive.UnpackV1.Value, FileHeader, new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive));
|
||||
}
|
||||
|
||||
|
||||
return new RarStream(archive.UnpackV2017.Value, FileHeader, new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive));
|
||||
}
|
||||
|
||||
public bool IsComplete
|
||||
{
|
||||
get
|
||||
{
|
||||
return parts.Select(fp => fp.FileHeader).Any(fh => !fh.IsSplitAfter);
|
||||
}
|
||||
public bool IsComplete
|
||||
{
|
||||
get
|
||||
{
|
||||
return parts.Select(fp => fp.FileHeader).Any(fh => !fh.IsSplitAfter);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckIncomplete()
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace SharpCompress.Archives.Rar
|
||||
yield return part;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal static IEnumerable<RarVolume> GetParts(FileInfo fileInfo, ReaderOptions options)
|
||||
{
|
||||
FileInfoRarArchiveVolume part = new FileInfoRarArchiveVolume(fileInfo, options);
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace SharpCompress.Archives.SevenZip
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> SIGNATURE => new byte[] {(byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
private static ReadOnlySpan<byte> SIGNATURE => new byte[] { (byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C };
|
||||
|
||||
private static bool SignatureMatch(Stream stream)
|
||||
{
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace SharpCompress.Archives.Tar
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with a FileInfo object to an existing file.
|
||||
/// </summary>
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace SharpCompress.Archives.Zip
|
||||
/// if the compression method is set to deflate
|
||||
/// </summary>
|
||||
public CompressionLevel DeflateCompressionLevel { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor expects a filepath to an existing file.
|
||||
/// </summary>
|
||||
@@ -57,7 +57,7 @@ namespace SharpCompress.Archives.Zip
|
||||
stream.CheckNotNull(nameof(stream));
|
||||
return new ZipArchive(stream, readerOptions ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
|
||||
public static bool IsZipFile(string filePath, string? password = null)
|
||||
{
|
||||
return IsZipFile(new FileInfo(filePath), password);
|
||||
@@ -97,7 +97,7 @@ namespace SharpCompress.Archives.Zip
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with a FileInfo object to an existing file.
|
||||
/// </summary>
|
||||
|
||||
@@ -47,7 +47,8 @@ namespace SharpCompress.Common
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override void Flush() {
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public override long Length => _stream.Length;
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace SharpCompress.Common
|
||||
/// <summary>
|
||||
/// Extract to specific directory, retaining filename
|
||||
/// </summary>
|
||||
public static void WriteEntryToDirectory(IEntry entry,
|
||||
public static void WriteEntryToDirectory(IEntry entry,
|
||||
string destinationDirectory,
|
||||
ExtractionOptions? options,
|
||||
ExtractionOptions? options,
|
||||
Action<string, ExtractionOptions?> write)
|
||||
{
|
||||
string destinationFileName;
|
||||
@@ -18,9 +18,9 @@ namespace SharpCompress.Common
|
||||
string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory);
|
||||
|
||||
options ??= new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
if (options.ExtractFullPath)
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace SharpCompress.Common
|
||||
destinationFileName = Path.Combine(destdir, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
destinationFileName = Path.Combine(fullDestinationDirectoryPath, file);
|
||||
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace SharpCompress.Common
|
||||
Directory.CreateDirectory(destinationFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void WriteEntryToFile(IEntry entry, string destinationFileName,
|
||||
ExtractionOptions? options,
|
||||
Action<string, FileMode> openAndWrite)
|
||||
@@ -76,9 +76,9 @@ namespace SharpCompress.Common
|
||||
{
|
||||
FileMode fm = FileMode.Create;
|
||||
options ??= new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
if (!options.Overwrite)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Common
|
||||
/// <summary>
|
||||
/// overwrite target if it exists
|
||||
/// </summary>
|
||||
public bool Overwrite {get; set; }
|
||||
public bool Overwrite { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// extract with internal directory structure
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
internal class AvHeader : RarHeader
|
||||
{
|
||||
public AvHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Av)
|
||||
public AvHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Av)
|
||||
{
|
||||
if (IsRar5)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
internal class ArchiveCryptHeader : RarHeader
|
||||
{
|
||||
|
||||
|
||||
private const int CRYPT_VERSION = 0; // Supported encryption version.
|
||||
private const int SIZE_SALT50 = 16;
|
||||
private const int SIZE_SALT30 = 8;
|
||||
@@ -15,14 +15,14 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
private const int SIZE_PSWCHECK_CSUM = 4;
|
||||
private const int CRYPT5_KDF_LG2_COUNT = 15; // LOG2 of PDKDF2 iteration count.
|
||||
private const int CRYPT5_KDF_LG2_COUNT_MAX = 24; // LOG2 of maximum accepted iteration count.
|
||||
|
||||
|
||||
|
||||
|
||||
private bool _usePswCheck;
|
||||
private uint _lg2Count; // Log2 of PBKDF2 repetition count.
|
||||
private byte[] _salt;
|
||||
private byte[] _pswCheck;
|
||||
private byte[] _pswCheckCsm;
|
||||
|
||||
|
||||
public ArchiveCryptHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Crypt)
|
||||
{
|
||||
@@ -35,12 +35,12 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
//error?
|
||||
return;
|
||||
}
|
||||
}
|
||||
var encryptionFlags = reader.ReadRarVIntUInt32();
|
||||
_usePswCheck = FlagUtility.HasFlag(encryptionFlags, EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
|
||||
_lg2Count = reader.ReadRarVIntByte(1);
|
||||
|
||||
|
||||
|
||||
//UsePswCheck = HasHeaderFlag(EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
|
||||
if (_lg2Count > CRYPT5_KDF_LG2_COUNT_MAX)
|
||||
{
|
||||
|
||||
@@ -4,14 +4,14 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
internal sealed class ArchiveHeader : RarHeader
|
||||
{
|
||||
public ArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Archive)
|
||||
public ArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Archive)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
if (IsRar5)
|
||||
{
|
||||
Flags = reader.ReadRarVIntUInt16();
|
||||
if (HasFlag(ArchiveFlagsV5.HAS_VOLUME_NUMBER))
|
||||
@@ -22,8 +22,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
//if (ExtraSize != 0) {
|
||||
// ReadLocator(reader);
|
||||
//}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags = HeaderFlags;
|
||||
HighPosAv = reader.ReadInt16();
|
||||
@@ -35,7 +35,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadLocator(MarkingBinaryReader reader) {
|
||||
private void ReadLocator(MarkingBinaryReader reader)
|
||||
{
|
||||
var size = reader.ReadRarVIntUInt16();
|
||||
var type = reader.ReadRarVIntUInt16();
|
||||
if (type != 1)
|
||||
@@ -47,18 +48,20 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
const ushort hasQuickOpenOffset = 0x01;
|
||||
const ushort hasRecoveryOffset = 0x02;
|
||||
ulong quickOpenOffset = 0;
|
||||
if ((flags & hasQuickOpenOffset) == hasQuickOpenOffset) {
|
||||
if ((flags & hasQuickOpenOffset) == hasQuickOpenOffset)
|
||||
{
|
||||
quickOpenOffset = reader.ReadRarVInt();
|
||||
}
|
||||
ulong recoveryOffset = 0;
|
||||
if ((flags & hasRecoveryOffset) == hasRecoveryOffset) {
|
||||
if ((flags & hasRecoveryOffset) == hasRecoveryOffset)
|
||||
{
|
||||
recoveryOffset = reader.ReadRarVInt();
|
||||
}
|
||||
}
|
||||
|
||||
private ushort Flags { get; set; }
|
||||
private ushort Flags { get; set; }
|
||||
|
||||
private bool HasFlag(ushort flag)
|
||||
private bool HasFlag(ushort flag)
|
||||
{
|
||||
return (Flags & flag) == flag;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
internal class CommentHeader : RarHeader
|
||||
{
|
||||
protected CommentHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Comment)
|
||||
{
|
||||
: base(header, reader, HeaderType.Comment)
|
||||
{
|
||||
if (IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
|
||||
@@ -4,14 +4,14 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
internal class EndArchiveHeader : RarHeader
|
||||
{
|
||||
public EndArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.EndArchive)
|
||||
public EndArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.EndArchive)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
if (IsRar5)
|
||||
{
|
||||
Flags = reader.ReadRarVIntUInt16();
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
private ushort Flags { get; set; }
|
||||
|
||||
private bool HasFlag(ushort flag)
|
||||
private bool HasFlag(ushort flag)
|
||||
{
|
||||
return (Flags & flag) == flag;
|
||||
}
|
||||
|
||||
@@ -21,18 +21,18 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
private uint _fileCrc;
|
||||
|
||||
public FileHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
|
||||
: base(header, reader, headerType)
|
||||
public FileHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
|
||||
: base(header, reader, headerType)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
if (IsRar5)
|
||||
{
|
||||
ReadFromReaderV5(reader);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadFromReaderV4(reader);
|
||||
}
|
||||
@@ -49,11 +49,13 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
FileAttributes = reader.ReadRarVIntUInt32();
|
||||
|
||||
if (HasFlag(FileFlagsV5.HAS_MOD_TIME)) {
|
||||
if (HasFlag(FileFlagsV5.HAS_MOD_TIME))
|
||||
{
|
||||
FileLastModifiedTime = Utility.UnixTimeToDateTime(reader.ReadUInt32());
|
||||
}
|
||||
|
||||
if (HasFlag(FileFlagsV5.HAS_CRC32)) {
|
||||
if (HasFlag(FileFlagsV5.HAS_CRC32))
|
||||
{
|
||||
FileCrc = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
@@ -65,7 +67,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
// but it was already used in RAR 1.5 and Unpack needs to distinguish
|
||||
// them.
|
||||
CompressionAlgorithm = (byte)((compressionInfo & 0x3f) + 50);
|
||||
|
||||
|
||||
// 7th bit (0x0040) defines the solid flag. If it is set, RAR continues to use the compression dictionary left after processing preceding files.
|
||||
// It can be set only for file headers and is never set for service headers.
|
||||
IsSolid = (compressionInfo & 0x40) == 0x40;
|
||||
@@ -74,7 +76,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
CompressionMethod = (byte)((compressionInfo >> 7) & 0x7);
|
||||
|
||||
// Bits 11 - 14 (0x3c00) define the minimum size of dictionary size required to extract data. Value 0 means 128 KB, 1 - 256 KB, ..., 14 - 2048 MB, 15 - 4096 MB.
|
||||
WindowSize = IsDirectory ? 0 : ((size_t)0x20000) << ((compressionInfo>>10) & 0xf);
|
||||
WindowSize = IsDirectory ? 0 : ((size_t)0x20000) << ((compressionInfo >> 10) & 0xf);
|
||||
|
||||
HostOs = reader.ReadRarVIntByte();
|
||||
|
||||
@@ -101,18 +103,20 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
FileName = ConvertPathV5(Encoding.UTF8.GetString(b, 0, b.Length));
|
||||
|
||||
// extra size seems to be redudant since we know the total header size
|
||||
if (ExtraSize != RemainingHeaderBytes(reader))
|
||||
if (ExtraSize != RemainingHeaderBytes(reader))
|
||||
{
|
||||
throw new InvalidFormatException("rar5 header size / extra size inconsistency");
|
||||
}
|
||||
|
||||
isEncryptedRar5 = false;
|
||||
|
||||
while (RemainingHeaderBytes(reader) > 0) {
|
||||
while (RemainingHeaderBytes(reader) > 0)
|
||||
{
|
||||
var size = reader.ReadRarVIntUInt16();
|
||||
int n = RemainingHeaderBytes(reader);
|
||||
var type = reader.ReadRarVIntUInt16();
|
||||
switch (type) {
|
||||
switch (type)
|
||||
{
|
||||
//TODO
|
||||
case 1: // file encryption
|
||||
{
|
||||
@@ -120,7 +124,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
//var version = reader.ReadRarVIntByte();
|
||||
//if (version != 0) throw new InvalidFormatException("unknown encryption algorithm " + version);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// case 2: // file hash
|
||||
// {
|
||||
@@ -131,38 +135,41 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
ushort flags = reader.ReadRarVIntUInt16();
|
||||
var isWindowsTime = (flags & 1) == 0;
|
||||
if ((flags & 0x2) == 0x2) {
|
||||
if ((flags & 0x2) == 0x2)
|
||||
{
|
||||
FileLastModifiedTime = ReadExtendedTimeV5(reader, isWindowsTime);
|
||||
}
|
||||
if ((flags & 0x4) == 0x4) {
|
||||
if ((flags & 0x4) == 0x4)
|
||||
{
|
||||
FileCreatedTime = ReadExtendedTimeV5(reader, isWindowsTime);
|
||||
}
|
||||
if ((flags & 0x8) == 0x8) {
|
||||
if ((flags & 0x8) == 0x8)
|
||||
{
|
||||
FileLastAccessedTime = ReadExtendedTimeV5(reader, isWindowsTime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//TODO
|
||||
// case 4: // file version
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
// case 5: // file system redirection
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
// case 6: // unix owner
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
// case 7: // service data
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
//TODO
|
||||
// case 4: // file version
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
// case 5: // file system redirection
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
// case 6: // unix owner
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
// case 7: // service data
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
|
||||
default:
|
||||
// skip unknown record types to allow new record types to be added in the future
|
||||
@@ -171,25 +178,26 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
// drain any trailing bytes of extra record
|
||||
int did = n - RemainingHeaderBytes(reader);
|
||||
int drain = size - did;
|
||||
if (drain > 0)
|
||||
if (drain > 0)
|
||||
{
|
||||
reader.ReadBytes(drain);
|
||||
}
|
||||
}
|
||||
|
||||
if (AdditionalDataSize != 0) {
|
||||
if (AdditionalDataSize != 0)
|
||||
{
|
||||
CompressedSize = AdditionalDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static DateTime ReadExtendedTimeV5(MarkingBinaryReader reader, bool isWindowsTime)
|
||||
private static DateTime ReadExtendedTimeV5(MarkingBinaryReader reader, bool isWindowsTime)
|
||||
{
|
||||
if (isWindowsTime)
|
||||
if (isWindowsTime)
|
||||
{
|
||||
return DateTime.FromFileTime(reader.ReadInt64());
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
return Utility.UnixTimeToDateTime(reader.ReadUInt32());
|
||||
}
|
||||
@@ -201,7 +209,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
// replace embedded \\ with valid filename char
|
||||
return path.Replace('\\', '-').Replace('/', '\\');
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -376,20 +384,22 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
private ushort Flags { get; set; }
|
||||
|
||||
private bool HasFlag(ushort flag)
|
||||
private bool HasFlag(ushort flag)
|
||||
{
|
||||
return (Flags & flag) == flag;
|
||||
}
|
||||
|
||||
internal uint FileCrc
|
||||
{
|
||||
get {
|
||||
if (IsRar5 && !HasFlag(FileFlagsV5.HAS_CRC32)) {
|
||||
//!!! rar5:
|
||||
internal uint FileCrc
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsRar5 && !HasFlag(FileFlagsV5.HAS_CRC32))
|
||||
{
|
||||
//!!! rar5:
|
||||
throw new InvalidOperationException("TODO rar5");
|
||||
}
|
||||
return _fileCrc;
|
||||
}
|
||||
return _fileCrc;
|
||||
}
|
||||
private set => _fileCrc = value;
|
||||
}
|
||||
|
||||
@@ -409,7 +419,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
//case 29: // rar 3.x compression
|
||||
//case 50: // RAR 5.0 compression algorithm.
|
||||
internal byte CompressionAlgorithm { get; private set; }
|
||||
|
||||
|
||||
public bool IsSolid { get; private set; }
|
||||
|
||||
// unused for UnpackV1 implementation (limitation)
|
||||
@@ -432,8 +442,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
public bool IsDirectory => HasFlag(IsRar5 ? FileFlagsV5.DIRECTORY : FileFlagsV4.DIRECTORY);
|
||||
|
||||
private bool isEncryptedRar5 = false;
|
||||
public bool IsEncrypted => IsRar5 ? isEncryptedRar5: HasFlag(FileFlagsV4.PASSWORD);
|
||||
|
||||
public bool IsEncrypted => IsRar5 ? isEncryptedRar5 : HasFlag(FileFlagsV4.PASSWORD);
|
||||
|
||||
internal DateTime? FileLastModifiedTime { get; private set; }
|
||||
|
||||
internal DateTime? FileCreatedTime { get; private set; }
|
||||
|
||||
@@ -42,10 +42,10 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
|
||||
internal static class EncryptionFlagsV5
|
||||
{
|
||||
{
|
||||
// RAR 5.0 archive encryption header specific flags.
|
||||
public const uint CHFL_CRYPT_PSWCHECK = 0x01; // Password check data is present.
|
||||
|
||||
|
||||
public const uint FHEXTRA_CRYPT_PSWCHECK = 0x01; // Password check data is present.
|
||||
public const uint FHEXTRA_CRYPT_HASHMAC = 0x02;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
internal interface IRarHeader
|
||||
internal interface IRarHeader
|
||||
{
|
||||
HeaderType HeaderType { get; }
|
||||
}
|
||||
|
||||
@@ -11,39 +11,39 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
public bool IsRar5 { get; }
|
||||
|
||||
private MarkHeader(bool isRar5)
|
||||
{
|
||||
private MarkHeader(bool isRar5)
|
||||
{
|
||||
IsRar5 = isRar5;
|
||||
}
|
||||
|
||||
public HeaderType HeaderType => HeaderType.Mark;
|
||||
|
||||
private static byte GetByte(Stream stream)
|
||||
private static byte GetByte(Stream stream)
|
||||
{
|
||||
var b = stream.ReadByte();
|
||||
if (b != -1)
|
||||
if (b != -1)
|
||||
{
|
||||
return (byte)b;
|
||||
}
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
public static MarkHeader Read(Stream stream, bool leaveStreamOpen, bool lookForHeader)
|
||||
public static MarkHeader Read(Stream stream, bool leaveStreamOpen, bool lookForHeader)
|
||||
{
|
||||
int maxScanIndex = lookForHeader ? MAX_SFX_SIZE : 0;
|
||||
try
|
||||
{
|
||||
int start = -1;
|
||||
var b = GetByte(stream); start++;
|
||||
while (start <= maxScanIndex)
|
||||
while (start <= maxScanIndex)
|
||||
{
|
||||
// Rar old signature: 52 45 7E 5E
|
||||
// Rar4 signature: 52 61 72 21 1A 07 00
|
||||
// Rar5 signature: 52 61 72 21 1A 07 01 00
|
||||
if (b == 0x52)
|
||||
if (b == 0x52)
|
||||
{
|
||||
b = GetByte(stream); start++;
|
||||
if (b == 0x61)
|
||||
if (b == 0x61)
|
||||
{
|
||||
b = GetByte(stream); start++;
|
||||
if (b != 0x72)
|
||||
@@ -70,7 +70,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
|
||||
b = GetByte(stream); start++;
|
||||
if (b == 1)
|
||||
if (b == 1)
|
||||
{
|
||||
b = GetByte(stream); start++;
|
||||
if (b != 0)
|
||||
@@ -79,13 +79,13 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
|
||||
return new MarkHeader(true); // Rar5
|
||||
}
|
||||
else if (b == 0)
|
||||
}
|
||||
else if (b == 0)
|
||||
{
|
||||
return new MarkHeader(false); // Rar4
|
||||
}
|
||||
}
|
||||
else if (b == 0x45)
|
||||
}
|
||||
}
|
||||
else if (b == 0x45)
|
||||
{
|
||||
b = GetByte(stream); start++;
|
||||
if (b != 0x7e)
|
||||
@@ -100,9 +100,9 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
|
||||
throw new InvalidFormatException("Rar format version pre-4 is unsupported.");
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = GetByte(stream); start++;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
internal sealed class NewSubHeaderType : IEquatable<NewSubHeaderType>
|
||||
{
|
||||
internal static readonly NewSubHeaderType SUBHEAD_TYPE_CMT = new ('C', 'M', 'T');
|
||||
internal static readonly NewSubHeaderType SUBHEAD_TYPE_CMT = new('C', 'M', 'T');
|
||||
|
||||
//internal static final NewSubHeaderType SUBHEAD_TYPE_ACL = new (new byte[]{'A','C','L'});
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
//internal static final NewSubHeaderType SUBHEAD_TYPE_AV = new (new byte[]{'A','V'});
|
||||
|
||||
internal static readonly NewSubHeaderType SUBHEAD_TYPE_RR = new ('R', 'R');
|
||||
internal static readonly NewSubHeaderType SUBHEAD_TYPE_RR = new('R', 'R');
|
||||
|
||||
//internal static final NewSubHeaderType SUBHEAD_TYPE_OS2EA = new (new byte[]{'E','A','2'});
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
// ProtectHeader is part of the Recovery Record feature
|
||||
internal sealed class ProtectHeader : RarHeader
|
||||
{
|
||||
public ProtectHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Protect)
|
||||
public ProtectHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Protect)
|
||||
{
|
||||
if (IsRar5)
|
||||
{
|
||||
|
||||
@@ -23,12 +23,12 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
}
|
||||
|
||||
private RarHeader(RarCrcBinaryReader reader, bool isRar5, ArchiveEncoding archiveEncoding)
|
||||
private RarHeader(RarCrcBinaryReader reader, bool isRar5, ArchiveEncoding archiveEncoding)
|
||||
{
|
||||
_headerType = HeaderType.Null;
|
||||
_isRar5 = isRar5;
|
||||
ArchiveEncoding = archiveEncoding;
|
||||
if (IsRar5)
|
||||
if (IsRar5)
|
||||
{
|
||||
HeaderCrc = reader.ReadUInt32();
|
||||
reader.ResetCrc();
|
||||
@@ -45,7 +45,9 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
{
|
||||
AdditionalDataSize = (long)reader.ReadRarVInt();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Mark();
|
||||
HeaderCrc = reader.ReadUInt16();
|
||||
reader.ResetCrc();
|
||||
@@ -59,7 +61,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
}
|
||||
|
||||
protected RarHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType) {
|
||||
protected RarHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
|
||||
{
|
||||
_headerType = headerType;
|
||||
_isRar5 = header.IsRar5;
|
||||
HeaderCrc = header.HeaderCrc;
|
||||
@@ -80,7 +83,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
VerifyHeaderCrc(reader.GetCrc32());
|
||||
}
|
||||
|
||||
protected int RemainingHeaderBytes(MarkingBinaryReader reader) {
|
||||
protected int RemainingHeaderBytes(MarkingBinaryReader reader)
|
||||
{
|
||||
return checked(HeaderSize - (int)reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
@@ -108,7 +112,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
|
||||
protected ushort HeaderFlags { get; }
|
||||
|
||||
protected bool HasHeaderFlag(ushort flag)
|
||||
protected bool HasHeaderFlag(ushort flag)
|
||||
{
|
||||
return (HeaderFlags & flag) == flag;
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
private RarHeader? TryReadNextHeader(Stream stream)
|
||||
{
|
||||
RarCrcBinaryReader reader;
|
||||
if (!IsEncrypted)
|
||||
if (!IsEncrypted)
|
||||
{
|
||||
reader = new RarCrcBinaryReader(stream);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Options.Password is null)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
case HeaderCodeV.RAR4_ARCHIVE_HEADER:
|
||||
{
|
||||
var ah = new ArchiveHeader(header, reader);
|
||||
if (ah.IsEncrypted == true)
|
||||
if (ah.IsEncrypted == true)
|
||||
{
|
||||
//!!! rar5 we don't know yet
|
||||
IsEncrypted = true;
|
||||
@@ -150,11 +150,11 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
return new EndArchiveHeader(header, reader);
|
||||
}
|
||||
case HeaderCodeV.RAR5_ARCHIVE_ENCRYPTION_HEADER:
|
||||
{
|
||||
var ch = new ArchiveCryptHeader(header, reader);
|
||||
IsEncrypted = true;
|
||||
return ch;
|
||||
}
|
||||
{
|
||||
var ch = new ArchiveCryptHeader(header, reader);
|
||||
IsEncrypted = true;
|
||||
return ch;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new InvalidFormatException("Unknown Rar Header: " + header.HeaderCode);
|
||||
@@ -162,21 +162,26 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
}
|
||||
}
|
||||
|
||||
private void SkipData(FileHeader fh, RarCrcBinaryReader reader) {
|
||||
switch (StreamingMode) {
|
||||
case StreamingMode.Seekable: {
|
||||
fh.DataStartPosition = reader.BaseStream.Position;
|
||||
reader.BaseStream.Position += fh.CompressedSize;
|
||||
}
|
||||
private void SkipData(FileHeader fh, RarCrcBinaryReader reader)
|
||||
{
|
||||
switch (StreamingMode)
|
||||
{
|
||||
case StreamingMode.Seekable:
|
||||
{
|
||||
fh.DataStartPosition = reader.BaseStream.Position;
|
||||
reader.BaseStream.Position += fh.CompressedSize;
|
||||
}
|
||||
break;
|
||||
case StreamingMode.Streaming: {
|
||||
//skip the data because it's useless?
|
||||
reader.BaseStream.Skip(fh.CompressedSize);
|
||||
}
|
||||
case StreamingMode.Streaming:
|
||||
{
|
||||
//skip the data because it's useless?
|
||||
reader.BaseStream.Skip(fh.CompressedSize);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
throw new InvalidFormatException("Invalid StreamingMode");
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new InvalidFormatException("Invalid StreamingMode");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace SharpCompress.Common.Rar.Headers
|
||||
internal class SignHeader : RarHeader
|
||||
{
|
||||
protected SignHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Sign)
|
||||
{
|
||||
: base(header, reader, HeaderType.Sign)
|
||||
{
|
||||
if (IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SharpCompress.Common.Rar
|
||||
/// As the V2017 port isn't complete, add this check to use the legacy Rar code.
|
||||
/// </summary>
|
||||
internal bool IsRarV3 => FileHeader.CompressionAlgorithm == 29 || FileHeader.CompressionAlgorithm == 36;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The File's 32 bit CRC Hash
|
||||
/// </summary>
|
||||
|
||||
@@ -27,13 +27,13 @@ namespace SharpCompress.Common.Rar
|
||||
|
||||
_rijndael = new RijndaelEngine();
|
||||
_aesInitializationVector = new byte[CRYPTO_BLOCK_SIZE];
|
||||
int rawLength = 2*_password.Length;
|
||||
int rawLength = 2 * _password.Length;
|
||||
byte[] rawPassword = new byte[rawLength + 8];
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes(_password);
|
||||
for (int i = 0; i < _password.Length; i++)
|
||||
{
|
||||
rawPassword[i*2] = passwordBytes[i];
|
||||
rawPassword[i*2 + 1] = 0;
|
||||
rawPassword[i * 2] = passwordBytes[i];
|
||||
rawPassword[i * 2 + 1] = 0;
|
||||
}
|
||||
for (int i = 0; i < _salt.Length; i++)
|
||||
{
|
||||
@@ -68,11 +68,11 @@ namespace SharpCompress.Common.Rar
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
aesKey[i*4 + j] = (byte)
|
||||
(((digest[i*4]*0x1000000) & 0xff000000 |
|
||||
(uint) ((digest[i*4 + 1]*0x10000) & 0xff0000) |
|
||||
(uint) ((digest[i*4 + 2]*0x100) & 0xff00) |
|
||||
(uint) (digest[i*4 + 3] & 0xff)) >> (j*8));
|
||||
aesKey[i * 4 + j] = (byte)
|
||||
(((digest[i * 4] * 0x1000000) & 0xff000000 |
|
||||
(uint)((digest[i * 4 + 1] * 0x10000) & 0xff0000) |
|
||||
(uint)((digest[i * 4 + 2] * 0x100) & 0xff00) |
|
||||
(uint)(digest[i * 4 + 3] & 0xff)) >> (j * 8));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,20 +39,20 @@ namespace SharpCompress.Common.Rar
|
||||
switch (header.HeaderType)
|
||||
{
|
||||
case HeaderType.Mark:
|
||||
{
|
||||
lastMarkHeader = (MarkHeader)header;
|
||||
}
|
||||
{
|
||||
lastMarkHeader = (MarkHeader)header;
|
||||
}
|
||||
break;
|
||||
case HeaderType.Archive:
|
||||
{
|
||||
ArchiveHeader = (ArchiveHeader)header;
|
||||
}
|
||||
{
|
||||
ArchiveHeader = (ArchiveHeader)header;
|
||||
}
|
||||
break;
|
||||
case HeaderType.File:
|
||||
{
|
||||
var fh = (FileHeader)header;
|
||||
yield return CreateFilePart(lastMarkHeader!, fh);
|
||||
}
|
||||
{
|
||||
var fh = (FileHeader)header;
|
||||
yield return CreateFilePart(lastMarkHeader!, fh);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
{
|
||||
// v3.13 incorrectly worked with empty folders
|
||||
// v4.07: Loop for skipping empty folders
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
if (folderIndex >= _folders.Count)
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
|
||||
private void WaitAttribute(BlockType attribute)
|
||||
{
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
BlockType? type = ReadId();
|
||||
if (type == attribute)
|
||||
@@ -452,7 +452,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#endif
|
||||
|
||||
BlockType? type;
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
type = ReadId();
|
||||
if (type == BlockType.End)
|
||||
@@ -508,7 +508,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
int index = 0;
|
||||
for (int i = 0; i < numFolders; i++)
|
||||
{
|
||||
var f = new CFolder {_firstPackStreamId = index};
|
||||
var f = new CFolder { _firstPackStreamId = index };
|
||||
folders.Add(f);
|
||||
GetNextFolderItem(f);
|
||||
index += f._packStreams.Count;
|
||||
@@ -539,7 +539,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#endif
|
||||
}
|
||||
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
BlockType? type = ReadId();
|
||||
if (type == BlockType.End)
|
||||
@@ -580,7 +580,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
numUnpackStreamsInFolders = null;
|
||||
|
||||
BlockType? type;
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
type = ReadId();
|
||||
if (type == BlockType.NumUnpackStream)
|
||||
@@ -672,7 +672,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
|
||||
digests = null;
|
||||
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
if (type == BlockType.Crc)
|
||||
{
|
||||
@@ -755,7 +755,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
unpackSizes = null;
|
||||
digests = null;
|
||||
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
switch (ReadId())
|
||||
{
|
||||
@@ -926,7 +926,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
BitVector antiFileVector = null;
|
||||
int numEmptyStreams = 0;
|
||||
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
type = ReadId();
|
||||
if (type == BlockType.End)
|
||||
@@ -961,7 +961,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#if DEBUG
|
||||
Log.Write("WinAttributes:");
|
||||
#endif
|
||||
ReadAttributeVector(dataVector, numFiles, delegate(int i, uint? attr)
|
||||
ReadAttributeVector(dataVector, numFiles, delegate (int i, uint? attr)
|
||||
{
|
||||
// Some third party implementations established an unofficial extension
|
||||
// of the 7z archive format by placing posix file attributes in the high
|
||||
@@ -1049,7 +1049,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#if DEBUG
|
||||
Log.Write("StartPos:");
|
||||
#endif
|
||||
ReadNumberVector(dataVector, numFiles, delegate(int i, long? startPos)
|
||||
ReadNumberVector(dataVector, numFiles, delegate (int i, long? startPos)
|
||||
{
|
||||
db._files[i].StartPos = startPos;
|
||||
#if DEBUG
|
||||
@@ -1064,7 +1064,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#if DEBUG
|
||||
Log.Write("CTime:");
|
||||
#endif
|
||||
ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time)
|
||||
ReadDateTimeVector(dataVector, numFiles, delegate (int i, DateTime? time)
|
||||
{
|
||||
db._files[i].CTime = time;
|
||||
#if DEBUG
|
||||
@@ -1079,7 +1079,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#if DEBUG
|
||||
Log.Write("ATime:");
|
||||
#endif
|
||||
ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time)
|
||||
ReadDateTimeVector(dataVector, numFiles, delegate (int i, DateTime? time)
|
||||
{
|
||||
db._files[i].ATime = time;
|
||||
#if DEBUG
|
||||
@@ -1094,7 +1094,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
#if DEBUG
|
||||
Log.Write("MTime:");
|
||||
#endif
|
||||
ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time)
|
||||
ReadDateTimeVector(dataVector, numFiles, delegate (int i, DateTime? time)
|
||||
{
|
||||
db._files[i].MTime = time;
|
||||
#if DEBUG
|
||||
@@ -1485,7 +1485,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
int numItems = allFilesMode
|
||||
? db._files.Count
|
||||
: indices.Length;
|
||||
|
||||
|
||||
if (numItems == 0)
|
||||
{
|
||||
return;
|
||||
@@ -1554,7 +1554,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
Stream s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes,
|
||||
folderInfo, db.PasswordProvider);
|
||||
byte[] buffer = new byte[4 << 10];
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
int processed = s.Read(buffer, 0, buffer.Length);
|
||||
if (processed == 0)
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
{
|
||||
int ending = Offset;
|
||||
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
if (ending + 2 > _ending)
|
||||
{
|
||||
|
||||
@@ -84,20 +84,20 @@ namespace SharpCompress.Common.SevenZip
|
||||
{
|
||||
var coder = Folder!._coders.First();
|
||||
switch (coder._methodId._id)
|
||||
{
|
||||
{
|
||||
case K_LZMA:
|
||||
case K_LZMA2:
|
||||
{
|
||||
return CompressionType.LZMA;
|
||||
}
|
||||
{
|
||||
return CompressionType.LZMA;
|
||||
}
|
||||
case K_PPMD:
|
||||
{
|
||||
return CompressionType.PPMd;
|
||||
}
|
||||
{
|
||||
return CompressionType.PPMd;
|
||||
}
|
||||
case K_B_ZIP2:
|
||||
{
|
||||
return CompressionType.BZip2;
|
||||
}
|
||||
{
|
||||
return CompressionType.BZip2;
|
||||
}
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -261,9 +261,9 @@ namespace SharpCompress.Common.Tar.Headers
|
||||
}
|
||||
|
||||
|
||||
private static readonly byte[] eightSpaces = {
|
||||
private static readonly byte[] eightSpaces = {
|
||||
(byte)' ', (byte)' ', (byte)' ', (byte)' ',
|
||||
(byte)' ', (byte)' ', (byte)' ', (byte)' '
|
||||
(byte)' ', (byte)' ', (byte)' ', (byte)' '
|
||||
};
|
||||
|
||||
internal static int RecalculateChecksum(byte[] buf)
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
byte[] name = reader.ReadBytes(nameLength);
|
||||
byte[] extra = reader.ReadBytes(extraLength);
|
||||
byte[] comment = reader.ReadBytes(commentLength);
|
||||
|
||||
|
||||
// According to .ZIP File Format Specification
|
||||
//
|
||||
// For example: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
|
||||
@@ -40,7 +40,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
// Bit 11: Language encoding flag (EFS). If this bit is set,
|
||||
// the filename and comment fields for this file
|
||||
// MUST be encoded using UTF-8. (see APPENDIX D)
|
||||
|
||||
|
||||
if (Flags.HasFlag(HeaderFlags.Efs))
|
||||
{
|
||||
Name = ArchiveEncoding.DecodeUTF8(name);
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
ushort extraLength = reader.ReadUInt16();
|
||||
byte[] name = reader.ReadBytes(nameLength);
|
||||
byte[] extra = reader.ReadBytes(extraLength);
|
||||
|
||||
|
||||
// According to .ZIP File Format Specification
|
||||
//
|
||||
// For example: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
|
||||
@@ -32,7 +32,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
// Bit 11: Language encoding flag (EFS). If this bit is set,
|
||||
// the filename and comment fields for this file
|
||||
// MUST be encoded using UTF-8. (see APPENDIX D)
|
||||
|
||||
|
||||
if (Flags.HasFlag(HeaderFlags.Efs))
|
||||
{
|
||||
Name = ArchiveEncoding.DecodeUTF8(name);
|
||||
@@ -41,7 +41,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
{
|
||||
Name = ArchiveEncoding.Decode(name);
|
||||
}
|
||||
|
||||
|
||||
LoadExtra(extra);
|
||||
|
||||
var unicodePathExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnicodePathExtraField);
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
: base(type, length, dataBytes)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
internal byte Version => DataBytes[0];
|
||||
|
||||
internal byte[] NameCrc32
|
||||
@@ -115,7 +115,7 @@ namespace SharpCompress.Common.Zip.Headers
|
||||
VolumeNumber = BinaryPrimitives.ReadUInt32LittleEndian(DataBytes.AsSpan(24));
|
||||
return;
|
||||
default:
|
||||
throw new ArchiveException("Unexpected size of of Zip64 extended information extra field");
|
||||
throw new ArchiveException("Unexpected size of of Zip64 extended information extra field");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Common.Zip
|
||||
internal class PkwareTraditionalEncryptionData
|
||||
{
|
||||
private static readonly CRC32 CRC32 = new CRC32();
|
||||
private readonly UInt32[] _keys = {0x12345678, 0x23456789, 0x34567890};
|
||||
private readonly UInt32[] _keys = { 0x12345678, 0x23456789, 0x34567890 };
|
||||
private readonly ArchiveEncoding _archiveEncoding;
|
||||
|
||||
private PkwareTraditionalEncryptionData(string password, ArchiveEncoding archiveEncoding)
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace SharpCompress.Common.Zip
|
||||
if (Header.HasData && !Skipped)
|
||||
{
|
||||
_decompressionStream ??= GetCompressedStream();
|
||||
|
||||
|
||||
_decompressionStream.Skip();
|
||||
|
||||
if (_decompressionStream is DeflateStream deflateStream)
|
||||
|
||||
@@ -57,11 +57,11 @@ namespace SharpCompress.Common.Zip
|
||||
var local_header = ((LocalEntryHeader)header);
|
||||
|
||||
// If we have CompressedSize, there is data to be read
|
||||
if( local_header.CompressedSize > 0 )
|
||||
if (local_header.CompressedSize > 0)
|
||||
{
|
||||
header.HasData = true;
|
||||
} // Check if zip is streaming ( Length is 0 and is declared in PostDataDescriptor )
|
||||
else if( local_header.Flags.HasFlag(HeaderFlags.UsePostDataDescriptor) )
|
||||
else if (local_header.Flags.HasFlag(HeaderFlags.UsePostDataDescriptor))
|
||||
{
|
||||
bool isRecording = rewindableStream.IsRecording;
|
||||
if (!isRecording)
|
||||
|
||||
@@ -33,8 +33,10 @@ namespace SharpCompress.Common.Zip
|
||||
|
||||
private int KeySizeInBytes
|
||||
{
|
||||
get { return KeyLengthInBytes(_keySize);
|
||||
}
|
||||
get
|
||||
{
|
||||
return KeyLengthInBytes(_keySize);
|
||||
}
|
||||
}
|
||||
|
||||
internal static int KeyLengthInBytes(WinzipAesKeySize keySize)
|
||||
|
||||
@@ -27,33 +27,33 @@ namespace SharpCompress.Common.Zip
|
||||
switch (_filePart.Header.CompressionMethod)
|
||||
{
|
||||
case ZipCompressionMethod.BZip2:
|
||||
{
|
||||
return CompressionType.BZip2;
|
||||
}
|
||||
{
|
||||
return CompressionType.BZip2;
|
||||
}
|
||||
case ZipCompressionMethod.Deflate:
|
||||
{
|
||||
return CompressionType.Deflate;
|
||||
}
|
||||
{
|
||||
return CompressionType.Deflate;
|
||||
}
|
||||
case ZipCompressionMethod.Deflate64:
|
||||
{
|
||||
return CompressionType.Deflate64;
|
||||
}
|
||||
{
|
||||
return CompressionType.Deflate64;
|
||||
}
|
||||
case ZipCompressionMethod.LZMA:
|
||||
{
|
||||
return CompressionType.LZMA;
|
||||
}
|
||||
{
|
||||
return CompressionType.LZMA;
|
||||
}
|
||||
case ZipCompressionMethod.PPMd:
|
||||
{
|
||||
return CompressionType.PPMd;
|
||||
}
|
||||
{
|
||||
return CompressionType.PPMd;
|
||||
}
|
||||
case ZipCompressionMethod.None:
|
||||
{
|
||||
return CompressionType.None;
|
||||
}
|
||||
{
|
||||
return CompressionType.None;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return CompressionType.Unknown;
|
||||
}
|
||||
{
|
||||
return CompressionType.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,72 +60,72 @@ namespace SharpCompress.Common.Zip
|
||||
switch (method)
|
||||
{
|
||||
case ZipCompressionMethod.None:
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
case ZipCompressionMethod.Deflate:
|
||||
{
|
||||
return new DeflateStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
{
|
||||
return new DeflateStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
case ZipCompressionMethod.Deflate64:
|
||||
{
|
||||
return new Deflate64Stream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
{
|
||||
return new Deflate64Stream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
case ZipCompressionMethod.BZip2:
|
||||
{
|
||||
return new BZip2Stream(stream, CompressionMode.Decompress, false);
|
||||
}
|
||||
{
|
||||
return new BZip2Stream(stream, CompressionMode.Decompress, false);
|
||||
}
|
||||
case ZipCompressionMethod.LZMA:
|
||||
{
|
||||
if (FlagUtility.HasFlag(Header.Flags, HeaderFlags.Encrypted))
|
||||
{
|
||||
throw new NotSupportedException("LZMA with pkware encryption.");
|
||||
if (FlagUtility.HasFlag(Header.Flags, HeaderFlags.Encrypted))
|
||||
{
|
||||
throw new NotSupportedException("LZMA with pkware encryption.");
|
||||
}
|
||||
var reader = new BinaryReader(stream);
|
||||
reader.ReadUInt16(); //LZMA version
|
||||
var props = new byte[reader.ReadUInt16()];
|
||||
reader.Read(props, 0, props.Length);
|
||||
return new LzmaStream(props, stream,
|
||||
Header.CompressedSize > 0 ? Header.CompressedSize - 4 - props.Length : -1,
|
||||
FlagUtility.HasFlag(Header.Flags, HeaderFlags.Bit1)
|
||||
? -1
|
||||
: (long)Header.UncompressedSize);
|
||||
}
|
||||
var reader = new BinaryReader(stream);
|
||||
reader.ReadUInt16(); //LZMA version
|
||||
var props = new byte[reader.ReadUInt16()];
|
||||
reader.Read(props, 0, props.Length);
|
||||
return new LzmaStream(props, stream,
|
||||
Header.CompressedSize > 0 ? Header.CompressedSize - 4 - props.Length : -1,
|
||||
FlagUtility.HasFlag(Header.Flags, HeaderFlags.Bit1)
|
||||
? -1
|
||||
: (long)Header.UncompressedSize);
|
||||
}
|
||||
case ZipCompressionMethod.PPMd:
|
||||
{
|
||||
var props = new byte[2];
|
||||
stream.ReadFully(props);
|
||||
return new PpmdStream(new PpmdProperties(props), stream, false);
|
||||
}
|
||||
{
|
||||
var props = new byte[2];
|
||||
stream.ReadFully(props);
|
||||
return new PpmdStream(new PpmdProperties(props), stream, false);
|
||||
}
|
||||
case ZipCompressionMethod.WinzipAes:
|
||||
{
|
||||
ExtraData data = Header.Extra.Where(x => x.Type == ExtraDataType.WinZipAes).SingleOrDefault();
|
||||
if (data is null)
|
||||
{
|
||||
throw new InvalidFormatException("No Winzip AES extra data found.");
|
||||
}
|
||||
if (data.Length != 7)
|
||||
{
|
||||
throw new InvalidFormatException("Winzip data length is not 7.");
|
||||
}
|
||||
ushort compressedMethod = BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes);
|
||||
ExtraData data = Header.Extra.Where(x => x.Type == ExtraDataType.WinZipAes).SingleOrDefault();
|
||||
if (data is null)
|
||||
{
|
||||
throw new InvalidFormatException("No Winzip AES extra data found.");
|
||||
}
|
||||
if (data.Length != 7)
|
||||
{
|
||||
throw new InvalidFormatException("Winzip data length is not 7.");
|
||||
}
|
||||
ushort compressedMethod = BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes);
|
||||
|
||||
if (compressedMethod != 0x01 && compressedMethod != 0x02)
|
||||
{
|
||||
throw new InvalidFormatException("Unexpected vendor version number for WinZip AES metadata");
|
||||
}
|
||||
if (compressedMethod != 0x01 && compressedMethod != 0x02)
|
||||
{
|
||||
throw new InvalidFormatException("Unexpected vendor version number for WinZip AES metadata");
|
||||
}
|
||||
|
||||
ushort vendorId = BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes.AsSpan(2));
|
||||
if (vendorId != 0x4541)
|
||||
{
|
||||
throw new InvalidFormatException("Unexpected vendor ID for WinZip AES metadata");
|
||||
ushort vendorId = BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes.AsSpan(2));
|
||||
if (vendorId != 0x4541)
|
||||
{
|
||||
throw new InvalidFormatException("Unexpected vendor ID for WinZip AES metadata");
|
||||
}
|
||||
return CreateDecompressionStream(stream, (ZipCompressionMethod)BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes.AsSpan(5)));
|
||||
}
|
||||
return CreateDecompressionStream(stream, (ZipCompressionMethod)BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes.AsSpan(5)));
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new NotSupportedException("CompressionMethod: " + Header.CompressionMethod);
|
||||
}
|
||||
{
|
||||
throw new NotSupportedException("CompressionMethod: " + Header.CompressionMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,23 +159,23 @@ namespace SharpCompress.Common.Zip
|
||||
case ZipCompressionMethod.BZip2:
|
||||
case ZipCompressionMethod.LZMA:
|
||||
case ZipCompressionMethod.PPMd:
|
||||
{
|
||||
return new PkwareTraditionalCryptoStream(plainStream, Header.ComposeEncryptionData(plainStream), CryptoMode.Decrypt);
|
||||
}
|
||||
{
|
||||
return new PkwareTraditionalCryptoStream(plainStream, Header.ComposeEncryptionData(plainStream), CryptoMode.Decrypt);
|
||||
}
|
||||
|
||||
case ZipCompressionMethod.WinzipAes:
|
||||
{
|
||||
if (Header.WinzipAesEncryptionData != null)
|
||||
{
|
||||
return new WinzipAesCryptoStream(plainStream, Header.WinzipAesEncryptionData, Header.CompressedSize - 10);
|
||||
if (Header.WinzipAesEncryptionData != null)
|
||||
{
|
||||
return new WinzipAesCryptoStream(plainStream, Header.WinzipAesEncryptionData, Header.CompressedSize - 10);
|
||||
}
|
||||
return plainStream;
|
||||
}
|
||||
return plainStream;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,20 +35,20 @@ namespace SharpCompress.Common.Zip
|
||||
switch (headerBytes)
|
||||
{
|
||||
case ENTRY_HEADER_BYTES:
|
||||
{
|
||||
var entryHeader = new LocalEntryHeader(_archiveEncoding);
|
||||
entryHeader.Read(reader);
|
||||
LoadHeader(entryHeader, reader.BaseStream);
|
||||
{
|
||||
var entryHeader = new LocalEntryHeader(_archiveEncoding);
|
||||
entryHeader.Read(reader);
|
||||
LoadHeader(entryHeader, reader.BaseStream);
|
||||
|
||||
_lastEntryHeader = entryHeader;
|
||||
return entryHeader;
|
||||
}
|
||||
_lastEntryHeader = entryHeader;
|
||||
return entryHeader;
|
||||
}
|
||||
case DIRECTORY_START_HEADER_BYTES:
|
||||
{
|
||||
var entry = new DirectoryEntryHeader(_archiveEncoding);
|
||||
entry.Read(reader);
|
||||
return entry;
|
||||
}
|
||||
{
|
||||
var entry = new DirectoryEntryHeader(_archiveEncoding);
|
||||
entry.Read(reader);
|
||||
return entry;
|
||||
}
|
||||
case POST_DATA_DESCRIPTOR:
|
||||
{
|
||||
if (FlagUtility.HasFlag(_lastEntryHeader!.Flags, HeaderFlags.UsePostDataDescriptor))
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace SharpCompress.Compressors.Deflate
|
||||
private const int MANY = 1440;
|
||||
|
||||
// Table for deflate from PKZIP's appnote.txt.
|
||||
internal static readonly int[] border = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
internal static readonly int[] border = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||
|
||||
internal ZlibCodec _codec; // pointer back to this zlib stream
|
||||
internal int[] bb = new int[1]; // bit length tree depth
|
||||
@@ -561,35 +561,35 @@ namespace SharpCompress.Compressors.Deflate
|
||||
}
|
||||
|
||||
tb[0] = -1;
|
||||
{
|
||||
var bl = new[] {9}; // must be <= 9 for lookahead assumptions
|
||||
var bd = new[] {6}; // must be <= 9 for lookahead assumptions
|
||||
var tl = new int[1];
|
||||
var td = new int[1];
|
||||
|
||||
t = table;
|
||||
t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl,
|
||||
td, hufts, _codec);
|
||||
|
||||
if (t != ZlibConstants.Z_OK)
|
||||
{
|
||||
if (t == ZlibConstants.Z_DATA_ERROR)
|
||||
{
|
||||
blens = null;
|
||||
mode = InflateBlockMode.BAD;
|
||||
}
|
||||
r = t;
|
||||
var bl = new[] { 9 }; // must be <= 9 for lookahead assumptions
|
||||
var bd = new[] { 6 }; // must be <= 9 for lookahead assumptions
|
||||
var tl = new int[1];
|
||||
var td = new int[1];
|
||||
|
||||
bitb = b;
|
||||
bitk = k;
|
||||
_codec.AvailableBytesIn = n;
|
||||
_codec.TotalBytesIn += p - _codec.NextIn;
|
||||
_codec.NextIn = p;
|
||||
writeAt = q;
|
||||
return Flush(r);
|
||||
t = table;
|
||||
t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl,
|
||||
td, hufts, _codec);
|
||||
|
||||
if (t != ZlibConstants.Z_OK)
|
||||
{
|
||||
if (t == ZlibConstants.Z_DATA_ERROR)
|
||||
{
|
||||
blens = null;
|
||||
mode = InflateBlockMode.BAD;
|
||||
}
|
||||
r = t;
|
||||
|
||||
bitb = b;
|
||||
bitk = k;
|
||||
_codec.AvailableBytesIn = n;
|
||||
_codec.TotalBytesIn += p - _codec.NextIn;
|
||||
_codec.NextIn = p;
|
||||
writeAt = q;
|
||||
return Flush(r);
|
||||
}
|
||||
codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]);
|
||||
}
|
||||
codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]);
|
||||
}
|
||||
mode = InflateBlockMode.CODES;
|
||||
goto case InflateBlockMode.CODES;
|
||||
|
||||
@@ -1567,7 +1567,7 @@ namespace SharpCompress.Compressors.Deflate
|
||||
private const int PRESET_DICT = 0x20;
|
||||
|
||||
private const int Z_DEFLATED = 8;
|
||||
private static readonly byte[] mark = {0, 0, 0xff, 0xff};
|
||||
private static readonly byte[] mark = { 0, 0, 0xff, 0xff };
|
||||
|
||||
internal ZlibCodec _codec; // pointer back to this zlib stream
|
||||
internal InflateBlocks blocks; // current inflate_blocks state
|
||||
|
||||
@@ -374,7 +374,7 @@ namespace SharpCompress.Compressors.Deflate
|
||||
};
|
||||
|
||||
// extra bits for each bit length code
|
||||
internal static readonly int[] extra_blbits = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
||||
internal static readonly int[] extra_blbits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 };
|
||||
|
||||
internal static readonly StaticTree Literals;
|
||||
internal static readonly StaticTree Distances;
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace SharpCompress.Compressors.Deflate
|
||||
/// <summary>
|
||||
/// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
|
||||
/// </summary>
|
||||
#if NETCF
|
||||
#if NETCF
|
||||
public const int WorkingBufferSizeDefault = 8192;
|
||||
#else
|
||||
public const int WorkingBufferSizeDefault = 16384;
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace SharpCompress.Compressors.Deflate64
|
||||
private void Reset()
|
||||
{
|
||||
_state = //_hasFormatReader ?
|
||||
//InflaterState.ReadingHeader : // start by reading Header info
|
||||
//InflaterState.ReadingHeader : // start by reading Header info
|
||||
InflaterState.ReadingBFinal; // start by reading BFinal bit
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace SharpCompress.Compressors.Deflate64
|
||||
//if (_hasFormatReader)
|
||||
// _state = InflaterState.StartReadingFooter;
|
||||
//else
|
||||
_state = InflaterState.Done;
|
||||
_state = InflaterState.Done;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -38,14 +38,14 @@ namespace SharpCompress.Compressors.Deflate64
|
||||
public void WriteLengthDistance(int length, int distance)
|
||||
{
|
||||
Debug.Assert((_bytesUsed + length) <= WINDOW_SIZE, "No Enough space");
|
||||
|
||||
|
||||
// move backwards distance bytes in the output stream,
|
||||
// and copy length bytes from this position to the output stream.
|
||||
_bytesUsed += length;
|
||||
int copyStart = (_end - distance) & WINDOW_MASK; // start position for coping.
|
||||
|
||||
int border = WINDOW_SIZE - length;
|
||||
if (copyStart <= border && _end < border)
|
||||
if (copyStart <= border && _end < border)
|
||||
{
|
||||
if (length <= distance)
|
||||
{
|
||||
|
||||
@@ -4,9 +4,9 @@ namespace SharpCompress.Compressors.Filters
|
||||
{
|
||||
internal class BCJFilter : Filter
|
||||
{
|
||||
private static readonly bool[] MASK_TO_ALLOWED_STATUS = {true, true, true, false, true, false, false, false};
|
||||
private static readonly bool[] MASK_TO_ALLOWED_STATUS = { true, true, true, false, true, false, false, false };
|
||||
|
||||
private static readonly int[] MASK_TO_BIT_NUMBER = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
private static readonly int[] MASK_TO_BIT_NUMBER = { 0, 1, 2, 2, 3, 3, 3, 3 };
|
||||
|
||||
private int _pos;
|
||||
private int _prevMask;
|
||||
|
||||
@@ -23,12 +23,12 @@ namespace SharpCompress.Compressors.LZMA
|
||||
mStream = input;
|
||||
mLimit = limit;
|
||||
|
||||
if (((uint) input.Length & 15) != 0)
|
||||
if (((uint)input.Length & 15) != 0)
|
||||
{
|
||||
throw new NotSupportedException("AES decoder does not support padding.");
|
||||
}
|
||||
|
||||
Init(info, out int numCyclesPower, out byte[] salt, out byte[] seed);
|
||||
Init(info, out int numCyclesPower, out byte[] salt, out byte[] seed);
|
||||
|
||||
byte[] password = Encoding.Unicode.GetBytes(pass.CryptoGetTextPassword());
|
||||
byte[] key = InitKey(numCyclesPower, salt, password);
|
||||
@@ -67,7 +67,7 @@ namespace SharpCompress.Compressors.LZMA
|
||||
public override long Position => mWritten;
|
||||
|
||||
public override long Length => mLimit;
|
||||
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (count == 0
|
||||
@@ -107,7 +107,7 @@ namespace SharpCompress.Compressors.LZMA
|
||||
// the stream length is not a multiple of the block size.
|
||||
if (count > mLimit - mWritten)
|
||||
{
|
||||
count = (int) (mLimit - mWritten);
|
||||
count = (int)(mLimit - mWritten);
|
||||
}
|
||||
|
||||
// We cannot transform less than 16 bytes into the target buffer,
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace SharpCompress.Compressors.LZMA
|
||||
|
||||
byte prevByte = 0;
|
||||
uint processedBytes = 0;
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
byte b = 0;
|
||||
uint i;
|
||||
|
||||
@@ -766,7 +766,7 @@ namespace SharpCompress.Compressors.LZMA
|
||||
{
|
||||
offs += 2;
|
||||
}
|
||||
for (;; len++)
|
||||
for (; ; len++)
|
||||
{
|
||||
UInt32 distance = _matchDistances[offs + 1];
|
||||
UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
|
||||
@@ -1107,7 +1107,7 @@ namespace SharpCompress.Compressors.LZMA
|
||||
offs += 2;
|
||||
}
|
||||
|
||||
for (UInt32 lenTest = startLen;; lenTest++)
|
||||
for (UInt32 lenTest = startLen; ; lenTest++)
|
||||
{
|
||||
UInt32 curBack = _matchDistances[offs + 1];
|
||||
UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
|
||||
@@ -1665,129 +1665,129 @@ namespace SharpCompress.Compressors.LZMA
|
||||
switch (propIDs[i])
|
||||
{
|
||||
case CoderPropId.NumFastBytes:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 numFastBytes = (Int32)prop;
|
||||
if (numFastBytes < 5 || numFastBytes > Base.K_MATCH_MAX_LEN)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_numFastBytes = (UInt32)numFastBytes;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.Algorithm:
|
||||
{
|
||||
/*
|
||||
if (!(prop is Int32))
|
||||
throw new InvalidParamException();
|
||||
Int32 maximize = (Int32)prop;
|
||||
_fastMode = (maximize == 0);
|
||||
_maxMode = (maximize >= 2);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case CoderPropId.MatchFinder:
|
||||
{
|
||||
if (!(prop is String))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
EMatchFinderType matchFinderIndexPrev = _matchFinderType;
|
||||
int m = FindMatchFinder(((string)prop).ToUpper());
|
||||
if (m < 0)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_matchFinderType = (EMatchFinderType)m;
|
||||
if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
|
||||
{
|
||||
_dictionarySizePrev = 0xFFFFFFFF;
|
||||
_matchFinder = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CoderPropId.DictionarySize:
|
||||
{
|
||||
const int kDicLogSizeMaxCompress = 30;
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
;
|
||||
Int32 dictionarySize = (Int32)prop;
|
||||
if (dictionarySize < (UInt32)(1 << Base.K_DIC_LOG_SIZE_MIN) ||
|
||||
dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_dictionarySize = (UInt32)dictionarySize;
|
||||
int dicLogSize;
|
||||
for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
|
||||
{
|
||||
if (dictionarySize <= ((UInt32)(1) << dicLogSize))
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
break;
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 numFastBytes = (Int32)prop;
|
||||
if (numFastBytes < 5 || numFastBytes > Base.K_MATCH_MAX_LEN)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_numFastBytes = (UInt32)numFastBytes;
|
||||
break;
|
||||
}
|
||||
_distTableSize = (UInt32)dicLogSize * 2;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.PosStateBits:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
case CoderPropId.Algorithm:
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
/*
|
||||
if (!(prop is Int32))
|
||||
throw new InvalidParamException();
|
||||
Int32 maximize = (Int32)prop;
|
||||
_fastMode = (maximize == 0);
|
||||
_maxMode = (maximize >= 2);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
Int32 v = (Int32)prop;
|
||||
if (v < 0 || v > (UInt32)Base.K_NUM_POS_STATES_BITS_ENCODING_MAX)
|
||||
case CoderPropId.MatchFinder:
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
if (!(prop is String))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
EMatchFinderType matchFinderIndexPrev = _matchFinderType;
|
||||
int m = FindMatchFinder(((string)prop).ToUpper());
|
||||
if (m < 0)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_matchFinderType = (EMatchFinderType)m;
|
||||
if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
|
||||
{
|
||||
_dictionarySizePrev = 0xFFFFFFFF;
|
||||
_matchFinder = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
_posStateBits = v;
|
||||
_posStateMask = (((UInt32)1) << _posStateBits) - 1;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.LitPosBits:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
case CoderPropId.DictionarySize:
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 v = (Int32)prop;
|
||||
if (v < 0 || v > Base.K_NUM_LIT_POS_STATES_BITS_ENCODING_MAX)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_numLiteralPosStateBits = v;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.LitContextBits:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 v = (Int32)prop;
|
||||
if (v < 0 || v > Base.K_NUM_LIT_CONTEXT_BITS_MAX)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
const int kDicLogSizeMaxCompress = 30;
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
;
|
||||
_numLiteralContextBits = v;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.EndMarker:
|
||||
{
|
||||
if (!(prop is Boolean))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
Int32 dictionarySize = (Int32)prop;
|
||||
if (dictionarySize < (UInt32)(1 << Base.K_DIC_LOG_SIZE_MIN) ||
|
||||
dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_dictionarySize = (UInt32)dictionarySize;
|
||||
int dicLogSize;
|
||||
for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
|
||||
{
|
||||
if (dictionarySize <= ((UInt32)(1) << dicLogSize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
_distTableSize = (UInt32)dicLogSize * 2;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.PosStateBits:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 v = (Int32)prop;
|
||||
if (v < 0 || v > (UInt32)Base.K_NUM_POS_STATES_BITS_ENCODING_MAX)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_posStateBits = v;
|
||||
_posStateMask = (((UInt32)1) << _posStateBits) - 1;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.LitPosBits:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 v = (Int32)prop;
|
||||
if (v < 0 || v > Base.K_NUM_LIT_POS_STATES_BITS_ENCODING_MAX)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
_numLiteralPosStateBits = v;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.LitContextBits:
|
||||
{
|
||||
if (!(prop is Int32))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
Int32 v = (Int32)prop;
|
||||
if (v < 0 || v > Base.K_NUM_LIT_CONTEXT_BITS_MAX)
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
;
|
||||
_numLiteralContextBits = v;
|
||||
break;
|
||||
}
|
||||
case CoderPropId.EndMarker:
|
||||
{
|
||||
if (!(prop is Boolean))
|
||||
{
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
SetWriteEndMarkerMode((Boolean)prop);
|
||||
break;
|
||||
}
|
||||
SetWriteEndMarkerMode((Boolean)prop);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InvalidParamException();
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace SharpCompress.Compressors.PPMd.H
|
||||
|
||||
private readonly int[][] _binSumm = new int[128][]; // binary SEE-contexts
|
||||
|
||||
private static readonly int[] INIT_BIN_ESC = {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
|
||||
private static readonly int[] INIT_BIN_ESC = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051 };
|
||||
|
||||
// Temp fields
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
@@ -846,7 +846,7 @@ namespace SharpCompress.Compressors.PPMd.H
|
||||
_charMask[rs.Symbol] = 0;
|
||||
_prevSuccess = 0;
|
||||
}
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
State s = _tempState1.Initialize(Heap);
|
||||
int i;
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace SharpCompress.Compressors.PPMd.H
|
||||
private int _suffix; // pointer ppmcontext
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'ExpEscape'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int[] EXP_ESCAPE = {25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2};
|
||||
public static readonly int[] EXP_ESCAPE = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
|
||||
// Temp fields
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
0x6051
|
||||
};
|
||||
|
||||
private static ReadOnlySpan<byte> EXPONENTIAL_ESCAPES => new byte[] {25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2};
|
||||
private static ReadOnlySpan<byte> EXPONENTIAL_ESCAPES => new byte[] { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
|
||||
#region Public Methods
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
_coder.RangeEncoderNormalize(target);
|
||||
}
|
||||
|
||||
StopEncoding:
|
||||
StopEncoding:
|
||||
_coder.RangeEncoderFlush(target);
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
_coder.RangeDecoderNormalize(source);
|
||||
}
|
||||
|
||||
StopDecoding:
|
||||
StopDecoding:
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
_maximumContext = foundStateSuccessor;
|
||||
return;
|
||||
|
||||
RestartModel:
|
||||
RestartModel:
|
||||
RestoreModel(currentContext, minimumContext, foundStateSuccessor);
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
(byte)(((context.Suffix.NumberStatistics == 0) ? 1 : 0) & ((state.Frequency < 24) ? 1 : 0));
|
||||
}
|
||||
|
||||
LoopEntry:
|
||||
LoopEntry:
|
||||
if (state.Successor != upBranch)
|
||||
{
|
||||
context = state.Successor;
|
||||
@@ -643,7 +643,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
}
|
||||
while (context.Suffix != PpmContext.ZERO);
|
||||
|
||||
NoLoop:
|
||||
NoLoop:
|
||||
if (stateIndex == 0)
|
||||
{
|
||||
return context;
|
||||
@@ -767,7 +767,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0);
|
||||
}
|
||||
|
||||
LoopEntry:
|
||||
LoopEntry:
|
||||
if (state.Successor != PpmContext.ZERO)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -363,7 +363,7 @@ namespace SharpCompress.Compressors.PPMd.I1
|
||||
_numberMasked = context.NumberStatistics;
|
||||
return;
|
||||
|
||||
SymbolFound:
|
||||
SymbolFound:
|
||||
_coder._lowCount = lowCount;
|
||||
lowCount += state.Frequency;
|
||||
_coder._highCount = lowCount;
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace SharpCompress.Compressors.PPMd
|
||||
if (Version == PpmdVersion.I1)
|
||||
{
|
||||
_allocator ??= new Allocator();
|
||||
|
||||
|
||||
_allocator.Start(_allocatorSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ namespace SharpCompress.Compressors.Rar
|
||||
{
|
||||
private static readonly uint[] crcTab;
|
||||
|
||||
public static uint CheckCrc(uint startCrc, byte b) {
|
||||
return (crcTab[((int) ((int) startCrc ^ (int) b)) & 0xff] ^ (startCrc >> 8));
|
||||
public static uint CheckCrc(uint startCrc, byte b)
|
||||
{
|
||||
return (crcTab[((int)((int)startCrc ^ (int)b)) & 0xff] ^ (startCrc >> 8));
|
||||
}
|
||||
|
||||
public static uint CheckCrc(uint startCrc, byte[] data, int offset, int count)
|
||||
|
||||
@@ -36,7 +36,8 @@ namespace SharpCompress.Compressors.Rar
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!isDisposed) {
|
||||
if (!isDisposed)
|
||||
{
|
||||
isDisposed = true;
|
||||
base.Dispose(disposing);
|
||||
readStream.Dispose();
|
||||
|
||||
@@ -2,9 +2,9 @@ namespace SharpCompress.Compressors.Rar.UnpackV1.Decode
|
||||
{
|
||||
internal enum FilterType : byte
|
||||
{
|
||||
// These values must not be changed, because we use them directly
|
||||
// in RAR5 compression and decompression code.
|
||||
FILTER_DELTA=0, FILTER_E8, FILTER_E8E9, FILTER_ARM,
|
||||
FILTER_AUDIO, FILTER_RGB, FILTER_ITANIUM, FILTER_PPM, FILTER_NONE
|
||||
// These values must not be changed, because we use them directly
|
||||
// in RAR5 compression and decompression code.
|
||||
FILTER_DELTA = 0, FILTER_E8, FILTER_E8E9, FILTER_ARM,
|
||||
FILTER_AUDIO, FILTER_RGB, FILTER_ITANIUM, FILTER_PPM, FILTER_NONE
|
||||
}
|
||||
}
|
||||
@@ -15,27 +15,27 @@ namespace SharpCompress.Compressors.Rar.UnpackV1.Decode
|
||||
public const int DC = 60;
|
||||
public const int LDC = 17;
|
||||
public const int RC = 28;
|
||||
// 20171217: NOTE: these constants seem to have been updated in the unrar src code
|
||||
// at some unknown point. updating causes decompression failure, not sure why.
|
||||
// public const int NC = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
// public const int DC = 64;
|
||||
// public const int LDC = 16;
|
||||
// public const int RC = 44;
|
||||
// 20171217: NOTE: these constants seem to have been updated in the unrar src code
|
||||
// at some unknown point. updating causes decompression failure, not sure why.
|
||||
// public const int NC = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
// public const int DC = 64;
|
||||
// public const int LDC = 16;
|
||||
// public const int RC = 44;
|
||||
public const int HUFF_TABLE_SIZE = NC + DC + RC + LDC;
|
||||
public const int BC = 20;
|
||||
public const int BC = 20;
|
||||
|
||||
public const uint NC30 = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC30 = 60;
|
||||
public const uint NC30 = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC30 = 60;
|
||||
public const uint LDC30 = 17;
|
||||
public const uint RC30 = 28;
|
||||
public const uint BC30 = 20;
|
||||
public const uint RC30 = 28;
|
||||
public const uint BC30 = 20;
|
||||
public const uint HUFF_TABLE_SIZE30 = NC30 + DC30 + RC30 + LDC30;
|
||||
|
||||
public const int NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const int DC20 = 48;
|
||||
public const int RC20 = 28;
|
||||
public const int BC20 = 19;
|
||||
public const int MC20 = 257;
|
||||
public const int NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const int DC20 = 48;
|
||||
public const int RC20 = 28;
|
||||
public const int BC20 = 19;
|
||||
public const int MC20 = 257;
|
||||
|
||||
// Largest alphabet size among all values listed above.
|
||||
public const uint LARGEST_TABLE_SIZE = 306;
|
||||
|
||||
@@ -16,7 +16,8 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
{
|
||||
private readonly BitInput Inp;
|
||||
|
||||
public Unpack() {
|
||||
public Unpack()
|
||||
{
|
||||
// to ease in porting Unpack50.cs
|
||||
Inp = this;
|
||||
}
|
||||
@@ -86,7 +87,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
|
||||
private int lowDistRepCount;
|
||||
|
||||
private static readonly int[] DBitLengthCounts = {4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 0, 12};
|
||||
private static readonly int[] DBitLengthCounts = { 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 0, 12 };
|
||||
|
||||
private FileHeader fileHeader;
|
||||
|
||||
@@ -677,7 +678,8 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
destUnpSize -= size;
|
||||
}
|
||||
|
||||
private void InsertOldDist(uint distance) {
|
||||
private void InsertOldDist(uint distance)
|
||||
{
|
||||
// TODO uint
|
||||
InsertOldDist((int)distance);
|
||||
}
|
||||
@@ -696,9 +698,10 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
lastLength = length;
|
||||
}
|
||||
|
||||
private void CopyString(uint length, uint distance) {
|
||||
private void CopyString(uint length, uint distance)
|
||||
{
|
||||
// TODO uint
|
||||
CopyString((int)length, (int)distance) ;
|
||||
CopyString((int)length, (int)distance);
|
||||
}
|
||||
|
||||
private void CopyString(int length, int distance)
|
||||
@@ -743,7 +746,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
unpPtr = 0;
|
||||
wrPtr = 0;
|
||||
PpmEscChar = 2;
|
||||
WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
WriteBorder = Math.Min(MaxWinSize, UNPACK_MAX_WRITE) & MaxWinMask;
|
||||
|
||||
InitFilters();
|
||||
}
|
||||
@@ -755,35 +758,35 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
unpInitData20(solid);
|
||||
}
|
||||
|
||||
//void Unpack::UnpInitData(bool Solid)
|
||||
//{
|
||||
// if (!Solid)
|
||||
// {
|
||||
// memset(OldDist,0,sizeof(OldDist));
|
||||
// OldDistPtr=0;
|
||||
// LastDist=LastLength=0;
|
||||
//// memset(Window,0,MaxWinSize);
|
||||
// memset(&BlockTables,0,sizeof(BlockTables));
|
||||
// UnpPtr=WrPtr=0;
|
||||
// WriteBorder=Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
// }
|
||||
// // Filters never share several solid files, so we can safely reset them
|
||||
// // even in solid archive.
|
||||
// InitFilters();
|
||||
//
|
||||
// Inp.InitBitInput();
|
||||
// WrittenFileSize=0;
|
||||
// ReadTop=0;
|
||||
// ReadBorder=0;
|
||||
//
|
||||
// memset(&BlockHeader,0,sizeof(BlockHeader));
|
||||
// BlockHeader.BlockSize=-1; // '-1' means not defined yet.
|
||||
//#ifndef SFX_MODULE
|
||||
// UnpInitData20(Solid);
|
||||
//#endif
|
||||
// UnpInitData30(Solid);
|
||||
// UnpInitData50(Solid);
|
||||
//}
|
||||
//void Unpack::UnpInitData(bool Solid)
|
||||
//{
|
||||
// if (!Solid)
|
||||
// {
|
||||
// memset(OldDist,0,sizeof(OldDist));
|
||||
// OldDistPtr=0;
|
||||
// LastDist=LastLength=0;
|
||||
//// memset(Window,0,MaxWinSize);
|
||||
// memset(&BlockTables,0,sizeof(BlockTables));
|
||||
// UnpPtr=WrPtr=0;
|
||||
// WriteBorder=Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
// }
|
||||
// // Filters never share several solid files, so we can safely reset them
|
||||
// // even in solid archive.
|
||||
// InitFilters();
|
||||
//
|
||||
// Inp.InitBitInput();
|
||||
// WrittenFileSize=0;
|
||||
// ReadTop=0;
|
||||
// ReadBorder=0;
|
||||
//
|
||||
// memset(&BlockHeader,0,sizeof(BlockHeader));
|
||||
// BlockHeader.BlockSize=-1; // '-1' means not defined yet.
|
||||
//#ifndef SFX_MODULE
|
||||
// UnpInitData20(Solid);
|
||||
//#endif
|
||||
// UnpInitData30(Solid);
|
||||
// UnpInitData50(Solid);
|
||||
//}
|
||||
|
||||
private void InitFilters()
|
||||
{
|
||||
@@ -1063,7 +1066,7 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
UnpackFilter Filter;
|
||||
if (NewFilter)
|
||||
|
||||
// new filter code, never used before since VM reset
|
||||
// new filter code, never used before since VM reset
|
||||
{
|
||||
// too many different filters, corrupt archive
|
||||
if (FiltPos > 1024)
|
||||
@@ -1121,8 +1124,8 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
|
||||
if ((firstByte & 0x10) != 0)
|
||||
|
||||
// set registers to optional parameters
|
||||
// if any
|
||||
// set registers to optional parameters
|
||||
// if any
|
||||
{
|
||||
int InitMask = Utility.URShift(Inp.GetBits(), 9);
|
||||
Inp.AddBits(7);
|
||||
@@ -1208,7 +1211,7 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
}
|
||||
if ((firstByte & 8) != 0)
|
||||
|
||||
// put data block passed as parameter if any
|
||||
// put data block passed as parameter if any
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
, 0xffff
|
||||
};
|
||||
|
||||
private static readonly int[] PosL1 = {0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32};
|
||||
private static readonly int[] PosL1 = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };
|
||||
|
||||
private const int STARTL2 = 3;
|
||||
|
||||
@@ -76,39 +76,39 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
0xa000, 0xc000, 0xd000, 0xe000, 0xea00, 0xee00, 0xf000, 0xf200, 0xf240, 0xffff
|
||||
};
|
||||
|
||||
private static readonly int[] PosL2 = {0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36};
|
||||
private static readonly int[] PosL2 = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };
|
||||
|
||||
private const int STARTHF0 = 4;
|
||||
|
||||
private static readonly int[] DecHf0 = {0x8000, 0xc000, 0xe000, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xffff};
|
||||
private static readonly int[] DecHf0 = { 0x8000, 0xc000, 0xe000, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xffff };
|
||||
|
||||
private static readonly int[] PosHf0 = {0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33, 33};
|
||||
private static readonly int[] PosHf0 = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33, 33 };
|
||||
|
||||
private const int STARTHF1 = 5;
|
||||
|
||||
private static readonly int[] DecHf1 = {0x2000, 0xc000, 0xe000, 0xf000, 0xf200, 0xf200, 0xf7e0, 0xffff};
|
||||
private static readonly int[] DecHf1 = { 0x2000, 0xc000, 0xe000, 0xf000, 0xf200, 0xf200, 0xf7e0, 0xffff };
|
||||
|
||||
private static readonly int[] PosHf1 = {0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80, 127};
|
||||
private static readonly int[] PosHf1 = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80, 127 };
|
||||
|
||||
private const int STARTHF2 = 5;
|
||||
|
||||
private static readonly int[] DecHf2 = {0x1000, 0x2400, 0x8000, 0xc000, 0xfa00, 0xffff, 0xffff, 0xffff};
|
||||
private static readonly int[] DecHf2 = { 0x1000, 0x2400, 0x8000, 0xc000, 0xfa00, 0xffff, 0xffff, 0xffff };
|
||||
|
||||
private static readonly int[] PosHf2 = {0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0};
|
||||
private static readonly int[] PosHf2 = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };
|
||||
|
||||
private const int STARTHF3 = 6;
|
||||
|
||||
private static readonly int[] DecHf3 = {0x800, 0x2400, 0xee00, 0xfe80, 0xffff, 0xffff, 0xffff};
|
||||
private static readonly int[] DecHf3 = { 0x800, 0x2400, 0xee00, 0xfe80, 0xffff, 0xffff, 0xffff };
|
||||
|
||||
private static readonly int[] PosHf3 = {0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0};
|
||||
private static readonly int[] PosHf3 = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };
|
||||
|
||||
private const int STARTHF4 = 8;
|
||||
|
||||
private static readonly int[] DecHf4 = {0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
|
||||
private static readonly int[] DecHf4 = { 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff };
|
||||
|
||||
private static readonly int[] PosHf4 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0};
|
||||
private static readonly int[] PosHf4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0 };
|
||||
|
||||
private static readonly int[] ShortLen1 = {1, 3, 4, 4, 5, 6, 7, 8, 8, 4, 4, 5, 6, 6, 4, 0};
|
||||
private static readonly int[] ShortLen1 = { 1, 3, 4, 4, 5, 6, 7, 8, 8, 4, 4, 5, 6, 6, 4, 0 };
|
||||
|
||||
private static readonly int[] ShortXor1 =
|
||||
{
|
||||
@@ -116,7 +116,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
, 0x9c, 0xb0
|
||||
};
|
||||
|
||||
private static readonly int[] ShortLen2 = {2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0};
|
||||
private static readonly int[] ShortLen2 = { 2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0 };
|
||||
|
||||
private static readonly int[] ShortXor2 =
|
||||
{
|
||||
@@ -290,7 +290,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
BitField = Utility.URShift(BitField, 8);
|
||||
if (AvrLn1 < 37)
|
||||
{
|
||||
for (Length = 0;; Length++)
|
||||
for (Length = 0; ; Length++)
|
||||
{
|
||||
if (((BitField ^ ShortXor1[Length]) & (~(Utility.URShift(0xff, getShortLen1(Length))))) == 0)
|
||||
{
|
||||
@@ -301,7 +301,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Length = 0;; Length++)
|
||||
for (Length = 0; ; Length++)
|
||||
{
|
||||
if (((BitField ^ ShortXor2[Length]) & (~(0xff >> getShortLen2(Length)))) == 0)
|
||||
{
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
, 16, 16, 16, 16, 16, 16, 16
|
||||
};
|
||||
|
||||
private static readonly int[] SDDecode = {0, 4, 8, 16, 32, 64, 128, 192};
|
||||
private static readonly int[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
|
||||
|
||||
private static readonly int[] SDBits = {2, 2, 3, 4, 5, 6, 6, 6};
|
||||
private static readonly int[] SDBits = { 2, 2, 3, 4, 5, 6, 6, 6 };
|
||||
|
||||
private void unpack20(bool solid)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,29 +3,29 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
{
|
||||
internal partial class Unpack
|
||||
{
|
||||
private uint SlotToLength(uint Slot)
|
||||
private uint SlotToLength(uint Slot)
|
||||
{
|
||||
//uint LBits,Length=2;
|
||||
int LBits;
|
||||
uint Length=2;
|
||||
if (Slot<8)
|
||||
{
|
||||
LBits=0;
|
||||
Length+=Slot;
|
||||
}
|
||||
else
|
||||
{
|
||||
//LBits=Slot/4-1;
|
||||
LBits=(int)(Slot/4-1);
|
||||
Length+=(4 | (Slot & 3)) << LBits;
|
||||
}
|
||||
//uint LBits,Length=2;
|
||||
int LBits;
|
||||
uint Length = 2;
|
||||
if (Slot < 8)
|
||||
{
|
||||
LBits = 0;
|
||||
Length += Slot;
|
||||
}
|
||||
else
|
||||
{
|
||||
//LBits=Slot/4-1;
|
||||
LBits = (int)(Slot / 4 - 1);
|
||||
Length += (4 | (Slot & 3)) << LBits;
|
||||
}
|
||||
|
||||
if (LBits>0)
|
||||
{
|
||||
Length+=getbits()>>(16-LBits);
|
||||
AddBits(LBits);
|
||||
}
|
||||
return Length;
|
||||
if (LBits > 0)
|
||||
{
|
||||
Length += getbits() >> (16 - LBits);
|
||||
AddBits(LBits);
|
||||
}
|
||||
return Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
|
||||
{
|
||||
internal static class UnpackUtility
|
||||
{
|
||||
//!!! TODO rename methods
|
||||
internal static uint DecodeNumber(this BitInput input, Decode.Decode dec) {
|
||||
//!!! TODO rename methods
|
||||
internal static uint DecodeNumber(this BitInput input, Decode.Decode dec)
|
||||
{
|
||||
return (uint)input.decodeNumber(dec);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,57 +15,57 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
internal partial class BitInput
|
||||
{
|
||||
|
||||
public BitInput(bool AllocBuffer)
|
||||
{
|
||||
ExternalBuffer=false;
|
||||
if (AllocBuffer)
|
||||
{
|
||||
// getbits32 attempts to read data from InAddr, ... InAddr+3 positions.
|
||||
// So let's allocate 3 additional bytes for situation, when we need to
|
||||
// read only 1 byte from the last position of buffer and avoid a crash
|
||||
// from access to next 3 bytes, which contents we do not need.
|
||||
size_t BufSize=MAX_SIZE+3;
|
||||
InBuf=new byte[BufSize];
|
||||
public BitInput(bool AllocBuffer)
|
||||
{
|
||||
ExternalBuffer = false;
|
||||
if (AllocBuffer)
|
||||
{
|
||||
// getbits32 attempts to read data from InAddr, ... InAddr+3 positions.
|
||||
// So let's allocate 3 additional bytes for situation, when we need to
|
||||
// read only 1 byte from the last position of buffer and avoid a crash
|
||||
// from access to next 3 bytes, which contents we do not need.
|
||||
size_t BufSize = MAX_SIZE + 3;
|
||||
InBuf = new byte[BufSize];
|
||||
|
||||
// Ensure that we get predictable results when accessing bytes in area
|
||||
// not filled with read data.
|
||||
//memset(InBuf,0,BufSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
InBuf=null;
|
||||
}
|
||||
}
|
||||
// Ensure that we get predictable results when accessing bytes in area
|
||||
// not filled with read data.
|
||||
//memset(InBuf,0,BufSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
InBuf = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//BitInput::~BitInput()
|
||||
//{
|
||||
// if (!ExternalBuffer)
|
||||
// delete[] InBuf;
|
||||
//}
|
||||
//
|
||||
//BitInput::~BitInput()
|
||||
//{
|
||||
// if (!ExternalBuffer)
|
||||
// delete[] InBuf;
|
||||
//}
|
||||
//
|
||||
|
||||
public
|
||||
void faddbits(uint Bits)
|
||||
{
|
||||
// Function wrapped version of inline addbits to save code size.
|
||||
addbits(Bits);
|
||||
}
|
||||
public
|
||||
void faddbits(uint Bits)
|
||||
{
|
||||
// Function wrapped version of inline addbits to save code size.
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
public
|
||||
uint fgetbits()
|
||||
{
|
||||
// Function wrapped version of inline getbits to save code size.
|
||||
return getbits();
|
||||
}
|
||||
public
|
||||
uint fgetbits()
|
||||
{
|
||||
// Function wrapped version of inline getbits to save code size.
|
||||
return getbits();
|
||||
}
|
||||
|
||||
private void SetExternalBuffer(byte []Buf)
|
||||
{
|
||||
//if (InBuf!=NULL && !ExternalBuffer)
|
||||
// delete[] InBuf;
|
||||
InBuf=Buf;
|
||||
ExternalBuffer=true;
|
||||
}
|
||||
private void SetExternalBuffer(byte[] Buf)
|
||||
{
|
||||
//if (InBuf!=NULL && !ExternalBuffer)
|
||||
// delete[] InBuf;
|
||||
InBuf = Buf;
|
||||
ExternalBuffer = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
{
|
||||
|
||||
internal partial class BitInput
|
||||
{
|
||||
public const int MAX_SIZE=0x8000; // Size of input buffer.
|
||||
|
||||
public int InAddr; // Curent byte position in the buffer.
|
||||
public int InBit; // Current bit position in the current byte.
|
||||
|
||||
public bool ExternalBuffer;
|
||||
|
||||
//BitInput(bool AllocBuffer);
|
||||
//~BitInput();
|
||||
|
||||
public byte[] InBuf; // Dynamically allocated input buffer.
|
||||
|
||||
public
|
||||
void InitBitInput()
|
||||
internal partial class BitInput
|
||||
{
|
||||
InAddr=InBit=0;
|
||||
}
|
||||
|
||||
// Move forward by 'Bits' bits.
|
||||
public void addbits(uint _Bits)
|
||||
{
|
||||
var Bits = checked((int)_Bits);
|
||||
Bits+=InBit;
|
||||
InAddr+=Bits>>3;
|
||||
InBit=Bits&7;
|
||||
}
|
||||
|
||||
// Return 16 bits from current position in the buffer.
|
||||
// Bit at (InAddr,InBit) has the highest position in returning data.
|
||||
public uint getbits()
|
||||
{
|
||||
uint BitField=(uint)InBuf[InAddr] << 16;
|
||||
BitField|=(uint)InBuf[InAddr+1] << 8;
|
||||
BitField|=(uint)InBuf[InAddr+2];
|
||||
BitField >>= (8-InBit);
|
||||
return BitField & 0xffff;
|
||||
}
|
||||
public const int MAX_SIZE = 0x8000; // Size of input buffer.
|
||||
|
||||
// Return 32 bits from current position in the buffer.
|
||||
// Bit at (InAddr,InBit) has the highest position in returning data.
|
||||
public uint getbits32()
|
||||
{
|
||||
uint BitField=(uint)InBuf[InAddr] << 24;
|
||||
BitField|=(uint)InBuf[InAddr+1] << 16;
|
||||
BitField|=(uint)InBuf[InAddr+2] << 8;
|
||||
BitField|=(uint)InBuf[InAddr+3];
|
||||
BitField <<= InBit;
|
||||
BitField|=(uint)InBuf[InAddr+4] >> (8-InBit);
|
||||
return BitField & 0xffffffff;
|
||||
}
|
||||
|
||||
//void faddbits(uint Bits);
|
||||
//uint fgetbits();
|
||||
|
||||
// Check if buffer has enough space for IncPtr bytes. Returns 'true'
|
||||
// if buffer will be overflown.
|
||||
private bool Overflow(uint IncPtr)
|
||||
{
|
||||
return InAddr+IncPtr>=MAX_SIZE;
|
||||
}
|
||||
public int InAddr; // Curent byte position in the buffer.
|
||||
public int InBit; // Current bit position in the current byte.
|
||||
|
||||
//void SetExternalBuffer(byte *Buf);
|
||||
}
|
||||
public bool ExternalBuffer;
|
||||
|
||||
//BitInput(bool AllocBuffer);
|
||||
//~BitInput();
|
||||
|
||||
public byte[] InBuf; // Dynamically allocated input buffer.
|
||||
|
||||
public
|
||||
void InitBitInput()
|
||||
{
|
||||
InAddr = InBit = 0;
|
||||
}
|
||||
|
||||
// Move forward by 'Bits' bits.
|
||||
public void addbits(uint _Bits)
|
||||
{
|
||||
var Bits = checked((int)_Bits);
|
||||
Bits += InBit;
|
||||
InAddr += Bits >> 3;
|
||||
InBit = Bits & 7;
|
||||
}
|
||||
|
||||
// Return 16 bits from current position in the buffer.
|
||||
// Bit at (InAddr,InBit) has the highest position in returning data.
|
||||
public uint getbits()
|
||||
{
|
||||
uint BitField = (uint)InBuf[InAddr] << 16;
|
||||
BitField |= (uint)InBuf[InAddr + 1] << 8;
|
||||
BitField |= (uint)InBuf[InAddr + 2];
|
||||
BitField >>= (8 - InBit);
|
||||
return BitField & 0xffff;
|
||||
}
|
||||
|
||||
// Return 32 bits from current position in the buffer.
|
||||
// Bit at (InAddr,InBit) has the highest position in returning data.
|
||||
public uint getbits32()
|
||||
{
|
||||
uint BitField = (uint)InBuf[InAddr] << 24;
|
||||
BitField |= (uint)InBuf[InAddr + 1] << 16;
|
||||
BitField |= (uint)InBuf[InAddr + 2] << 8;
|
||||
BitField |= (uint)InBuf[InAddr + 3];
|
||||
BitField <<= InBit;
|
||||
BitField |= (uint)InBuf[InAddr + 4] >> (8 - InBit);
|
||||
return BitField & 0xffffffff;
|
||||
}
|
||||
|
||||
//void faddbits(uint Bits);
|
||||
//uint fgetbits();
|
||||
|
||||
// Check if buffer has enough space for IncPtr bytes. Returns 'true'
|
||||
// if buffer will be overflown.
|
||||
private bool Overflow(uint IncPtr)
|
||||
{
|
||||
return InAddr + IncPtr >= MAX_SIZE;
|
||||
}
|
||||
|
||||
//void SetExternalBuffer(byte *Buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,169 +15,178 @@ using System;
|
||||
|
||||
namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
{
|
||||
internal partial class FragmentedWindow
|
||||
internal partial class FragmentedWindow
|
||||
{
|
||||
|
||||
public FragmentedWindow()
|
||||
{
|
||||
//memset(Mem,0,sizeof(Mem));
|
||||
//memset(MemSize,0,sizeof(MemSize));
|
||||
}
|
||||
public FragmentedWindow()
|
||||
{
|
||||
//memset(Mem,0,sizeof(Mem));
|
||||
//memset(MemSize,0,sizeof(MemSize));
|
||||
}
|
||||
|
||||
|
||||
//FragmentedWindow::~FragmentedWindow()
|
||||
//{
|
||||
// Reset();
|
||||
//}
|
||||
//FragmentedWindow::~FragmentedWindow()
|
||||
//{
|
||||
// Reset();
|
||||
//}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
for (uint I=0;I<Mem.Length;I++)
|
||||
{
|
||||
if (Mem[I]!=null)
|
||||
{
|
||||
//free(Mem[I]);
|
||||
Mem[I]=null;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Reset()
|
||||
{
|
||||
for (uint I = 0; I < Mem.Length; I++)
|
||||
{
|
||||
if (Mem[I] != null)
|
||||
{
|
||||
//free(Mem[I]);
|
||||
Mem[I] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Init(size_t WinSize)
|
||||
{
|
||||
Reset();
|
||||
public void Init(size_t WinSize)
|
||||
{
|
||||
Reset();
|
||||
|
||||
uint BlockNum=0;
|
||||
size_t TotalSize=0; // Already allocated.
|
||||
while (TotalSize<WinSize && BlockNum<Mem.Length)
|
||||
{
|
||||
size_t Size=WinSize-TotalSize; // Size needed to allocate.
|
||||
uint BlockNum = 0;
|
||||
size_t TotalSize = 0; // Already allocated.
|
||||
while (TotalSize < WinSize && BlockNum < Mem.Length)
|
||||
{
|
||||
size_t Size = WinSize - TotalSize; // Size needed to allocate.
|
||||
|
||||
// Minimum still acceptable block size. Next allocations cannot be larger
|
||||
// than current, so we do not need blocks if they are smaller than
|
||||
// "size left / attempts left". Also we do not waste time to blocks
|
||||
// smaller than some arbitrary constant.
|
||||
size_t MinSize=Math.Max(Size/(size_t)(Mem.Length-BlockNum), 0x400000);
|
||||
// Minimum still acceptable block size. Next allocations cannot be larger
|
||||
// than current, so we do not need blocks if they are smaller than
|
||||
// "size left / attempts left". Also we do not waste time to blocks
|
||||
// smaller than some arbitrary constant.
|
||||
size_t MinSize = Math.Max(Size / (size_t)(Mem.Length - BlockNum), 0x400000);
|
||||
|
||||
byte[] NewMem=null;
|
||||
while (Size>=MinSize)
|
||||
{
|
||||
NewMem=new byte[Size];
|
||||
if (NewMem!=null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
byte[] NewMem = null;
|
||||
while (Size >= MinSize)
|
||||
{
|
||||
NewMem = new byte[Size];
|
||||
if (NewMem != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Size-=Size/32;
|
||||
}
|
||||
if (NewMem==null)
|
||||
//throw std::bad_alloc();
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
Size -= Size / 32;
|
||||
}
|
||||
if (NewMem == null)
|
||||
//throw std::bad_alloc();
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
// Clean the window to generate the same output when unpacking corrupt
|
||||
// RAR files, which may access to unused areas of sliding dictionary.
|
||||
// sharpcompress: don't need this, freshly allocated above
|
||||
//Utility.Memset(NewMem,0,Size);
|
||||
// Clean the window to generate the same output when unpacking corrupt
|
||||
// RAR files, which may access to unused areas of sliding dictionary.
|
||||
// sharpcompress: don't need this, freshly allocated above
|
||||
//Utility.Memset(NewMem,0,Size);
|
||||
|
||||
Mem[BlockNum]=NewMem;
|
||||
TotalSize+=Size;
|
||||
MemSize[BlockNum]=TotalSize;
|
||||
BlockNum++;
|
||||
}
|
||||
if (TotalSize<WinSize) // Not found enough free blocks.
|
||||
//throw std::bad_alloc();
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
Mem[BlockNum] = NewMem;
|
||||
TotalSize += Size;
|
||||
MemSize[BlockNum] = TotalSize;
|
||||
BlockNum++;
|
||||
}
|
||||
if (TotalSize < WinSize) // Not found enough free blocks.
|
||||
//throw std::bad_alloc();
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public byte this[size_t Item] {
|
||||
get {
|
||||
if (Item<MemSize[0])
|
||||
{
|
||||
return Mem[0][Item];
|
||||
}
|
||||
public byte this[size_t Item]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Item < MemSize[0])
|
||||
{
|
||||
return Mem[0][Item];
|
||||
}
|
||||
|
||||
for (uint I=1;I<MemSize.Length;I++)
|
||||
{
|
||||
if (Item<MemSize[I])
|
||||
{
|
||||
return Mem[I][Item-MemSize[I-1]];
|
||||
}
|
||||
}
|
||||
for (uint I = 1; I < MemSize.Length; I++)
|
||||
{
|
||||
if (Item < MemSize[I])
|
||||
{
|
||||
return Mem[I][Item - MemSize[I - 1]];
|
||||
}
|
||||
}
|
||||
|
||||
return Mem[0][0]; // Must never happen;
|
||||
}
|
||||
set {
|
||||
if (Item<MemSize[0]) {
|
||||
Mem[0][Item] = value;
|
||||
return;
|
||||
}
|
||||
for (uint I=1;I<MemSize.Length;I++)
|
||||
{
|
||||
if (Item<MemSize[I]) {
|
||||
Mem[I][Item-MemSize[I-1]] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return Mem[0][0]; // Must never happen;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Item < MemSize[0])
|
||||
{
|
||||
Mem[0][Item] = value;
|
||||
return;
|
||||
}
|
||||
for (uint I = 1; I < MemSize.Length; I++)
|
||||
{
|
||||
if (Item < MemSize[I])
|
||||
{
|
||||
Mem[I][Item - MemSize[I - 1]] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Mem[0][0] = value; // Must never happen;
|
||||
}
|
||||
}
|
||||
Mem[0][0] = value; // Must never happen;
|
||||
}
|
||||
}
|
||||
|
||||
// sharpcompress: added the following code
|
||||
public void GetBuffer(size_t Item, out byte[] buf, out uint offset) {
|
||||
if (Item<MemSize[0]) {
|
||||
//return Mem[0][Item];
|
||||
buf = Mem[0]; offset = Item; return;
|
||||
}
|
||||
for (uint I=1;I<MemSize.Length;I++) {
|
||||
if (Item<MemSize[I]) {
|
||||
//return Mem[I][Item-MemSize[I-1]];
|
||||
buf = Mem[I]; offset = Item-MemSize[I-1]; return;
|
||||
}
|
||||
}
|
||||
//return Mem[0][0]; // Must never happen;
|
||||
buf = Mem[0]; offset = 0; return; // Must never happen;
|
||||
}
|
||||
// sharpcompress: added the following code
|
||||
public void GetBuffer(size_t Item, out byte[] buf, out uint offset)
|
||||
{
|
||||
if (Item < MemSize[0])
|
||||
{
|
||||
//return Mem[0][Item];
|
||||
buf = Mem[0]; offset = Item; return;
|
||||
}
|
||||
for (uint I = 1; I < MemSize.Length; I++)
|
||||
{
|
||||
if (Item < MemSize[I])
|
||||
{
|
||||
//return Mem[I][Item-MemSize[I-1]];
|
||||
buf = Mem[I]; offset = Item - MemSize[I - 1]; return;
|
||||
}
|
||||
}
|
||||
//return Mem[0][0]; // Must never happen;
|
||||
buf = Mem[0]; offset = 0; return; // Must never happen;
|
||||
}
|
||||
|
||||
public void CopyString(uint Length,uint Distance,ref size_t UnpPtr,size_t MaxWinMask)
|
||||
{
|
||||
size_t SrcPtr=UnpPtr-Distance;
|
||||
while (Length-- > 0)
|
||||
{
|
||||
this[UnpPtr]=this[SrcPtr++ & MaxWinMask];
|
||||
// We need to have masked UnpPtr after quit from loop, so it must not
|
||||
// be replaced with '(*this)[UnpPtr++ & MaxWinMask]'
|
||||
UnpPtr=(UnpPtr+1) & MaxWinMask;
|
||||
}
|
||||
}
|
||||
public void CopyString(uint Length, uint Distance, ref size_t UnpPtr, size_t MaxWinMask)
|
||||
{
|
||||
size_t SrcPtr = UnpPtr - Distance;
|
||||
while (Length-- > 0)
|
||||
{
|
||||
this[UnpPtr] = this[SrcPtr++ & MaxWinMask];
|
||||
// We need to have masked UnpPtr after quit from loop, so it must not
|
||||
// be replaced with '(*this)[UnpPtr++ & MaxWinMask]'
|
||||
UnpPtr = (UnpPtr + 1) & MaxWinMask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void CopyData(byte[] Dest, size_t destOffset, size_t WinPos,size_t Size)
|
||||
{
|
||||
for (size_t I=0;I<Size;I++)
|
||||
{
|
||||
Dest[destOffset+I]=this[WinPos+I];
|
||||
}
|
||||
}
|
||||
public void CopyData(byte[] Dest, size_t destOffset, size_t WinPos, size_t Size)
|
||||
{
|
||||
for (size_t I = 0; I < Size; I++)
|
||||
{
|
||||
Dest[destOffset + I] = this[WinPos + I];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public size_t GetBlockSize(size_t StartPos,size_t RequiredSize)
|
||||
{
|
||||
for (uint I=0;I<MemSize.Length;I++)
|
||||
{
|
||||
if (StartPos<MemSize[I])
|
||||
{
|
||||
return Math.Min(MemSize[I]-StartPos,RequiredSize);
|
||||
}
|
||||
}
|
||||
public size_t GetBlockSize(size_t StartPos, size_t RequiredSize)
|
||||
{
|
||||
for (uint I = 0; I < MemSize.Length; I++)
|
||||
{
|
||||
if (StartPos < MemSize[I])
|
||||
{
|
||||
return Math.Min(MemSize[I] - StartPos, RequiredSize);
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // Must never be here.
|
||||
}
|
||||
return 0; // Must never be here.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,54 +3,54 @@
|
||||
internal static class PackDef
|
||||
{
|
||||
|
||||
// Combine pack and unpack constants to class to avoid polluting global
|
||||
// namespace with numerous short names.
|
||||
public const uint MAX_LZ_MATCH = 0x1001;
|
||||
public const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3.
|
||||
public const uint LOW_DIST_REP_COUNT = 16;
|
||||
// Combine pack and unpack constants to class to avoid polluting global
|
||||
// namespace with numerous short names.
|
||||
public const uint MAX_LZ_MATCH = 0x1001;
|
||||
public const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3.
|
||||
public const uint LOW_DIST_REP_COUNT = 16;
|
||||
|
||||
public const uint NC = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC = 64;
|
||||
public const uint LDC = 16;
|
||||
public const uint RC = 44;
|
||||
public const uint HUFF_TABLE_SIZE = NC + DC + RC + LDC;
|
||||
public const uint BC = 20;
|
||||
public const uint NC = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC = 64;
|
||||
public const uint LDC = 16;
|
||||
public const uint RC = 44;
|
||||
public const uint HUFF_TABLE_SIZE = NC + DC + RC + LDC;
|
||||
public const uint BC = 20;
|
||||
|
||||
public const uint NC30 = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC30 = 60;
|
||||
public const uint LDC30 = 17;
|
||||
public const uint RC30 = 28;
|
||||
public const uint BC30 = 20;
|
||||
public const uint HUFF_TABLE_SIZE30 = NC30 + DC30 + RC30 + LDC30;
|
||||
public const uint NC30 = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC30 = 60;
|
||||
public const uint LDC30 = 17;
|
||||
public const uint RC30 = 28;
|
||||
public const uint BC30 = 20;
|
||||
public const uint HUFF_TABLE_SIZE30 = NC30 + DC30 + RC30 + LDC30;
|
||||
|
||||
public const uint NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC20 = 48;
|
||||
public const uint RC20 = 28;
|
||||
public const uint BC20 = 19;
|
||||
public const uint MC20 = 257;
|
||||
public const uint NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
public const uint DC20 = 48;
|
||||
public const uint RC20 = 28;
|
||||
public const uint BC20 = 19;
|
||||
public const uint MC20 = 257;
|
||||
|
||||
// Largest alphabet size among all values listed above.
|
||||
public const uint LARGEST_TABLE_SIZE = 306;
|
||||
// Largest alphabet size among all values listed above.
|
||||
public const uint LARGEST_TABLE_SIZE = 306;
|
||||
|
||||
// enum {
|
||||
// CODE_HUFFMAN, CODE_LZ, CODE_REPEATLZ, CODE_CACHELZ, CODE_STARTFILE,
|
||||
// CODE_ENDFILE, CODE_FILTER, CODE_FILTERDATA
|
||||
// };
|
||||
// enum {
|
||||
// CODE_HUFFMAN, CODE_LZ, CODE_REPEATLZ, CODE_CACHELZ, CODE_STARTFILE,
|
||||
// CODE_ENDFILE, CODE_FILTER, CODE_FILTERDATA
|
||||
// };
|
||||
|
||||
|
||||
//enum FilterType {
|
||||
// These values must not be changed, because we use them directly
|
||||
// in RAR5 compression and decompression code.
|
||||
public const int FILTER_DELTA = 0;
|
||||
public const int FILTER_E8 = 1;
|
||||
public const int FILTER_E8E9 = 2;
|
||||
public const int FILTER_ARM = 3;
|
||||
public const int FILTER_AUDIO = 4;
|
||||
public const int FILTER_RGB = 5;
|
||||
public const int FILTER_ITANIUM = 6;
|
||||
public const int FILTER_PPM = 7;
|
||||
public const int FILTER_NONE = 8;
|
||||
//}
|
||||
//enum FilterType {
|
||||
// These values must not be changed, because we use them directly
|
||||
// in RAR5 compression and decompression code.
|
||||
public const int FILTER_DELTA = 0;
|
||||
public const int FILTER_E8 = 1;
|
||||
public const int FILTER_E8E9 = 2;
|
||||
public const int FILTER_ARM = 3;
|
||||
public const int FILTER_AUDIO = 4;
|
||||
public const int FILTER_RGB = 5;
|
||||
public const int FILTER_ITANIUM = 6;
|
||||
public const int FILTER_PPM = 7;
|
||||
public const int FILTER_NONE = 8;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,18 +21,22 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
private Stream readStream;
|
||||
private Stream writeStream;
|
||||
|
||||
private void _UnpackCtor() {
|
||||
for (int i = 0; i < AudV.Length; i++) {
|
||||
private void _UnpackCtor()
|
||||
{
|
||||
for (int i = 0; i < AudV.Length; i++)
|
||||
{
|
||||
AudV[i] = new AudioVariables();
|
||||
}
|
||||
}
|
||||
|
||||
private int UnpIO_UnpRead(byte[] buf, int offset, int count) {
|
||||
private int UnpIO_UnpRead(byte[] buf, int offset, int count)
|
||||
{
|
||||
// NOTE: caller has logic to check for -1 for error we throw instead.
|
||||
return readStream.Read(buf, offset, count);
|
||||
}
|
||||
|
||||
private void UnpIO_UnpWrite(byte[] buf, size_t offset, uint count) {
|
||||
private void UnpIO_UnpWrite(byte[] buf, size_t offset, uint count)
|
||||
{
|
||||
writeStream.Write(buf, checked((int)offset), checked((int)count));
|
||||
}
|
||||
|
||||
@@ -49,7 +53,8 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
this.fileHeader = fileHeader;
|
||||
this.readStream = readStream;
|
||||
this.writeStream = writeStream;
|
||||
if (!fileHeader.IsStored) {
|
||||
if (!fileHeader.IsStored)
|
||||
{
|
||||
Init(fileHeader.WindowSize, fileHeader.IsSolid);
|
||||
}
|
||||
Suspended = false;
|
||||
@@ -61,7 +66,9 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
if (fileHeader.IsStored)
|
||||
{
|
||||
UnstoreFile();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
DoUnpack(fileHeader.CompressionAlgorithm, fileHeader.IsSolid);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +76,8 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
private void UnstoreFile()
|
||||
{
|
||||
var b = new byte[0x10000];
|
||||
do {
|
||||
do
|
||||
{
|
||||
int n = readStream.Read(b, 0, (int)Math.Min(b.Length, DestUnpSize));
|
||||
if (n == 0)
|
||||
{
|
||||
@@ -79,12 +87,12 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
DestUnpSize -= n;
|
||||
} while (!Suspended);
|
||||
}
|
||||
|
||||
|
||||
public bool Suspended { get; set; }
|
||||
|
||||
public long DestSize { get => DestUnpSize; }
|
||||
|
||||
public int Char
|
||||
public int Char
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -97,9 +105,10 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
}
|
||||
}
|
||||
|
||||
public int PpmEscChar { get => PPMEscChar; set => PPMEscChar = value; }
|
||||
public int PpmEscChar { get => PPMEscChar; set => PPMEscChar = value; }
|
||||
|
||||
public static byte[] EnsureCapacity(byte[] array, int length) {
|
||||
public static byte[] EnsureCapacity(byte[] array, int length)
|
||||
{
|
||||
return array.Length < length ? new byte[length] : array;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,109 +14,109 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
{
|
||||
internal partial class Unpack
|
||||
{
|
||||
//#define rotls(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n))))
|
||||
//#define rotrs(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n))))
|
||||
//#define rotl32(x,n) rotls(x,n,32)
|
||||
//#define rotr32(x,n) rotrs(x,n,32)
|
||||
//
|
||||
//inline uint RawGet2(const void *Data)
|
||||
//{
|
||||
// byte *D=(byte *)Data;
|
||||
// return D[0]+(D[1]<<8);
|
||||
//}
|
||||
//#define rotls(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n))))
|
||||
//#define rotrs(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n))))
|
||||
//#define rotl32(x,n) rotls(x,n,32)
|
||||
//#define rotr32(x,n) rotrs(x,n,32)
|
||||
//
|
||||
//inline uint RawGet2(const void *Data)
|
||||
//{
|
||||
// byte *D=(byte *)Data;
|
||||
// return D[0]+(D[1]<<8);
|
||||
//}
|
||||
|
||||
private uint32 RawGet4(byte[] D, int offset)
|
||||
{
|
||||
return (uint)(D[offset]+(D[offset+1]<<8)+(D[offset+2]<<16)+(D[offset+3]<<24));
|
||||
}
|
||||
{
|
||||
return (uint)(D[offset] + (D[offset + 1] << 8) + (D[offset + 2] << 16) + (D[offset + 3] << 24));
|
||||
}
|
||||
|
||||
//inline uint64 RawGet8(const void *Data)
|
||||
//{
|
||||
//#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
|
||||
// byte *D=(byte *)Data;
|
||||
// return INT32TO64(RawGet4(D+4),RawGet4(D));
|
||||
//#else
|
||||
// return *(uint64 *)Data;
|
||||
//#endif
|
||||
//}
|
||||
//
|
||||
//
|
||||
//inline void RawPut2(uint Field,void *Data)
|
||||
//{
|
||||
// byte *D=(byte *)Data;
|
||||
// D[0]=(byte)(Field);
|
||||
// D[1]=(byte)(Field>>8);
|
||||
//}
|
||||
//inline uint64 RawGet8(const void *Data)
|
||||
//{
|
||||
//#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
|
||||
// byte *D=(byte *)Data;
|
||||
// return INT32TO64(RawGet4(D+4),RawGet4(D));
|
||||
//#else
|
||||
// return *(uint64 *)Data;
|
||||
//#endif
|
||||
//}
|
||||
//
|
||||
//
|
||||
//inline void RawPut2(uint Field,void *Data)
|
||||
//{
|
||||
// byte *D=(byte *)Data;
|
||||
// D[0]=(byte)(Field);
|
||||
// D[1]=(byte)(Field>>8);
|
||||
//}
|
||||
|
||||
private void RawPut4(uint32 Field,byte[] D, int offset)
|
||||
{
|
||||
D[offset]=(byte)(Field);
|
||||
D[offset+1]=(byte)(Field>>8);
|
||||
D[offset+2]=(byte)(Field>>16);
|
||||
D[offset+3]=(byte)(Field>>24);
|
||||
}
|
||||
private void RawPut4(uint32 Field, byte[] D, int offset)
|
||||
{
|
||||
D[offset] = (byte)(Field);
|
||||
D[offset + 1] = (byte)(Field >> 8);
|
||||
D[offset + 2] = (byte)(Field >> 16);
|
||||
D[offset + 3] = (byte)(Field >> 24);
|
||||
}
|
||||
|
||||
//inline void RawPut8(uint64 Field,void *Data)
|
||||
//{
|
||||
//#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
|
||||
// byte *D=(byte *)Data;
|
||||
// D[0]=(byte)(Field);
|
||||
// D[1]=(byte)(Field>>8);
|
||||
// D[2]=(byte)(Field>>16);
|
||||
// D[3]=(byte)(Field>>24);
|
||||
// D[4]=(byte)(Field>>32);
|
||||
// D[5]=(byte)(Field>>40);
|
||||
// D[6]=(byte)(Field>>48);
|
||||
// D[7]=(byte)(Field>>56);
|
||||
//#else
|
||||
// *(uint64 *)Data=Field;
|
||||
//#endif
|
||||
//}
|
||||
//inline void RawPut8(uint64 Field,void *Data)
|
||||
//{
|
||||
//#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
|
||||
// byte *D=(byte *)Data;
|
||||
// D[0]=(byte)(Field);
|
||||
// D[1]=(byte)(Field>>8);
|
||||
// D[2]=(byte)(Field>>16);
|
||||
// D[3]=(byte)(Field>>24);
|
||||
// D[4]=(byte)(Field>>32);
|
||||
// D[5]=(byte)(Field>>40);
|
||||
// D[6]=(byte)(Field>>48);
|
||||
// D[7]=(byte)(Field>>56);
|
||||
//#else
|
||||
// *(uint64 *)Data=Field;
|
||||
//#endif
|
||||
//}
|
||||
|
||||
|
||||
//#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
|
||||
//#define USE_MEM_BYTESWAP
|
||||
//#endif
|
||||
//#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
|
||||
//#define USE_MEM_BYTESWAP
|
||||
//#endif
|
||||
|
||||
// Load 4 big endian bytes from memory and return uint32.
|
||||
//inline uint32 RawGetBE4(const byte *m)
|
||||
//{
|
||||
//#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
|
||||
// return _byteswap_ulong(*(uint32 *)m);
|
||||
//#elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
|
||||
// return __builtin_bswap32(*(uint32 *)m);
|
||||
//#else
|
||||
// return uint32(m[0]<<24) | uint32(m[1]<<16) | uint32(m[2]<<8) | m[3];
|
||||
//#endif
|
||||
//}
|
||||
// Load 4 big endian bytes from memory and return uint32.
|
||||
//inline uint32 RawGetBE4(const byte *m)
|
||||
//{
|
||||
//#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
|
||||
// return _byteswap_ulong(*(uint32 *)m);
|
||||
//#elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
|
||||
// return __builtin_bswap32(*(uint32 *)m);
|
||||
//#else
|
||||
// return uint32(m[0]<<24) | uint32(m[1]<<16) | uint32(m[2]<<8) | m[3];
|
||||
//#endif
|
||||
//}
|
||||
|
||||
|
||||
// Save integer to memory as big endian.
|
||||
//inline void RawPutBE4(uint32 i,byte *mem)
|
||||
//{
|
||||
//#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
|
||||
// *(uint32*)mem = _byteswap_ulong(i);
|
||||
//#elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
|
||||
// *(uint32*)mem = __builtin_bswap32(i);
|
||||
//#else
|
||||
// mem[0]=byte(i>>24);
|
||||
// mem[1]=byte(i>>16);
|
||||
// mem[2]=byte(i>>8);
|
||||
// mem[3]=byte(i);
|
||||
//#endif
|
||||
//}
|
||||
// Save integer to memory as big endian.
|
||||
//inline void RawPutBE4(uint32 i,byte *mem)
|
||||
//{
|
||||
//#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
|
||||
// *(uint32*)mem = _byteswap_ulong(i);
|
||||
//#elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
|
||||
// *(uint32*)mem = __builtin_bswap32(i);
|
||||
//#else
|
||||
// mem[0]=byte(i>>24);
|
||||
// mem[1]=byte(i>>16);
|
||||
// mem[2]=byte(i>>8);
|
||||
// mem[3]=byte(i);
|
||||
//#endif
|
||||
//}
|
||||
|
||||
|
||||
//inline uint32 ByteSwap32(uint32 i)
|
||||
//{
|
||||
//#ifdef _MSC_VER
|
||||
// return _byteswap_ulong(i);
|
||||
//#elif (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
|
||||
// return __builtin_bswap32(i);
|
||||
//#else
|
||||
// return (rotl32(i,24)&0xFF00FF00)|(rotl32(i,8)&0x00FF00FF);
|
||||
//#endif
|
||||
//}
|
||||
//inline uint32 ByteSwap32(uint32 i)
|
||||
//{
|
||||
//#ifdef _MSC_VER
|
||||
// return _byteswap_ulong(i);
|
||||
//#elif (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
|
||||
// return __builtin_bswap32(i);
|
||||
//#else
|
||||
// return (rotl32(i,24)&0xFF00FF00)|(rotl32(i,8)&0x00FF00FF);
|
||||
//#endif
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,484 +17,485 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
{
|
||||
internal partial class Unpack
|
||||
{
|
||||
private void CopyString20(uint Length,uint Distance)
|
||||
{
|
||||
LastDist=OldDist[OldDistPtr++ & 3]=Distance;
|
||||
LastLength=Length;
|
||||
DestUnpSize-=Length;
|
||||
CopyString(Length,Distance);
|
||||
}
|
||||
|
||||
|
||||
internal static class Unpack20Local {
|
||||
public static readonly byte[] LDecode={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
public static readonly byte[] LBits= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
public static readonly uint[] DDecode={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
|
||||
public static readonly byte[] DBits= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
public static readonly byte[] SDDecode={0,4,8,16,32,64,128,192};
|
||||
public static readonly byte[] SDBits= {2,2,3, 4, 5, 6, 6, 6};
|
||||
}
|
||||
|
||||
private void Unpack20(bool Solid)
|
||||
{
|
||||
uint Bits;
|
||||
|
||||
if (Suspended)
|
||||
{
|
||||
UnpPtr=WrPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpInitData(Solid);
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!Solid || !TablesRead2) && !ReadTables20())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
--DestUnpSize;
|
||||
}
|
||||
|
||||
while (DestUnpSize>=0)
|
||||
{
|
||||
UnpPtr&=MaxWinMask;
|
||||
|
||||
if (Inp.InAddr>ReadTop-30)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
|
||||
{
|
||||
UnpWriteBuf20();
|
||||
if (Suspended)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
uint AudioNumber=DecodeNumber(Inp,MD[UnpCurChannel]);
|
||||
|
||||
if (AudioNumber==256)
|
||||
{
|
||||
if (!ReadTables20())
|
||||
private void CopyString20(uint Length, uint Distance)
|
||||
{
|
||||
break;
|
||||
LastDist = OldDist[OldDistPtr++ & 3] = Distance;
|
||||
LastLength = Length;
|
||||
DestUnpSize -= Length;
|
||||
CopyString(Length, Distance);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
Window[UnpPtr++]=DecodeAudio((int)AudioNumber);
|
||||
if (++UnpCurChannel==UnpChannels)
|
||||
{
|
||||
UnpCurChannel=0;
|
||||
}
|
||||
|
||||
--DestUnpSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint Number=DecodeNumber(Inp,BlockTables.LD);
|
||||
if (Number<256)
|
||||
{
|
||||
Window[UnpPtr++]=(byte)Number;
|
||||
--DestUnpSize;
|
||||
continue;
|
||||
}
|
||||
if (Number>269)
|
||||
{
|
||||
uint Length=(uint)(LDecode[Number-=270]+3);
|
||||
if ((Bits=LBits[Number])>0)
|
||||
{
|
||||
Length+=Inp.getbits()>>(int)(16-Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
|
||||
uint DistNumber=DecodeNumber(Inp,BlockTables.DD);
|
||||
uint Distance=DDecode[DistNumber]+1;
|
||||
if ((Bits=DBits[DistNumber])>0)
|
||||
{
|
||||
Distance+=Inp.getbits()>>(int)(16-Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
|
||||
if (Distance>=0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x40000L)
|
||||
internal static class Unpack20Local
|
||||
{
|
||||
Length++;
|
||||
}
|
||||
}
|
||||
|
||||
CopyString20(Length,Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number==269)
|
||||
{
|
||||
if (!ReadTables20())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (Number==256)
|
||||
{
|
||||
CopyString20(LastLength,LastDist);
|
||||
continue;
|
||||
}
|
||||
if (Number<261)
|
||||
{
|
||||
uint Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
|
||||
uint LengthNumber=DecodeNumber(Inp,BlockTables.RD);
|
||||
uint Length=(uint)(LDecode[LengthNumber]+2);
|
||||
if ((Bits=LBits[LengthNumber])>0)
|
||||
{
|
||||
Length+=Inp.getbits()>>(int)(16-Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
if (Distance>=0x101)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x40000)
|
||||
{
|
||||
Length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
CopyString20(Length,Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number<270)
|
||||
{
|
||||
uint Distance=(uint)(SDDecode[Number-=261]+1);
|
||||
if ((Bits=SDBits[Number])>0)
|
||||
{
|
||||
Distance+=Inp.getbits()>>(int)(16-Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
CopyString20(2,Distance);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ReadLastTables();
|
||||
UnpWriteBuf20();
|
||||
}
|
||||
|
||||
private void UnpWriteBuf20()
|
||||
{
|
||||
if (UnpPtr!=WrPtr)
|
||||
{
|
||||
UnpSomeRead=true;
|
||||
}
|
||||
|
||||
if (UnpPtr<WrPtr)
|
||||
{
|
||||
UnpIO_UnpWrite(Window, WrPtr,(uint)(-(int)WrPtr & MaxWinMask));
|
||||
UnpIO_UnpWrite(Window,0,UnpPtr);
|
||||
UnpAllBuf=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpIO_UnpWrite(Window,WrPtr,UnpPtr-WrPtr);
|
||||
}
|
||||
|
||||
WrPtr=UnpPtr;
|
||||
}
|
||||
|
||||
private bool ReadTables20()
|
||||
{
|
||||
byte[] BitLength = new byte[BC20];
|
||||
byte[] Table = new byte[MC20*4];
|
||||
if (Inp.InAddr>ReadTop-25)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint BitField=Inp.getbits();
|
||||
UnpAudioBlock=(BitField & 0x8000)!=0;
|
||||
|
||||
if ((BitField & 0x4000) != 0)
|
||||
{
|
||||
new Span<byte>(UnpOldTable20).Clear();
|
||||
}
|
||||
|
||||
Inp.addbits(2);
|
||||
|
||||
uint TableSize;
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
UnpChannels=((BitField>>12) & 3)+1;
|
||||
if (UnpCurChannel>=UnpChannels)
|
||||
{
|
||||
UnpCurChannel=0;
|
||||
}
|
||||
|
||||
Inp.addbits(2);
|
||||
TableSize=MC20*UnpChannels;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableSize=NC20+DC20+RC20;
|
||||
}
|
||||
|
||||
for (uint I=0;I<BC20;I++)
|
||||
{
|
||||
BitLength[I]=(byte)(Inp.getbits() >> 12);
|
||||
Inp.addbits(4);
|
||||
}
|
||||
MakeDecodeTables(BitLength,0,BlockTables.BD,BC20);
|
||||
for (uint I=0;I<TableSize;)
|
||||
{
|
||||
if (Inp.InAddr>ReadTop-5)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint Number=DecodeNumber(Inp,BlockTables.BD);
|
||||
if (Number<16)
|
||||
{
|
||||
Table[I]=(byte)((Number+UnpOldTable20[I]) & 0xf);
|
||||
I++;
|
||||
}
|
||||
else
|
||||
if (Number==16)
|
||||
{
|
||||
uint N=(Inp.getbits() >> 14)+3;
|
||||
Inp.addbits(2);
|
||||
if (I==0)
|
||||
{
|
||||
return false; // We cannot have "repeat previous" code at the first position.
|
||||
}
|
||||
else
|
||||
{
|
||||
while (N-- > 0 && I<TableSize)
|
||||
{
|
||||
Table[I]=Table[I-1];
|
||||
I++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint N;
|
||||
if (Number==17)
|
||||
{
|
||||
N=(Inp.getbits() >> 13)+3;
|
||||
Inp.addbits(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
N=(Inp.getbits() >> 9)+11;
|
||||
Inp.addbits(7);
|
||||
}
|
||||
while (N-- > 0 && I<TableSize)
|
||||
{
|
||||
Table[I++]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
TablesRead2=true;
|
||||
if (Inp.InAddr>ReadTop)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
for (uint I=0;I<UnpChannels;I++)
|
||||
{
|
||||
MakeDecodeTables(Table,(int)(I*MC20),MD[I],MC20);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeDecodeTables(Table,0,BlockTables.LD,NC20);
|
||||
MakeDecodeTables(Table,(int)NC20,BlockTables.DD,DC20);
|
||||
MakeDecodeTables(Table,(int)(NC20+DC20),BlockTables.RD,RC20);
|
||||
}
|
||||
//x memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
|
||||
Array.Copy(Table,UnpOldTable20,UnpOldTable20.Length);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ReadLastTables()
|
||||
{
|
||||
if (ReadTop>=Inp.InAddr+5)
|
||||
{
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
if (DecodeNumber(Inp,MD[UnpCurChannel])==256)
|
||||
{
|
||||
ReadTables20();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (DecodeNumber(Inp,BlockTables.LD)==269)
|
||||
{
|
||||
ReadTables20();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UnpInitData20(bool Solid)
|
||||
{
|
||||
if (!Solid)
|
||||
{
|
||||
TablesRead2=false;
|
||||
UnpAudioBlock=false;
|
||||
UnpChannelDelta=0;
|
||||
UnpCurChannel=0;
|
||||
UnpChannels=1;
|
||||
|
||||
//memset(AudV,0,sizeof(AudV));
|
||||
AudV = new AudioVariables[4];
|
||||
new Span<byte>(UnpOldTable20).Clear();
|
||||
//memset(MD,0,sizeof(MD));
|
||||
MD = new DecodeTable[4];
|
||||
}
|
||||
}
|
||||
|
||||
private byte DecodeAudio(int Delta)
|
||||
{
|
||||
AudioVariables V=AudV[UnpCurChannel];
|
||||
V.ByteCount++;
|
||||
V.D4=V.D3;
|
||||
V.D3=V.D2;
|
||||
V.D2=V.LastDelta-V.D1;
|
||||
V.D1=V.LastDelta;
|
||||
int PCh=8*V.LastChar+V.K1*V.D1+V.K2*V.D2+V.K3*V.D3+V.K4*V.D4+V.K5*UnpChannelDelta;
|
||||
PCh=(PCh>>3) & 0xFF;
|
||||
|
||||
uint Ch=(uint)(PCh-Delta);
|
||||
|
||||
int D=(sbyte)Delta;
|
||||
// Left shift of negative value is undefined behavior in C++,
|
||||
// so we cast it to unsigned to follow the standard.
|
||||
D=(int)((uint)D<<3);
|
||||
|
||||
V.Dif[0]+=(uint)Math.Abs(D);
|
||||
V.Dif[1]+=(uint)Math.Abs(D-V.D1);
|
||||
V.Dif[2]+=(uint)Math.Abs(D+V.D1);
|
||||
V.Dif[3]+=(uint)Math.Abs(D-V.D2);
|
||||
V.Dif[4]+=(uint)Math.Abs(D+V.D2);
|
||||
V.Dif[5]+=(uint)Math.Abs(D-V.D3);
|
||||
V.Dif[6]+=(uint)Math.Abs(D+V.D3);
|
||||
V.Dif[7]+=(uint)Math.Abs(D-V.D4);
|
||||
V.Dif[8]+=(uint)Math.Abs(D+V.D4);
|
||||
V.Dif[9]+=(uint)Math.Abs(D-UnpChannelDelta);
|
||||
V.Dif[10]+=(uint)Math.Abs(D+UnpChannelDelta);
|
||||
|
||||
UnpChannelDelta=V.LastDelta=(sbyte)(Ch-V.LastChar);
|
||||
V.LastChar=(int)Ch;
|
||||
|
||||
if ((V.ByteCount & 0x1F)==0)
|
||||
{
|
||||
uint MinDif=V.Dif[0],NumMinDif=0;
|
||||
V.Dif[0]=0;
|
||||
for (uint I=1;I<V.Dif.Length;I++)
|
||||
{
|
||||
if (V.Dif[I]<MinDif)
|
||||
{
|
||||
MinDif=V.Dif[I];
|
||||
NumMinDif=I;
|
||||
}
|
||||
V.Dif[I]=0;
|
||||
}
|
||||
switch(NumMinDif)
|
||||
{
|
||||
case 1:
|
||||
if (V.K1>=-16)
|
||||
{
|
||||
V.K1--;
|
||||
public static readonly byte[] LDecode = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224 };
|
||||
public static readonly byte[] LBits = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
|
||||
public static readonly uint[] DDecode = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768U, 49152U, 65536, 98304, 131072, 196608, 262144, 327680, 393216, 458752, 524288, 589824, 655360, 720896, 786432, 851968, 917504, 983040 };
|
||||
public static readonly byte[] DBits = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
|
||||
public static readonly byte[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
|
||||
public static readonly byte[] SDBits = { 2, 2, 3, 4, 5, 6, 6, 6 };
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
if (V.K1<16)
|
||||
private void Unpack20(bool Solid)
|
||||
{
|
||||
V.K1++;
|
||||
uint Bits;
|
||||
|
||||
if (Suspended)
|
||||
{
|
||||
UnpPtr = WrPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpInitData(Solid);
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!Solid || !TablesRead2) && !ReadTables20())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
--DestUnpSize;
|
||||
}
|
||||
|
||||
while (DestUnpSize >= 0)
|
||||
{
|
||||
UnpPtr &= MaxWinMask;
|
||||
|
||||
if (Inp.InAddr > ReadTop - 30)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((WrPtr - UnpPtr) & MaxWinMask) < 270 && WrPtr != UnpPtr)
|
||||
{
|
||||
UnpWriteBuf20();
|
||||
if (Suspended)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
uint AudioNumber = DecodeNumber(Inp, MD[UnpCurChannel]);
|
||||
|
||||
if (AudioNumber == 256)
|
||||
{
|
||||
if (!ReadTables20())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
Window[UnpPtr++] = DecodeAudio((int)AudioNumber);
|
||||
if (++UnpCurChannel == UnpChannels)
|
||||
{
|
||||
UnpCurChannel = 0;
|
||||
}
|
||||
|
||||
--DestUnpSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint Number = DecodeNumber(Inp, BlockTables.LD);
|
||||
if (Number < 256)
|
||||
{
|
||||
Window[UnpPtr++] = (byte)Number;
|
||||
--DestUnpSize;
|
||||
continue;
|
||||
}
|
||||
if (Number > 269)
|
||||
{
|
||||
uint Length = (uint)(LDecode[Number -= 270] + 3);
|
||||
if ((Bits = LBits[Number]) > 0)
|
||||
{
|
||||
Length += Inp.getbits() >> (int)(16 - Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
|
||||
uint DistNumber = DecodeNumber(Inp, BlockTables.DD);
|
||||
uint Distance = DDecode[DistNumber] + 1;
|
||||
if ((Bits = DBits[DistNumber]) > 0)
|
||||
{
|
||||
Distance += Inp.getbits() >> (int)(16 - Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
|
||||
if (Distance >= 0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance >= 0x40000L)
|
||||
{
|
||||
Length++;
|
||||
}
|
||||
}
|
||||
|
||||
CopyString20(Length, Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number == 269)
|
||||
{
|
||||
if (!ReadTables20())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (Number == 256)
|
||||
{
|
||||
CopyString20(LastLength, LastDist);
|
||||
continue;
|
||||
}
|
||||
if (Number < 261)
|
||||
{
|
||||
uint Distance = OldDist[(OldDistPtr - (Number - 256)) & 3];
|
||||
uint LengthNumber = DecodeNumber(Inp, BlockTables.RD);
|
||||
uint Length = (uint)(LDecode[LengthNumber] + 2);
|
||||
if ((Bits = LBits[LengthNumber]) > 0)
|
||||
{
|
||||
Length += Inp.getbits() >> (int)(16 - Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
if (Distance >= 0x101)
|
||||
{
|
||||
Length++;
|
||||
if (Distance >= 0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance >= 0x40000)
|
||||
{
|
||||
Length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
CopyString20(Length, Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number < 270)
|
||||
{
|
||||
uint Distance = (uint)(SDDecode[Number -= 261] + 1);
|
||||
if ((Bits = SDBits[Number]) > 0)
|
||||
{
|
||||
Distance += Inp.getbits() >> (int)(16 - Bits);
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
CopyString20(2, Distance);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ReadLastTables();
|
||||
UnpWriteBuf20();
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (V.K2>=-16)
|
||||
private void UnpWriteBuf20()
|
||||
{
|
||||
V.K2--;
|
||||
if (UnpPtr != WrPtr)
|
||||
{
|
||||
UnpSomeRead = true;
|
||||
}
|
||||
|
||||
if (UnpPtr < WrPtr)
|
||||
{
|
||||
UnpIO_UnpWrite(Window, WrPtr, (uint)(-(int)WrPtr & MaxWinMask));
|
||||
UnpIO_UnpWrite(Window, 0, UnpPtr);
|
||||
UnpAllBuf = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpIO_UnpWrite(Window, WrPtr, UnpPtr - WrPtr);
|
||||
}
|
||||
|
||||
WrPtr = UnpPtr;
|
||||
}
|
||||
|
||||
break;
|
||||
case 4:
|
||||
if (V.K2<16)
|
||||
private bool ReadTables20()
|
||||
{
|
||||
V.K2++;
|
||||
byte[] BitLength = new byte[BC20];
|
||||
byte[] Table = new byte[MC20 * 4];
|
||||
if (Inp.InAddr > ReadTop - 25)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint BitField = Inp.getbits();
|
||||
UnpAudioBlock = (BitField & 0x8000) != 0;
|
||||
|
||||
if ((BitField & 0x4000) != 0)
|
||||
{
|
||||
new Span<byte>(UnpOldTable20).Clear();
|
||||
}
|
||||
|
||||
Inp.addbits(2);
|
||||
|
||||
uint TableSize;
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
UnpChannels = ((BitField >> 12) & 3) + 1;
|
||||
if (UnpCurChannel >= UnpChannels)
|
||||
{
|
||||
UnpCurChannel = 0;
|
||||
}
|
||||
|
||||
Inp.addbits(2);
|
||||
TableSize = MC20 * UnpChannels;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableSize = NC20 + DC20 + RC20;
|
||||
}
|
||||
|
||||
for (uint I = 0; I < BC20; I++)
|
||||
{
|
||||
BitLength[I] = (byte)(Inp.getbits() >> 12);
|
||||
Inp.addbits(4);
|
||||
}
|
||||
MakeDecodeTables(BitLength, 0, BlockTables.BD, BC20);
|
||||
for (uint I = 0; I < TableSize;)
|
||||
{
|
||||
if (Inp.InAddr > ReadTop - 5)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint Number = DecodeNumber(Inp, BlockTables.BD);
|
||||
if (Number < 16)
|
||||
{
|
||||
Table[I] = (byte)((Number + UnpOldTable20[I]) & 0xf);
|
||||
I++;
|
||||
}
|
||||
else
|
||||
if (Number == 16)
|
||||
{
|
||||
uint N = (Inp.getbits() >> 14) + 3;
|
||||
Inp.addbits(2);
|
||||
if (I == 0)
|
||||
{
|
||||
return false; // We cannot have "repeat previous" code at the first position.
|
||||
}
|
||||
else
|
||||
{
|
||||
while (N-- > 0 && I < TableSize)
|
||||
{
|
||||
Table[I] = Table[I - 1];
|
||||
I++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint N;
|
||||
if (Number == 17)
|
||||
{
|
||||
N = (Inp.getbits() >> 13) + 3;
|
||||
Inp.addbits(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
N = (Inp.getbits() >> 9) + 11;
|
||||
Inp.addbits(7);
|
||||
}
|
||||
while (N-- > 0 && I < TableSize)
|
||||
{
|
||||
Table[I++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
TablesRead2 = true;
|
||||
if (Inp.InAddr > ReadTop)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
for (uint I = 0; I < UnpChannels; I++)
|
||||
{
|
||||
MakeDecodeTables(Table, (int)(I * MC20), MD[I], MC20);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeDecodeTables(Table, 0, BlockTables.LD, NC20);
|
||||
MakeDecodeTables(Table, (int)NC20, BlockTables.DD, DC20);
|
||||
MakeDecodeTables(Table, (int)(NC20 + DC20), BlockTables.RD, RC20);
|
||||
}
|
||||
//x memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
|
||||
Array.Copy(Table, UnpOldTable20, UnpOldTable20.Length);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case 5:
|
||||
if (V.K3>=-16)
|
||||
private void ReadLastTables()
|
||||
{
|
||||
V.K3--;
|
||||
if (ReadTop >= Inp.InAddr + 5)
|
||||
{
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
if (DecodeNumber(Inp, MD[UnpCurChannel]) == 256)
|
||||
{
|
||||
ReadTables20();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (DecodeNumber(Inp, BlockTables.LD) == 269)
|
||||
{
|
||||
ReadTables20();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 6:
|
||||
if (V.K3<16)
|
||||
private void UnpInitData20(bool Solid)
|
||||
{
|
||||
V.K3++;
|
||||
if (!Solid)
|
||||
{
|
||||
TablesRead2 = false;
|
||||
UnpAudioBlock = false;
|
||||
UnpChannelDelta = 0;
|
||||
UnpCurChannel = 0;
|
||||
UnpChannels = 1;
|
||||
|
||||
//memset(AudV,0,sizeof(AudV));
|
||||
AudV = new AudioVariables[4];
|
||||
new Span<byte>(UnpOldTable20).Clear();
|
||||
//memset(MD,0,sizeof(MD));
|
||||
MD = new DecodeTable[4];
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 7:
|
||||
if (V.K4>=-16)
|
||||
private byte DecodeAudio(int Delta)
|
||||
{
|
||||
V.K4--;
|
||||
}
|
||||
AudioVariables V = AudV[UnpCurChannel];
|
||||
V.ByteCount++;
|
||||
V.D4 = V.D3;
|
||||
V.D3 = V.D2;
|
||||
V.D2 = V.LastDelta - V.D1;
|
||||
V.D1 = V.LastDelta;
|
||||
int PCh = 8 * V.LastChar + V.K1 * V.D1 + V.K2 * V.D2 + V.K3 * V.D3 + V.K4 * V.D4 + V.K5 * UnpChannelDelta;
|
||||
PCh = (PCh >> 3) & 0xFF;
|
||||
|
||||
break;
|
||||
case 8:
|
||||
if (V.K4<16)
|
||||
{
|
||||
V.K4++;
|
||||
}
|
||||
uint Ch = (uint)(PCh - Delta);
|
||||
|
||||
break;
|
||||
case 9:
|
||||
if (V.K5>=-16)
|
||||
{
|
||||
V.K5--;
|
||||
}
|
||||
int D = (sbyte)Delta;
|
||||
// Left shift of negative value is undefined behavior in C++,
|
||||
// so we cast it to unsigned to follow the standard.
|
||||
D = (int)((uint)D << 3);
|
||||
|
||||
break;
|
||||
case 10:
|
||||
if (V.K5<16)
|
||||
{
|
||||
V.K5++;
|
||||
}
|
||||
V.Dif[0] += (uint)Math.Abs(D);
|
||||
V.Dif[1] += (uint)Math.Abs(D - V.D1);
|
||||
V.Dif[2] += (uint)Math.Abs(D + V.D1);
|
||||
V.Dif[3] += (uint)Math.Abs(D - V.D2);
|
||||
V.Dif[4] += (uint)Math.Abs(D + V.D2);
|
||||
V.Dif[5] += (uint)Math.Abs(D - V.D3);
|
||||
V.Dif[6] += (uint)Math.Abs(D + V.D3);
|
||||
V.Dif[7] += (uint)Math.Abs(D - V.D4);
|
||||
V.Dif[8] += (uint)Math.Abs(D + V.D4);
|
||||
V.Dif[9] += (uint)Math.Abs(D - UnpChannelDelta);
|
||||
V.Dif[10] += (uint)Math.Abs(D + UnpChannelDelta);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (byte)Ch;
|
||||
}
|
||||
UnpChannelDelta = V.LastDelta = (sbyte)(Ch - V.LastChar);
|
||||
V.LastChar = (int)Ch;
|
||||
|
||||
if ((V.ByteCount & 0x1F) == 0)
|
||||
{
|
||||
uint MinDif = V.Dif[0], NumMinDif = 0;
|
||||
V.Dif[0] = 0;
|
||||
for (uint I = 1; I < V.Dif.Length; I++)
|
||||
{
|
||||
if (V.Dif[I] < MinDif)
|
||||
{
|
||||
MinDif = V.Dif[I];
|
||||
NumMinDif = I;
|
||||
}
|
||||
V.Dif[I] = 0;
|
||||
}
|
||||
switch (NumMinDif)
|
||||
{
|
||||
case 1:
|
||||
if (V.K1 >= -16)
|
||||
{
|
||||
V.K1--;
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
if (V.K1 < 16)
|
||||
{
|
||||
V.K1++;
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (V.K2 >= -16)
|
||||
{
|
||||
V.K2--;
|
||||
}
|
||||
|
||||
break;
|
||||
case 4:
|
||||
if (V.K2 < 16)
|
||||
{
|
||||
V.K2++;
|
||||
}
|
||||
|
||||
break;
|
||||
case 5:
|
||||
if (V.K3 >= -16)
|
||||
{
|
||||
V.K3--;
|
||||
}
|
||||
|
||||
break;
|
||||
case 6:
|
||||
if (V.K3 < 16)
|
||||
{
|
||||
V.K3++;
|
||||
}
|
||||
|
||||
break;
|
||||
case 7:
|
||||
if (V.K4 >= -16)
|
||||
{
|
||||
V.K4--;
|
||||
}
|
||||
|
||||
break;
|
||||
case 8:
|
||||
if (V.K4 < 16)
|
||||
{
|
||||
V.K4++;
|
||||
}
|
||||
|
||||
break;
|
||||
case 9:
|
||||
if (V.K5 >= -16)
|
||||
{
|
||||
V.K5--;
|
||||
}
|
||||
|
||||
break;
|
||||
case 10:
|
||||
if (V.K5 < 16)
|
||||
{
|
||||
V.K5++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (byte)Ch;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,183 +20,183 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
internal sealed partial class Unpack : BitInput
|
||||
{
|
||||
|
||||
public Unpack(/* ComprDataIO *DataIO */)
|
||||
//:Inp(true),VMCodeInp(true)
|
||||
: base(true)
|
||||
{
|
||||
_UnpackCtor();
|
||||
public Unpack(/* ComprDataIO *DataIO */)
|
||||
//:Inp(true),VMCodeInp(true)
|
||||
: base(true)
|
||||
{
|
||||
_UnpackCtor();
|
||||
|
||||
//UnpIO=DataIO;
|
||||
Window=null;
|
||||
Fragmented=false;
|
||||
Suspended=false;
|
||||
UnpAllBuf=false;
|
||||
UnpSomeRead=false;
|
||||
//UnpIO=DataIO;
|
||||
Window = null;
|
||||
Fragmented = false;
|
||||
Suspended = false;
|
||||
UnpAllBuf = false;
|
||||
UnpSomeRead = false;
|
||||
#if RarV2017_RAR_SMP
|
||||
MaxUserThreads=1;
|
||||
UnpThreadPool=CreateThreadPool();
|
||||
ReadBufMT=null;
|
||||
UnpThreadData=null;
|
||||
#endif
|
||||
MaxWinSize=0;
|
||||
MaxWinMask=0;
|
||||
MaxWinSize = 0;
|
||||
MaxWinMask = 0;
|
||||
|
||||
// Perform initialization, which should be done only once for all files.
|
||||
// It prevents crash if first DoUnpack call is later made with wrong
|
||||
// (true) 'Solid' value.
|
||||
UnpInitData(false);
|
||||
// Perform initialization, which should be done only once for all files.
|
||||
// It prevents crash if first DoUnpack call is later made with wrong
|
||||
// (true) 'Solid' value.
|
||||
UnpInitData(false);
|
||||
#if !RarV2017_SFX_MODULE
|
||||
// RAR 1.5 decompression initialization
|
||||
UnpInitData15(false);
|
||||
InitHuff();
|
||||
// RAR 1.5 decompression initialization
|
||||
UnpInitData15(false);
|
||||
InitHuff();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// later: may need Dispose() if we support thread pool
|
||||
//Unpack::~Unpack()
|
||||
//{
|
||||
// InitFilters30(false);
|
||||
//
|
||||
// if (Window!=null)
|
||||
// free(Window);
|
||||
//#if RarV2017_RAR_SMP
|
||||
// DestroyThreadPool(UnpThreadPool);
|
||||
// delete[] ReadBufMT;
|
||||
// delete[] UnpThreadData;
|
||||
//#endif
|
||||
//}
|
||||
// later: may need Dispose() if we support thread pool
|
||||
//Unpack::~Unpack()
|
||||
//{
|
||||
// InitFilters30(false);
|
||||
//
|
||||
// if (Window!=null)
|
||||
// free(Window);
|
||||
//#if RarV2017_RAR_SMP
|
||||
// DestroyThreadPool(UnpThreadPool);
|
||||
// delete[] ReadBufMT;
|
||||
// delete[] UnpThreadData;
|
||||
//#endif
|
||||
//}
|
||||
|
||||
private void Init(size_t WinSize,bool Solid)
|
||||
{
|
||||
// If 32-bit RAR unpacks an archive with 4 GB dictionary, the window size
|
||||
// will be 0 because of size_t overflow. Let's issue the memory error.
|
||||
if (WinSize==0)
|
||||
//ErrHandler.MemoryError();
|
||||
{
|
||||
throw new InvalidFormatException("invalid window size (possibly due to a rar file with a 4GB being unpacked on a 32-bit platform)");
|
||||
}
|
||||
private void Init(size_t WinSize, bool Solid)
|
||||
{
|
||||
// If 32-bit RAR unpacks an archive with 4 GB dictionary, the window size
|
||||
// will be 0 because of size_t overflow. Let's issue the memory error.
|
||||
if (WinSize == 0)
|
||||
//ErrHandler.MemoryError();
|
||||
{
|
||||
throw new InvalidFormatException("invalid window size (possibly due to a rar file with a 4GB being unpacked on a 32-bit platform)");
|
||||
}
|
||||
|
||||
// Minimum window size must be at least twice more than maximum possible
|
||||
// size of filter block, which is 0x10000 in RAR now. If window size is
|
||||
// smaller, we can have a block with never cleared flt->NextWindow flag
|
||||
// in UnpWriteBuf(). Minimum window size 0x20000 would be enough, but let's
|
||||
// use 0x40000 for extra safety and possible filter area size expansion.
|
||||
const size_t MinAllocSize=0x40000;
|
||||
if (WinSize<MinAllocSize)
|
||||
{
|
||||
WinSize=MinAllocSize;
|
||||
}
|
||||
// Minimum window size must be at least twice more than maximum possible
|
||||
// size of filter block, which is 0x10000 in RAR now. If window size is
|
||||
// smaller, we can have a block with never cleared flt->NextWindow flag
|
||||
// in UnpWriteBuf(). Minimum window size 0x20000 would be enough, but let's
|
||||
// use 0x40000 for extra safety and possible filter area size expansion.
|
||||
const size_t MinAllocSize = 0x40000;
|
||||
if (WinSize < MinAllocSize)
|
||||
{
|
||||
WinSize = MinAllocSize;
|
||||
}
|
||||
|
||||
if (WinSize<=MaxWinSize) // Use the already allocated window.
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (WinSize <= MaxWinSize) // Use the already allocated window.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((WinSize>>16)>0x10000) // Window size must not exceed 4 GB.
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((WinSize >> 16) > 0x10000) // Window size must not exceed 4 GB.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Archiving code guarantees that window size does not grow in the same
|
||||
// solid stream. So if we are here, we are either creating a new window
|
||||
// or increasing the size of non-solid window. So we could safely reject
|
||||
// current window data without copying them to a new window, though being
|
||||
// extra cautious, we still handle the solid window grow case below.
|
||||
bool Grow=Solid && (Window!=null || Fragmented);
|
||||
// Archiving code guarantees that window size does not grow in the same
|
||||
// solid stream. So if we are here, we are either creating a new window
|
||||
// or increasing the size of non-solid window. So we could safely reject
|
||||
// current window data without copying them to a new window, though being
|
||||
// extra cautious, we still handle the solid window grow case below.
|
||||
bool Grow = Solid && (Window != null || Fragmented);
|
||||
|
||||
// We do not handle growth for existing fragmented window.
|
||||
if (Grow && Fragmented)
|
||||
//throw std::bad_alloc();
|
||||
{
|
||||
throw new InvalidFormatException("Grow && Fragmented");
|
||||
}
|
||||
// We do not handle growth for existing fragmented window.
|
||||
if (Grow && Fragmented)
|
||||
//throw std::bad_alloc();
|
||||
{
|
||||
throw new InvalidFormatException("Grow && Fragmented");
|
||||
}
|
||||
|
||||
byte[] NewWindow=Fragmented ? null : new byte[WinSize];
|
||||
byte[] NewWindow = Fragmented ? null : new byte[WinSize];
|
||||
|
||||
if (NewWindow==null)
|
||||
{
|
||||
if (Grow || WinSize<0x1000000)
|
||||
{
|
||||
// We do not support growth for new fragmented window.
|
||||
// Also exclude RAR4 and small dictionaries.
|
||||
//throw std::bad_alloc();
|
||||
throw new InvalidFormatException("Grow || WinSize<0x1000000");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Window!=null) // If allocated by preceding files.
|
||||
{
|
||||
//free(Window);
|
||||
Window=null;
|
||||
}
|
||||
FragWindow.Init(WinSize);
|
||||
Fragmented=true;
|
||||
}
|
||||
}
|
||||
if (NewWindow == null)
|
||||
{
|
||||
if (Grow || WinSize < 0x1000000)
|
||||
{
|
||||
// We do not support growth for new fragmented window.
|
||||
// Also exclude RAR4 and small dictionaries.
|
||||
//throw std::bad_alloc();
|
||||
throw new InvalidFormatException("Grow || WinSize<0x1000000");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Window != null) // If allocated by preceding files.
|
||||
{
|
||||
//free(Window);
|
||||
Window = null;
|
||||
}
|
||||
FragWindow.Init(WinSize);
|
||||
Fragmented = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Fragmented)
|
||||
{
|
||||
// Clean the window to generate the same output when unpacking corrupt
|
||||
// RAR files, which may access unused areas of sliding dictionary.
|
||||
// sharpcompress: don't need this, freshly allocated above
|
||||
//memset(NewWindow,0,WinSize);
|
||||
if (!Fragmented)
|
||||
{
|
||||
// Clean the window to generate the same output when unpacking corrupt
|
||||
// RAR files, which may access unused areas of sliding dictionary.
|
||||
// sharpcompress: don't need this, freshly allocated above
|
||||
//memset(NewWindow,0,WinSize);
|
||||
|
||||
|
||||
// If Window is not NULL, it means that window size has grown.
|
||||
// In solid streams we need to copy data to a new window in such case.
|
||||
// RAR archiving code does not allow it in solid streams now,
|
||||
// but let's implement it anyway just in case we'll change it sometimes.
|
||||
if (Grow)
|
||||
{
|
||||
for (size_t I=1;I<=MaxWinSize;I++)
|
||||
{
|
||||
NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
|
||||
}
|
||||
}
|
||||
// If Window is not NULL, it means that window size has grown.
|
||||
// In solid streams we need to copy data to a new window in such case.
|
||||
// RAR archiving code does not allow it in solid streams now,
|
||||
// but let's implement it anyway just in case we'll change it sometimes.
|
||||
if (Grow)
|
||||
{
|
||||
for (size_t I = 1; I <= MaxWinSize; I++)
|
||||
{
|
||||
NewWindow[(UnpPtr - I) & (WinSize - 1)] = Window[(UnpPtr - I) & (MaxWinSize - 1)];
|
||||
}
|
||||
}
|
||||
|
||||
//if (Window!=null)
|
||||
// free(Window);
|
||||
Window=NewWindow;
|
||||
}
|
||||
//if (Window!=null)
|
||||
// free(Window);
|
||||
Window = NewWindow;
|
||||
}
|
||||
|
||||
MaxWinSize=WinSize;
|
||||
MaxWinMask=MaxWinSize-1;
|
||||
}
|
||||
MaxWinSize = WinSize;
|
||||
MaxWinMask = MaxWinSize - 1;
|
||||
}
|
||||
|
||||
private void DoUnpack(uint Method,bool Solid)
|
||||
{
|
||||
// Methods <50 will crash in Fragmented mode when accessing NULL Window.
|
||||
// They cannot be called in such mode now, but we check it below anyway
|
||||
// just for extra safety.
|
||||
switch(Method)
|
||||
{
|
||||
private void DoUnpack(uint Method, bool Solid)
|
||||
{
|
||||
// Methods <50 will crash in Fragmented mode when accessing NULL Window.
|
||||
// They cannot be called in such mode now, but we check it below anyway
|
||||
// just for extra safety.
|
||||
switch (Method)
|
||||
{
|
||||
#if !RarV2017_SFX_MODULE
|
||||
case 15: // rar 1.5 compression
|
||||
if (!Fragmented)
|
||||
{
|
||||
Unpack15(Solid);
|
||||
}
|
||||
case 15: // rar 1.5 compression
|
||||
if (!Fragmented)
|
||||
{
|
||||
Unpack15(Solid);
|
||||
}
|
||||
|
||||
break;
|
||||
case 20: // rar 2.x compression
|
||||
case 26: // files larger than 2GB
|
||||
if (!Fragmented)
|
||||
{
|
||||
Unpack20(Solid);
|
||||
}
|
||||
break;
|
||||
case 20: // rar 2.x compression
|
||||
case 26: // files larger than 2GB
|
||||
if (!Fragmented)
|
||||
{
|
||||
Unpack20(Solid);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
#endif
|
||||
#if !RarV2017_RAR5ONLY
|
||||
case 29: // rar 3.x compression
|
||||
if (!Fragmented)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
case 29: // rar 3.x compression
|
||||
if (!Fragmented)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
#endif
|
||||
case 50: // RAR 5.0 compression algorithm.
|
||||
case 50: // RAR 5.0 compression algorithm.
|
||||
#if RarV2017_RAR_SMP
|
||||
if (MaxUserThreads>1)
|
||||
{
|
||||
@@ -212,198 +212,198 @@ public Unpack(/* ComprDataIO *DataIO */)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Unpack5(Solid);
|
||||
break;
|
||||
Unpack5(Solid);
|
||||
break;
|
||||
#if !Rar2017_NOSTRICT
|
||||
default: throw new InvalidFormatException("unknown compression method " + Method);
|
||||
default: throw new InvalidFormatException("unknown compression method " + Method);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UnpInitData(bool Solid)
|
||||
{
|
||||
if (!Solid)
|
||||
{
|
||||
new Span<uint>(OldDist).Clear();
|
||||
OldDistPtr=0;
|
||||
LastDist=LastLength=0;
|
||||
// memset(Window,0,MaxWinSize);
|
||||
//memset(&BlockTables,0,sizeof(BlockTables));
|
||||
BlockTables = new UnpackBlockTables();
|
||||
// sharpcompress: no default ctor for struct
|
||||
BlockTables.Init();
|
||||
UnpPtr=WrPtr=0;
|
||||
WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
|
||||
}
|
||||
// Filters never share several solid files, so we can safely reset them
|
||||
// even in solid archive.
|
||||
InitFilters();
|
||||
private void UnpInitData(bool Solid)
|
||||
{
|
||||
if (!Solid)
|
||||
{
|
||||
new Span<uint>(OldDist).Clear();
|
||||
OldDistPtr = 0;
|
||||
LastDist = LastLength = 0;
|
||||
// memset(Window,0,MaxWinSize);
|
||||
//memset(&BlockTables,0,sizeof(BlockTables));
|
||||
BlockTables = new UnpackBlockTables();
|
||||
// sharpcompress: no default ctor for struct
|
||||
BlockTables.Init();
|
||||
UnpPtr = WrPtr = 0;
|
||||
WriteBorder = Math.Min(MaxWinSize, UNPACK_MAX_WRITE) & MaxWinMask;
|
||||
}
|
||||
// Filters never share several solid files, so we can safely reset them
|
||||
// even in solid archive.
|
||||
InitFilters();
|
||||
|
||||
Inp.InitBitInput();
|
||||
WrittenFileSize=0;
|
||||
ReadTop=0;
|
||||
ReadBorder=0;
|
||||
Inp.InitBitInput();
|
||||
WrittenFileSize = 0;
|
||||
ReadTop = 0;
|
||||
ReadBorder = 0;
|
||||
|
||||
//memset(&BlockHeader,0,sizeof(BlockHeader));
|
||||
BlockHeader = new UnpackBlockHeader();
|
||||
BlockHeader.BlockSize=-1; // '-1' means not defined yet.
|
||||
//memset(&BlockHeader,0,sizeof(BlockHeader));
|
||||
BlockHeader = new UnpackBlockHeader();
|
||||
BlockHeader.BlockSize = -1; // '-1' means not defined yet.
|
||||
#if !RarV2017_SFX_MODULE
|
||||
UnpInitData20(Solid);
|
||||
UnpInitData20(Solid);
|
||||
#endif
|
||||
//UnpInitData30(Solid);
|
||||
UnpInitData50(Solid);
|
||||
}
|
||||
//UnpInitData30(Solid);
|
||||
UnpInitData50(Solid);
|
||||
}
|
||||
|
||||
|
||||
// LengthTable contains the length in bits for every element of alphabet.
|
||||
// Dec is the structure to decode Huffman code/
|
||||
// Size is size of length table and DecodeNum field in Dec structure,
|
||||
private void MakeDecodeTables(byte[] LengthTable, int offset, DecodeTable Dec,uint Size)
|
||||
{
|
||||
// Size of alphabet and DecodePos array.
|
||||
Dec.MaxNum=Size;
|
||||
// LengthTable contains the length in bits for every element of alphabet.
|
||||
// Dec is the structure to decode Huffman code/
|
||||
// Size is size of length table and DecodeNum field in Dec structure,
|
||||
private void MakeDecodeTables(byte[] LengthTable, int offset, DecodeTable Dec, uint Size)
|
||||
{
|
||||
// Size of alphabet and DecodePos array.
|
||||
Dec.MaxNum = Size;
|
||||
|
||||
// Calculate how many entries for every bit length in LengthTable we have.
|
||||
uint[] LengthCount = new uint[16];
|
||||
//memset(LengthCount,0,sizeof(LengthCount));
|
||||
for (size_t I=0;I<Size;I++)
|
||||
{
|
||||
LengthCount[LengthTable[offset+I] & 0xf]++;
|
||||
}
|
||||
// Calculate how many entries for every bit length in LengthTable we have.
|
||||
uint[] LengthCount = new uint[16];
|
||||
//memset(LengthCount,0,sizeof(LengthCount));
|
||||
for (size_t I = 0; I < Size; I++)
|
||||
{
|
||||
LengthCount[LengthTable[offset + I] & 0xf]++;
|
||||
}
|
||||
|
||||
// We must not calculate the number of zero length codes.
|
||||
LengthCount[0]=0;
|
||||
// We must not calculate the number of zero length codes.
|
||||
LengthCount[0] = 0;
|
||||
|
||||
// Set the entire DecodeNum to zero.
|
||||
//memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
|
||||
new Span<ushort>(Dec.DecodeNum).Clear();
|
||||
// Set the entire DecodeNum to zero.
|
||||
//memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
|
||||
new Span<ushort>(Dec.DecodeNum).Clear();
|
||||
|
||||
// Initialize not really used entry for zero length code.
|
||||
Dec.DecodePos[0]=0;
|
||||
// Initialize not really used entry for zero length code.
|
||||
Dec.DecodePos[0] = 0;
|
||||
|
||||
// Start code for bit length 1 is 0.
|
||||
Dec.DecodeLen[0]=0;
|
||||
// Start code for bit length 1 is 0.
|
||||
Dec.DecodeLen[0] = 0;
|
||||
|
||||
// Right aligned upper limit code for current bit length.
|
||||
uint UpperLimit=0;
|
||||
// Right aligned upper limit code for current bit length.
|
||||
uint UpperLimit = 0;
|
||||
|
||||
for (int I=1;I<16;I++)
|
||||
{
|
||||
// Adjust the upper limit code.
|
||||
UpperLimit+=LengthCount[I];
|
||||
for (int I = 1; I < 16; I++)
|
||||
{
|
||||
// Adjust the upper limit code.
|
||||
UpperLimit += LengthCount[I];
|
||||
|
||||
// Left aligned upper limit code.
|
||||
uint LeftAligned=UpperLimit<<(16-I);
|
||||
// Left aligned upper limit code.
|
||||
uint LeftAligned = UpperLimit << (16 - I);
|
||||
|
||||
// Prepare the upper limit code for next bit length.
|
||||
UpperLimit*=2;
|
||||
// Prepare the upper limit code for next bit length.
|
||||
UpperLimit *= 2;
|
||||
|
||||
// Store the left aligned upper limit code.
|
||||
Dec.DecodeLen[I]=(uint)LeftAligned;
|
||||
// Store the left aligned upper limit code.
|
||||
Dec.DecodeLen[I] = (uint)LeftAligned;
|
||||
|
||||
// Every item of this array contains the sum of all preceding items.
|
||||
// So it contains the start position in code list for every bit length.
|
||||
Dec.DecodePos[I]=Dec.DecodePos[I-1]+LengthCount[I-1];
|
||||
}
|
||||
// Every item of this array contains the sum of all preceding items.
|
||||
// So it contains the start position in code list for every bit length.
|
||||
Dec.DecodePos[I] = Dec.DecodePos[I - 1] + LengthCount[I - 1];
|
||||
}
|
||||
|
||||
// Prepare the copy of DecodePos. We'll modify this copy below,
|
||||
// so we cannot use the original DecodePos.
|
||||
uint[] CopyDecodePos = new uint[Dec.DecodePos.Length];
|
||||
//memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
|
||||
Array.Copy(Dec.DecodePos, CopyDecodePos, CopyDecodePos.Length);
|
||||
// Prepare the copy of DecodePos. We'll modify this copy below,
|
||||
// so we cannot use the original DecodePos.
|
||||
uint[] CopyDecodePos = new uint[Dec.DecodePos.Length];
|
||||
//memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
|
||||
Array.Copy(Dec.DecodePos, CopyDecodePos, CopyDecodePos.Length);
|
||||
|
||||
// For every bit length in the bit length table and so for every item
|
||||
// of alphabet.
|
||||
for (uint I=0;I<Size;I++)
|
||||
{
|
||||
// Get the current bit length.
|
||||
byte _CurBitLength=(byte)(LengthTable[offset+I] & 0xf);
|
||||
// For every bit length in the bit length table and so for every item
|
||||
// of alphabet.
|
||||
for (uint I = 0; I < Size; I++)
|
||||
{
|
||||
// Get the current bit length.
|
||||
byte _CurBitLength = (byte)(LengthTable[offset + I] & 0xf);
|
||||
|
||||
if (_CurBitLength!=0)
|
||||
{
|
||||
// Last position in code list for current bit length.
|
||||
uint LastPos=CopyDecodePos[_CurBitLength];
|
||||
if (_CurBitLength != 0)
|
||||
{
|
||||
// Last position in code list for current bit length.
|
||||
uint LastPos = CopyDecodePos[_CurBitLength];
|
||||
|
||||
// Prepare the decode table, so this position in code list will be
|
||||
// decoded to current alphabet item number.
|
||||
Dec.DecodeNum[LastPos]=(ushort)I;
|
||||
// Prepare the decode table, so this position in code list will be
|
||||
// decoded to current alphabet item number.
|
||||
Dec.DecodeNum[LastPos] = (ushort)I;
|
||||
|
||||
// We'll use next position number for this bit length next time.
|
||||
// So we pass through the entire range of positions available
|
||||
// for every bit length.
|
||||
CopyDecodePos[_CurBitLength]++;
|
||||
}
|
||||
}
|
||||
// We'll use next position number for this bit length next time.
|
||||
// So we pass through the entire range of positions available
|
||||
// for every bit length.
|
||||
CopyDecodePos[_CurBitLength]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Define the number of bits to process in quick mode. We use more bits
|
||||
// for larger alphabets. More bits means that more codes will be processed
|
||||
// in quick mode, but also that more time will be spent to preparation
|
||||
// of tables for quick decode.
|
||||
switch (Size)
|
||||
{
|
||||
case NC:
|
||||
case NC20:
|
||||
case NC30:
|
||||
Dec.QuickBits=MAX_QUICK_DECODE_BITS;
|
||||
break;
|
||||
default:
|
||||
Dec.QuickBits=MAX_QUICK_DECODE_BITS-3;
|
||||
break;
|
||||
}
|
||||
// Define the number of bits to process in quick mode. We use more bits
|
||||
// for larger alphabets. More bits means that more codes will be processed
|
||||
// in quick mode, but also that more time will be spent to preparation
|
||||
// of tables for quick decode.
|
||||
switch (Size)
|
||||
{
|
||||
case NC:
|
||||
case NC20:
|
||||
case NC30:
|
||||
Dec.QuickBits = MAX_QUICK_DECODE_BITS;
|
||||
break;
|
||||
default:
|
||||
Dec.QuickBits = MAX_QUICK_DECODE_BITS - 3;
|
||||
break;
|
||||
}
|
||||
|
||||
// Size of tables for quick mode.
|
||||
uint QuickDataSize=1U<<(int)Dec.QuickBits;
|
||||
// Size of tables for quick mode.
|
||||
uint QuickDataSize = 1U << (int)Dec.QuickBits;
|
||||
|
||||
// Bit length for current code, start from 1 bit codes. It is important
|
||||
// to use 1 bit instead of 0 for minimum code length, so we are moving
|
||||
// forward even when processing a corrupt archive.
|
||||
//uint CurBitLength=1;
|
||||
byte CurBitLength=1;
|
||||
// Bit length for current code, start from 1 bit codes. It is important
|
||||
// to use 1 bit instead of 0 for minimum code length, so we are moving
|
||||
// forward even when processing a corrupt archive.
|
||||
//uint CurBitLength=1;
|
||||
byte CurBitLength = 1;
|
||||
|
||||
// For every right aligned bit string which supports the quick decoding.
|
||||
for (uint Code=0;Code<QuickDataSize;Code++)
|
||||
{
|
||||
// Left align the current code, so it will be in usual bit field format.
|
||||
uint BitField=Code<<(int)(16-Dec.QuickBits);
|
||||
// For every right aligned bit string which supports the quick decoding.
|
||||
for (uint Code = 0; Code < QuickDataSize; Code++)
|
||||
{
|
||||
// Left align the current code, so it will be in usual bit field format.
|
||||
uint BitField = Code << (int)(16 - Dec.QuickBits);
|
||||
|
||||
// Prepare the table for quick decoding of bit lengths.
|
||||
// Prepare the table for quick decoding of bit lengths.
|
||||
|
||||
// Find the upper limit for current bit field and adjust the bit length
|
||||
// accordingly if necessary.
|
||||
while (CurBitLength<Dec.DecodeLen.Length && BitField>=Dec.DecodeLen[CurBitLength])
|
||||
{
|
||||
CurBitLength++;
|
||||
}
|
||||
// Find the upper limit for current bit field and adjust the bit length
|
||||
// accordingly if necessary.
|
||||
while (CurBitLength < Dec.DecodeLen.Length && BitField >= Dec.DecodeLen[CurBitLength])
|
||||
{
|
||||
CurBitLength++;
|
||||
}
|
||||
|
||||
// Translation of right aligned bit string to bit length.
|
||||
Dec.QuickLen[Code]=CurBitLength;
|
||||
// Translation of right aligned bit string to bit length.
|
||||
Dec.QuickLen[Code] = CurBitLength;
|
||||
|
||||
// Prepare the table for quick translation of position in code list
|
||||
// to position in alphabet.
|
||||
// Prepare the table for quick translation of position in code list
|
||||
// to position in alphabet.
|
||||
|
||||
// Calculate the distance from the start code for current bit length.
|
||||
uint Dist=BitField-Dec.DecodeLen[CurBitLength-1];
|
||||
// Calculate the distance from the start code for current bit length.
|
||||
uint Dist = BitField - Dec.DecodeLen[CurBitLength - 1];
|
||||
|
||||
// Right align the distance.
|
||||
Dist>>=(16-CurBitLength);
|
||||
// Right align the distance.
|
||||
Dist >>= (16 - CurBitLength);
|
||||
|
||||
// Now we can calculate the position in the code list. It is the sum
|
||||
// of first position for current bit length and right aligned distance
|
||||
// between our bit field and start code for current bit length.
|
||||
uint Pos;
|
||||
if (CurBitLength<Dec.DecodePos.Length &&
|
||||
(Pos=Dec.DecodePos[CurBitLength]+Dist)<Size)
|
||||
{
|
||||
// Define the code to alphabet number translation.
|
||||
Dec.QuickNum[Code]=Dec.DecodeNum[Pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can be here for length table filled with zeroes only (empty).
|
||||
Dec.QuickNum[Code]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now we can calculate the position in the code list. It is the sum
|
||||
// of first position for current bit length and right aligned distance
|
||||
// between our bit field and start code for current bit length.
|
||||
uint Pos;
|
||||
if (CurBitLength < Dec.DecodePos.Length &&
|
||||
(Pos = Dec.DecodePos[CurBitLength] + Dist) < Size)
|
||||
{
|
||||
// Define the code to alphabet number translation.
|
||||
Dec.QuickNum[Code] = Dec.DecodeNum[Pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can be here for length table filled with zeroes only (empty).
|
||||
Dec.QuickNum[Code] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,165 +15,165 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
{
|
||||
internal partial class Unpack
|
||||
{
|
||||
private void InsertOldDist(uint Distance)
|
||||
{
|
||||
OldDist[3]=OldDist[2];
|
||||
OldDist[2]=OldDist[1];
|
||||
OldDist[1]=OldDist[0];
|
||||
OldDist[0]=Distance;
|
||||
}
|
||||
private void InsertOldDist(uint Distance)
|
||||
{
|
||||
OldDist[3] = OldDist[2];
|
||||
OldDist[2] = OldDist[1];
|
||||
OldDist[1] = OldDist[0];
|
||||
OldDist[0] = Distance;
|
||||
}
|
||||
|
||||
//#ifdef _MSC_VER
|
||||
//#define FAST_MEMCPY
|
||||
//#endif
|
||||
//#ifdef _MSC_VER
|
||||
//#define FAST_MEMCPY
|
||||
//#endif
|
||||
|
||||
private void CopyString(uint Length,uint Distance)
|
||||
{
|
||||
size_t SrcPtr=UnpPtr-Distance;
|
||||
private void CopyString(uint Length, uint Distance)
|
||||
{
|
||||
size_t SrcPtr = UnpPtr - Distance;
|
||||
|
||||
if (SrcPtr<MaxWinSize-MAX_LZ_MATCH && UnpPtr<MaxWinSize-MAX_LZ_MATCH)
|
||||
{
|
||||
// If we are not close to end of window, we do not need to waste time
|
||||
// to "& MaxWinMask" pointer protection.
|
||||
if (SrcPtr < MaxWinSize - MAX_LZ_MATCH && UnpPtr < MaxWinSize - MAX_LZ_MATCH)
|
||||
{
|
||||
// If we are not close to end of window, we do not need to waste time
|
||||
// to "& MaxWinMask" pointer protection.
|
||||
|
||||
// TODO: sharpcompress: non-optimized loop, we may be able to unroll and speed up
|
||||
var Window = this.Window;
|
||||
while (Length-- > 0)
|
||||
{
|
||||
Window[UnpPtr++] = Window[SrcPtr++];
|
||||
}
|
||||
// TODO: sharpcompress: non-optimized loop, we may be able to unroll and speed up
|
||||
var Window = this.Window;
|
||||
while (Length-- > 0)
|
||||
{
|
||||
Window[UnpPtr++] = Window[SrcPtr++];
|
||||
}
|
||||
|
||||
// byte *Src=Window+SrcPtr;
|
||||
// byte *Dest=Window+UnpPtr;
|
||||
// UnpPtr+=Length;
|
||||
//
|
||||
//#if FAST_MEMCPY
|
||||
// if (Distance<Length) // Overlapping strings
|
||||
//#endif
|
||||
// while (Length>=8)
|
||||
// {
|
||||
// Dest[0]=Src[0];
|
||||
// Dest[1]=Src[1];
|
||||
// Dest[2]=Src[2];
|
||||
// Dest[3]=Src[3];
|
||||
// Dest[4]=Src[4];
|
||||
// Dest[5]=Src[5];
|
||||
// Dest[6]=Src[6];
|
||||
// Dest[7]=Src[7];
|
||||
//
|
||||
// Src+=8;
|
||||
// Dest+=8;
|
||||
// Length-=8;
|
||||
// }
|
||||
//#if FAST_MEMCPY
|
||||
// else
|
||||
// while (Length>=8)
|
||||
// {
|
||||
// // In theory we still could overlap here.
|
||||
// // Supposing Distance == MaxWinSize - 1 we have memcpy(Src, Src + 1, 8).
|
||||
// // But for real RAR archives Distance <= MaxWinSize - MAX_LZ_MATCH
|
||||
// // always, so overlap here is impossible.
|
||||
//
|
||||
// // This memcpy expanded inline by MSVC. We could also use uint64
|
||||
// // assignment, which seems to provide about the same speed.
|
||||
// memcpy(Dest,Src,8);
|
||||
//
|
||||
// Src+=8;
|
||||
// Dest+=8;
|
||||
// Length-=8;
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
// // Unroll the loop for 0 - 7 bytes left. Note that we use nested "if"s.
|
||||
// if (Length>0) { Dest[0]=Src[0];
|
||||
// if (Length>1) { Dest[1]=Src[1];
|
||||
// if (Length>2) { Dest[2]=Src[2];
|
||||
// if (Length>3) { Dest[3]=Src[3];
|
||||
// if (Length>4) { Dest[4]=Src[4];
|
||||
// if (Length>5) { Dest[5]=Src[5];
|
||||
// if (Length>6) { Dest[6]=Src[6]; } } } } } } } // Close all nested "if"s.
|
||||
}
|
||||
else
|
||||
{
|
||||
while (Length-- > 0) // Slow copying with all possible precautions.
|
||||
{
|
||||
Window[UnpPtr]=Window[SrcPtr++ & MaxWinMask];
|
||||
// We need to have masked UnpPtr after quit from loop, so it must not
|
||||
// be replaced with 'Window[UnpPtr++ & MaxWinMask]'
|
||||
UnpPtr=(UnpPtr+1) & MaxWinMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
// byte *Src=Window+SrcPtr;
|
||||
// byte *Dest=Window+UnpPtr;
|
||||
// UnpPtr+=Length;
|
||||
//
|
||||
//#if FAST_MEMCPY
|
||||
// if (Distance<Length) // Overlapping strings
|
||||
//#endif
|
||||
// while (Length>=8)
|
||||
// {
|
||||
// Dest[0]=Src[0];
|
||||
// Dest[1]=Src[1];
|
||||
// Dest[2]=Src[2];
|
||||
// Dest[3]=Src[3];
|
||||
// Dest[4]=Src[4];
|
||||
// Dest[5]=Src[5];
|
||||
// Dest[6]=Src[6];
|
||||
// Dest[7]=Src[7];
|
||||
//
|
||||
// Src+=8;
|
||||
// Dest+=8;
|
||||
// Length-=8;
|
||||
// }
|
||||
//#if FAST_MEMCPY
|
||||
// else
|
||||
// while (Length>=8)
|
||||
// {
|
||||
// // In theory we still could overlap here.
|
||||
// // Supposing Distance == MaxWinSize - 1 we have memcpy(Src, Src + 1, 8).
|
||||
// // But for real RAR archives Distance <= MaxWinSize - MAX_LZ_MATCH
|
||||
// // always, so overlap here is impossible.
|
||||
//
|
||||
// // This memcpy expanded inline by MSVC. We could also use uint64
|
||||
// // assignment, which seems to provide about the same speed.
|
||||
// memcpy(Dest,Src,8);
|
||||
//
|
||||
// Src+=8;
|
||||
// Dest+=8;
|
||||
// Length-=8;
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
// // Unroll the loop for 0 - 7 bytes left. Note that we use nested "if"s.
|
||||
// if (Length>0) { Dest[0]=Src[0];
|
||||
// if (Length>1) { Dest[1]=Src[1];
|
||||
// if (Length>2) { Dest[2]=Src[2];
|
||||
// if (Length>3) { Dest[3]=Src[3];
|
||||
// if (Length>4) { Dest[4]=Src[4];
|
||||
// if (Length>5) { Dest[5]=Src[5];
|
||||
// if (Length>6) { Dest[6]=Src[6]; } } } } } } } // Close all nested "if"s.
|
||||
}
|
||||
else
|
||||
{
|
||||
while (Length-- > 0) // Slow copying with all possible precautions.
|
||||
{
|
||||
Window[UnpPtr] = Window[SrcPtr++ & MaxWinMask];
|
||||
// We need to have masked UnpPtr after quit from loop, so it must not
|
||||
// be replaced with 'Window[UnpPtr++ & MaxWinMask]'
|
||||
UnpPtr = (UnpPtr + 1) & MaxWinMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private uint DecodeNumber(BitInput Inp,DecodeTable Dec)
|
||||
{
|
||||
// Left aligned 15 bit length raw bit field.
|
||||
uint BitField=Inp.getbits() & 0xfffe;
|
||||
private uint DecodeNumber(BitInput Inp, DecodeTable Dec)
|
||||
{
|
||||
// Left aligned 15 bit length raw bit field.
|
||||
uint BitField = Inp.getbits() & 0xfffe;
|
||||
|
||||
if (BitField<Dec.DecodeLen[Dec.QuickBits])
|
||||
{
|
||||
uint Code=BitField>>(int)(16-Dec.QuickBits);
|
||||
Inp.addbits(Dec.QuickLen[Code]);
|
||||
return Dec.QuickNum[Code];
|
||||
}
|
||||
if (BitField < Dec.DecodeLen[Dec.QuickBits])
|
||||
{
|
||||
uint Code = BitField >> (int)(16 - Dec.QuickBits);
|
||||
Inp.addbits(Dec.QuickLen[Code]);
|
||||
return Dec.QuickNum[Code];
|
||||
}
|
||||
|
||||
// Detect the real bit length for current code.
|
||||
uint Bits=15;
|
||||
for (uint I=Dec.QuickBits+1;I<15;I++)
|
||||
{
|
||||
if (BitField<Dec.DecodeLen[I])
|
||||
{
|
||||
Bits=I;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Detect the real bit length for current code.
|
||||
uint Bits = 15;
|
||||
for (uint I = Dec.QuickBits + 1; I < 15; I++)
|
||||
{
|
||||
if (BitField < Dec.DecodeLen[I])
|
||||
{
|
||||
Bits = I;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Inp.addbits(Bits);
|
||||
|
||||
// Calculate the distance from the start code for current bit length.
|
||||
uint Dist=BitField-Dec.DecodeLen[Bits-1];
|
||||
Inp.addbits(Bits);
|
||||
|
||||
// Start codes are left aligned, but we need the normal right aligned
|
||||
// number. So we shift the distance to the right.
|
||||
Dist>>=(int)(16-Bits);
|
||||
// Calculate the distance from the start code for current bit length.
|
||||
uint Dist = BitField - Dec.DecodeLen[Bits - 1];
|
||||
|
||||
// Now we can calculate the position in the code list. It is the sum
|
||||
// of first position for current bit length and right aligned distance
|
||||
// between our bit field and start code for current bit length.
|
||||
uint Pos=Dec.DecodePos[Bits]+Dist;
|
||||
// Start codes are left aligned, but we need the normal right aligned
|
||||
// number. So we shift the distance to the right.
|
||||
Dist >>= (int)(16 - Bits);
|
||||
|
||||
// Out of bounds safety check required for damaged archives.
|
||||
if (Pos>=Dec.MaxNum)
|
||||
{
|
||||
Pos=0;
|
||||
}
|
||||
// Now we can calculate the position in the code list. It is the sum
|
||||
// of first position for current bit length and right aligned distance
|
||||
// between our bit field and start code for current bit length.
|
||||
uint Pos = Dec.DecodePos[Bits] + Dist;
|
||||
|
||||
// Convert the position in the code list to position in alphabet
|
||||
// and return it.
|
||||
return Dec.DecodeNum[Pos];
|
||||
}
|
||||
// Out of bounds safety check required for damaged archives.
|
||||
if (Pos >= Dec.MaxNum)
|
||||
{
|
||||
Pos = 0;
|
||||
}
|
||||
|
||||
private uint SlotToLength(BitInput Inp,uint Slot)
|
||||
{
|
||||
uint LBits,Length=2;
|
||||
if (Slot<8)
|
||||
{
|
||||
LBits=0;
|
||||
Length+=Slot;
|
||||
}
|
||||
else
|
||||
{
|
||||
LBits=Slot/4-1;
|
||||
Length+=(4 | (Slot & 3)) << (int)LBits;
|
||||
}
|
||||
// Convert the position in the code list to position in alphabet
|
||||
// and return it.
|
||||
return Dec.DecodeNum[Pos];
|
||||
}
|
||||
|
||||
if (LBits>0)
|
||||
{
|
||||
Length+=Inp.getbits()>>(int)(16-LBits);
|
||||
Inp.addbits(LBits);
|
||||
}
|
||||
return Length;
|
||||
}
|
||||
private uint SlotToLength(BitInput Inp, uint Slot)
|
||||
{
|
||||
uint LBits, Length = 2;
|
||||
if (Slot < 8)
|
||||
{
|
||||
LBits = 0;
|
||||
Length += Slot;
|
||||
}
|
||||
else
|
||||
{
|
||||
LBits = Slot / 4 - 1;
|
||||
Length += (4 | (Slot & 3)) << (int)LBits;
|
||||
}
|
||||
|
||||
if (LBits > 0)
|
||||
{
|
||||
Length += Inp.getbits() >> (int)(16 - LBits);
|
||||
Inp.addbits(LBits);
|
||||
}
|
||||
return Length;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,101 +24,102 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
{
|
||||
|
||||
|
||||
// Maximum allowed number of compressed bits processed in quick mode.
|
||||
public const int MAX_QUICK_DECODE_BITS =10;
|
||||
// Maximum allowed number of compressed bits processed in quick mode.
|
||||
public const int MAX_QUICK_DECODE_BITS = 10;
|
||||
|
||||
// Maximum number of filters per entire data block. Must be at least
|
||||
// twice more than MAX_PACK_FILTERS to store filters from two data blocks.
|
||||
public const int MAX_UNPACK_FILTERS =8192;
|
||||
// Maximum number of filters per entire data block. Must be at least
|
||||
// twice more than MAX_PACK_FILTERS to store filters from two data blocks.
|
||||
public const int MAX_UNPACK_FILTERS = 8192;
|
||||
|
||||
// Maximum number of filters per entire data block for RAR3 unpack.
|
||||
// Must be at least twice more than v3_MAX_PACK_FILTERS to store filters
|
||||
// from two data blocks.
|
||||
public const int MAX3_UNPACK_FILTERS =8192;
|
||||
// Maximum number of filters per entire data block for RAR3 unpack.
|
||||
// Must be at least twice more than v3_MAX_PACK_FILTERS to store filters
|
||||
// from two data blocks.
|
||||
public const int MAX3_UNPACK_FILTERS = 8192;
|
||||
|
||||
// Limit maximum number of channels in RAR3 delta filter to some reasonable
|
||||
// value to prevent too slow processing of corrupt archives with invalid
|
||||
// channels number. Must be equal or larger than v3_MAX_FILTER_CHANNELS.
|
||||
// No need to provide it for RAR5, which uses only 5 bits to store channels.
|
||||
private const int MAX3_UNPACK_CHANNELS =1024;
|
||||
// Limit maximum number of channels in RAR3 delta filter to some reasonable
|
||||
// value to prevent too slow processing of corrupt archives with invalid
|
||||
// channels number. Must be equal or larger than v3_MAX_FILTER_CHANNELS.
|
||||
// No need to provide it for RAR5, which uses only 5 bits to store channels.
|
||||
private const int MAX3_UNPACK_CHANNELS = 1024;
|
||||
|
||||
// Maximum size of single filter block. We restrict it to limit memory
|
||||
// allocation. Must be equal or larger than MAX_ANALYZE_SIZE.
|
||||
public const int MAX_FILTER_BLOCK_SIZE =0x400000;
|
||||
// Maximum size of single filter block. We restrict it to limit memory
|
||||
// allocation. Must be equal or larger than MAX_ANALYZE_SIZE.
|
||||
public const int MAX_FILTER_BLOCK_SIZE = 0x400000;
|
||||
|
||||
// Write data in 4 MB or smaller blocks. Must not exceed PACK_MAX_WRITE,
|
||||
// so we keep number of buffered filter in unpacker reasonable.
|
||||
public const int UNPACK_MAX_WRITE =0x400000;
|
||||
// Write data in 4 MB or smaller blocks. Must not exceed PACK_MAX_WRITE,
|
||||
// so we keep number of buffered filter in unpacker reasonable.
|
||||
public const int UNPACK_MAX_WRITE = 0x400000;
|
||||
}
|
||||
|
||||
// Decode compressed bit fields to alphabet numbers.
|
||||
// Decode compressed bit fields to alphabet numbers.
|
||||
internal sealed class DecodeTable
|
||||
{
|
||||
// Real size of DecodeNum table.
|
||||
public uint MaxNum;
|
||||
{
|
||||
// Real size of DecodeNum table.
|
||||
public uint MaxNum;
|
||||
|
||||
// Left aligned start and upper limit codes defining code space
|
||||
// ranges for bit lengths. DecodeLen[BitLength-1] defines the start of
|
||||
// range for bit length and DecodeLen[BitLength] defines next code
|
||||
// after the end of range or in other words the upper limit code
|
||||
// for specified bit length.
|
||||
public readonly uint[] DecodeLen = new uint[16];
|
||||
// Left aligned start and upper limit codes defining code space
|
||||
// ranges for bit lengths. DecodeLen[BitLength-1] defines the start of
|
||||
// range for bit length and DecodeLen[BitLength] defines next code
|
||||
// after the end of range or in other words the upper limit code
|
||||
// for specified bit length.
|
||||
public readonly uint[] DecodeLen = new uint[16];
|
||||
|
||||
// Every item of this array contains the sum of all preceding items.
|
||||
// So it contains the start position in code list for every bit length.
|
||||
public readonly uint[] DecodePos = new uint[16];
|
||||
// Every item of this array contains the sum of all preceding items.
|
||||
// So it contains the start position in code list for every bit length.
|
||||
public readonly uint[] DecodePos = new uint[16];
|
||||
|
||||
// Number of compressed bits processed in quick mode.
|
||||
// Must not exceed MAX_QUICK_DECODE_BITS.
|
||||
public uint QuickBits;
|
||||
// Number of compressed bits processed in quick mode.
|
||||
// Must not exceed MAX_QUICK_DECODE_BITS.
|
||||
public uint QuickBits;
|
||||
|
||||
// Translates compressed bits (up to QuickBits length)
|
||||
// to bit length in quick mode.
|
||||
public readonly byte[] QuickLen = new byte[1<<MAX_QUICK_DECODE_BITS];
|
||||
// Translates compressed bits (up to QuickBits length)
|
||||
// to bit length in quick mode.
|
||||
public readonly byte[] QuickLen = new byte[1 << MAX_QUICK_DECODE_BITS];
|
||||
|
||||
// Translates compressed bits (up to QuickBits length)
|
||||
// to position in alphabet in quick mode.
|
||||
// 'ushort' saves some memory and even provides a little speed gain
|
||||
// comparting to 'uint' here.
|
||||
public readonly ushort[] QuickNum = new ushort[1<<MAX_QUICK_DECODE_BITS];
|
||||
// Translates compressed bits (up to QuickBits length)
|
||||
// to position in alphabet in quick mode.
|
||||
// 'ushort' saves some memory and even provides a little speed gain
|
||||
// comparting to 'uint' here.
|
||||
public readonly ushort[] QuickNum = new ushort[1 << MAX_QUICK_DECODE_BITS];
|
||||
|
||||
// Translate the position in code list to position in alphabet.
|
||||
// We do not allocate it dynamically to avoid performance overhead
|
||||
// introduced by pointer, so we use the largest possible table size
|
||||
// as array dimension. Real size of this array is defined in MaxNum.
|
||||
// We use this array if compressed bit field is too lengthy
|
||||
// for QuickLen based translation.
|
||||
// 'ushort' saves some memory and even provides a little speed gain
|
||||
// comparting to 'uint' here.
|
||||
public readonly ushort[] DecodeNum = new ushort[LARGEST_TABLE_SIZE];
|
||||
};
|
||||
// Translate the position in code list to position in alphabet.
|
||||
// We do not allocate it dynamically to avoid performance overhead
|
||||
// introduced by pointer, so we use the largest possible table size
|
||||
// as array dimension. Real size of this array is defined in MaxNum.
|
||||
// We use this array if compressed bit field is too lengthy
|
||||
// for QuickLen based translation.
|
||||
// 'ushort' saves some memory and even provides a little speed gain
|
||||
// comparting to 'uint' here.
|
||||
public readonly ushort[] DecodeNum = new ushort[LARGEST_TABLE_SIZE];
|
||||
};
|
||||
|
||||
internal struct UnpackBlockHeader
|
||||
{
|
||||
public int BlockSize;
|
||||
public int BlockBitSize;
|
||||
public int BlockStart;
|
||||
public int HeaderSize;
|
||||
public bool LastBlockInFile;
|
||||
public bool TablePresent;
|
||||
};
|
||||
{
|
||||
public int BlockSize;
|
||||
public int BlockBitSize;
|
||||
public int BlockStart;
|
||||
public int HeaderSize;
|
||||
public bool LastBlockInFile;
|
||||
public bool TablePresent;
|
||||
};
|
||||
|
||||
internal struct UnpackBlockTables
|
||||
{
|
||||
public DecodeTable LD; // Decode literals.
|
||||
public DecodeTable DD; // Decode distances.
|
||||
public DecodeTable LDD; // Decode lower bits of distances.
|
||||
public DecodeTable RD; // Decode repeating distances.
|
||||
public DecodeTable BD; // Decode bit lengths in Huffman table.
|
||||
{
|
||||
public DecodeTable LD; // Decode literals.
|
||||
public DecodeTable DD; // Decode distances.
|
||||
public DecodeTable LDD; // Decode lower bits of distances.
|
||||
public DecodeTable RD; // Decode repeating distances.
|
||||
public DecodeTable BD; // Decode bit lengths in Huffman table.
|
||||
|
||||
public void Init() {
|
||||
LD = new DecodeTable();
|
||||
DD = new DecodeTable();
|
||||
LDD = new DecodeTable();
|
||||
RD = new DecodeTable();
|
||||
BD = new DecodeTable();
|
||||
}
|
||||
};
|
||||
public void Init()
|
||||
{
|
||||
LD = new DecodeTable();
|
||||
DD = new DecodeTable();
|
||||
LDD = new DecodeTable();
|
||||
RD = new DecodeTable();
|
||||
BD = new DecodeTable();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#if RarV2017_RAR_SMP
|
||||
@@ -171,95 +172,95 @@ struct UnpackThreadData
|
||||
#endif
|
||||
|
||||
|
||||
//struct UnpackFilter
|
||||
//struct UnpackFilter
|
||||
internal class UnpackFilter
|
||||
{
|
||||
public byte Type;
|
||||
public uint BlockStart;
|
||||
public uint BlockLength;
|
||||
public byte Channels;
|
||||
// uint Width;
|
||||
// byte PosR;
|
||||
public bool NextWindow;
|
||||
};
|
||||
{
|
||||
public byte Type;
|
||||
public uint BlockStart;
|
||||
public uint BlockLength;
|
||||
public byte Channels;
|
||||
// uint Width;
|
||||
// byte PosR;
|
||||
public bool NextWindow;
|
||||
};
|
||||
|
||||
|
||||
//struct UnpackFilter30
|
||||
//struct UnpackFilter30
|
||||
internal class UnpackFilter30
|
||||
{
|
||||
public uint BlockStart;
|
||||
public uint BlockLength;
|
||||
public bool NextWindow;
|
||||
{
|
||||
public uint BlockStart;
|
||||
public uint BlockLength;
|
||||
public bool NextWindow;
|
||||
|
||||
// Position of parent filter in Filters array used as prototype for filter
|
||||
// in PrgStack array. Not defined for filters in Filters array.
|
||||
public uint ParentFilter;
|
||||
// Position of parent filter in Filters array used as prototype for filter
|
||||
// in PrgStack array. Not defined for filters in Filters array.
|
||||
public uint ParentFilter;
|
||||
|
||||
/*#if !RarV2017_RAR5ONLY
|
||||
public VM_PreparedProgram Prg;
|
||||
#endif*/
|
||||
};
|
||||
/*#if !RarV2017_RAR5ONLY
|
||||
public VM_PreparedProgram Prg;
|
||||
#endif*/
|
||||
};
|
||||
|
||||
internal class AudioVariables // For RAR 2.0 archives only.
|
||||
{
|
||||
public int K1,K2,K3,K4,K5;
|
||||
public int D1,D2,D3,D4;
|
||||
public int LastDelta;
|
||||
public readonly uint[] Dif = new uint[11];
|
||||
public uint ByteCount;
|
||||
public int LastChar;
|
||||
};
|
||||
{
|
||||
public int K1, K2, K3, K4, K5;
|
||||
public int D1, D2, D3, D4;
|
||||
public int LastDelta;
|
||||
public readonly uint[] Dif = new uint[11];
|
||||
public uint ByteCount;
|
||||
public int LastChar;
|
||||
};
|
||||
|
||||
|
||||
// We can use the fragmented dictionary in case heap does not have the single
|
||||
// large enough memory block. It is slower than normal dictionary.
|
||||
// We can use the fragmented dictionary in case heap does not have the single
|
||||
// large enough memory block. It is slower than normal dictionary.
|
||||
internal partial class FragmentedWindow
|
||||
{
|
||||
private const int MAX_MEM_BLOCKS=32;
|
||||
{
|
||||
private const int MAX_MEM_BLOCKS = 32;
|
||||
|
||||
//void Reset();
|
||||
private readonly byte[][] Mem = new byte[MAX_MEM_BLOCKS][];
|
||||
private readonly size_t[] MemSize = new size_t[MAX_MEM_BLOCKS];
|
||||
//void Reset();
|
||||
private readonly byte[][] Mem = new byte[MAX_MEM_BLOCKS][];
|
||||
private readonly size_t[] MemSize = new size_t[MAX_MEM_BLOCKS];
|
||||
|
||||
//FragmentedWindow();
|
||||
//~FragmentedWindow();
|
||||
//void Init(size_t WinSize);
|
||||
//byte& operator [](size_t Item);
|
||||
//void CopyString(uint Length,uint Distance,size_t &UnpPtr,size_t MaxWinMask);
|
||||
//void CopyData(byte *Dest,size_t WinPos,size_t Size);
|
||||
//size_t GetBlockSize(size_t StartPos,size_t RequiredSize);
|
||||
};
|
||||
//FragmentedWindow();
|
||||
//~FragmentedWindow();
|
||||
//void Init(size_t WinSize);
|
||||
//byte& operator [](size_t Item);
|
||||
//void CopyString(uint Length,uint Distance,size_t &UnpPtr,size_t MaxWinMask);
|
||||
//void CopyData(byte *Dest,size_t WinPos,size_t Size);
|
||||
//size_t GetBlockSize(size_t StartPos,size_t RequiredSize);
|
||||
};
|
||||
|
||||
|
||||
internal partial class Unpack
|
||||
{
|
||||
internal partial class Unpack
|
||||
{
|
||||
|
||||
//void Unpack5(bool Solid);
|
||||
//void Unpack5MT(bool Solid);
|
||||
//bool UnpReadBuf();
|
||||
//void UnpWriteBuf();
|
||||
//byte* ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt);
|
||||
//void UnpWriteArea(size_t StartPtr,size_t EndPtr);
|
||||
//void UnpWriteData(byte *Data,size_t Size);
|
||||
//_forceinline uint SlotToLength(BitInput &Inp,uint Slot);
|
||||
//void UnpInitData50(bool Solid);
|
||||
//bool ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header);
|
||||
//bool ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables);
|
||||
//void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size);
|
||||
//_forceinline uint DecodeNumber(BitInput &Inp,DecodeTable *Dec);
|
||||
//void CopyString();
|
||||
//inline void InsertOldDist(uint Distance);
|
||||
//void UnpInitData(bool Solid);
|
||||
//_forceinline void CopyString(uint Length,uint Distance);
|
||||
//uint ReadFilterData(BitInput &Inp);
|
||||
//bool ReadFilter(BitInput &Inp,UnpackFilter &Filter);
|
||||
//bool AddFilter(UnpackFilter &Filter);
|
||||
//bool AddFilter();
|
||||
//void InitFilters();
|
||||
//void Unpack5(bool Solid);
|
||||
//void Unpack5MT(bool Solid);
|
||||
//bool UnpReadBuf();
|
||||
//void UnpWriteBuf();
|
||||
//byte* ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt);
|
||||
//void UnpWriteArea(size_t StartPtr,size_t EndPtr);
|
||||
//void UnpWriteData(byte *Data,size_t Size);
|
||||
//_forceinline uint SlotToLength(BitInput &Inp,uint Slot);
|
||||
//void UnpInitData50(bool Solid);
|
||||
//bool ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header);
|
||||
//bool ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables);
|
||||
//void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size);
|
||||
//_forceinline uint DecodeNumber(BitInput &Inp,DecodeTable *Dec);
|
||||
//void CopyString();
|
||||
//inline void InsertOldDist(uint Distance);
|
||||
//void UnpInitData(bool Solid);
|
||||
//_forceinline void CopyString(uint Length,uint Distance);
|
||||
//uint ReadFilterData(BitInput &Inp);
|
||||
//bool ReadFilter(BitInput &Inp,UnpackFilter &Filter);
|
||||
//bool AddFilter(UnpackFilter &Filter);
|
||||
//bool AddFilter();
|
||||
//void InitFilters();
|
||||
|
||||
//ComprDataIO *UnpIO;
|
||||
//BitInput Inp;
|
||||
private BitInput Inp { get { return this; } } // hopefully this gets inlined
|
||||
//ComprDataIO *UnpIO;
|
||||
//BitInput Inp;
|
||||
private BitInput Inp { get { return this; } } // hopefully this gets inlined
|
||||
|
||||
#if RarV2017_RAR_SMP
|
||||
void InitMT();
|
||||
@@ -272,152 +273,152 @@ internal partial class Unpack
|
||||
byte *ReadBufMT;
|
||||
#endif
|
||||
|
||||
private byte[] FilterSrcMemory = Array.Empty<byte>();
|
||||
private byte[] FilterDstMemory = Array.Empty<byte>();
|
||||
private byte[] FilterSrcMemory = Array.Empty<byte>();
|
||||
private byte[] FilterDstMemory = Array.Empty<byte>();
|
||||
|
||||
// Filters code, one entry per filter.
|
||||
private readonly List<UnpackFilter> Filters = new List<UnpackFilter>();
|
||||
// Filters code, one entry per filter.
|
||||
private readonly List<UnpackFilter> Filters = new List<UnpackFilter>();
|
||||
|
||||
private readonly uint[] OldDist = new uint[4];
|
||||
private uint OldDistPtr;
|
||||
private uint LastLength;
|
||||
private readonly uint[] OldDist = new uint[4];
|
||||
private uint OldDistPtr;
|
||||
private uint LastLength;
|
||||
|
||||
// LastDist is necessary only for RAR2 and older with circular OldDist
|
||||
// array. In RAR3 last distance is always stored in OldDist[0].
|
||||
private uint LastDist;
|
||||
// LastDist is necessary only for RAR2 and older with circular OldDist
|
||||
// array. In RAR3 last distance is always stored in OldDist[0].
|
||||
private uint LastDist;
|
||||
|
||||
private size_t UnpPtr,WrPtr;
|
||||
|
||||
// Top border of read packed data.
|
||||
private int ReadTop;
|
||||
private size_t UnpPtr, WrPtr;
|
||||
|
||||
// Border to call UnpReadBuf. We use it instead of (ReadTop-C)
|
||||
// for optimization reasons. Ensures that we have C bytes in buffer
|
||||
// unless we are at the end of file.
|
||||
private int ReadBorder;
|
||||
// Top border of read packed data.
|
||||
private int ReadTop;
|
||||
|
||||
private UnpackBlockHeader BlockHeader;
|
||||
private UnpackBlockTables BlockTables;
|
||||
// Border to call UnpReadBuf. We use it instead of (ReadTop-C)
|
||||
// for optimization reasons. Ensures that we have C bytes in buffer
|
||||
// unless we are at the end of file.
|
||||
private int ReadBorder;
|
||||
|
||||
private size_t WriteBorder;
|
||||
private UnpackBlockHeader BlockHeader;
|
||||
private UnpackBlockTables BlockTables;
|
||||
|
||||
private byte[] Window;
|
||||
private size_t WriteBorder;
|
||||
|
||||
private readonly FragmentedWindow FragWindow = new FragmentedWindow();
|
||||
private bool Fragmented;
|
||||
private byte[] Window;
|
||||
|
||||
private int64 DestUnpSize;
|
||||
private readonly FragmentedWindow FragWindow = new FragmentedWindow();
|
||||
private bool Fragmented;
|
||||
|
||||
//bool Suspended;
|
||||
private bool UnpAllBuf;
|
||||
private bool UnpSomeRead;
|
||||
private int64 WrittenFileSize;
|
||||
private bool FileExtracted;
|
||||
private int64 DestUnpSize;
|
||||
|
||||
//bool Suspended;
|
||||
private bool UnpAllBuf;
|
||||
private bool UnpSomeRead;
|
||||
private int64 WrittenFileSize;
|
||||
private bool FileExtracted;
|
||||
|
||||
|
||||
/***************************** Unpack v 1.5 *********************************/
|
||||
//void Unpack15(bool Solid);
|
||||
//void ShortLZ();
|
||||
//void LongLZ();
|
||||
//void HuffDecode();
|
||||
//void GetFlagsBuf();
|
||||
//void UnpInitData15(int Solid);
|
||||
//void InitHuff();
|
||||
//void CorrHuff(ushort *CharSet,byte *NumToPlace);
|
||||
//void CopyString15(uint Distance,uint Length);
|
||||
//uint DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab);
|
||||
/***************************** Unpack v 1.5 *********************************/
|
||||
//void Unpack15(bool Solid);
|
||||
//void ShortLZ();
|
||||
//void LongLZ();
|
||||
//void HuffDecode();
|
||||
//void GetFlagsBuf();
|
||||
//void UnpInitData15(int Solid);
|
||||
//void InitHuff();
|
||||
//void CorrHuff(ushort *CharSet,byte *NumToPlace);
|
||||
//void CopyString15(uint Distance,uint Length);
|
||||
//uint DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab);
|
||||
|
||||
private readonly ushort[] ChSet = new ushort[256],ChSetA = new ushort[256],ChSetB = new ushort[256],ChSetC = new ushort[256];
|
||||
private readonly byte[] NToPl = new byte[256],NToPlB = new byte[256],NToPlC = new byte[256];
|
||||
private uint FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
|
||||
private int Buf60,NumHuf,StMode,LCount,FlagsCnt;
|
||||
private readonly ushort[] ChSet = new ushort[256], ChSetA = new ushort[256], ChSetB = new ushort[256], ChSetC = new ushort[256];
|
||||
private readonly byte[] NToPl = new byte[256], NToPlB = new byte[256], NToPlC = new byte[256];
|
||||
private uint FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
|
||||
private int Buf60, NumHuf, StMode, LCount, FlagsCnt;
|
||||
|
||||
private uint Nhfb,Nlzb,MaxDist3;
|
||||
/***************************** Unpack v 1.5 *********************************/
|
||||
private uint Nhfb, Nlzb, MaxDist3;
|
||||
/***************************** Unpack v 1.5 *********************************/
|
||||
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
//void Unpack20(bool Solid);
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
//void Unpack20(bool Solid);
|
||||
|
||||
private DecodeTable[] MD = new DecodeTable[4]; // Decode multimedia data, up to 4 channels.
|
||||
private DecodeTable[] MD = new DecodeTable[4]; // Decode multimedia data, up to 4 channels.
|
||||
|
||||
private readonly byte[] UnpOldTable20 = new byte[MC20*4];
|
||||
private bool UnpAudioBlock;
|
||||
private uint UnpChannels,UnpCurChannel;
|
||||
private readonly byte[] UnpOldTable20 = new byte[MC20 * 4];
|
||||
private bool UnpAudioBlock;
|
||||
private uint UnpChannels, UnpCurChannel;
|
||||
|
||||
private int UnpChannelDelta;
|
||||
//void CopyString20(uint Length,uint Distance);
|
||||
//bool ReadTables20();
|
||||
//void UnpWriteBuf20();
|
||||
//void UnpInitData20(int Solid);
|
||||
//void ReadLastTables();
|
||||
//byte DecodeAudio(int Delta);
|
||||
private AudioVariables[] AudV = new AudioVariables[4];
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
private int UnpChannelDelta;
|
||||
//void CopyString20(uint Length,uint Distance);
|
||||
//bool ReadTables20();
|
||||
//void UnpWriteBuf20();
|
||||
//void UnpInitData20(int Solid);
|
||||
//void ReadLastTables();
|
||||
//byte DecodeAudio(int Delta);
|
||||
private AudioVariables[] AudV = new AudioVariables[4];
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
|
||||
/***************************** Unpack v 3.0 *********************************/
|
||||
public const int BLOCK_LZ = 0;
|
||||
public const int BLOCK_PPM = 1;
|
||||
/***************************** Unpack v 3.0 *********************************/
|
||||
public const int BLOCK_LZ = 0;
|
||||
public const int BLOCK_PPM = 1;
|
||||
|
||||
//void UnpInitData30(bool Solid);
|
||||
//void Unpack29(bool Solid);
|
||||
//void InitFilters30(bool Solid);
|
||||
//bool ReadEndOfBlock();
|
||||
//bool ReadVMCode();
|
||||
//bool ReadVMCodePPM();
|
||||
//bool AddVMCode(uint FirstByte,byte *Code,int CodeSize);
|
||||
//int SafePPMDecodeChar();
|
||||
//bool ReadTables30();
|
||||
//bool UnpReadBuf30();
|
||||
//void UnpWriteBuf30();
|
||||
//void ExecuteCode(VM_PreparedProgram *Prg);
|
||||
//void UnpInitData30(bool Solid);
|
||||
//void Unpack29(bool Solid);
|
||||
//void InitFilters30(bool Solid);
|
||||
//bool ReadEndOfBlock();
|
||||
//bool ReadVMCode();
|
||||
//bool ReadVMCodePPM();
|
||||
//bool AddVMCode(uint FirstByte,byte *Code,int CodeSize);
|
||||
//int SafePPMDecodeChar();
|
||||
//bool ReadTables30();
|
||||
//bool UnpReadBuf30();
|
||||
//void UnpWriteBuf30();
|
||||
//void ExecuteCode(VM_PreparedProgram *Prg);
|
||||
|
||||
private int PrevLowDist,LowDistRepCount;
|
||||
private int PrevLowDist, LowDistRepCount;
|
||||
|
||||
/*#if !RarV2017_RAR5ONLY
|
||||
ModelPPM PPM;
|
||||
#endif*/
|
||||
private int PPMEscChar;
|
||||
/*#if !RarV2017_RAR5ONLY
|
||||
ModelPPM PPM;
|
||||
#endif*/
|
||||
private int PPMEscChar;
|
||||
|
||||
private readonly byte [] UnpOldTable = new byte[HUFF_TABLE_SIZE30];
|
||||
private int UnpBlockType;
|
||||
private readonly byte[] UnpOldTable = new byte[HUFF_TABLE_SIZE30];
|
||||
private int UnpBlockType;
|
||||
|
||||
// If we already read decoding tables for Unpack v2,v3,v5.
|
||||
// We should not use a single variable for all algorithm versions,
|
||||
// because we can have a corrupt archive with one algorithm file
|
||||
// followed by another algorithm file with "solid" flag and we do not
|
||||
// want to reuse tables from one algorithm in another.
|
||||
private bool TablesRead2,TablesRead3,TablesRead5;
|
||||
// If we already read decoding tables for Unpack v2,v3,v5.
|
||||
// We should not use a single variable for all algorithm versions,
|
||||
// because we can have a corrupt archive with one algorithm file
|
||||
// followed by another algorithm file with "solid" flag and we do not
|
||||
// want to reuse tables from one algorithm in another.
|
||||
private bool TablesRead2, TablesRead3, TablesRead5;
|
||||
|
||||
// Virtual machine to execute filters code.
|
||||
/*#if !RarV2017_RAR5ONLY
|
||||
RarVM VM;
|
||||
#endif*/
|
||||
|
||||
// Buffer to read VM filters code. We moved it here from AddVMCode
|
||||
// function to reduce time spent in BitInput constructor.
|
||||
private readonly BitInput VMCodeInp = new BitInput(true);
|
||||
// Virtual machine to execute filters code.
|
||||
/*#if !RarV2017_RAR5ONLY
|
||||
RarVM VM;
|
||||
#endif*/
|
||||
|
||||
// Filters code, one entry per filter.
|
||||
private readonly List<UnpackFilter30> Filters30 = new List<UnpackFilter30>();
|
||||
// Buffer to read VM filters code. We moved it here from AddVMCode
|
||||
// function to reduce time spent in BitInput constructor.
|
||||
private readonly BitInput VMCodeInp = new BitInput(true);
|
||||
|
||||
// Filters stack, several entrances of same filter are possible.
|
||||
private readonly List<UnpackFilter30> PrgStack = new List<UnpackFilter30>();
|
||||
// Filters code, one entry per filter.
|
||||
private readonly List<UnpackFilter30> Filters30 = new List<UnpackFilter30>();
|
||||
|
||||
// Lengths of preceding data blocks, one length of one last block
|
||||
// for every filter. Used to reduce the size required to write
|
||||
// the data block length if lengths are repeating.
|
||||
private readonly List<int> OldFilterLengths = new List<int>();
|
||||
// Filters stack, several entrances of same filter are possible.
|
||||
private readonly List<UnpackFilter30> PrgStack = new List<UnpackFilter30>();
|
||||
|
||||
private int LastFilter;
|
||||
/***************************** Unpack v 3.0 *********************************/
|
||||
// Lengths of preceding data blocks, one length of one last block
|
||||
// for every filter. Used to reduce the size required to write
|
||||
// the data block length if lengths are repeating.
|
||||
private readonly List<int> OldFilterLengths = new List<int>();
|
||||
|
||||
//Unpack(ComprDataIO *DataIO);
|
||||
//~Unpack();
|
||||
//void Init(size_t WinSize,bool Solid);
|
||||
//void DoUnpack(uint Method,bool Solid);
|
||||
private bool IsFileExtracted() {return(FileExtracted);}
|
||||
private void SetDestSize(int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
|
||||
private void SetSuspended(bool Suspended) {this.Suspended=Suspended;}
|
||||
private int LastFilter;
|
||||
/***************************** Unpack v 3.0 *********************************/
|
||||
|
||||
//Unpack(ComprDataIO *DataIO);
|
||||
//~Unpack();
|
||||
//void Init(size_t WinSize,bool Solid);
|
||||
//void DoUnpack(uint Method,bool Solid);
|
||||
private bool IsFileExtracted() { return (FileExtracted); }
|
||||
private void SetDestSize(int64 DestSize) { DestUnpSize = DestSize; FileExtracted = false; }
|
||||
private void SetSuspended(bool Suspended) { this.Suspended = Suspended; }
|
||||
|
||||
#if RarV2017_RAR_SMP
|
||||
// More than 8 threads are unlikely to provide a noticeable gain
|
||||
@@ -427,18 +428,18 @@ internal partial class Unpack
|
||||
void UnpackDecode(UnpackThreadData &D);
|
||||
#endif
|
||||
|
||||
private size_t MaxWinSize;
|
||||
private size_t MaxWinMask;
|
||||
private size_t MaxWinSize;
|
||||
private size_t MaxWinMask;
|
||||
|
||||
private uint GetChar()
|
||||
{
|
||||
if (Inp.InAddr>MAX_SIZE-30)
|
||||
{
|
||||
UnpReadBuf();
|
||||
}
|
||||
private uint GetChar()
|
||||
{
|
||||
if (Inp.InAddr > MAX_SIZE - 30)
|
||||
{
|
||||
UnpReadBuf();
|
||||
}
|
||||
|
||||
return(Inp.InBuf[Inp.InAddr++]);
|
||||
}
|
||||
return (Inp.InBuf[Inp.InAddr++]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace SharpCompress.Compressors.Rar.VM
|
||||
public int inAddr;
|
||||
public int inBit;
|
||||
|
||||
// TODO: rename var
|
||||
public int InAddr { get { return inAddr; } set { inAddr = value; } }
|
||||
public int InBit { get { return inBit; } set { inBit = value; } }
|
||||
// TODO: rename var
|
||||
public int InAddr { get { return inAddr; } set { inAddr = value; } }
|
||||
public int InBit { get { return inBit; } set { inBit = value; } }
|
||||
public bool ExternalBuffer;
|
||||
|
||||
|
||||
@@ -28,7 +28,8 @@ namespace SharpCompress.Compressors.Rar.VM
|
||||
inBit = 0;
|
||||
}
|
||||
|
||||
internal void faddbits(uint bits) {
|
||||
internal void faddbits(uint bits)
|
||||
{
|
||||
// TODO uint
|
||||
AddBits((int)bits);
|
||||
}
|
||||
@@ -44,12 +45,14 @@ namespace SharpCompress.Compressors.Rar.VM
|
||||
inBit = bits & 7;
|
||||
}
|
||||
|
||||
internal uint fgetbits() {
|
||||
internal uint fgetbits()
|
||||
{
|
||||
// TODO uint
|
||||
return (uint)GetBits();
|
||||
}
|
||||
|
||||
internal uint getbits() {
|
||||
internal uint getbits()
|
||||
{
|
||||
// TODO uint
|
||||
return (uint)GetBits();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,9 +2,9 @@ namespace SharpCompress.Compressors.Xz
|
||||
{
|
||||
public enum CheckType : byte
|
||||
{
|
||||
NONE = 0x00,
|
||||
CRC32 = 0x01,
|
||||
CRC64 = 0x04,
|
||||
NONE = 0x00,
|
||||
CRC32 = 0x01,
|
||||
CRC64 = 0x04,
|
||||
SHA256 = 0x0A
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace SharpCompress.Compressors.Xz
|
||||
public static UInt64 Compute(UInt64 seed, byte[] buffer)
|
||||
{
|
||||
Table ??= CreateTable(Iso3309Polynomial);
|
||||
|
||||
|
||||
return CalculateHash(seed, Table, buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace SharpCompress.Compressors.Xz
|
||||
private bool _crcChecked;
|
||||
private ulong _bytesRead;
|
||||
|
||||
public XZBlock(Stream stream, CheckType checkType, int checkSize)
|
||||
public XZBlock(Stream stream, CheckType checkType, int checkSize)
|
||||
: base(stream)
|
||||
{
|
||||
_checkType = checkType;
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace SharpCompress.Compressors.Xz
|
||||
NextBlock();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
for (; ; )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SharpCompress.Crypto
|
||||
public const uint DefaultSeed = 0xffffffffu;
|
||||
|
||||
private static uint[] defaultTable;
|
||||
|
||||
|
||||
private readonly uint[] table;
|
||||
private uint hash;
|
||||
|
||||
|
||||
@@ -132,25 +132,30 @@ namespace SharpCompress.IO
|
||||
// and highest bit in every byte is the continuation flag. If highest bit is 0, this is the last byte in sequence.
|
||||
// So first byte contains 7 least significant bits of integer and continuation flag. Second byte, if present,
|
||||
// contains next 7 bits and so on.
|
||||
public ulong ReadRarVInt(int maxBytes = 10) {
|
||||
public ulong ReadRarVInt(int maxBytes = 10)
|
||||
{
|
||||
// hopefully this gets inlined
|
||||
return DoReadRarVInt((maxBytes - 1) * 7);
|
||||
}
|
||||
|
||||
private ulong DoReadRarVInt(int maxShift) {
|
||||
private ulong DoReadRarVInt(int maxShift)
|
||||
{
|
||||
int shift = 0;
|
||||
ulong result = 0;
|
||||
do {
|
||||
do
|
||||
{
|
||||
byte b0 = ReadByte();
|
||||
uint b1 = ((uint)b0) & 0x7f;
|
||||
ulong n = b1;
|
||||
ulong shifted = n << shift;
|
||||
if (n != shifted >> shift) {
|
||||
if (n != shifted >> shift)
|
||||
{
|
||||
// overflow
|
||||
break;
|
||||
}
|
||||
result |= shifted;
|
||||
if (b0 == b1) {
|
||||
if (b0 == b1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
shift += 7;
|
||||
@@ -159,35 +164,42 @@ namespace SharpCompress.IO
|
||||
throw new FormatException("malformed vint");
|
||||
}
|
||||
|
||||
public uint ReadRarVIntUInt32(int maxBytes = 5) {
|
||||
public uint ReadRarVIntUInt32(int maxBytes = 5)
|
||||
{
|
||||
// hopefully this gets inlined
|
||||
return DoReadRarVIntUInt32((maxBytes - 1) * 7);
|
||||
}
|
||||
|
||||
public ushort ReadRarVIntUInt16(int maxBytes = 3) {
|
||||
public ushort ReadRarVIntUInt16(int maxBytes = 3)
|
||||
{
|
||||
// hopefully this gets inlined
|
||||
return checked((ushort)DoReadRarVIntUInt32((maxBytes - 1) * 7));
|
||||
}
|
||||
|
||||
public byte ReadRarVIntByte(int maxBytes = 2) {
|
||||
public byte ReadRarVIntByte(int maxBytes = 2)
|
||||
{
|
||||
// hopefully this gets inlined
|
||||
return checked((byte)DoReadRarVIntUInt32((maxBytes - 1) * 7));
|
||||
}
|
||||
|
||||
private uint DoReadRarVIntUInt32(int maxShift) {
|
||||
private uint DoReadRarVIntUInt32(int maxShift)
|
||||
{
|
||||
int shift = 0;
|
||||
uint result = 0;
|
||||
do {
|
||||
do
|
||||
{
|
||||
byte b0 = ReadByte();
|
||||
uint b1 = ((uint)b0) & 0x7f;
|
||||
uint n = b1;
|
||||
uint shifted = n << shift;
|
||||
if (n != shifted >> shift) {
|
||||
if (n != shifted >> shift)
|
||||
{
|
||||
// overflow
|
||||
break;
|
||||
}
|
||||
result |= shifted;
|
||||
if (b0 == b1) {
|
||||
if (b0 == b1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
shift += 7;
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace SharpCompress.IO
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
bufferStream.TransferTo(buffer);
|
||||
//create new memorystream to allow proper resizing as memorystream could be a user provided buffer
|
||||
//https://github.com/adamhathcock/sharpcompress/issues/306
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace SharpCompress
|
||||
private readonly Func<T> _lazyFunc;
|
||||
private bool _evaluated;
|
||||
private T _value;
|
||||
|
||||
|
||||
public Lazy(Func<T> lazyFunc)
|
||||
{
|
||||
_lazyFunc = lazyFunc;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace SharpCompress.Readers
|
||||
private bool completed;
|
||||
private IEnumerator<TEntry>? entriesForCurrentReadStream;
|
||||
private bool wroteCurrentEntry;
|
||||
|
||||
|
||||
public event EventHandler<ReaderExtractionEventArgs<IEntry>>? EntryExtractionProgress;
|
||||
|
||||
public event EventHandler<CompressedBytesReadEventArgs>? CompressedBytesRead;
|
||||
@@ -131,8 +131,8 @@ namespace SharpCompress.Readers
|
||||
|
||||
private void Skip()
|
||||
{
|
||||
if (ArchiveType != ArchiveType.Rar
|
||||
&& !Entry.IsSolid
|
||||
if (ArchiveType != ArchiveType.Rar
|
||||
&& !Entry.IsSolid
|
||||
&& Entry.CompressedSize > 0)
|
||||
{
|
||||
//not solid and has a known compressed size then we can skip raw bytes.
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace SharpCompress.Readers
|
||||
/// <summary>
|
||||
/// Extract to specific file
|
||||
/// </summary>
|
||||
public static void WriteEntryToFile(this IReader reader,
|
||||
public static void WriteEntryToFile(this IReader reader,
|
||||
string destinationFileName,
|
||||
ExtractionOptions? options = null)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace SharpCompress.Readers.Rar
|
||||
|
||||
internal override bool NextEntryForCurrentStream()
|
||||
{
|
||||
if (!base.NextEntryForCurrentStream()) {
|
||||
if (!base.NextEntryForCurrentStream())
|
||||
{
|
||||
// if we're got another stream to try to process then do so
|
||||
return streams.MoveNext() && LoadStreamForReading(streams.Current);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ namespace SharpCompress.Readers.Rar
|
||||
|
||||
internal override void ValidateArchive(RarVolume archive)
|
||||
{
|
||||
if (archive.IsMultiVolume) {
|
||||
if (archive.IsMultiVolume)
|
||||
{
|
||||
var msg = "Streamed archive is a Multi-volume archive. Use different RarReader method to extract.";
|
||||
throw new MultiVolumeExtractionException(msg);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ namespace SharpCompress.Readers
|
||||
{
|
||||
stream.CheckNotNull(nameof(stream));
|
||||
options = options ?? new ReaderOptions()
|
||||
{
|
||||
LeaveStreamOpen = false
|
||||
};
|
||||
{
|
||||
LeaveStreamOpen = false
|
||||
};
|
||||
RewindableStream rewindableStream = new RewindableStream(stream);
|
||||
rewindableStream.StartRecording();
|
||||
if (ZipArchive.IsZipFile(rewindableStream, options.Password))
|
||||
|
||||
@@ -33,29 +33,29 @@ namespace SharpCompress.Readers.Tar
|
||||
switch (compressionType)
|
||||
{
|
||||
case CompressionType.BZip2:
|
||||
{
|
||||
return new BZip2Stream(stream, CompressionMode.Decompress, false);
|
||||
}
|
||||
{
|
||||
return new BZip2Stream(stream, CompressionMode.Decompress, false);
|
||||
}
|
||||
case CompressionType.GZip:
|
||||
{
|
||||
return new GZipStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
{
|
||||
return new GZipStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
case CompressionType.LZip:
|
||||
{
|
||||
return new LZipStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
{
|
||||
return new LZipStream(stream, CompressionMode.Decompress);
|
||||
}
|
||||
case CompressionType.Xz:
|
||||
{
|
||||
return new XZStream(stream);
|
||||
}
|
||||
{
|
||||
return new XZStream(stream);
|
||||
}
|
||||
case CompressionType.None:
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new NotSupportedException("Invalid compression type: " + compressionType);
|
||||
}
|
||||
{
|
||||
throw new NotSupportedException("Invalid compression type: " + compressionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SharpCompress.Writers.GZip
|
||||
{
|
||||
destination = new NonDisposingStream(destination);
|
||||
}
|
||||
InitalizeStream(new GZipStream(destination, CompressionMode.Compress,
|
||||
InitalizeStream(new GZipStream(destination, CompressionMode.Compress,
|
||||
options?.CompressionLevel ?? CompressionLevel.Default,
|
||||
WriterOptions.ArchiveEncoding.GetEncoding()));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace SharpCompress.Writers.GZip
|
||||
: base(CompressionType.GZip)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
internal GZipWriterOptions(WriterOptions options)
|
||||
: base(options.CompressionType)
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace SharpCompress.Writers.GZip
|
||||
CompressionLevel = writerOptions.CompressionLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public CompressionLevel CompressionLevel { get; set; } = CompressionLevel.Default;
|
||||
}
|
||||
}
|
||||
@@ -32,24 +32,24 @@ namespace SharpCompress.Writers.Tar
|
||||
case CompressionType.None:
|
||||
break;
|
||||
case CompressionType.BZip2:
|
||||
{
|
||||
destination = new BZip2Stream(destination, CompressionMode.Compress, false);
|
||||
}
|
||||
{
|
||||
destination = new BZip2Stream(destination, CompressionMode.Compress, false);
|
||||
}
|
||||
break;
|
||||
case CompressionType.GZip:
|
||||
{
|
||||
destination = new GZipStream(destination, CompressionMode.Compress);
|
||||
}
|
||||
{
|
||||
destination = new GZipStream(destination, CompressionMode.Compress);
|
||||
}
|
||||
break;
|
||||
case CompressionType.LZip:
|
||||
{
|
||||
destination = new LZipStream(destination, CompressionMode.Compress);
|
||||
}
|
||||
{
|
||||
destination = new LZipStream(destination, CompressionMode.Compress);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
throw new InvalidFormatException("Tar does not support compression: " + options.CompressionType);
|
||||
}
|
||||
{
|
||||
throw new InvalidFormatException("Tar does not support compression: " + options.CompressionType);
|
||||
}
|
||||
}
|
||||
InitalizeStream(destination);
|
||||
}
|
||||
@@ -106,22 +106,23 @@ namespace SharpCompress.Writers.Tar
|
||||
{
|
||||
if (isDisposing)
|
||||
{
|
||||
if (finalizeArchiveOnClose) {
|
||||
if (finalizeArchiveOnClose)
|
||||
{
|
||||
PadTo512(0, true);
|
||||
PadTo512(0, true);
|
||||
}
|
||||
switch (OutputStream)
|
||||
{
|
||||
case BZip2Stream b:
|
||||
{
|
||||
b.Finish();
|
||||
break;
|
||||
}
|
||||
{
|
||||
b.Finish();
|
||||
break;
|
||||
}
|
||||
case LZipStream l:
|
||||
{
|
||||
l.Finish();
|
||||
break;
|
||||
}
|
||||
{
|
||||
l.Finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user