mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-09 05:24:55 +00:00
Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f3124a84f | ||
|
|
59eb5bd9c4 | ||
|
|
ad2b6bb4f7 | ||
|
|
51d64ee10e | ||
|
|
1159efc6cc | ||
|
|
3cfb76a56f | ||
|
|
7a1ad6688a | ||
|
|
4f4af6e3fd | ||
|
|
2736b79097 | ||
|
|
8da2ffa433 | ||
|
|
5bf3d6dc32 | ||
|
|
30d4380afe | ||
|
|
c8b5aad482 | ||
|
|
fa1d440947 | ||
|
|
a89fc3a276 | ||
|
|
3875f62453 | ||
|
|
23e1447ab6 | ||
|
|
91364c6a7c | ||
|
|
a070493fba | ||
|
|
ca0a6ab72c | ||
|
|
10e0562a82 | ||
|
|
44998a2a2b | ||
|
|
f8e033e560 | ||
|
|
5842da84af | ||
|
|
10cc270170 | ||
|
|
f51bdd56aa | ||
|
|
7f79c49f93 | ||
|
|
e4920255f0 | ||
|
|
f8e8273d39 | ||
|
|
ceddab98d1 | ||
|
|
0faa176791 | ||
|
|
9b0e0ee536 | ||
|
|
881d2756db | ||
|
|
ab5af40999 | ||
|
|
6aeef8dcf9 | ||
|
|
5d62196dde | ||
|
|
7fe27ac310 | ||
|
|
1e300349ce | ||
|
|
6b01a7b08e | ||
|
|
34d948df18 | ||
|
|
27091c4f1d | ||
|
|
970a3d7f2a | ||
|
|
2bedbbfc54 | ||
|
|
8de33f0db3 | ||
|
|
df4eab67dc | ||
|
|
2d13bc0046 | ||
|
|
704a0cb35d | ||
|
|
06a983e445 | ||
|
|
2d10df8b87 | ||
|
|
baf66db9dc | ||
|
|
3545693999 | ||
|
|
84fb99c2c8 | ||
|
|
21e2983ae1 | ||
|
|
004e0941d5 | ||
|
|
188a426dde | ||
|
|
6fcfae8bfe | ||
|
|
9515350f52 | ||
|
|
6b88f82656 | ||
|
|
e42d953f47 | ||
|
|
9c257faf26 | ||
|
|
d18cad6d76 | ||
|
|
061273be22 | ||
|
|
b89de6caad | ||
|
|
9bc0a1d7c7 | ||
|
|
eee518b7fa | ||
|
|
b7b78edaa3 | ||
|
|
3eaac68ab4 | ||
|
|
a7672190e9 | ||
|
|
4e4e89b6eb | ||
|
|
33dd519f56 | ||
|
|
5c1149aa8b | ||
|
|
9061e92af6 | ||
|
|
49f5ceaa9b | ||
|
|
525b309d37 | ||
|
|
bdb3a787fc | ||
|
|
a9601ef848 |
@@ -3,10 +3,11 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"csharpier": {
|
||||
"version": "0.28.1",
|
||||
"version": "0.30.6",
|
||||
"commands": [
|
||||
"dotnet-csharpier"
|
||||
]
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Bullseye" Version="5.0.0" />
|
||||
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageVersion Include="FluentAssertions" Version="7.0.0" />
|
||||
<PackageVersion Include="Glob" Version="1.1.9" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageVersion Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageVersion Include="SimpleExec" Version="12.0.0" />
|
||||
<PackageVersion Include="System.Memory" Version="4.5.5" />
|
||||
<PackageVersion Include="System.Buffers" Version="4.6.0" />
|
||||
<PackageVersion Include="System.Memory" Version="4.6.0" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
<PackageVersion Include="xunit" Version="2.7.1" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.8" />
|
||||
<PackageVersion Include="xunit.SkippableFact" Version="1.4.13" />
|
||||
<PackageVersion Include="ZstdSharp.Port" Version="0.8.0" />
|
||||
<PackageVersion Include="xunit" Version="2.9.3" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
|
||||
<PackageVersion Include="xunit.SkippableFact" Version="1.5.23" />
|
||||
<PackageVersion Include="ZstdSharp.Port" Version="0.8.4" />
|
||||
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| Archive Format | Compression Format(s) | Compress/Decompress | Archive API | Reader API | Writer API |
|
||||
| ---------------------- | ------------------------------------------------- | ------------------- | --------------- | ---------- | ------------- |
|
||||
| Rar | Rar | Decompress (1) | RarArchive | RarReader | N/A |
|
||||
| Zip (2) | None, DEFLATE, Deflate64, BZip2, LZMA/LZMA2, PPMd | Both | ZipArchive | ZipReader | ZipWriter |
|
||||
| Zip (2) | None, Shrink, Reduce, Implode, DEFLATE, Deflate64, BZip2, LZMA/LZMA2, PPMd | Both | ZipArchive | ZipReader | ZipWriter |
|
||||
| Tar | None | Both | TarArchive | TarReader | TarWriter (3) |
|
||||
| Tar.GZip | DEFLATE | Both | TarArchive | TarReader | TarWriter (3) |
|
||||
| Tar.BZip2 | BZip2 | Both | TarArchive | TarReader | TarWriter (3) |
|
||||
|
||||
2
USAGE.md
2
USAGE.md
@@ -27,7 +27,7 @@ To deal with the "correct" rules as well as the expectations of users, I've deci
|
||||
|
||||
To be explicit though, consider always using the overloads that use `ReaderOptions` or `WriterOptions` and explicitly set `LeaveStreamOpen` the way you want.
|
||||
|
||||
If using Compression Stream classes directly and you don't want the wrapped stream to be closed. Use the `NonDisposingStream` as a wrapped to prevent the stream being disposed. The change in 0.21 simplified a lot even though the usage is a bit more convoluted.
|
||||
If using Compression Stream classes directly and you don't want the wrapped stream to be closed. Use the `NonDisposingStream` as a wrapper to prevent the stream being disposed. The change in 0.21 simplified a lot even though the usage is a bit more convoluted.
|
||||
|
||||
## Samples
|
||||
|
||||
|
||||
@@ -14,11 +14,31 @@
|
||||
"resolved": "1.1.9",
|
||||
"contentHash": "AfK5+ECWYTP7G3AAdnU8IfVj+QpGjrh9GC2mpdcJzCvtQ4pnerAGwHsxJ9D4/RnhDUz2DSzd951O/lQjQby2Sw=="
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"SimpleExec": {
|
||||
"type": "Direct",
|
||||
"requested": "[12.0.0, )",
|
||||
"resolved": "12.0.0",
|
||||
"contentHash": "ptxlWtxC8vM6Y6e3h9ZTxBBkOWnWrm/Sa1HT+2i1xcXY3Hx2hmKDZP5RShPf8Xr9D+ivlrXNy57ktzyH8kyt+Q=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
|
||||
4,
|
||||
3,
|
||||
2,
|
||||
1 // tap2
|
||||
1, // tap2
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -189,9 +189,10 @@ public static class ArchiveFactory
|
||||
|
||||
foreach (var factory in Factory.Factories)
|
||||
{
|
||||
var isArchive = factory.IsArchive(stream);
|
||||
stream.Position = startPosition;
|
||||
|
||||
if (factory.IsArchive(stream, null))
|
||||
if (isArchive)
|
||||
{
|
||||
type = factory.KnownArchiveType;
|
||||
return true;
|
||||
@@ -239,4 +240,6 @@ public static class ArchiveFactory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IArchiveFactory AutoFactory { get; } = new AutoArchiveFactory();
|
||||
}
|
||||
|
||||
27
src/SharpCompress/Archives/AutoArchiveFactory.cs
Normal file
27
src/SharpCompress/Archives/AutoArchiveFactory.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Readers;
|
||||
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
class AutoArchiveFactory : IArchiveFactory
|
||||
{
|
||||
public string Name => nameof(AutoArchiveFactory);
|
||||
|
||||
public ArchiveType? KnownArchiveType => null;
|
||||
|
||||
public IEnumerable<string> GetSupportedExtensions() => throw new NotSupportedException();
|
||||
|
||||
public bool IsArchive(Stream stream, string? password = null) =>
|
||||
throw new NotSupportedException();
|
||||
|
||||
public FileInfo? GetFilePart(int index, FileInfo part1) => throw new NotSupportedException();
|
||||
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFactory.Open(stream, readerOptions);
|
||||
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFactory.Open(fileInfo, readerOptions);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="sourceStream"></param>
|
||||
private GZipArchive(SourceStream sourceStream)
|
||||
: base(ArchiveType.Tar, sourceStream) { }
|
||||
: base(ArchiveType.GZip, sourceStream) { }
|
||||
|
||||
protected override IEnumerable<GZipVolume> LoadVolumes(SourceStream sourceStream)
|
||||
{
|
||||
|
||||
@@ -54,14 +54,26 @@ public static class IArchiveExtensions
|
||||
var entry = entries.Entry;
|
||||
if (entry.IsDirectory)
|
||||
{
|
||||
var dirPath = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
|
||||
if (
|
||||
Path.GetDirectoryName(dirPath + "/") is { } emptyDirectory
|
||||
&& seenDirectories.Add(dirPath)
|
||||
)
|
||||
{
|
||||
Directory.CreateDirectory(emptyDirectory);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create each directory
|
||||
// Create each directory if not already created
|
||||
var path = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
|
||||
if (Path.GetDirectoryName(path) is { } directory && seenDirectories.Add(path))
|
||||
if (Path.GetDirectoryName(path) is { } directory)
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
if (!Directory.Exists(directory) && !seenDirectories.Contains(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
seenDirectories.Add(directory);
|
||||
}
|
||||
}
|
||||
|
||||
// Write file
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SharpCompress.Common.Rar;
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace SharpCompress.Archives.Rar;
|
||||
|
||||
public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
{
|
||||
private bool _disposed;
|
||||
internal Lazy<IRarUnpack> UnpackV2017 { get; } =
|
||||
new(() => new Compressors.Rar.UnpackV2017.Unpack());
|
||||
internal Lazy<IRarUnpack> UnpackV1 { get; } = new(() => new Compressors.Rar.UnpackV1.Unpack());
|
||||
@@ -25,6 +26,20 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
private RarArchive(SourceStream sourceStream)
|
||||
: base(ArchiveType.Rar, sourceStream) { }
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (UnpackV1.IsValueCreated && UnpackV1.Value is IDisposable unpackV1)
|
||||
{
|
||||
unpackV1.Dispose();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<RarArchiveEntry> LoadEntries(IEnumerable<RarVolume> volumes) =>
|
||||
RarArchiveEntryFactory.GetEntries(this, volumes, ReaderOptions);
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ public class SevenZipArchive : AbstractArchive<SevenZipArchiveEntry, SevenZipVol
|
||||
{
|
||||
stream.Position = 0;
|
||||
var reader = new ArchiveReader();
|
||||
reader.Open(stream);
|
||||
reader.Open(stream, lookForHeader: ReaderOptions.LookForHeader);
|
||||
_database = reader.ReadDatabase(new PasswordProvider(ReaderOptions.Password));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
[assembly: InternalsVisibleTo(
|
||||
"SharpCompress.Test,PublicKey=0024000004800000940000000602000000240000525341310004000001000100158bebf1433f76dffc356733c138babea7a47536c65ed8009b16372c6f4edbb20554db74a62687f56b97c20a6ce8c4b123280279e33c894e7b3aa93ab3c573656fde4db576cfe07dba09619ead26375b25d2c4a8e43f7be257d712b0dd2eb546f67adb09281338618a58ac834fc038dd7e2740a7ab3591826252e4f4516306dc"
|
||||
)]
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Buffers;
|
||||
|
||||
namespace SharpCompress;
|
||||
|
||||
internal static class BufferPool
|
||||
{
|
||||
/// <summary>
|
||||
/// gets a buffer from the pool
|
||||
/// </summary>
|
||||
/// <param name="bufferSize">size of the buffer</param>
|
||||
/// <returns>the buffer</returns>
|
||||
public static byte[] Rent(int bufferSize)
|
||||
{
|
||||
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
|
||||
return ArrayPool<byte>.Shared.Rent(bufferSize);
|
||||
#else
|
||||
return new byte[bufferSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a buffer to the pool
|
||||
/// </summary>
|
||||
/// <param name="buffer">the buffer to return</param>
|
||||
public static void Return(byte[] buffer)
|
||||
{
|
||||
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
#else
|
||||
// no-op
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -6,5 +6,5 @@ public enum ArchiveType
|
||||
Zip,
|
||||
Tar,
|
||||
SevenZip,
|
||||
GZip
|
||||
GZip,
|
||||
}
|
||||
|
||||
@@ -16,5 +16,10 @@ public enum CompressionType
|
||||
Unknown,
|
||||
Deflate64,
|
||||
Shrink,
|
||||
Lzw
|
||||
Lzw,
|
||||
Reduce1,
|
||||
Reduce2,
|
||||
Reduce3,
|
||||
Reduce4,
|
||||
Explode,
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ internal static class ExtractionMethods
|
||||
options ??= new ExtractionOptions() { Overwrite = true };
|
||||
|
||||
var file = Path.GetFileName(entry.Key.NotNull("Entry Key is null")).NotNull("File is null");
|
||||
file = Utility.ReplaceInvalidFileNameChars(file);
|
||||
if (options.ExtractFullPath)
|
||||
{
|
||||
var folder = Path.GetDirectoryName(entry.Key.NotNull("Entry Key is null"))
|
||||
|
||||
@@ -13,7 +13,7 @@ public enum HeaderType : byte
|
||||
Sign,
|
||||
NewSub,
|
||||
EndArchive,
|
||||
Crypt
|
||||
Crypt,
|
||||
}
|
||||
|
||||
internal static class HeaderCodeV
|
||||
|
||||
@@ -61,9 +61,8 @@ public abstract class RarVolume : Volume
|
||||
var fh = (FileHeader)header;
|
||||
if (fh.FileName == "CMT")
|
||||
{
|
||||
var part = CreateFilePart(lastMarkHeader!, fh);
|
||||
var buffer = new byte[fh.CompressedSize];
|
||||
part.GetCompressedStream().Read(buffer, 0, buffer.Length);
|
||||
fh.PackedStream.Read(buffer, 0, buffer.Length);
|
||||
Comment = Encoding.UTF8.GetString(buffer, 0, buffer.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1220,23 +1220,46 @@ internal class ArchiveReader
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public void Open(Stream stream)
|
||||
public void Open(Stream stream, bool lookForHeader)
|
||||
{
|
||||
Close();
|
||||
|
||||
_streamOrigin = stream.Position;
|
||||
_streamEnding = stream.Length;
|
||||
|
||||
// TODO: Check Signature!
|
||||
_header = new byte[0x20];
|
||||
for (var offset = 0; offset < 0x20; )
|
||||
var canScan = lookForHeader ? 0x80000 - 20 : 0;
|
||||
while (true)
|
||||
{
|
||||
var delta = stream.Read(_header, offset, 0x20 - offset);
|
||||
if (delta == 0)
|
||||
// TODO: Check Signature!
|
||||
_header = new byte[0x20];
|
||||
for (var offset = 0; offset < 0x20; )
|
||||
{
|
||||
throw new EndOfStreamException();
|
||||
var delta = stream.Read(_header, offset, 0x20 - offset);
|
||||
if (delta == 0)
|
||||
{
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
offset += delta;
|
||||
}
|
||||
offset += delta;
|
||||
|
||||
if (
|
||||
!lookForHeader
|
||||
|| _header
|
||||
.AsSpan(0, length: 6)
|
||||
.SequenceEqual<byte>([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (canScan == 0)
|
||||
{
|
||||
throw new InvalidFormatException("Unable to find 7z signature");
|
||||
}
|
||||
|
||||
canScan--;
|
||||
stream.Position = ++_streamOrigin;
|
||||
}
|
||||
|
||||
_stream = stream;
|
||||
|
||||
@@ -86,7 +86,7 @@ internal class SevenZipFilePart : FilePart
|
||||
K_LZMA or K_LZMA2 => CompressionType.LZMA,
|
||||
K_PPMD => CompressionType.PPMd,
|
||||
K_B_ZIP2 => CompressionType.BZip2,
|
||||
_ => throw new NotImplementedException()
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -14,5 +14,5 @@ internal enum EntryType : byte
|
||||
LongName = (byte)'L',
|
||||
SparseFile = (byte)'S',
|
||||
VolumeHeader = (byte)'V',
|
||||
GlobalExtendedHeader = (byte)'g'
|
||||
GlobalExtendedHeader = (byte)'g',
|
||||
}
|
||||
|
||||
@@ -101,57 +101,85 @@ internal sealed class TarHeader
|
||||
|
||||
internal bool Read(BinaryReader reader)
|
||||
{
|
||||
var buffer = ReadBlock(reader);
|
||||
if (buffer.Length == 0)
|
||||
string? longName = null;
|
||||
string? longLinkName = null;
|
||||
var hasLongValue = true;
|
||||
byte[] buffer;
|
||||
EntryType entryType;
|
||||
|
||||
do
|
||||
{
|
||||
buffer = ReadBlock(reader);
|
||||
|
||||
if (buffer.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
entryType = ReadEntryType(buffer);
|
||||
|
||||
// LongName and LongLink headers can follow each other and need
|
||||
// to apply to the header that follows them.
|
||||
if (entryType == EntryType.LongName)
|
||||
{
|
||||
longName = ReadLongName(reader, buffer);
|
||||
continue;
|
||||
}
|
||||
else if (entryType == EntryType.LongLink)
|
||||
{
|
||||
longLinkName = ReadLongName(reader, buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
hasLongValue = false;
|
||||
} while (hasLongValue);
|
||||
|
||||
// Check header checksum
|
||||
if (!checkChecksum(buffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// for symlinks, additionally read the linkname
|
||||
if (ReadEntryType(buffer) == EntryType.SymLink)
|
||||
{
|
||||
LinkName = ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
|
||||
}
|
||||
|
||||
if (ReadEntryType(buffer) == EntryType.LongName)
|
||||
{
|
||||
Name = ReadLongName(reader, buffer);
|
||||
buffer = ReadBlock(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
Name = ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
|
||||
}
|
||||
|
||||
EntryType = ReadEntryType(buffer);
|
||||
Name = longName ?? ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
|
||||
EntryType = entryType;
|
||||
Size = ReadSize(buffer);
|
||||
|
||||
// for symlinks, additionally read the linkname
|
||||
if (entryType == EntryType.SymLink || entryType == EntryType.HardLink)
|
||||
{
|
||||
LinkName = longLinkName ?? ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
|
||||
}
|
||||
|
||||
Mode = ReadAsciiInt64Base8(buffer, 100, 7);
|
||||
if (EntryType == EntryType.Directory)
|
||||
|
||||
if (entryType == EntryType.Directory)
|
||||
{
|
||||
Mode |= 0b1_000_000_000;
|
||||
}
|
||||
|
||||
UserId = ReadAsciiInt64Base8oldGnu(buffer, 108, 7);
|
||||
GroupId = ReadAsciiInt64Base8oldGnu(buffer, 116, 7);
|
||||
var unixTimeStamp = ReadAsciiInt64Base8(buffer, 136, 11);
|
||||
LastModifiedTime = EPOCH.AddSeconds(unixTimeStamp).ToLocalTime();
|
||||
|
||||
var unixTimeStamp = ReadAsciiInt64Base8(buffer, 136, 11);
|
||||
|
||||
LastModifiedTime = EPOCH.AddSeconds(unixTimeStamp).ToLocalTime();
|
||||
Magic = ArchiveEncoding.Decode(buffer, 257, 6).TrimNulls();
|
||||
|
||||
if (!string.IsNullOrEmpty(Magic) && "ustar".Equals(Magic))
|
||||
{
|
||||
var namePrefix = ArchiveEncoding.Decode(buffer, 345, 157);
|
||||
namePrefix = namePrefix.TrimNulls();
|
||||
var namePrefix = ArchiveEncoding.Decode(buffer, 345, 157).TrimNulls();
|
||||
|
||||
if (!string.IsNullOrEmpty(namePrefix))
|
||||
{
|
||||
Name = namePrefix + "/" + Name;
|
||||
}
|
||||
}
|
||||
if (EntryType != EntryType.LongName && Name.Length == 0)
|
||||
|
||||
if (entryType != EntryType.LongName && Name.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -286,9 +314,45 @@ internal sealed class TarHeader
|
||||
(byte)' ',
|
||||
(byte)' ',
|
||||
(byte)' ',
|
||||
(byte)' '
|
||||
(byte)' ',
|
||||
};
|
||||
|
||||
internal static bool checkChecksum(byte[] buf)
|
||||
{
|
||||
const int eightSpacesChksum = 256;
|
||||
var buffer = new Span<byte>(buf).Slice(0, 512);
|
||||
int posix_sum = eightSpacesChksum;
|
||||
int sun_sum = eightSpacesChksum;
|
||||
|
||||
foreach (byte b in buffer)
|
||||
{
|
||||
posix_sum += b;
|
||||
sun_sum += unchecked((sbyte)b);
|
||||
}
|
||||
|
||||
// Special case, empty file header
|
||||
if (posix_sum == eightSpacesChksum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Remove current checksum from calculation
|
||||
foreach (byte b in buffer.Slice(148, 8))
|
||||
{
|
||||
posix_sum -= b;
|
||||
sun_sum -= unchecked((sbyte)b);
|
||||
}
|
||||
|
||||
// Read and compare checksum for header
|
||||
var crc = ReadAsciiInt64Base8(buf, 148, 7);
|
||||
if (crc != posix_sum && crc != sun_sum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static int RecalculateChecksum(byte[] buf)
|
||||
{
|
||||
// Set default value for checksum. That is 8 spaces.
|
||||
|
||||
@@ -13,5 +13,5 @@ internal enum HeaderFlags : ushort
|
||||
EnhancedDeflate = 16,
|
||||
|
||||
//Bit 11: Language encoding flag
|
||||
Efs = 2048
|
||||
Efs = 2048,
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ internal enum ExtraDataType : ushort
|
||||
// -Info-ZIP Unicode Path Extra Field
|
||||
UnicodePathExtraField = 0x7075,
|
||||
Zip64ExtendedInformationExtraField = 0x0001,
|
||||
UnixTimeExtraField = 0x5455
|
||||
UnixTimeExtraField = 0x5455,
|
||||
}
|
||||
|
||||
internal class ExtraData
|
||||
@@ -166,10 +166,10 @@ internal sealed class UnixTimeExtraField : ExtraData
|
||||
return Tuple.Create<DateTime?, DateTime?, DateTime?>(null, null, null);
|
||||
}
|
||||
|
||||
var flags = DataBytes[0];
|
||||
var isModifiedTimeSpecified = (flags & 0x01) == 1;
|
||||
var isLastAccessTimeSpecified = (flags & 0x02) == 1;
|
||||
var isCreationTimeSpecified = (flags & 0x04) == 1;
|
||||
var flags = (RecordedTimeFlag)DataBytes[0];
|
||||
var isModifiedTimeSpecified = flags.HasFlag(RecordedTimeFlag.LastModified);
|
||||
var isLastAccessTimeSpecified = flags.HasFlag(RecordedTimeFlag.LastAccessed);
|
||||
var isCreationTimeSpecified = flags.HasFlag(RecordedTimeFlag.Created);
|
||||
var currentIndex = 1;
|
||||
DateTime? modifiedTime = null;
|
||||
DateTime? lastAccessTime = null;
|
||||
@@ -189,7 +189,7 @@ internal sealed class UnixTimeExtraField : ExtraData
|
||||
{
|
||||
if (currentIndex + 4 > DataBytes.Length)
|
||||
{
|
||||
throw new ArchiveException("Invalid UnicodeExtraTime field");
|
||||
return Tuple.Create<DateTime?, DateTime?, DateTime?>(null, null, null);
|
||||
}
|
||||
|
||||
var lastAccessEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
|
||||
@@ -206,7 +206,7 @@ internal sealed class UnixTimeExtraField : ExtraData
|
||||
{
|
||||
if (currentIndex + 4 > DataBytes.Length)
|
||||
{
|
||||
throw new ArchiveException("Invalid UnicodeExtraTime field");
|
||||
return Tuple.Create<DateTime?, DateTime?, DateTime?>(null, null, null);
|
||||
}
|
||||
|
||||
var creationTimeEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
|
||||
@@ -222,6 +222,15 @@ internal sealed class UnixTimeExtraField : ExtraData
|
||||
return Tuple.Create(modifiedTime, lastAccessTime, creationTime);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum RecordedTimeFlag
|
||||
{
|
||||
None = 0,
|
||||
LastModified = 1,
|
||||
LastAccessed = 2,
|
||||
Created = 4,
|
||||
}
|
||||
}
|
||||
|
||||
internal static class LocalEntryHeaderExtraFactory
|
||||
@@ -229,11 +238,14 @@ internal static class LocalEntryHeaderExtraFactory
|
||||
internal static ExtraData Create(ExtraDataType type, ushort length, byte[] extraData) =>
|
||||
type switch
|
||||
{
|
||||
ExtraDataType.UnicodePathExtraField
|
||||
=> new ExtraUnicodePathExtraField(type, length, extraData),
|
||||
ExtraDataType.Zip64ExtendedInformationExtraField
|
||||
=> new Zip64ExtendedInformationExtraField(type, length, extraData),
|
||||
ExtraDataType.UnicodePathExtraField => new ExtraUnicodePathExtraField(
|
||||
type,
|
||||
length,
|
||||
extraData
|
||||
),
|
||||
ExtraDataType.Zip64ExtendedInformationExtraField =>
|
||||
new Zip64ExtendedInformationExtraField(type, length, extraData),
|
||||
ExtraDataType.UnixTimeExtraField => new UnixTimeExtraField(type, length, extraData),
|
||||
_ => new ExtraData(type, length, extraData)
|
||||
_ => new ExtraData(type, length, extraData),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ internal enum ZipHeaderType
|
||||
DirectoryEnd,
|
||||
Split,
|
||||
Zip64DirectoryEnd,
|
||||
Zip64DirectoryEndLocator
|
||||
Zip64DirectoryEndLocator,
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace SharpCompress.Common.Zip;
|
||||
internal enum CryptoMode
|
||||
{
|
||||
Encrypt,
|
||||
Decrypt
|
||||
Decrypt,
|
||||
}
|
||||
|
||||
internal class PkwareTraditionalCryptoStream : Stream
|
||||
|
||||
@@ -36,10 +36,7 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
|
||||
uint headerBytes = 0;
|
||||
if (
|
||||
_lastEntryHeader != null
|
||||
&& (
|
||||
FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)
|
||||
|| _lastEntryHeader.IsZip64
|
||||
)
|
||||
&& FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)
|
||||
)
|
||||
{
|
||||
if (_lastEntryHeader.Part is null)
|
||||
@@ -49,7 +46,9 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
|
||||
reader = ((StreamingZipFilePart)_lastEntryHeader.Part).FixStreamedFileLocation(
|
||||
ref rewindableStream
|
||||
);
|
||||
|
||||
var pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
|
||||
|
||||
var crc = reader.ReadUInt32();
|
||||
if (crc == POST_DATA_DESCRIPTOR)
|
||||
{
|
||||
@@ -82,6 +81,60 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
|
||||
_lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
|
||||
}
|
||||
}
|
||||
else if (_lastEntryHeader != null && _lastEntryHeader.IsZip64)
|
||||
{
|
||||
if (_lastEntryHeader.Part is null)
|
||||
continue;
|
||||
|
||||
reader = ((StreamingZipFilePart)_lastEntryHeader.Part).FixStreamedFileLocation(
|
||||
ref rewindableStream
|
||||
);
|
||||
|
||||
var pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
|
||||
|
||||
headerBytes = reader.ReadUInt32();
|
||||
|
||||
var version = reader.ReadUInt16();
|
||||
var flags = (HeaderFlags)reader.ReadUInt16();
|
||||
var compressionMethod = (ZipCompressionMethod)reader.ReadUInt16();
|
||||
var lastModifiedDate = reader.ReadUInt16();
|
||||
var lastModifiedTime = reader.ReadUInt16();
|
||||
|
||||
var crc = reader.ReadUInt32();
|
||||
|
||||
if (crc == POST_DATA_DESCRIPTOR)
|
||||
{
|
||||
crc = reader.ReadUInt32();
|
||||
}
|
||||
_lastEntryHeader.Crc = crc;
|
||||
|
||||
// The DataDescriptor can be either 64bit or 32bit
|
||||
var compressed_size = reader.ReadUInt32();
|
||||
var uncompressed_size = reader.ReadUInt32();
|
||||
|
||||
// Check if we have header or 64bit DataDescriptor
|
||||
var test_header = !(headerBytes == 0x04034b50 || headerBytes == 0x02014b50);
|
||||
|
||||
var test_64bit = ((long)uncompressed_size << 32) | compressed_size;
|
||||
if (test_64bit == _lastEntryHeader.CompressedSize && test_header)
|
||||
{
|
||||
_lastEntryHeader.UncompressedSize =
|
||||
((long)reader.ReadUInt32() << 32) | headerBytes;
|
||||
headerBytes = reader.ReadUInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastEntryHeader.UncompressedSize = uncompressed_size;
|
||||
}
|
||||
|
||||
if (pos.HasValue)
|
||||
{
|
||||
_lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
|
||||
|
||||
// 4 = First 4 bytes of the entry header (i.e. 50 4B 03 04)
|
||||
rewindableStream.Position = pos.Value + 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
headerBytes = reader.ReadUInt32();
|
||||
|
||||
@@ -4,5 +4,5 @@ internal enum WinzipAesKeySize
|
||||
{
|
||||
KeySize128 = 1,
|
||||
KeySize192 = 2,
|
||||
KeySize256 = 3
|
||||
KeySize256 = 3,
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@ internal enum ZipCompressionMethod
|
||||
{
|
||||
None = 0,
|
||||
Shrink = 1,
|
||||
Reduce1 = 2,
|
||||
Reduce2 = 3,
|
||||
Reduce3 = 4,
|
||||
Reduce4 = 5,
|
||||
Explode = 6,
|
||||
Deflate = 8,
|
||||
Deflate64 = 9,
|
||||
BZip2 = 12,
|
||||
@@ -11,5 +16,5 @@ internal enum ZipCompressionMethod
|
||||
ZStd = 93,
|
||||
Xz = 95,
|
||||
PPMd = 98,
|
||||
WinzipAes = 0x63 //http://www.winzip.com/aes_info.htm
|
||||
WinzipAes = 0x63, //http://www.winzip.com/aes_info.htm
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SharpCompress.Common.Zip.Headers;
|
||||
|
||||
namespace SharpCompress.Common.Zip;
|
||||
@@ -15,10 +16,19 @@ public class ZipEntry : Entry
|
||||
return;
|
||||
}
|
||||
_filePart = filePart;
|
||||
|
||||
LastModifiedTime = Utility.DosDateToDateTime(
|
||||
filePart.Header.LastModifiedDate,
|
||||
filePart.Header.LastModifiedTime
|
||||
);
|
||||
|
||||
var times =
|
||||
filePart.Header.Extra.FirstOrDefault(header =>
|
||||
header.GetType() == typeof(UnixTimeExtraField)
|
||||
) as UnixTimeExtraField;
|
||||
|
||||
LastAccessedTime = times?.UnicodeTimes.Item2;
|
||||
CreatedTime = times?.UnicodeTimes.Item3;
|
||||
}
|
||||
|
||||
public override CompressionType CompressionType =>
|
||||
@@ -31,7 +41,12 @@ public class ZipEntry : Entry
|
||||
ZipCompressionMethod.PPMd => CompressionType.PPMd,
|
||||
ZipCompressionMethod.None => CompressionType.None,
|
||||
ZipCompressionMethod.Shrink => CompressionType.Shrink,
|
||||
_ => CompressionType.Unknown
|
||||
ZipCompressionMethod.Reduce1 => CompressionType.Reduce1,
|
||||
ZipCompressionMethod.Reduce2 => CompressionType.Reduce2,
|
||||
ZipCompressionMethod.Reduce3 => CompressionType.Reduce3,
|
||||
ZipCompressionMethod.Reduce4 => CompressionType.Reduce4,
|
||||
ZipCompressionMethod.Explode => CompressionType.Explode,
|
||||
_ => CompressionType.Unknown,
|
||||
};
|
||||
|
||||
public override long Crc => _filePart?.Header.Crc ?? 0;
|
||||
@@ -46,9 +61,17 @@ public class ZipEntry : Entry
|
||||
|
||||
public override DateTime? LastModifiedTime { get; }
|
||||
|
||||
public override DateTime? CreatedTime => null;
|
||||
/// <inheritdoc/>
|
||||
/// <remarks>
|
||||
/// The returned time is UTC, not local.
|
||||
/// </remarks>
|
||||
public override DateTime? CreatedTime { get; }
|
||||
|
||||
public override DateTime? LastAccessedTime => null;
|
||||
/// <inheritdoc/>
|
||||
/// <remarks>
|
||||
/// The returned time is UTC, not local.
|
||||
/// </remarks>
|
||||
public override DateTime? LastAccessedTime { get; }
|
||||
|
||||
public override DateTime? ArchivedTime => null;
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ using SharpCompress.Compressors;
|
||||
using SharpCompress.Compressors.BZip2;
|
||||
using SharpCompress.Compressors.Deflate;
|
||||
using SharpCompress.Compressors.Deflate64;
|
||||
using SharpCompress.Compressors.Explode;
|
||||
using SharpCompress.Compressors.LZMA;
|
||||
using SharpCompress.Compressors.PPMd;
|
||||
using SharpCompress.Compressors.Reduce;
|
||||
using SharpCompress.Compressors.Shrink;
|
||||
using SharpCompress.Compressors.Xz;
|
||||
using SharpCompress.IO;
|
||||
@@ -89,6 +91,32 @@ internal abstract class ZipFilePart : FilePart
|
||||
Header.UncompressedSize
|
||||
);
|
||||
}
|
||||
case ZipCompressionMethod.Reduce1:
|
||||
{
|
||||
return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 1);
|
||||
}
|
||||
case ZipCompressionMethod.Reduce2:
|
||||
{
|
||||
return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 2);
|
||||
}
|
||||
case ZipCompressionMethod.Reduce3:
|
||||
{
|
||||
return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 3);
|
||||
}
|
||||
case ZipCompressionMethod.Reduce4:
|
||||
{
|
||||
return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 4);
|
||||
}
|
||||
case ZipCompressionMethod.Explode:
|
||||
{
|
||||
return new ExplodeStream(
|
||||
stream,
|
||||
Header.CompressedSize,
|
||||
Header.UncompressedSize,
|
||||
Header.Flags
|
||||
);
|
||||
}
|
||||
|
||||
case ZipCompressionMethod.Deflate:
|
||||
{
|
||||
return new DeflateStream(stream, CompressionMode.Decompress);
|
||||
@@ -203,6 +231,10 @@ internal abstract class ZipFilePart : FilePart
|
||||
{
|
||||
case ZipCompressionMethod.None:
|
||||
case ZipCompressionMethod.Shrink:
|
||||
case ZipCompressionMethod.Reduce1:
|
||||
case ZipCompressionMethod.Reduce2:
|
||||
case ZipCompressionMethod.Reduce3:
|
||||
case ZipCompressionMethod.Reduce4:
|
||||
case ZipCompressionMethod.Deflate:
|
||||
case ZipCompressionMethod.Deflate64:
|
||||
case ZipCompressionMethod.BZip2:
|
||||
|
||||
@@ -56,11 +56,11 @@ internal class ZipHeaderFactory
|
||||
case POST_DATA_DESCRIPTOR:
|
||||
{
|
||||
if (
|
||||
FlagUtility.HasFlag(
|
||||
_lastEntryHeader != null
|
||||
&& FlagUtility.HasFlag(
|
||||
_lastEntryHeader.NotNull().Flags,
|
||||
HeaderFlags.UsePostDataDescriptor
|
||||
)
|
||||
&& _lastEntryHeader != null
|
||||
)
|
||||
{
|
||||
_lastEntryHeader.Crc = reader.ReadUInt32();
|
||||
|
||||
@@ -555,6 +555,6 @@ internal class BZip2Constants
|
||||
858,
|
||||
364,
|
||||
936,
|
||||
638
|
||||
638,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#nullable disable
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -42,14 +42,17 @@ internal class CBZip2InputStream : Stream
|
||||
private static void Cadvise()
|
||||
{
|
||||
//System.out.Println("CRC Error");
|
||||
//throw new CCoruptionError();
|
||||
throw new InvalidOperationException("BZip2 error");
|
||||
}
|
||||
|
||||
private static void BadBGLengths() => Cadvise();
|
||||
|
||||
private static void BitStreamEOF() => Cadvise();
|
||||
|
||||
private static void CompressedStreamEOF() => Cadvise();
|
||||
private static void CompressedStreamEOF()
|
||||
{
|
||||
throw new InvalidOperationException("BZip2 compressed file ends unexpectedly");
|
||||
}
|
||||
|
||||
private void MakeMaps()
|
||||
{
|
||||
|
||||
@@ -1829,7 +1829,7 @@ internal sealed class CBZip2OutputStream : Stream
|
||||
88573,
|
||||
265720,
|
||||
797161,
|
||||
2391484
|
||||
2391484,
|
||||
};
|
||||
|
||||
private void AllocateCompressStructures()
|
||||
|
||||
@@ -288,7 +288,7 @@ internal class CRC
|
||||
unchecked((int)0xbcb4666d),
|
||||
unchecked((int)0xb8757bda),
|
||||
unchecked((int)0xb5365d03),
|
||||
unchecked((int)0xb1f740b4)
|
||||
unchecked((int)0xb1f740b4),
|
||||
};
|
||||
|
||||
public CRC() => InitialiseCRC();
|
||||
|
||||
@@ -3,5 +3,5 @@ namespace SharpCompress.Compressors;
|
||||
public enum CompressionMode
|
||||
{
|
||||
Compress = 0,
|
||||
Decompress = 1
|
||||
Decompress = 1,
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ internal sealed partial class DeflateManager
|
||||
5,
|
||||
5,
|
||||
5,
|
||||
0
|
||||
0,
|
||||
};
|
||||
|
||||
// extra bits for each distance code
|
||||
@@ -141,7 +141,7 @@ internal sealed partial class DeflateManager
|
||||
12,
|
||||
12,
|
||||
13,
|
||||
13
|
||||
13,
|
||||
};
|
||||
|
||||
internal enum BlockState
|
||||
@@ -149,14 +149,14 @@ internal sealed partial class DeflateManager
|
||||
NeedMore = 0, // block not completed, need more input or more output
|
||||
BlockDone, // block flush performed
|
||||
FinishStarted, // finish started, need only more output at next deflate
|
||||
FinishDone // finish done, accept no more input or output
|
||||
FinishDone, // finish done, accept no more input or output
|
||||
}
|
||||
|
||||
internal enum DeflateFlavor
|
||||
{
|
||||
Store,
|
||||
Fast,
|
||||
Slow
|
||||
Slow,
|
||||
}
|
||||
|
||||
private const int MEM_LEVEL_MAX = 9;
|
||||
@@ -214,7 +214,7 @@ internal sealed partial class DeflateManager
|
||||
new Config(8, 16, 128, 128, DeflateFlavor.Slow),
|
||||
new Config(8, 32, 128, 256, DeflateFlavor.Slow),
|
||||
new Config(32, 128, 258, 1024, DeflateFlavor.Slow),
|
||||
new Config(32, 258, 258, 4096, DeflateFlavor.Slow)
|
||||
new Config(32, 258, 258, 4096, DeflateFlavor.Slow),
|
||||
};
|
||||
|
||||
private static readonly Config[] Table;
|
||||
@@ -233,7 +233,7 @@ internal sealed partial class DeflateManager
|
||||
"insufficient memory",
|
||||
"buffer error",
|
||||
"incompatible version",
|
||||
""
|
||||
"",
|
||||
};
|
||||
|
||||
// preset dictionary flag in zlib header
|
||||
@@ -1793,7 +1793,7 @@ internal sealed partial class DeflateManager
|
||||
DeflateFlavor.Store => DeflateNone,
|
||||
DeflateFlavor.Fast => DeflateFast,
|
||||
DeflateFlavor.Slow => DeflateSlow,
|
||||
_ => DeflateFunction
|
||||
_ => DeflateFunction,
|
||||
};
|
||||
|
||||
internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
|
||||
|
||||
@@ -39,5 +39,5 @@ public enum FlushType
|
||||
Full,
|
||||
|
||||
/// <summary>Signals the end of the compression/decompression stream.</summary>
|
||||
Finish
|
||||
Finish,
|
||||
}
|
||||
|
||||
@@ -1615,7 +1615,7 @@ internal sealed class InfTree
|
||||
79,
|
||||
0,
|
||||
9,
|
||||
255
|
||||
255,
|
||||
};
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
@@ -1716,7 +1716,7 @@ internal sealed class InfTree
|
||||
193,
|
||||
192,
|
||||
5,
|
||||
24577
|
||||
24577,
|
||||
};
|
||||
|
||||
// Tables for deflate from PKZIP's appnote.txt.
|
||||
@@ -1753,7 +1753,7 @@ internal sealed class InfTree
|
||||
227,
|
||||
258,
|
||||
0,
|
||||
0
|
||||
0,
|
||||
};
|
||||
|
||||
// see note #13 above about 258
|
||||
@@ -1790,7 +1790,7 @@ internal sealed class InfTree
|
||||
5,
|
||||
0,
|
||||
112,
|
||||
112
|
||||
112,
|
||||
};
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
@@ -1825,7 +1825,7 @@ internal sealed class InfTree
|
||||
8193,
|
||||
12289,
|
||||
16385,
|
||||
24577
|
||||
24577,
|
||||
};
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
@@ -1860,7 +1860,7 @@ internal sealed class InfTree
|
||||
12,
|
||||
12,
|
||||
13,
|
||||
13
|
||||
13,
|
||||
};
|
||||
|
||||
// If BMAX needs to be larger than 16, then h and x[] should be uLong.
|
||||
|
||||
@@ -93,7 +93,7 @@ internal sealed class InflateBlocks
|
||||
2,
|
||||
14,
|
||||
1,
|
||||
15
|
||||
15,
|
||||
};
|
||||
|
||||
internal ZlibCodec _codec; // pointer back to this zlib stream
|
||||
@@ -815,7 +815,7 @@ internal sealed class InflateBlocks
|
||||
CODES = 6, // processing fixed or dynamic block
|
||||
DRY = 7, // output remaining window bytes
|
||||
DONE = 8, // finished last block, done
|
||||
BAD = 9 // ot a data error--stuck here
|
||||
BAD = 9, // ot a data error--stuck here
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -842,7 +842,7 @@ internal static class InternalInflateConstants
|
||||
0x00001fff,
|
||||
0x00003fff,
|
||||
0x00007fff,
|
||||
0x0000ffff
|
||||
0x0000ffff,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2054,7 +2054,7 @@ internal sealed class InflateManager
|
||||
CHECK2 = 10, // two check bytes to go
|
||||
CHECK1 = 11, // one check byte to go
|
||||
DONE = 12, // finished check, done
|
||||
BAD = 13 // got an error--stay here
|
||||
BAD = 13, // got an error--stay here
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -95,7 +95,7 @@ internal sealed partial class DeflateManager
|
||||
2,
|
||||
14,
|
||||
1,
|
||||
15
|
||||
15,
|
||||
};
|
||||
|
||||
// The lengths of the bit length codes are sent in order of decreasing
|
||||
@@ -618,7 +618,7 @@ internal sealed partial class DeflateManager
|
||||
29,
|
||||
29,
|
||||
29,
|
||||
29
|
||||
29,
|
||||
};
|
||||
|
||||
internal static readonly sbyte[] LengthCode =
|
||||
@@ -878,7 +878,7 @@ internal sealed partial class DeflateManager
|
||||
27,
|
||||
27,
|
||||
27,
|
||||
28
|
||||
28,
|
||||
};
|
||||
|
||||
internal static readonly int[] LengthBase =
|
||||
@@ -911,7 +911,7 @@ internal sealed partial class DeflateManager
|
||||
160,
|
||||
192,
|
||||
224,
|
||||
0
|
||||
0,
|
||||
};
|
||||
|
||||
internal static readonly int[] DistanceBase =
|
||||
@@ -945,7 +945,7 @@ internal sealed partial class DeflateManager
|
||||
8192,
|
||||
12288,
|
||||
16384,
|
||||
24576
|
||||
24576,
|
||||
};
|
||||
|
||||
internal short[] dyn_tree; // the dynamic tree
|
||||
|
||||
@@ -143,7 +143,7 @@ public enum CompressionLevel
|
||||
/// <summary>
|
||||
/// A synonym for BestCompression.
|
||||
/// </summary>
|
||||
Level9 = BestCompression
|
||||
Level9 = BestCompression,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -171,7 +171,7 @@ public enum CompressionStrategy
|
||||
/// Using <c>HuffmanOnly</c> will force the compressor to do Huffman encoding only, with no
|
||||
/// string matching.
|
||||
/// </summary>
|
||||
HuffmanOnly = 2
|
||||
HuffmanOnly = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -859,7 +859,7 @@ internal sealed class StaticTree
|
||||
99,
|
||||
8,
|
||||
227,
|
||||
8
|
||||
8,
|
||||
};
|
||||
|
||||
internal static readonly short[] distTreeCodes =
|
||||
@@ -923,7 +923,7 @@ internal sealed class StaticTree
|
||||
7,
|
||||
5,
|
||||
23,
|
||||
5
|
||||
5,
|
||||
};
|
||||
|
||||
// extra bits for each bit length code
|
||||
@@ -947,7 +947,7 @@ internal sealed class StaticTree
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
7
|
||||
7,
|
||||
};
|
||||
|
||||
internal static readonly StaticTree Literals;
|
||||
|
||||
@@ -39,7 +39,7 @@ internal enum ZlibStreamFlavor
|
||||
{
|
||||
ZLIB = 1950,
|
||||
DEFLATE = 1951,
|
||||
GZIP = 1952
|
||||
GZIP = 1952,
|
||||
}
|
||||
|
||||
internal class ZlibBaseStream : Stream
|
||||
@@ -655,6 +655,6 @@ internal class ZlibBaseStream : Stream
|
||||
{
|
||||
Writer,
|
||||
Reader,
|
||||
Undefined
|
||||
Undefined,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ internal enum BlockType
|
||||
{
|
||||
Uncompressed = 0,
|
||||
Static = 1,
|
||||
Dynamic = 2
|
||||
Dynamic = 2,
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ internal static class FastEncoderStatics
|
||||
0x7e,
|
||||
0x7c,
|
||||
0x1f,
|
||||
0x3f
|
||||
0x3f,
|
||||
};
|
||||
|
||||
internal static ReadOnlySpan<byte> B_FINAL_FAST_ENCODER_TREE_STRUCTURE_DATA =>
|
||||
@@ -214,7 +214,7 @@ internal static class FastEncoderStatics
|
||||
0x7e,
|
||||
0x7c,
|
||||
0x1f,
|
||||
0x3f
|
||||
0x3f,
|
||||
};
|
||||
|
||||
// Output a currentMatch with length matchLen (>= MIN_MATCH) and displacement matchPos
|
||||
@@ -762,7 +762,7 @@ internal static class FastEncoderStatics
|
||||
0x0039e7f1,
|
||||
0x003be7f1,
|
||||
0x003de7f1,
|
||||
0x000047eb
|
||||
0x000047eb,
|
||||
};
|
||||
|
||||
internal static readonly uint[] FAST_ENCODER_DISTANCE_CODE_INFO =
|
||||
@@ -798,7 +798,7 @@ internal static class FastEncoderStatics
|
||||
0x000007d5,
|
||||
0x000017d5,
|
||||
0x00000000,
|
||||
0x00000100
|
||||
0x00000100,
|
||||
};
|
||||
|
||||
internal static readonly uint[] BIT_MASK =
|
||||
@@ -818,7 +818,7 @@ internal static class FastEncoderStatics
|
||||
4095,
|
||||
8191,
|
||||
16383,
|
||||
32767
|
||||
32767,
|
||||
};
|
||||
internal static readonly byte[] EXTRA_LENGTH_BITS =
|
||||
{
|
||||
@@ -850,7 +850,7 @@ internal static class FastEncoderStatics
|
||||
5,
|
||||
5,
|
||||
5,
|
||||
0
|
||||
0,
|
||||
};
|
||||
internal static readonly byte[] EXTRA_DISTANCE_BITS =
|
||||
{
|
||||
@@ -885,7 +885,7 @@ internal static class FastEncoderStatics
|
||||
13,
|
||||
13,
|
||||
0,
|
||||
0
|
||||
0,
|
||||
};
|
||||
internal const int NUM_CHARS = 256;
|
||||
internal const int NUM_LENGTH_BASE_CODES = 29;
|
||||
|
||||
@@ -70,7 +70,7 @@ internal sealed class InflaterManaged
|
||||
5,
|
||||
5,
|
||||
5,
|
||||
16
|
||||
16,
|
||||
};
|
||||
|
||||
// The base length for length code 257 - 285.
|
||||
@@ -105,7 +105,7 @@ internal sealed class InflaterManaged
|
||||
163,
|
||||
195,
|
||||
227,
|
||||
3
|
||||
3,
|
||||
};
|
||||
|
||||
// The base distance for distance code 0 - 31
|
||||
@@ -143,7 +143,7 @@ internal sealed class InflaterManaged
|
||||
16385,
|
||||
24577,
|
||||
32769,
|
||||
49153
|
||||
49153,
|
||||
};
|
||||
|
||||
// code lengths for code length alphabet is stored in following order
|
||||
@@ -184,7 +184,7 @@ internal sealed class InflaterManaged
|
||||
0x07,
|
||||
0x17,
|
||||
0x0f,
|
||||
0x1f
|
||||
0x1f,
|
||||
};
|
||||
|
||||
private readonly OutputWindow _output;
|
||||
|
||||
@@ -37,5 +37,5 @@ internal enum InflaterState
|
||||
ReadingFooter = 22,
|
||||
VerifyingFooter = 23,
|
||||
|
||||
Done = 24 // Finished
|
||||
Done = 24, // Finished
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ internal enum MatchState
|
||||
{
|
||||
HasSymbol = 1,
|
||||
HasMatch = 2,
|
||||
HasSymbolAndMatch = 3
|
||||
HasSymbolAndMatch = 3,
|
||||
}
|
||||
|
||||
746
src/SharpCompress/Compressors/Explode/ExplodeStream.cs
Normal file
746
src/SharpCompress/Compressors/Explode/ExplodeStream.cs
Normal file
@@ -0,0 +1,746 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Zip.Headers;
|
||||
|
||||
namespace SharpCompress.Compressors.Explode;
|
||||
|
||||
public class ExplodeStream : Stream
|
||||
{
|
||||
private const int INVALID_CODE = 99;
|
||||
private const int WSIZE = 64 * 1024;
|
||||
|
||||
private readonly long unCompressedSize;
|
||||
private readonly int compressedSize;
|
||||
private readonly HeaderFlags generalPurposeBitFlag;
|
||||
private readonly Stream inStream;
|
||||
|
||||
private huftNode[]? hufLiteralCodeTable; /* literal code table */
|
||||
private huftNode[] hufLengthCodeTable = []; /* length code table */
|
||||
private huftNode[] hufDistanceCodeTable = []; /* distance code table */
|
||||
|
||||
private int bitsForLiteralCodeTable;
|
||||
private int bitsForLengthCodeTable;
|
||||
private int bitsForDistanceCodeTable;
|
||||
private int numOfUncodedLowerDistanceBits; /* number of uncoded lower distance bits */
|
||||
|
||||
private ulong bitBuffer;
|
||||
private int bitBufferCount;
|
||||
|
||||
private readonly byte[] windowsBuffer;
|
||||
private uint maskForLiteralCodeTable;
|
||||
private uint maskForLengthCodeTable;
|
||||
private uint maskForDistanceCodeTable;
|
||||
private uint maskForDistanceLowBits;
|
||||
private long outBytesCount;
|
||||
|
||||
private int windowIndex;
|
||||
private int distance;
|
||||
private int length;
|
||||
|
||||
internal ExplodeStream(
|
||||
Stream inStr,
|
||||
long compressedSize,
|
||||
long uncompressedSize,
|
||||
HeaderFlags generalPurposeBitFlag
|
||||
)
|
||||
{
|
||||
inStream = inStr;
|
||||
this.compressedSize = (int)compressedSize;
|
||||
unCompressedSize = (long)uncompressedSize;
|
||||
this.generalPurposeBitFlag = generalPurposeBitFlag;
|
||||
explode_SetTables();
|
||||
|
||||
windowsBuffer = new byte[WSIZE];
|
||||
explode_var_init();
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
public override bool CanSeek => false;
|
||||
public override bool CanWrite => false;
|
||||
public override long Length => unCompressedSize;
|
||||
public override long Position
|
||||
{
|
||||
get => outBytesCount;
|
||||
set { }
|
||||
}
|
||||
|
||||
static uint[] mask_bits = new uint[]
|
||||
{
|
||||
0x0000,
|
||||
0x0001,
|
||||
0x0003,
|
||||
0x0007,
|
||||
0x000f,
|
||||
0x001f,
|
||||
0x003f,
|
||||
0x007f,
|
||||
0x00ff,
|
||||
0x01ff,
|
||||
0x03ff,
|
||||
0x07ff,
|
||||
0x0fff,
|
||||
0x1fff,
|
||||
0x3fff,
|
||||
0x7fff,
|
||||
0xffff,
|
||||
};
|
||||
|
||||
/* Tables for length and distance */
|
||||
static int[] cplen2 = new int[]
|
||||
{
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
60,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
64,
|
||||
65,
|
||||
};
|
||||
|
||||
static int[] cplen3 = new int[]
|
||||
{
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
60,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
64,
|
||||
65,
|
||||
66,
|
||||
};
|
||||
|
||||
static int[] extra = new int[]
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
8,
|
||||
};
|
||||
|
||||
static int[] cpdist4 = new int[]
|
||||
{
|
||||
1,
|
||||
65,
|
||||
129,
|
||||
193,
|
||||
257,
|
||||
321,
|
||||
385,
|
||||
449,
|
||||
513,
|
||||
577,
|
||||
641,
|
||||
705,
|
||||
769,
|
||||
833,
|
||||
897,
|
||||
961,
|
||||
1025,
|
||||
1089,
|
||||
1153,
|
||||
1217,
|
||||
1281,
|
||||
1345,
|
||||
1409,
|
||||
1473,
|
||||
1537,
|
||||
1601,
|
||||
1665,
|
||||
1729,
|
||||
1793,
|
||||
1857,
|
||||
1921,
|
||||
1985,
|
||||
2049,
|
||||
2113,
|
||||
2177,
|
||||
2241,
|
||||
2305,
|
||||
2369,
|
||||
2433,
|
||||
2497,
|
||||
2561,
|
||||
2625,
|
||||
2689,
|
||||
2753,
|
||||
2817,
|
||||
2881,
|
||||
2945,
|
||||
3009,
|
||||
3073,
|
||||
3137,
|
||||
3201,
|
||||
3265,
|
||||
3329,
|
||||
3393,
|
||||
3457,
|
||||
3521,
|
||||
3585,
|
||||
3649,
|
||||
3713,
|
||||
3777,
|
||||
3841,
|
||||
3905,
|
||||
3969,
|
||||
4033,
|
||||
};
|
||||
|
||||
static int[] cpdist8 = new int[]
|
||||
{
|
||||
1,
|
||||
129,
|
||||
257,
|
||||
385,
|
||||
513,
|
||||
641,
|
||||
769,
|
||||
897,
|
||||
1025,
|
||||
1153,
|
||||
1281,
|
||||
1409,
|
||||
1537,
|
||||
1665,
|
||||
1793,
|
||||
1921,
|
||||
2049,
|
||||
2177,
|
||||
2305,
|
||||
2433,
|
||||
2561,
|
||||
2689,
|
||||
2817,
|
||||
2945,
|
||||
3073,
|
||||
3201,
|
||||
3329,
|
||||
3457,
|
||||
3585,
|
||||
3713,
|
||||
3841,
|
||||
3969,
|
||||
4097,
|
||||
4225,
|
||||
4353,
|
||||
4481,
|
||||
4609,
|
||||
4737,
|
||||
4865,
|
||||
4993,
|
||||
5121,
|
||||
5249,
|
||||
5377,
|
||||
5505,
|
||||
5633,
|
||||
5761,
|
||||
5889,
|
||||
6017,
|
||||
6145,
|
||||
6273,
|
||||
6401,
|
||||
6529,
|
||||
6657,
|
||||
6785,
|
||||
6913,
|
||||
7041,
|
||||
7169,
|
||||
7297,
|
||||
7425,
|
||||
7553,
|
||||
7681,
|
||||
7809,
|
||||
7937,
|
||||
8065,
|
||||
};
|
||||
|
||||
private int get_tree(int[] arrBitLengths, int numberExpected)
|
||||
/* Get the bit lengths for a code representation from the compressed
|
||||
stream. If get_tree() returns 4, then there is an error in the data.
|
||||
Otherwise zero is returned. */
|
||||
{
|
||||
/* get bit lengths */
|
||||
int inIndex = inStream.ReadByte() + 1; /* length/count pairs to read */
|
||||
int outIndex = 0; /* next code */
|
||||
do
|
||||
{
|
||||
int nextByte = inStream.ReadByte();
|
||||
int bitLengthOfCodes = (nextByte & 0xf) + 1; /* bits in code (1..16) */
|
||||
int numOfCodes = ((nextByte & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */
|
||||
if (outIndex + numOfCodes > numberExpected)
|
||||
return 4; /* don't overflow arrBitLengths[] */
|
||||
do
|
||||
{
|
||||
arrBitLengths[outIndex++] = bitLengthOfCodes;
|
||||
} while ((--numOfCodes) != 0);
|
||||
} while ((--inIndex) != 0);
|
||||
|
||||
return outIndex != numberExpected ? 4 : 0; /* should have read numberExpected of them */
|
||||
}
|
||||
|
||||
private int explode_SetTables()
|
||||
{
|
||||
int returnCode; /* return codes */
|
||||
int[] arrBitLengthsForCodes = new int[256]; /* bit lengths for codes */
|
||||
|
||||
bitsForLiteralCodeTable = 0; /* bits for tb */
|
||||
bitsForLengthCodeTable = 7;
|
||||
bitsForDistanceCodeTable = (compressedSize) > 200000 ? 8 : 7;
|
||||
|
||||
if ((generalPurposeBitFlag & HeaderFlags.Bit2) != 0)
|
||||
/* With literal tree--minimum match length is 3 */
|
||||
{
|
||||
bitsForLiteralCodeTable = 9; /* base table size for literals */
|
||||
if ((returnCode = get_tree(arrBitLengthsForCodes, 256)) != 0)
|
||||
return returnCode;
|
||||
|
||||
if (
|
||||
(
|
||||
returnCode = HuftTree.huftbuid(
|
||||
arrBitLengthsForCodes,
|
||||
256,
|
||||
256,
|
||||
[],
|
||||
[],
|
||||
out hufLiteralCodeTable,
|
||||
ref bitsForLiteralCodeTable
|
||||
)
|
||||
) != 0
|
||||
)
|
||||
return returnCode;
|
||||
|
||||
if ((returnCode = get_tree(arrBitLengthsForCodes, 64)) != 0)
|
||||
return returnCode;
|
||||
|
||||
if (
|
||||
(
|
||||
returnCode = HuftTree.huftbuid(
|
||||
arrBitLengthsForCodes,
|
||||
64,
|
||||
0,
|
||||
cplen3,
|
||||
extra,
|
||||
out hufLengthCodeTable,
|
||||
ref bitsForLengthCodeTable
|
||||
)
|
||||
) != 0
|
||||
)
|
||||
return returnCode;
|
||||
}
|
||||
else
|
||||
/* No literal tree--minimum match length is 2 */
|
||||
{
|
||||
if ((returnCode = get_tree(arrBitLengthsForCodes, 64)) != 0)
|
||||
return returnCode;
|
||||
|
||||
hufLiteralCodeTable = null;
|
||||
|
||||
if (
|
||||
(
|
||||
returnCode = HuftTree.huftbuid(
|
||||
arrBitLengthsForCodes,
|
||||
64,
|
||||
0,
|
||||
cplen2,
|
||||
extra,
|
||||
out hufLengthCodeTable,
|
||||
ref bitsForLengthCodeTable
|
||||
)
|
||||
) != 0
|
||||
)
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
if ((returnCode = get_tree(arrBitLengthsForCodes, 64)) != 0)
|
||||
return (int)returnCode;
|
||||
|
||||
if ((generalPurposeBitFlag & HeaderFlags.Bit1) != 0) /* true if 8K */
|
||||
{
|
||||
numOfUncodedLowerDistanceBits = 7;
|
||||
returnCode = HuftTree.huftbuid(
|
||||
arrBitLengthsForCodes,
|
||||
64,
|
||||
0,
|
||||
cpdist8,
|
||||
extra,
|
||||
out hufDistanceCodeTable,
|
||||
ref bitsForDistanceCodeTable
|
||||
);
|
||||
}
|
||||
else /* else 4K */
|
||||
{
|
||||
numOfUncodedLowerDistanceBits = 6;
|
||||
returnCode = HuftTree.huftbuid(
|
||||
arrBitLengthsForCodes,
|
||||
64,
|
||||
0,
|
||||
cpdist4,
|
||||
extra,
|
||||
out hufDistanceCodeTable,
|
||||
ref bitsForDistanceCodeTable
|
||||
);
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
private void NeedBits(int numberOfBits)
|
||||
{
|
||||
while (bitBufferCount < (numberOfBits))
|
||||
{
|
||||
bitBuffer |= (uint)inStream.ReadByte() << bitBufferCount;
|
||||
bitBufferCount += 8;
|
||||
}
|
||||
}
|
||||
|
||||
private void DumpBits(int numberOfBits)
|
||||
{
|
||||
bitBuffer >>= numberOfBits;
|
||||
bitBufferCount -= numberOfBits;
|
||||
}
|
||||
|
||||
int DecodeHuft(huftNode[] htab, int bits, uint mask, out huftNode huftPointer, out int e)
|
||||
{
|
||||
NeedBits(bits);
|
||||
|
||||
int tabOffset = (int)(~bitBuffer & mask);
|
||||
huftPointer = htab[tabOffset];
|
||||
|
||||
while (true)
|
||||
{
|
||||
DumpBits(huftPointer.NumberOfBitsUsed);
|
||||
e = huftPointer.NumberOfExtraBits;
|
||||
if (e <= 32)
|
||||
break;
|
||||
if (e == INVALID_CODE)
|
||||
return 1;
|
||||
|
||||
e &= 31;
|
||||
NeedBits(e);
|
||||
|
||||
tabOffset = (int)(~bitBuffer & mask_bits[e]);
|
||||
huftPointer = huftPointer.ChildNodes[tabOffset];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void explode_var_init()
|
||||
{
|
||||
/* explode the coded data */
|
||||
bitBuffer = 0;
|
||||
bitBufferCount = 0;
|
||||
maskForLiteralCodeTable = mask_bits[bitsForLiteralCodeTable]; //only used in explode_lit
|
||||
maskForLengthCodeTable = mask_bits[bitsForLengthCodeTable];
|
||||
maskForDistanceCodeTable = mask_bits[bitsForDistanceCodeTable];
|
||||
maskForDistanceLowBits = mask_bits[numOfUncodedLowerDistanceBits];
|
||||
outBytesCount = 0;
|
||||
|
||||
windowIndex = 0; /* initialize bit buffer, window */
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int countIndex = 0;
|
||||
while (countIndex < count && outBytesCount < unCompressedSize) /* do until unCompressedSize bytes uncompressed */
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
NeedBits(1);
|
||||
bool literal = (bitBuffer & 1) == 1;
|
||||
DumpBits(1);
|
||||
|
||||
huftNode huftPointer;
|
||||
if (literal) /* then literal--decode it */
|
||||
{
|
||||
byte nextByte;
|
||||
if (hufLiteralCodeTable != null)
|
||||
{
|
||||
/* get coded literal */
|
||||
if (
|
||||
DecodeHuft(
|
||||
hufLiteralCodeTable,
|
||||
bitsForLiteralCodeTable,
|
||||
maskForLiteralCodeTable,
|
||||
out huftPointer,
|
||||
out _
|
||||
) != 0
|
||||
)
|
||||
throw new Exception("Error decoding literal value");
|
||||
|
||||
nextByte = (byte)huftPointer.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
NeedBits(8);
|
||||
nextByte = (byte)bitBuffer;
|
||||
DumpBits(8);
|
||||
}
|
||||
|
||||
buffer[offset + (countIndex++)] = nextByte;
|
||||
windowsBuffer[windowIndex++] = nextByte;
|
||||
outBytesCount++;
|
||||
|
||||
if (windowIndex == WSIZE)
|
||||
windowIndex = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
NeedBits(numOfUncodedLowerDistanceBits); /* get distance low bits */
|
||||
distance = (int)(bitBuffer & maskForDistanceLowBits);
|
||||
DumpBits(numOfUncodedLowerDistanceBits);
|
||||
|
||||
/* get coded distance high bits */
|
||||
if (
|
||||
DecodeHuft(
|
||||
hufDistanceCodeTable,
|
||||
bitsForDistanceCodeTable,
|
||||
maskForDistanceCodeTable,
|
||||
out huftPointer,
|
||||
out _
|
||||
) != 0
|
||||
)
|
||||
throw new Exception("Error decoding distance high bits");
|
||||
|
||||
distance = windowIndex - (distance + huftPointer.Value); /* construct offset */
|
||||
|
||||
/* get coded length */
|
||||
if (
|
||||
DecodeHuft(
|
||||
hufLengthCodeTable,
|
||||
bitsForLengthCodeTable,
|
||||
maskForLengthCodeTable,
|
||||
out huftPointer,
|
||||
out int extraBitLength
|
||||
) != 0
|
||||
)
|
||||
throw new Exception("Error decoding coded length");
|
||||
|
||||
length = huftPointer.Value;
|
||||
|
||||
if (extraBitLength != 0) /* get length extra bits */
|
||||
{
|
||||
NeedBits(8);
|
||||
length += (int)(bitBuffer & 0xff);
|
||||
DumpBits(8);
|
||||
}
|
||||
|
||||
if (length > (unCompressedSize - outBytesCount))
|
||||
length = (int)(unCompressedSize - outBytesCount);
|
||||
|
||||
distance &= WSIZE - 1;
|
||||
}
|
||||
|
||||
while (length != 0 && countIndex < count)
|
||||
{
|
||||
byte nextByte = windowsBuffer[distance++];
|
||||
buffer[offset + (countIndex++)] = nextByte;
|
||||
windowsBuffer[windowIndex++] = nextByte;
|
||||
outBytesCount++;
|
||||
|
||||
if (distance == WSIZE)
|
||||
distance = 0;
|
||||
|
||||
if (windowIndex == WSIZE)
|
||||
windowIndex = 0;
|
||||
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
return countIndex;
|
||||
}
|
||||
}
|
||||
269
src/SharpCompress/Compressors/Explode/HuftTree.cs
Normal file
269
src/SharpCompress/Compressors/Explode/HuftTree.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* This code has been converted to C# based on the original huft_tree code found in
|
||||
* inflate.c -- by Mark Adler version c17e, 30 Mar 2007
|
||||
*/
|
||||
|
||||
namespace SharpCompress.Compressors.Explode;
|
||||
|
||||
public class huftNode
|
||||
{
|
||||
public int NumberOfExtraBits; /* number of extra bits or operation */
|
||||
public int NumberOfBitsUsed; /* number of bits in this code or subcode */
|
||||
public int Value; /* literal, length base, or distance base */
|
||||
public huftNode[] ChildNodes = []; /* next level of table */
|
||||
}
|
||||
|
||||
public static class HuftTree
|
||||
{
|
||||
private const int INVALID_CODE = 99;
|
||||
|
||||
/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
|
||||
private const int BMAX = 16; /* maximum bit length of any code (16 for explode) */
|
||||
private const int N_MAX = 288; /* maximum number of codes in any set */
|
||||
|
||||
public static int huftbuid(
|
||||
int[] arrBitLengthForCodes,
|
||||
int numberOfCodes,
|
||||
int numberOfSimpleValueCodes,
|
||||
int[] arrBaseValuesForNonSimpleCodes,
|
||||
int[] arrExtraBitsForNonSimpleCodes,
|
||||
out huftNode[] outHufTable,
|
||||
ref int outBitsForTable
|
||||
)
|
||||
/* Given a list of code lengths and a maximum table size, make a set of
|
||||
tables to decode that set of codes. Return zero on success, one if
|
||||
the given code set is incomplete (the tables are still built in this
|
||||
case), two if the input is invalid (all zero length codes or an
|
||||
oversubscribed set of lengths), and three if not enough memory.
|
||||
The code with value 256 is special, and the tables are constructed
|
||||
so that no bits beyond that code are fetched when that code is
|
||||
decoded. */
|
||||
{
|
||||
outHufTable = [];
|
||||
|
||||
/* Generate counts for each bit length */
|
||||
int lengthOfEOBcode = numberOfCodes > 256 ? arrBitLengthForCodes[256] : BMAX; /* set length of EOB code, if any */
|
||||
|
||||
int[] arrBitLengthCount = new int[BMAX + 1];
|
||||
for (int i = 0; i < BMAX + 1; i++)
|
||||
arrBitLengthCount[i] = 0;
|
||||
|
||||
int pIndex = 0;
|
||||
int counterCurrentCode = numberOfCodes;
|
||||
do
|
||||
{
|
||||
arrBitLengthCount[arrBitLengthForCodes[pIndex]]++;
|
||||
pIndex++; /* assume all entries <= BMAX */
|
||||
} while ((--counterCurrentCode) != 0);
|
||||
|
||||
if (arrBitLengthCount[0] == numberOfCodes) /* null input--all zero length codes */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find minimum and maximum length, bound *outBitsForTable by those */
|
||||
int counter;
|
||||
for (counter = 1; counter <= BMAX; counter++)
|
||||
if (arrBitLengthCount[counter] != 0)
|
||||
break;
|
||||
|
||||
int numberOfBitsInCurrentCode = counter; /* minimum code length */
|
||||
if (outBitsForTable < counter)
|
||||
outBitsForTable = counter;
|
||||
|
||||
for (counterCurrentCode = BMAX; counterCurrentCode != 0; counterCurrentCode--)
|
||||
if (arrBitLengthCount[counterCurrentCode] != 0)
|
||||
break;
|
||||
|
||||
int maximumCodeLength = counterCurrentCode; /* maximum code length */
|
||||
if (outBitsForTable > counterCurrentCode)
|
||||
outBitsForTable = counterCurrentCode;
|
||||
|
||||
/* Adjust last length count to fill out codes, if needed */
|
||||
int numberOfDummyCodesAdded;
|
||||
for (
|
||||
numberOfDummyCodesAdded = 1 << counter;
|
||||
counter < counterCurrentCode;
|
||||
counter++, numberOfDummyCodesAdded <<= 1
|
||||
)
|
||||
if ((numberOfDummyCodesAdded -= arrBitLengthCount[counter]) < 0)
|
||||
return 2; /* bad input: more codes than bits */
|
||||
|
||||
if ((numberOfDummyCodesAdded -= arrBitLengthCount[counterCurrentCode]) < 0)
|
||||
return 2;
|
||||
|
||||
arrBitLengthCount[counterCurrentCode] += numberOfDummyCodesAdded;
|
||||
|
||||
/* Generate starting offsets into the value table for each length */
|
||||
int[] bitOffset = new int[BMAX + 1];
|
||||
bitOffset[1] = 0;
|
||||
counter = 0;
|
||||
pIndex = 1;
|
||||
int xIndex = 2;
|
||||
while ((--counterCurrentCode) != 0)
|
||||
{ /* note that i == g from above */
|
||||
bitOffset[xIndex++] = (counter += arrBitLengthCount[pIndex++]);
|
||||
}
|
||||
|
||||
/* Make a table of values in order of bit lengths */
|
||||
int[] arrValuesInOrderOfBitLength = new int[N_MAX];
|
||||
for (int i = 0; i < N_MAX; i++)
|
||||
arrValuesInOrderOfBitLength[i] = 0;
|
||||
|
||||
pIndex = 0;
|
||||
counterCurrentCode = 0;
|
||||
do
|
||||
{
|
||||
if ((counter = arrBitLengthForCodes[pIndex++]) != 0)
|
||||
arrValuesInOrderOfBitLength[bitOffset[counter]++] = counterCurrentCode;
|
||||
} while (++counterCurrentCode < numberOfCodes);
|
||||
|
||||
numberOfCodes = bitOffset[maximumCodeLength]; /* set numberOfCodes to length of v */
|
||||
|
||||
/* Generate the Huffman codes and for each, make the table entries */
|
||||
bitOffset[0] = counterCurrentCode = 0; /* first Huffman code is zero */
|
||||
pIndex = 0; /* grab values in bit order */
|
||||
int tableLevel = -1; /* no tables yet--level -1 */
|
||||
int bitsBeforeThisTable = 0;
|
||||
int[] arrLX = new int[BMAX + 1];
|
||||
int stackOfBitsPerTable = 1; /* stack of bits per table */
|
||||
arrLX[stackOfBitsPerTable - 1] = 0; /* no bits decoded yet */
|
||||
|
||||
huftNode[][] arrHufTableStack = new huftNode[BMAX][];
|
||||
huftNode[] pointerToCurrentTable = [];
|
||||
int numberOfEntriesInCurrentTable = 0;
|
||||
|
||||
bool first = true;
|
||||
|
||||
/* go through the bit lengths (k already is bits in shortest code) */
|
||||
for (; numberOfBitsInCurrentCode <= maximumCodeLength; numberOfBitsInCurrentCode++)
|
||||
{
|
||||
int counterForCodes = arrBitLengthCount[numberOfBitsInCurrentCode];
|
||||
while ((counterForCodes--) != 0)
|
||||
{
|
||||
/* here i is the Huffman code of length k bits for value *p */
|
||||
/* make tables up to required level */
|
||||
while (
|
||||
numberOfBitsInCurrentCode
|
||||
> bitsBeforeThisTable + arrLX[stackOfBitsPerTable + tableLevel]
|
||||
)
|
||||
{
|
||||
bitsBeforeThisTable += arrLX[stackOfBitsPerTable + (tableLevel++)]; /* add bits already decoded */
|
||||
|
||||
/* compute minimum size table less than or equal to *outBitsForTable bits */
|
||||
numberOfEntriesInCurrentTable =
|
||||
(numberOfEntriesInCurrentTable = maximumCodeLength - bitsBeforeThisTable)
|
||||
> outBitsForTable
|
||||
? outBitsForTable
|
||||
: numberOfEntriesInCurrentTable; /* upper limit */
|
||||
int fBitCounter1 =
|
||||
1 << (counter = numberOfBitsInCurrentCode - bitsBeforeThisTable);
|
||||
if (fBitCounter1 > counterForCodes + 1) /* try a k-w bit table */
|
||||
{ /* too few codes for k-w bit table */
|
||||
fBitCounter1 -= counterForCodes + 1; /* deduct codes from patterns left */
|
||||
xIndex = numberOfBitsInCurrentCode;
|
||||
while (++counter < numberOfEntriesInCurrentTable) /* try smaller tables up to z bits */
|
||||
{
|
||||
if ((fBitCounter1 <<= 1) <= arrBitLengthCount[++xIndex])
|
||||
break; /* enough codes to use up j bits */
|
||||
fBitCounter1 -= arrBitLengthCount[xIndex]; /* else deduct codes from patterns */
|
||||
}
|
||||
}
|
||||
if (
|
||||
bitsBeforeThisTable + counter > lengthOfEOBcode
|
||||
&& bitsBeforeThisTable < lengthOfEOBcode
|
||||
)
|
||||
counter = lengthOfEOBcode - bitsBeforeThisTable; /* make EOB code end at table */
|
||||
|
||||
numberOfEntriesInCurrentTable = 1 << counter; /* table entries for j-bit table */
|
||||
arrLX[stackOfBitsPerTable + tableLevel] = counter; /* set table size in stack */
|
||||
|
||||
/* allocate and link in new table */
|
||||
pointerToCurrentTable = new huftNode[numberOfEntriesInCurrentTable];
|
||||
|
||||
// set the pointer, pointed to by *outHufTable to the second huft in pointertoCurrentTable
|
||||
if (first)
|
||||
{
|
||||
outHufTable = pointerToCurrentTable; /* link to list for huft_free() */
|
||||
first = false;
|
||||
}
|
||||
|
||||
arrHufTableStack[tableLevel] = pointerToCurrentTable; /* table starts after link */
|
||||
|
||||
/* connect to last table, if there is one */
|
||||
if (tableLevel != 0)
|
||||
{
|
||||
bitOffset[tableLevel] = counterCurrentCode; /* save pattern for backing up */
|
||||
|
||||
huftNode vHuft = new huftNode
|
||||
{
|
||||
NumberOfBitsUsed = arrLX[stackOfBitsPerTable + tableLevel - 1], /* bits to dump before this table */
|
||||
NumberOfExtraBits = 32 + counter, /* bits in this table */
|
||||
ChildNodes = pointerToCurrentTable, /* pointer to this table */
|
||||
};
|
||||
|
||||
counter =
|
||||
(counterCurrentCode & ((1 << bitsBeforeThisTable) - 1))
|
||||
>> (bitsBeforeThisTable - arrLX[stackOfBitsPerTable + tableLevel - 1]);
|
||||
arrHufTableStack[tableLevel - 1][counter] = vHuft; /* connect to last table */
|
||||
}
|
||||
}
|
||||
|
||||
/* set up table entry in r */
|
||||
huftNode vHuft1 = new huftNode
|
||||
{
|
||||
NumberOfBitsUsed = numberOfBitsInCurrentCode - bitsBeforeThisTable,
|
||||
};
|
||||
|
||||
if (pIndex >= numberOfCodes)
|
||||
vHuft1.NumberOfExtraBits = INVALID_CODE; /* out of values--invalid code */
|
||||
else if (arrValuesInOrderOfBitLength[pIndex] < numberOfSimpleValueCodes)
|
||||
{
|
||||
vHuft1.NumberOfExtraBits = (
|
||||
arrValuesInOrderOfBitLength[pIndex] < 256 ? 32 : 31
|
||||
); /* 256 is end-of-block code */
|
||||
vHuft1.Value = arrValuesInOrderOfBitLength[pIndex++]; /* simple code is just the value */
|
||||
}
|
||||
else
|
||||
{
|
||||
vHuft1.NumberOfExtraBits = arrExtraBitsForNonSimpleCodes[
|
||||
arrValuesInOrderOfBitLength[pIndex] - numberOfSimpleValueCodes
|
||||
]; /* non-simple--look up in lists */
|
||||
vHuft1.Value = arrBaseValuesForNonSimpleCodes[
|
||||
arrValuesInOrderOfBitLength[pIndex++] - numberOfSimpleValueCodes
|
||||
];
|
||||
}
|
||||
|
||||
/* fill code-like entries with r */
|
||||
int fBitCounter2 = 1 << (numberOfBitsInCurrentCode - bitsBeforeThisTable);
|
||||
for (
|
||||
counter = counterCurrentCode >> bitsBeforeThisTable;
|
||||
counter < numberOfEntriesInCurrentTable;
|
||||
counter += fBitCounter2
|
||||
)
|
||||
pointerToCurrentTable[counter] = vHuft1;
|
||||
|
||||
/* backwards increment the k-bit code i */
|
||||
for (
|
||||
counter = 1 << (numberOfBitsInCurrentCode - 1);
|
||||
(counterCurrentCode & counter) != 0;
|
||||
counter >>= 1
|
||||
)
|
||||
counterCurrentCode ^= counter;
|
||||
counterCurrentCode ^= counter;
|
||||
|
||||
/* backup over finished tables */
|
||||
while (
|
||||
(counterCurrentCode & ((1 << bitsBeforeThisTable) - 1)) != bitOffset[tableLevel]
|
||||
)
|
||||
bitsBeforeThisTable -= arrLX[stackOfBitsPerTable + (--tableLevel)];
|
||||
}
|
||||
}
|
||||
|
||||
/* return actual size of base table */
|
||||
outBitsForTable = arrLX[stackOfBitsPerTable];
|
||||
|
||||
/* Return true (1) if we were given an incomplete table */
|
||||
return (numberOfDummyCodesAdded != 0 && maximumCodeLength != 1) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ internal class BCJFilter : Filter
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
false,
|
||||
};
|
||||
|
||||
private static readonly int[] MASK_TO_BIT_NUMBER = { 0, 1, 2, 2, 3, 3, 3, 3 };
|
||||
|
||||
@@ -39,7 +39,7 @@ internal class BCJFilterIA64 : Filter
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
0
|
||||
0,
|
||||
};
|
||||
|
||||
public BCJFilterIA64(bool isEncoder, Stream baseStream)
|
||||
|
||||
@@ -147,7 +147,7 @@ internal enum CoderPropId
|
||||
/// <summary>
|
||||
/// Specifies mode with end marker.
|
||||
/// </summary>
|
||||
EndMarker
|
||||
EndMarker,
|
||||
}
|
||||
|
||||
internal interface ISetCoderProperties
|
||||
|
||||
@@ -205,7 +205,7 @@ public sealed class LZipStream : Stream
|
||||
(byte)'I',
|
||||
(byte)'P',
|
||||
1,
|
||||
113
|
||||
113,
|
||||
};
|
||||
|
||||
public static void WriteHeaderSize(Stream stream)
|
||||
@@ -235,6 +235,6 @@ public sealed class LZipStream : Stream
|
||||
(byte)(dictionarySize & 0xff),
|
||||
(byte)((dictionarySize >> 8) & 0xff),
|
||||
(byte)((dictionarySize >> 16) & 0xff),
|
||||
(byte)((dictionarySize >> 24) & 0xff)
|
||||
(byte)((dictionarySize >> 24) & 0xff),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
|
||||
private enum EMatchFinderType
|
||||
{
|
||||
Bt2,
|
||||
Bt4
|
||||
Bt4,
|
||||
}
|
||||
|
||||
private const uint K_IFINITY_PRICE = 0xFFFFFFF;
|
||||
|
||||
@@ -38,7 +38,7 @@ public class LzmaEncoderProperties
|
||||
CoderPropId.Algorithm,
|
||||
CoderPropId.NumFastBytes,
|
||||
CoderPropId.MatchFinder,
|
||||
CoderPropId.EndMarker
|
||||
CoderPropId.EndMarker,
|
||||
};
|
||||
_properties = new object[]
|
||||
{
|
||||
@@ -49,7 +49,7 @@ public class LzmaEncoderProperties
|
||||
algorithm,
|
||||
numFastBytes,
|
||||
mf,
|
||||
eos
|
||||
eos,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ internal class ModelPpm
|
||||
0x64A1,
|
||||
0x5ABC,
|
||||
0x6632,
|
||||
0x6051
|
||||
0x6051,
|
||||
};
|
||||
|
||||
// Temp fields
|
||||
|
||||
@@ -59,7 +59,7 @@ internal partial class Model
|
||||
0x64A1,
|
||||
0x5ABC,
|
||||
0x6632,
|
||||
0x6051
|
||||
0x6051,
|
||||
};
|
||||
|
||||
private static ReadOnlySpan<byte> EXPONENTIAL_ESCAPES =>
|
||||
|
||||
@@ -24,5 +24,5 @@ internal enum ModelRestorationMethod
|
||||
/// <summary>
|
||||
/// Freeze the context tree (in some cases may result in poor compression).
|
||||
/// </summary>
|
||||
Freeze = 2
|
||||
Freeze = 2,
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ public enum PpmdVersion
|
||||
{
|
||||
H,
|
||||
H7Z,
|
||||
I1
|
||||
I1,
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ internal class RarBLAKE2spStream : RarStream
|
||||
0x510E527FU,
|
||||
0x9B05688CU,
|
||||
0x1F83D9ABU,
|
||||
0x5BE0CD19U
|
||||
0x5BE0CD19U,
|
||||
};
|
||||
|
||||
static readonly byte[][] k_BLAKE2S_Sigma =
|
||||
|
||||
@@ -9,7 +9,7 @@ internal static class RarCRC
|
||||
public static uint CheckCrc(uint startCrc, byte b) =>
|
||||
(crcTab[((int)startCrc ^ b) & 0xff] ^ (startCrc >> 8));
|
||||
|
||||
public static uint CheckCrc(uint startCrc, byte[] data, int offset, int count)
|
||||
public static uint CheckCrc(uint startCrc, ReadOnlySpan<byte> data, int offset, int count)
|
||||
{
|
||||
var size = Math.Min(data.Length - offset, count);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Rar.Headers;
|
||||
|
||||
@@ -14,7 +15,7 @@ internal class RarStream : Stream
|
||||
|
||||
private bool fetch;
|
||||
|
||||
private byte[] tmpBuffer = BufferPool.Rent(65536);
|
||||
private byte[] tmpBuffer = ArrayPool<byte>.Shared.Rent(65536);
|
||||
private int tmpOffset;
|
||||
private int tmpCount;
|
||||
|
||||
@@ -42,7 +43,7 @@ internal class RarStream : Stream
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
BufferPool.Return(this.tmpBuffer);
|
||||
ArrayPool<byte>.Shared.Return(this.tmpBuffer);
|
||||
this.tmpBuffer = null;
|
||||
}
|
||||
isDisposed = true;
|
||||
@@ -143,11 +144,11 @@ internal class RarStream : Stream
|
||||
this.tmpBuffer.Length * 2 > this.tmpCount + count
|
||||
? this.tmpBuffer.Length * 2
|
||||
: this.tmpCount + count;
|
||||
var newBuffer = BufferPool.Rent(newLength);
|
||||
var newBuffer = ArrayPool<byte>.Shared.Rent(newLength);
|
||||
Buffer.BlockCopy(this.tmpBuffer, 0, newBuffer, 0, this.tmpCount);
|
||||
var oldBuffer = this.tmpBuffer;
|
||||
this.tmpBuffer = newBuffer;
|
||||
BufferPool.Return(oldBuffer);
|
||||
ArrayPool<byte>.Shared.Return(oldBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ internal enum CodeType
|
||||
CODE_STARTFILE,
|
||||
CODE_ENDFILE,
|
||||
CODE_VM,
|
||||
CODE_VMDATA
|
||||
CODE_VMDATA,
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@ internal enum FilterType : byte
|
||||
FILTER_RGB,
|
||||
FILTER_ITANIUM,
|
||||
FILTER_PPM,
|
||||
FILTER_NONE
|
||||
FILTER_NONE,
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ namespace SharpCompress.Compressors.Rar.UnpackV1.PPM;
|
||||
internal enum BlockTypes
|
||||
{
|
||||
BLOCK_LZ = 0,
|
||||
BLOCK_PPM = 1
|
||||
BLOCK_PPM = 1,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
@@ -12,14 +13,28 @@ using SharpCompress.Compressors.Rar.VM;
|
||||
|
||||
namespace SharpCompress.Compressors.Rar.UnpackV1;
|
||||
|
||||
internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
|
||||
{
|
||||
private readonly BitInput Inp;
|
||||
private bool disposed;
|
||||
|
||||
public Unpack() =>
|
||||
// to ease in porting Unpack50.cs
|
||||
Inp = this;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (!externalWindow)
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(window);
|
||||
window = null;
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool FileExtracted { get; private set; }
|
||||
|
||||
public long DestSize
|
||||
@@ -74,7 +89,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
|
||||
private BlockTypes unpBlockType;
|
||||
|
||||
//private bool externalWindow;
|
||||
private bool externalWindow;
|
||||
|
||||
private long writtenFileSize;
|
||||
|
||||
@@ -104,22 +119,21 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
2,
|
||||
14,
|
||||
0,
|
||||
12
|
||||
12,
|
||||
};
|
||||
|
||||
private FileHeader fileHeader;
|
||||
|
||||
private void Init(byte[] window)
|
||||
{
|
||||
if (window is null)
|
||||
if (this.window is null && window is null)
|
||||
{
|
||||
this.window = new byte[PackDef.MAXWINSIZE];
|
||||
this.window = ArrayPool<byte>.Shared.Rent(PackDef.MAXWINSIZE);
|
||||
}
|
||||
else
|
||||
else if (window is not null)
|
||||
{
|
||||
this.window = window;
|
||||
|
||||
//externalWindow = true;
|
||||
externalWindow = true;
|
||||
}
|
||||
inAddr = 0;
|
||||
UnpInitData(false);
|
||||
@@ -175,31 +189,24 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
|
||||
private void UnstoreFile()
|
||||
{
|
||||
var buffer = new byte[0x10000];
|
||||
while (true)
|
||||
Span<byte> buffer = stackalloc byte[(int)Math.Min(0x10000, destUnpSize)];
|
||||
do
|
||||
{
|
||||
var code = readStream.Read(buffer, 0, (int)Math.Min(buffer.Length, destUnpSize));
|
||||
var code = readStream.Read(buffer);
|
||||
if (code == 0 || code == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
code = code < destUnpSize ? code : (int)destUnpSize;
|
||||
writeStream.Write(buffer, 0, code);
|
||||
if (destUnpSize >= 0)
|
||||
{
|
||||
destUnpSize -= code;
|
||||
}
|
||||
if (suspended)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
writeStream.Write(buffer.Slice(0, code));
|
||||
destUnpSize -= code;
|
||||
} while (!suspended && destUnpSize > 0);
|
||||
}
|
||||
|
||||
private void Unpack29(bool solid)
|
||||
{
|
||||
var DDecode = new int[PackDef.DC];
|
||||
var DBits = new byte[PackDef.DC];
|
||||
Span<int> DDecode = stackalloc int[PackDef.DC];
|
||||
Span<byte> DBits = stackalloc byte[PackDef.DC];
|
||||
|
||||
int Bits;
|
||||
|
||||
@@ -859,9 +866,9 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
|
||||
private bool ReadTables()
|
||||
{
|
||||
var bitLength = new byte[PackDef.BC];
|
||||
Span<byte> bitLength = stackalloc byte[PackDef.BC];
|
||||
Span<byte> table = stackalloc byte[PackDef.HUFF_TABLE_SIZE];
|
||||
|
||||
var table = new byte[PackDef.HUFF_TABLE_SIZE];
|
||||
if (inAddr > readTop - 25)
|
||||
{
|
||||
if (!unpReadBuf())
|
||||
@@ -989,7 +996,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
|
||||
// memcpy(unpOldTable,table,sizeof(unpOldTable));
|
||||
|
||||
Buffer.BlockCopy(table, 0, unpOldTable, 0, unpOldTable.Length);
|
||||
table.CopyTo(unpOldTable);
|
||||
return (true);
|
||||
}
|
||||
|
||||
@@ -1190,7 +1197,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
var VMCode = new byte[VMCodeSize];
|
||||
Span<byte> VMCode = stackalloc byte[VMCodeSize];
|
||||
for (var I = 0; I < VMCodeSize; I++)
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
|
||||
@@ -88,7 +88,7 @@ internal partial class Unpack
|
||||
0xf000,
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly int[] PosL1 = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };
|
||||
@@ -106,7 +106,7 @@ internal partial class Unpack
|
||||
0xf000,
|
||||
0xf200,
|
||||
0xf240,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly int[] PosL2 = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };
|
||||
@@ -123,7 +123,7 @@ internal partial class Unpack
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly int[] PosHf0 = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33, 33 };
|
||||
@@ -139,7 +139,7 @@ internal partial class Unpack
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xf7e0,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly int[] PosHf1 = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80, 127 };
|
||||
@@ -155,7 +155,7 @@ internal partial class Unpack
|
||||
0xfa00,
|
||||
0xffff,
|
||||
0xffff,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly int[] PosHf2 = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };
|
||||
@@ -170,7 +170,7 @@ internal partial class Unpack
|
||||
0xfe80,
|
||||
0xffff,
|
||||
0xffff,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly int[] PosHf3 = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };
|
||||
@@ -199,7 +199,7 @@ internal partial class Unpack
|
||||
0x90,
|
||||
0x98,
|
||||
0x9c,
|
||||
0xb0
|
||||
0xb0,
|
||||
};
|
||||
|
||||
private static readonly int[] ShortLen2 = { 2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0 };
|
||||
@@ -220,7 +220,7 @@ internal partial class Unpack
|
||||
0x90,
|
||||
0x98,
|
||||
0x9c,
|
||||
0xb0
|
||||
0xb0,
|
||||
};
|
||||
|
||||
private void unpack15(bool solid)
|
||||
|
||||
@@ -64,7 +64,7 @@ internal partial class Unpack
|
||||
128,
|
||||
160,
|
||||
192,
|
||||
224
|
||||
224,
|
||||
};
|
||||
|
||||
private static ReadOnlySpan<byte> LBits =>
|
||||
@@ -97,7 +97,7 @@ internal partial class Unpack
|
||||
5,
|
||||
5,
|
||||
5,
|
||||
5
|
||||
5,
|
||||
};
|
||||
|
||||
private static readonly int[] DDecode =
|
||||
@@ -149,7 +149,7 @@ internal partial class Unpack
|
||||
786432,
|
||||
851968,
|
||||
917504,
|
||||
983040
|
||||
983040,
|
||||
};
|
||||
|
||||
private static readonly int[] DBits =
|
||||
@@ -201,7 +201,7 @@ internal partial class Unpack
|
||||
16,
|
||||
16,
|
||||
16,
|
||||
16
|
||||
16,
|
||||
};
|
||||
|
||||
private static readonly int[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
|
||||
@@ -391,8 +391,8 @@ internal partial class Unpack
|
||||
|
||||
private bool ReadTables20()
|
||||
{
|
||||
var BitLength = new byte[PackDef.BC20];
|
||||
var Table = new byte[PackDef.MC20 * 4];
|
||||
Span<byte> BitLength = stackalloc byte[PackDef.BC20];
|
||||
Span<byte> Table = stackalloc byte[PackDef.MC20 * 4];
|
||||
int TableSize,
|
||||
N,
|
||||
I;
|
||||
|
||||
@@ -181,7 +181,12 @@ internal static class UnpackUtility
|
||||
return (dec.DecodeNum[N]);
|
||||
}
|
||||
|
||||
internal static void makeDecodeTables(byte[] lenTab, int offset, Decode.Decode dec, int size)
|
||||
internal static void makeDecodeTables(
|
||||
Span<byte> lenTab,
|
||||
int offset,
|
||||
Decode.Decode dec,
|
||||
int size
|
||||
)
|
||||
{
|
||||
Span<int> lenCount = stackalloc int[16];
|
||||
Span<int> tmpPos = stackalloc int[16];
|
||||
|
||||
@@ -19,7 +19,7 @@ internal partial class Unpack
|
||||
0xf000,
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly uint[] PosL1 = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };
|
||||
@@ -37,7 +37,7 @@ internal partial class Unpack
|
||||
0xf000,
|
||||
0xf200,
|
||||
0xf240,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly uint[] PosL2 = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };
|
||||
@@ -54,7 +54,7 @@ internal partial class Unpack
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly uint[] PosHf0 = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33, 33 };
|
||||
@@ -70,7 +70,7 @@ internal partial class Unpack
|
||||
0xf200,
|
||||
0xf200,
|
||||
0xf7e0,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly uint[] PosHf1 = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80, 127 };
|
||||
@@ -86,7 +86,7 @@ internal partial class Unpack
|
||||
0xfa00,
|
||||
0xffff,
|
||||
0xffff,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly uint[] PosHf2 = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };
|
||||
@@ -101,7 +101,7 @@ internal partial class Unpack
|
||||
0xfe80,
|
||||
0xffff,
|
||||
0xffff,
|
||||
0xffff
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private static readonly uint[] PosHf3 = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };
|
||||
@@ -225,7 +225,7 @@ internal partial class Unpack
|
||||
6,
|
||||
6,
|
||||
4,
|
||||
0
|
||||
0,
|
||||
};
|
||||
public static readonly uint[] ShortXor1 =
|
||||
{
|
||||
@@ -243,7 +243,7 @@ internal partial class Unpack
|
||||
0x90,
|
||||
0x98,
|
||||
0x9c,
|
||||
0xb0
|
||||
0xb0,
|
||||
};
|
||||
public static readonly uint[] ShortLen2 =
|
||||
{
|
||||
@@ -262,7 +262,7 @@ internal partial class Unpack
|
||||
6,
|
||||
6,
|
||||
4,
|
||||
0
|
||||
0,
|
||||
};
|
||||
public static readonly uint[] ShortXor2 =
|
||||
{
|
||||
@@ -280,7 +280,7 @@ internal partial class Unpack
|
||||
0x90,
|
||||
0x98,
|
||||
0x9c,
|
||||
0xb0
|
||||
0xb0,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ internal partial class Unpack
|
||||
128,
|
||||
160,
|
||||
192,
|
||||
224
|
||||
224,
|
||||
};
|
||||
public static readonly byte[] LBits =
|
||||
{
|
||||
@@ -84,7 +84,7 @@ internal partial class Unpack
|
||||
5,
|
||||
5,
|
||||
5,
|
||||
5
|
||||
5,
|
||||
};
|
||||
public static readonly uint[] DDecode =
|
||||
{
|
||||
@@ -135,7 +135,7 @@ internal partial class Unpack
|
||||
786432,
|
||||
851968,
|
||||
917504,
|
||||
983040
|
||||
983040,
|
||||
};
|
||||
public static readonly byte[] DBits =
|
||||
{
|
||||
@@ -186,7 +186,7 @@ internal partial class Unpack
|
||||
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 };
|
||||
|
||||
@@ -776,14 +776,14 @@ internal sealed class RarVM : BitInput
|
||||
}
|
||||
}
|
||||
|
||||
public void prepare(byte[] code, int codeSize, VMPreparedProgram prg)
|
||||
public void prepare(ReadOnlySpan<byte> code, int codeSize, VMPreparedProgram prg)
|
||||
{
|
||||
InitBitInput();
|
||||
var cpLength = Math.Min(MAX_SIZE, codeSize);
|
||||
|
||||
// memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
|
||||
|
||||
Buffer.BlockCopy(code, 0, InBuf, 0, cpLength);
|
||||
code.Slice(0, cpLength).CopyTo(InBuf);
|
||||
byte xorSum = 0;
|
||||
for (var i = 1; i < codeSize; i++)
|
||||
{
|
||||
@@ -1105,7 +1105,7 @@ internal sealed class RarVM : BitInput
|
||||
}
|
||||
}
|
||||
|
||||
private VMStandardFilters IsStandardFilter(byte[] code, int codeSize)
|
||||
private VMStandardFilters IsStandardFilter(ReadOnlySpan<byte> code, int codeSize)
|
||||
{
|
||||
VMStandardFilterSignature[] stdList =
|
||||
{
|
||||
@@ -1115,7 +1115,7 @@ internal sealed class RarVM : BitInput
|
||||
new(29, 0x0e06077d, VMStandardFilters.VMSF_DELTA),
|
||||
new(149, 0x1c2c5dc8, VMStandardFilters.VMSF_RGB),
|
||||
new(216, 0xbc85e701, VMStandardFilters.VMSF_AUDIO),
|
||||
new(40, 0x46b9c560, VMStandardFilters.VMSF_UPCASE)
|
||||
new(40, 0x46b9c560, VMStandardFilters.VMSF_UPCASE),
|
||||
};
|
||||
var CodeCRC = RarCRC.CheckCrc(0xffffffff, code, 0, code.Length) ^ 0xffffffff;
|
||||
for (var i = 0; i < stdList.Length; i++)
|
||||
|
||||
@@ -53,6 +53,6 @@ internal class VMCmdFlags
|
||||
VMCF_OP2 | VMCF_BYTEMODE,
|
||||
VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS,
|
||||
VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS,
|
||||
VMCF_OP0
|
||||
VMCF_OP0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,5 +66,5 @@ internal enum VMCommands
|
||||
VM_NEGB = 52,
|
||||
VM_NEGD = 53,
|
||||
|
||||
VM_STANDARD = 54
|
||||
VM_STANDARD = 54,
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ internal enum VMFlags
|
||||
None = 0,
|
||||
VM_FC = 1,
|
||||
VM_FZ = 2,
|
||||
VM_FS = 80000000
|
||||
VM_FS = 80000000,
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ internal enum VMOpType
|
||||
VM_OPREG = 0,
|
||||
VM_OPINT = 1,
|
||||
VM_OPREGMEM = 2,
|
||||
VM_OPNONE = 3
|
||||
VM_OPNONE = 3,
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ internal enum VMStandardFilters
|
||||
VMSF_RGB = 4,
|
||||
VMSF_AUDIO = 5,
|
||||
VMSF_DELTA = 6,
|
||||
VMSF_UPCASE = 7
|
||||
VMSF_UPCASE = 7,
|
||||
}
|
||||
|
||||
249
src/SharpCompress/Compressors/Reduce/ReduceStream.cs
Normal file
249
src/SharpCompress/Compressors/Reduce/ReduceStream.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SharpCompress.Compressors.Reduce;
|
||||
|
||||
public class ReduceStream : Stream
|
||||
{
|
||||
private readonly long unCompressedSize;
|
||||
private readonly long compressedSize;
|
||||
private readonly Stream inStream;
|
||||
|
||||
private long inByteCount;
|
||||
private const int EOF = 1234;
|
||||
|
||||
private readonly int factor;
|
||||
private readonly int distanceMask;
|
||||
private readonly int lengthMask;
|
||||
|
||||
private long outBytesCount;
|
||||
|
||||
private readonly byte[] windowsBuffer;
|
||||
private int windowIndex;
|
||||
private int length;
|
||||
private int distance;
|
||||
|
||||
public ReduceStream(Stream inStr, long compsize, long unCompSize, int factor)
|
||||
{
|
||||
inStream = inStr;
|
||||
compressedSize = compsize;
|
||||
unCompressedSize = unCompSize;
|
||||
inByteCount = 0;
|
||||
outBytesCount = 0;
|
||||
|
||||
this.factor = factor;
|
||||
distanceMask = (int)mask_bits[factor] << 8;
|
||||
lengthMask = 0xff >> factor;
|
||||
|
||||
windowIndex = 0;
|
||||
length = 0;
|
||||
distance = 0;
|
||||
|
||||
windowsBuffer = new byte[WSIZE];
|
||||
|
||||
outByte = 0;
|
||||
|
||||
LoadBitLengthTable();
|
||||
LoadNextByteTable();
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
public override bool CanSeek => false;
|
||||
public override bool CanWrite => false;
|
||||
public override long Length => unCompressedSize;
|
||||
public override long Position
|
||||
{
|
||||
get => outBytesCount;
|
||||
set { }
|
||||
}
|
||||
|
||||
private const int RunLengthCode = 144;
|
||||
private const int WSIZE = 0x4000;
|
||||
|
||||
private readonly uint[] mask_bits = new uint[]
|
||||
{
|
||||
0x0000,
|
||||
0x0001,
|
||||
0x0003,
|
||||
0x0007,
|
||||
0x000f,
|
||||
0x001f,
|
||||
0x003f,
|
||||
0x007f,
|
||||
0x00ff,
|
||||
0x01ff,
|
||||
0x03ff,
|
||||
0x07ff,
|
||||
0x0fff,
|
||||
0x1fff,
|
||||
0x3fff,
|
||||
0x7fff,
|
||||
0xffff,
|
||||
};
|
||||
|
||||
private int bitBufferCount;
|
||||
private ulong bitBuffer;
|
||||
|
||||
private int NEXTBYTE()
|
||||
{
|
||||
if (inByteCount == compressedSize)
|
||||
return EOF;
|
||||
inByteCount++;
|
||||
return inStream.ReadByte();
|
||||
}
|
||||
|
||||
private void READBITS(int nbits, out byte zdest)
|
||||
{
|
||||
if (nbits > bitBufferCount)
|
||||
{
|
||||
int temp;
|
||||
while (bitBufferCount <= 8 * (int)(4 - 1) && (temp = NEXTBYTE()) != EOF)
|
||||
{
|
||||
bitBuffer |= (ulong)temp << bitBufferCount;
|
||||
bitBufferCount += 8;
|
||||
}
|
||||
}
|
||||
zdest = (byte)(bitBuffer & (ulong)mask_bits[nbits]);
|
||||
bitBuffer >>= nbits;
|
||||
bitBufferCount -= nbits;
|
||||
}
|
||||
|
||||
private byte[] bitCountTable = [];
|
||||
|
||||
private void LoadBitLengthTable()
|
||||
{
|
||||
byte[] bitPos = { 0, 2, 4, 8, 16, 32, 64, 128, 255 };
|
||||
bitCountTable = new byte[256];
|
||||
|
||||
for (byte i = 1; i <= 8; i++)
|
||||
{
|
||||
int vMin = bitPos[i - 1] + 1;
|
||||
int vMax = bitPos[i];
|
||||
for (int j = vMin; j <= vMax; j++)
|
||||
{
|
||||
bitCountTable[j] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[][] nextByteTable = [];
|
||||
|
||||
private void LoadNextByteTable()
|
||||
{
|
||||
nextByteTable = new byte[256][];
|
||||
for (int x = 255; x >= 0; x--)
|
||||
{
|
||||
READBITS(6, out byte Slen);
|
||||
nextByteTable[x] = new byte[Slen];
|
||||
for (int i = 0; i < Slen; i++)
|
||||
{
|
||||
READBITS(8, out nextByteTable[x][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte outByte;
|
||||
|
||||
private byte GetNextByte()
|
||||
{
|
||||
if (nextByteTable[outByte].Length == 0)
|
||||
{
|
||||
READBITS(8, out outByte);
|
||||
return outByte;
|
||||
}
|
||||
READBITS(1, out byte nextBit);
|
||||
if (nextBit == 1)
|
||||
{
|
||||
READBITS(8, out outByte);
|
||||
return outByte;
|
||||
}
|
||||
READBITS(bitCountTable[nextByteTable[outByte].Length], out byte nextByteIndex);
|
||||
outByte = nextByteTable[outByte][nextByteIndex];
|
||||
return outByte;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int countIndex = 0;
|
||||
while (countIndex < count && outBytesCount < unCompressedSize)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
byte nextByte = GetNextByte();
|
||||
if (nextByte != RunLengthCode)
|
||||
{
|
||||
buffer[offset + (countIndex++)] = nextByte;
|
||||
windowsBuffer[windowIndex++] = nextByte;
|
||||
outBytesCount++;
|
||||
if (windowIndex == WSIZE)
|
||||
windowIndex = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
nextByte = GetNextByte();
|
||||
if (nextByte == 0)
|
||||
{
|
||||
buffer[offset + (countIndex++)] = RunLengthCode;
|
||||
windowsBuffer[windowIndex++] = RunLengthCode;
|
||||
outBytesCount++;
|
||||
if (windowIndex == WSIZE)
|
||||
windowIndex = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int lengthDistanceByte = nextByte;
|
||||
length = lengthDistanceByte & lengthMask;
|
||||
if (length == lengthMask)
|
||||
{
|
||||
length += GetNextByte();
|
||||
}
|
||||
length += 3;
|
||||
|
||||
int distanceHighByte = (lengthDistanceByte << factor) & distanceMask;
|
||||
distance = windowIndex - (distanceHighByte + GetNextByte() + 1);
|
||||
|
||||
distance &= WSIZE - 1;
|
||||
}
|
||||
|
||||
while (length != 0 && countIndex < count)
|
||||
{
|
||||
byte nextByte = windowsBuffer[distance++];
|
||||
buffer[offset + (countIndex++)] = nextByte;
|
||||
windowsBuffer[windowIndex++] = nextByte;
|
||||
outBytesCount++;
|
||||
|
||||
if (distance == WSIZE)
|
||||
distance = 0;
|
||||
|
||||
if (windowIndex == WSIZE)
|
||||
windowIndex = 0;
|
||||
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
return countIndex;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace SharpCompress.Compressors.Shrink
|
||||
8191U,
|
||||
16383U,
|
||||
(uint)short.MaxValue,
|
||||
(uint)ushort.MaxValue
|
||||
(uint)ushort.MaxValue,
|
||||
};
|
||||
|
||||
public BitStream(byte[] src, int srcLen)
|
||||
|
||||
@@ -387,7 +387,7 @@ namespace SharpCompress.Compressors.Shrink
|
||||
{
|
||||
Ok,
|
||||
Full,
|
||||
Error
|
||||
Error,
|
||||
}
|
||||
|
||||
private struct CodeQueue
|
||||
|
||||
@@ -5,5 +5,5 @@ public enum CheckType : byte
|
||||
NONE = 0x00,
|
||||
CRC32 = 0x01,
|
||||
CRC64 = 0x04,
|
||||
SHA256 = 0x0A
|
||||
SHA256 = 0x0A,
|
||||
}
|
||||
|
||||
@@ -15,20 +15,19 @@ public abstract class BlockFilter : ReadOnlyStream
|
||||
ArchArmFilter = 0x07,
|
||||
ArchArmThumbFilter = 0x08,
|
||||
ArchSparcFilter = 0x09,
|
||||
Lzma2 = 0x21
|
||||
Lzma2 = 0x21,
|
||||
}
|
||||
|
||||
private static readonly Dictionary<FilterTypes, Func<BlockFilter>> FILTER_MAP =
|
||||
new()
|
||||
{
|
||||
{ FilterTypes.ArchX86Filter, () => new X86Filter() },
|
||||
{ FilterTypes.ArchPowerPcFilter, () => new PowerPCFilter() },
|
||||
{ FilterTypes.ArchIa64Filter, () => new IA64Filter() },
|
||||
{ FilterTypes.ArchArmFilter, () => new ArmFilter() },
|
||||
{ FilterTypes.ArchArmThumbFilter, () => new ArmThumbFilter() },
|
||||
{ FilterTypes.ArchSparcFilter, () => new SparcFilter() },
|
||||
{ FilterTypes.Lzma2, () => new Lzma2Filter() }
|
||||
};
|
||||
private static readonly Dictionary<FilterTypes, Func<BlockFilter>> FILTER_MAP = new()
|
||||
{
|
||||
{ FilterTypes.ArchX86Filter, () => new X86Filter() },
|
||||
{ FilterTypes.ArchPowerPcFilter, () => new PowerPCFilter() },
|
||||
{ FilterTypes.ArchIa64Filter, () => new IA64Filter() },
|
||||
{ FilterTypes.ArchArmFilter, () => new ArmFilter() },
|
||||
{ FilterTypes.ArchArmThumbFilter, () => new ArmThumbFilter() },
|
||||
{ FilterTypes.ArchSparcFilter, () => new SparcFilter() },
|
||||
{ FilterTypes.Lzma2, () => new Lzma2Filter() },
|
||||
};
|
||||
|
||||
public abstract bool AllowAsLast { get; }
|
||||
public abstract bool AllowAsNonLast { get; }
|
||||
|
||||
@@ -25,13 +25,14 @@ public sealed class XZBlock : XZReadOnlyStream
|
||||
private bool _endOfStream;
|
||||
private bool _paddingSkipped;
|
||||
private bool _crcChecked;
|
||||
private ulong _bytesRead;
|
||||
private readonly long _startPosition;
|
||||
|
||||
public XZBlock(Stream stream, CheckType checkType, int checkSize)
|
||||
: base(stream)
|
||||
{
|
||||
_checkType = checkType;
|
||||
_checkSize = checkSize;
|
||||
_startPosition = stream.Position;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
@@ -67,13 +68,12 @@ public sealed class XZBlock : XZReadOnlyStream
|
||||
CheckCrc();
|
||||
}
|
||||
|
||||
_bytesRead += (ulong)bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
private void SkipPadding()
|
||||
{
|
||||
var bytes = (int)(BaseStream.Position % 4);
|
||||
var bytes = (BaseStream.Position - _startPosition) % 4;
|
||||
if (bytes > 0)
|
||||
{
|
||||
var paddingBytes = new byte[4 - bytes];
|
||||
|
||||
@@ -3,5 +3,5 @@ namespace SharpCompress.IO;
|
||||
public enum StreamingMode
|
||||
{
|
||||
Streaming,
|
||||
Seekable
|
||||
Seekable,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SharpCompress;
|
||||
namespace SharpCompress.Helpers;
|
||||
|
||||
internal sealed class LazyReadOnlyCollection<T> : ICollection<T>
|
||||
{
|
||||
|
||||
@@ -4,9 +4,9 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace SharpCompress;
|
||||
namespace SharpCompress.Helpers;
|
||||
|
||||
public static class NotNullExtensions
|
||||
internal static class NotNullExtensions
|
||||
{
|
||||
public static IEnumerable<T> Empty<T>(this IEnumerable<T>? source) =>
|
||||
source ?? Enumerable.Empty<T>();
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SharpCompress;
|
||||
|
||||
public class ReadOnlyCollection<T> : ICollection<T>
|
||||
{
|
||||
private readonly ICollection<T> collection;
|
||||
|
||||
public ReadOnlyCollection(ICollection<T> collection) => this.collection = collection;
|
||||
|
||||
public void Add(T item) => throw new NotSupportedException();
|
||||
|
||||
public void Clear() => throw new NotSupportedException();
|
||||
|
||||
public bool Contains(T item) => collection.Contains(item);
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) => collection.CopyTo(array, arrayIndex);
|
||||
|
||||
public int Count => collection.Count;
|
||||
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public bool Remove(T item) => throw new NotSupportedException();
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => collection.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => throw new NotSupportedException();
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader, IReaderExtracti
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_entriesForCurrentReadStream?.Dispose();
|
||||
Volume?.Dispose();
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace SharpCompress.Readers.Rar;
|
||||
/// </summary>
|
||||
public abstract class RarReader : AbstractReader<RarReaderEntry, RarVolume>
|
||||
{
|
||||
private bool _disposed;
|
||||
private RarVolume? volume;
|
||||
private Lazy<IRarUnpack> UnpackV2017 { get; } =
|
||||
new(() => new Compressors.Rar.UnpackV2017.Unpack());
|
||||
@@ -21,6 +22,20 @@ public abstract class RarReader : AbstractReader<RarReaderEntry, RarVolume>
|
||||
internal RarReader(ReaderOptions options)
|
||||
: base(options, ArchiveType.Rar) { }
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (UnpackV1.IsValueCreated && UnpackV1.Value is IDisposable unpackV1)
|
||||
{
|
||||
unpackV1.Dispose();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void ValidateArchive(RarVolume archive);
|
||||
|
||||
public override RarVolume? Volume => volume;
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TarReader : AbstractReader<TarEntry, TarVolume>
|
||||
CompressionType.Xz => new XZStream(stream),
|
||||
CompressionType.Lzw => new LzwStream(stream),
|
||||
CompressionType.None => stream,
|
||||
_ => throw new NotSupportedException("Invalid compression type: " + compressionType)
|
||||
_ => throw new NotSupportedException("Invalid compression type: " + compressionType),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>SharpCompress - Pure C# Decompression/Compression</AssemblyTitle>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<VersionPrefix>0.37.2</VersionPrefix>
|
||||
<AssemblyVersion>0.37.2</AssemblyVersion>
|
||||
<FileVersion>0.37.2</FileVersion>
|
||||
<VersionPrefix>0.39.0</VersionPrefix>
|
||||
<AssemblyVersion>0.39.0</AssemblyVersion>
|
||||
<FileVersion>0.39.0</FileVersion>
|
||||
<Authors>Adam Hathcock</Authors>
|
||||
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net48;net481;netstandard2.0;net6.0;net8.0</TargetFrameworks>
|
||||
<AssemblyName>SharpCompress</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>../../SharpCompress.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
@@ -14,41 +14,32 @@
|
||||
<PackageTags>rar;unrar;zip;unzip;bzip2;gzip;tar;7zip;lzip;xz</PackageTags>
|
||||
<PackageProjectUrl>https://github.com/adamhathcock/sharpcompress</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<Copyright>Copyright (c) 2014 Adam Hathcock</Copyright>
|
||||
<Copyright>Copyright (c) 2025 Adam Hathcock</Copyright>
|
||||
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
<Description>SharpCompress is a compression library for NET Standard 2.0/NET Standard 2.1/NET 6.0/NET 8.0 that can unrar, decompress 7zip, decompress xz, zip/unzip, tar/untar lzip/unlzip, bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented.</Description>
|
||||
<Description>SharpCompress is a compression library for NET Standard 2.0/NET 4.8/NET 4.8.1/NET 6.0/NET 8.0 that can unrar, decompress 7zip, decompress xz, zip/unzip, tar/untar lzip/unlzip, bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented.</Description>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||
<IsTrimmable>true</IsTrimmable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Buffers" />
|
||||
<PackageReference Include="ZstdSharp.Port" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||
<PackageReference Include="System.Memory" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(VersionlessImplicitFrameworkDefine)' == 'NETFRAMEWORK' ">
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||
<PackageReference Include="System.Memory" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
global using SharpCompress.Helpers;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SharpCompress.Readers;
|
||||
|
||||
namespace SharpCompress;
|
||||
namespace SharpCompress.Helpers;
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public static class Utility
|
||||
internal static class Utility
|
||||
{
|
||||
public static ReadOnlyCollection<T> ToReadOnly<T>(this ICollection<T> items) => new(items);
|
||||
public static ReadOnlyCollection<T> ToReadOnly<T>(this IList<T> items) => new(items);
|
||||
|
||||
/// <summary>
|
||||
/// Performs an unsigned bitwise right shift with the specified number
|
||||
@@ -434,4 +436,17 @@ public static class Utility
|
||||
buffer[offset + 2] = (byte)(number >> 8);
|
||||
buffer[offset + 3] = (byte)number;
|
||||
}
|
||||
|
||||
public static string ReplaceInvalidFileNameChars(string fileName)
|
||||
{
|
||||
var invalidChars = new HashSet<char>(Path.GetInvalidFileNameChars());
|
||||
var sb = new StringBuilder(fileName.Length);
|
||||
foreach (var c in fileName)
|
||||
{
|
||||
var newChar = invalidChars.Contains(c) ? '_' : c;
|
||||
sb.Append(newChar);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class ZipWriter : AbstractWriter
|
||||
CompressionType.BZip2 => ZipCompressionMethod.BZip2,
|
||||
CompressionType.LZMA => ZipCompressionMethod.LZMA,
|
||||
CompressionType.PPMd => ZipCompressionMethod.PPMd,
|
||||
_ => throw new InvalidFormatException("Invalid compression method: " + compressionType)
|
||||
_ => throw new InvalidFormatException("Invalid compression method: " + compressionType),
|
||||
};
|
||||
|
||||
public override void Write(string entryPath, Stream source, DateTime? modificationTime) =>
|
||||
@@ -100,7 +100,7 @@ public class ZipWriter : AbstractWriter
|
||||
)
|
||||
{
|
||||
Comment = options.EntryComment,
|
||||
ModificationTime = options.ModificationDateTime
|
||||
ModificationTime = options.ModificationDateTime,
|
||||
};
|
||||
|
||||
// Use the archive default setting for zip64 and allow overrides
|
||||
|
||||
@@ -1,25 +1,7 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETFramework,Version=v4.6.2": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3"
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8": {
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
@@ -30,35 +12,21 @@
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"System.Buffers": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.5.5, )",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding.CodePages": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
|
||||
},
|
||||
"ZstdSharp.Port": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.8.0, )",
|
||||
"resolved": "0.8.0",
|
||||
"contentHash": "Z62eNBIu8E8YtbqlMy57tK3dV1+m2b9NhPeaYovB5exmLKvrGCqOhJTzrEUH5VyUWU6vwX3c1XHJGhW5HVs8dA==",
|
||||
"requested": "[0.8.4, )",
|
||||
"resolved": "0.8.4",
|
||||
"contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"System.Memory": "4.5.5"
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
@@ -66,21 +34,11 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net462": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
@@ -98,6 +56,117 @@
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8.1": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net481": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
|
||||
},
|
||||
"ZstdSharp.Port": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.8.4, )",
|
||||
"resolved": "0.8.4",
|
||||
"contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net481": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "Vv/20vgHS7VglVOVh8J3Iz/MA+VYKVRp9f7r2qiKBMuzviTOmocG70yq0Q8T5OTmCONkEAIJwETD1zhEfLkAXQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
".NETStandard,Version=v2.0": {
|
||||
@@ -129,15 +198,21 @@
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.5.5, )",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
"System.Buffers": "4.6.0",
|
||||
"System.Numerics.Vectors": "4.6.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.1.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding.CodePages": {
|
||||
@@ -152,12 +227,13 @@
|
||||
},
|
||||
"ZstdSharp.Port": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.8.0, )",
|
||||
"resolved": "0.8.0",
|
||||
"contentHash": "Z62eNBIu8E8YtbqlMy57tK3dV1+m2b9NhPeaYovB5exmLKvrGCqOhJTzrEUH5VyUWU6vwX3c1XHJGhW5HVs8dA==",
|
||||
"requested": "[0.8.4, )",
|
||||
"resolved": "0.8.4",
|
||||
"contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"System.Memory": "4.5.5"
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
@@ -175,20 +251,15 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "t+SoieZsRuEyiw/J+qXUbolyO219tKQQI0+2/YI+Qv7YdGValA6WiuokrNKqjrTNsy5ABWU11bdKOzUdheteXg=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
"resolved": "6.1.0",
|
||||
"contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
@@ -199,79 +270,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
".NETStandard,Version=v2.1": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw=="
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding.CodePages": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"ZstdSharp.Port": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.8.0, )",
|
||||
"resolved": "0.8.0",
|
||||
"contentHash": "Z62eNBIu8E8YtbqlMy57tK3dV1+m2b9NhPeaYovB5exmLKvrGCqOhJTzrEUH5VyUWU6vwX3c1XHJGhW5HVs8dA==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.5.5, )",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"net6.0": {
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
@@ -283,11 +281,17 @@
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
|
||||
},
|
||||
"ZstdSharp.Port": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.8.0, )",
|
||||
"resolved": "0.8.0",
|
||||
"contentHash": "Z62eNBIu8E8YtbqlMy57tK3dV1+m2b9NhPeaYovB5exmLKvrGCqOhJTzrEUH5VyUWU6vwX3c1XHJGhW5HVs8dA=="
|
||||
"requested": "[0.8.4, )",
|
||||
"resolved": "0.8.4",
|
||||
"contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
@@ -303,9 +307,9 @@
|
||||
"net8.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.4, )",
|
||||
"resolved": "8.0.4",
|
||||
"contentHash": "PZb5nfQ+U19nhnmnR9T1jw+LTmozhuG2eeuzuW5A7DqxD/UXW2ucjmNJqnqOuh8rdPzM3MQXoF8AfFCedJdCUw=="
|
||||
"requested": "[8.0.12, )",
|
||||
"resolved": "8.0.12",
|
||||
"contentHash": "FV4HnQ3JI15PHnJ5PGTbz+rYvrih42oLi/7UMIshNwCwUZhTq13UzrggtXk4ygrcMcN+4jsS6hhshx2p/Zd0ig=="
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
@@ -317,11 +321,17 @@
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.6.0, )",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
|
||||
},
|
||||
"ZstdSharp.Port": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.8.0, )",
|
||||
"resolved": "0.8.0",
|
||||
"contentHash": "Z62eNBIu8E8YtbqlMy57tK3dV1+m2b9NhPeaYovB5exmLKvrGCqOhJTzrEUH5VyUWU6vwX3c1XHJGhW5HVs8dA=="
|
||||
"requested": "[0.8.4, )",
|
||||
"resolved": "0.8.4",
|
||||
"contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
|
||||
@@ -73,27 +73,45 @@ public class ArchiveTests : ReaderTests
|
||||
}
|
||||
}
|
||||
|
||||
protected void ArchiveStreamRead(string testArchive, ReaderOptions? readerOptions = null)
|
||||
protected void ArchiveStreamRead(string testArchive, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveStreamRead(ArchiveFactory.AutoFactory, testArchive, readerOptions);
|
||||
|
||||
protected void ArchiveStreamRead(
|
||||
IArchiveFactory archiveFactory,
|
||||
string testArchive,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
|
||||
ArchiveStreamRead(readerOptions, testArchive);
|
||||
ArchiveStreamRead(archiveFactory, readerOptions, testArchive);
|
||||
}
|
||||
|
||||
protected void ArchiveStreamRead(
|
||||
ReaderOptions? readerOptions = null,
|
||||
params string[] testArchives
|
||||
) => ArchiveStreamRead(ArchiveFactory.AutoFactory, readerOptions, testArchives);
|
||||
|
||||
protected void ArchiveStreamRead(
|
||||
IArchiveFactory archiveFactory,
|
||||
ReaderOptions? readerOptions = null,
|
||||
params string[] testArchives
|
||||
) =>
|
||||
ArchiveStreamRead(
|
||||
archiveFactory,
|
||||
readerOptions,
|
||||
testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x))
|
||||
);
|
||||
|
||||
protected void ArchiveStreamRead(ReaderOptions? readerOptions, IEnumerable<string> testArchives)
|
||||
protected void ArchiveStreamRead(
|
||||
IArchiveFactory archiveFactory,
|
||||
ReaderOptions? readerOptions,
|
||||
IEnumerable<string> testArchives
|
||||
)
|
||||
{
|
||||
foreach (var path in testArchives)
|
||||
{
|
||||
using (var stream = NonDisposingStream.Create(File.OpenRead(path), true))
|
||||
using (var archive = ArchiveFactory.Open(stream, readerOptions))
|
||||
using (var archive = archiveFactory.Open(stream, readerOptions))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -218,10 +236,14 @@ public class ArchiveTests : ReaderTests
|
||||
}
|
||||
}
|
||||
|
||||
protected void ArchiveFileRead(string testArchive, ReaderOptions? readerOptions = null)
|
||||
protected void ArchiveFileRead(
|
||||
IArchiveFactory archiveFactory,
|
||||
string testArchive,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
|
||||
using (var archive = ArchiveFactory.Open(testArchive, readerOptions))
|
||||
using (var archive = archiveFactory.Open(new FileInfo(testArchive), readerOptions))
|
||||
{
|
||||
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
|
||||
{
|
||||
@@ -234,6 +256,9 @@ public class ArchiveTests : ReaderTests
|
||||
VerifyFiles();
|
||||
}
|
||||
|
||||
protected void ArchiveFileRead(string testArchive, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFileRead(ArchiveFactory.AutoFactory, testArchive, readerOptions);
|
||||
|
||||
protected void ArchiveFileSkip(
|
||||
string testArchive,
|
||||
string fileOrder,
|
||||
@@ -270,7 +295,7 @@ public class ArchiveTests : ReaderTests
|
||||
ExtractFullPath = true,
|
||||
Overwrite = true,
|
||||
PreserveAttributes = true,
|
||||
PreserveFileTime = true
|
||||
PreserveFileTime = true,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
21
tests/SharpCompress.Test/BZip2/BZip2ReaderTests.cs
Normal file
21
tests/SharpCompress.Test/BZip2/BZip2ReaderTests.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.IO;
|
||||
using SharpCompress.Readers;
|
||||
using SharpCompress.Readers.GZip;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test.BZip2;
|
||||
|
||||
public class BZip2ReaderTests : ReaderTests
|
||||
{
|
||||
[Fact]
|
||||
public void BZip2_Reader_Factory()
|
||||
{
|
||||
Stream stream = new MemoryStream(
|
||||
new byte[] { 0x42, 0x5a, 0x68, 0x34, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x35 }
|
||||
);
|
||||
Assert.Throws(typeof(InvalidOperationException), () => ReaderFactory.Open(stream));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user