Compare commits

...

51 Commits

Author SHA1 Message Date
Adam Hathcock
67be0cd9d7 Mark for 0.34.2 2023-11-15 11:32:51 +00:00
Adam Hathcock
902fadef83 Merge pull request #780 from caesay/cs/revert-disable-strongname
Revert change disabling strong name signing in 92df1ec
2023-11-15 11:22:02 +00:00
Adam Hathcock
2777b6411f Merge branch 'master' into cs/revert-disable-strongname 2023-11-15 11:18:30 +00:00
Adam Hathcock
e3235d7f04 Merge pull request #781 from adamhathcock/fix-formatting
Update csharpier and fix formatting
2023-11-15 11:18:04 +00:00
Adam Hathcock
dc89c8858e comment out more C++ bits 2023-11-15 11:14:39 +00:00
Adam Hathcock
d28a278d63 Comment out flag to allow formatting 2023-11-15 11:10:05 +00:00
Adam Hathcock
7080c2abd0 Update csharpier and fix formatting 2023-11-15 11:05:30 +00:00
Caelan Sayler
43f86bcab8 Revert change disabling strong name signing in 92df1ec 2023-11-14 16:34:58 +00:00
Adam Hathcock
7d9c875c4d Merge pull request #778 from LANCommander/throw-cancelled-exception
Throw ReaderCancelledException on reader cancelled
2023-11-13 08:34:15 +00:00
Pat Hartl
ed4099eb12 Throw ReaderCancelledException on reader cancelled 2023-11-10 23:36:14 -06:00
Adam Hathcock
632b83f75d Mark for 0.34.1 2023-10-02 08:44:14 +01:00
Adam Hathcock
66c92637f9 Merge pull request #769 from Erior/feature/766
Update Zstd to 0.7.2
2023-09-25 09:01:51 +01:00
Adam Hathcock
6bcaebc471 Merge pull request #768 from Erior/feature/761
Feature/761
2023-09-25 09:01:20 +01:00
Lars Vahlenberg
7feee1027c Update Zstd to 0.7.2 2023-09-23 16:02:27 +02:00
Lars Vahlenberg
4fd8c77fa9 CSharpier cleanup 2023-09-23 14:52:39 +02:00
Lars Vahlenberg
bc3bb2d323 Set FilePart properties for directory type 2023-09-23 14:51:08 +02:00
Adam Hathcock
7764684c68 Release for 0.34 2023-09-18 09:53:05 +01:00
Adam Hathcock
feb2c38572 fmt update 2023-09-18 09:48:31 +01:00
Adam Hathcock
6a97e82a2e Merge pull request #763 from btomblinson/master
#751 Add .tar.7z support
2023-09-18 09:47:01 +01:00
btomblinson
57c0d19cde #751 Add .tar.7z support 2023-09-17 17:46:56 -06:00
Adam Hathcock
e14ed89f3d Merge pull request #759 from Erior/feature/748
Feature/748
2023-09-14 09:05:48 +01:00
Adam Hathcock
6a14893a23 Merge branch 'master' into feature/748 2023-09-14 09:00:50 +01:00
Lars Vahlenberg
0f19735d33 Cleanup 2023-09-11 19:31:27 +02:00
Lars Vahlenberg
6a859ac65d Adding Filters to 7z 2023-09-11 19:24:54 +02:00
Adam Hathcock
4d9c24244c Merge pull request #758 from adamhathcock/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-11 10:47:54 +01:00
dependabot[bot]
cdeb288c4f Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 09:38:10 +00:00
Adam Hathcock
7f8016497b Merge pull request #750 from FlsZen/master
Add fast `ExtractToDirectoryAsync` extension method on `IArchive`
2023-09-07 15:05:15 +01:00
FlsZen
ec01225225 It looks like build format wants this on one line 2023-08-13 12:52:14 -04:00
James Hood
4e23b84999 Remove Task aspect 2023-07-21 13:17:42 -04:00
James Hood
c7c143fed9 Add ExtractToDirectoryAsync extension method on IArchive that is very fast compared to WriteToDirectory. 2023-07-19 08:22:15 -04:00
Adam Hathcock
4932171834 update csharpier 2023-06-12 09:53:00 +01:00
Adam Hathcock
00fc6c8e2f formatting 2023-06-12 09:52:35 +01:00
Adam Hathcock
1b73dab341 Merge remote-tracking branch 'Nanook/fixes-zstd' 2023-06-12 09:52:17 +01:00
Adam Hathcock
99e99c1ccd Merge branch 'master' into fixes-zstd 2023-06-12 09:45:35 +01:00
Adam Hathcock
14ce479ab7 Merge pull request #746 from rodesfl/patch-1
Added simple example
2023-06-12 09:31:17 +01:00
Rodrigo Lotrário
e7e873a1b2 Added simple example
Had some difficult figuring this one out, as this is so straight forward and is the simplest use case, maybe should be included at the top of the docs ?
2023-06-09 19:38:42 -03:00
Adam Hathcock
5a57428ec0 Merge pull request #745 from Erior/feature/Issue-743
Skip if we know the size, set blank password if not set for rar
2023-06-07 09:44:36 +01:00
Lars Vahlenberg
18e8e6ee98 Sharpier 2023-06-06 22:43:12 +02:00
Lars Vahlenberg
6bf6e51740 Skip if we know the size, set blank password if not set for rar 2023-06-06 22:27:53 +02:00
Adam Hathcock
b52a899a18 Merge pull request #740 from AlissaSabre/issue_739
Make ArchiveFactory.IsArchive(Stream, ...) public. Fix #739
2023-05-10 09:56:50 +01:00
Alissa Sabre
cf722a7120 Make ArchiveFactory.IsArchive(Stream, ...) public. Fix #739 2023-05-10 15:49:44 +09:00
Adam Hathcock
33cd1f3db8 Merge pull request #737 from Erior/feature/TarHeaderFactory-Infinite-loop
Check for broken file #736
2023-03-30 11:35:20 +01:00
Lars Vahlenberg
b7d2715ffd Remove whitespace 2023-03-29 19:39:03 +02:00
Lars Vahlenberg
fe63466d67 CSharpier 2023-03-29 18:18:17 +02:00
Lars Vahlenberg
0fb63eea99 Check for broken file 2023-03-28 23:07:21 +02:00
Adam Hathcock
59552804f6 fix badge 2023-03-21 14:11:18 +00:00
Adam Hathcock
579d6d73f8 build tests 2023-03-21 13:56:51 +00:00
Adam Hathcock
f83e3022ba add no restore to build 2023-03-21 13:54:45 +00:00
Adam Hathcock
bf93bbf5f8 fix restore 2023-03-21 13:44:02 +00:00
Adam Hathcock
fa2a52ff41 add caching and some cleanup 2023-03-21 13:41:36 +00:00
Nanook
92df1ecd5f ZStandard support added to zip/zipx (WinZip) and 7zip (mcmilk 7zip) 2023-02-02 01:06:18 +00:00
82 changed files with 889 additions and 271 deletions

View File

@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"csharpier": {
"version": "0.23.0",
"version": "0.26.1",
"commands": [
"dotnet-csharpier"
]

View File

@@ -14,10 +14,17 @@ jobs:
os: [windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: NuGet Caching
uses: actions/cache@v3
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('packages.lock.json', '*/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-
- run: dotnet run --project build/build.csproj
- uses: actions/upload-artifact@v3
with:

View File

@@ -5,7 +5,8 @@ SharpCompress is a compression library in pure C# for .NET Standard 2.0, 2.1, .N
The major feature is support for non-seekable streams so large files can be processed on the fly (i.e. download stream).
GitHub Actions Build -
[![GitHubActions](https://github.com/adamhathcock/sharpcompress/workflows/SharpCompress/badge.svg)](https://circleci.com/gh/adamhathcock/sharpcompress)
[![SharpCompress](https://github.com/adamhathcock/sharpcompress/actions/workflows/dotnetcore.yml/badge.svg)](https://github.com/adamhathcock/sharpcompress/actions/workflows/dotnetcore.yml)
[![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/sharpcompress/api/SharpCompress.html)
## Need Help?
@@ -42,6 +43,8 @@ I'm always looking for help or ideas. Please submit code or email with ideas. Un
## Version Log
* [Releases](https://github.com/adamhathcock/sharpcompress/releases)
### Version 0.18
* [Now on Github releases](https://github.com/adamhathcock/sharpcompress/releases/tag/0.18)

View File

@@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F18F1765-4A02-42FD-9BEF-F0E2FCBD9D17}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C5BE746-03E5-4895-9988-0B57F162F86C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0F0901FF-E8D9-426A-B5A2-17C7F47C1529}"
@@ -15,6 +13,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCompress.Test", "tests
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "build", "build\build.csproj", "{D4D613CB-5E94-47FB-85BE-B8423D20C545}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{CDB42573-7D22-4490-BA12-1B7FB99CE7FB}"
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
global.json = global.json
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

View File

@@ -33,6 +33,18 @@ If using Compression Stream classes directly and you don't want the wrapped stre
Also, look over the tests for more thorough [examples](https://github.com/adamhathcock/sharpcompress/tree/master/tests/SharpCompress.Test)
### Create Zip Archive from multiple files
```C#
using(var archive = ZipArchive.Create())
{
archive.AddEntry("file01.txt", "C:\\file01.txt");
archive.AddEntry("file02.txt", "C:\\file02.txt");
...
archive.SaveTo("C:\\temp.zip", CompressionType.Deflate);
}
```
### Create Zip Archive from all files in a directory to a file
```C#
@@ -143,4 +155,4 @@ foreach(var entry in tr.Entries)
{
Console.WriteLine($"{entry.Key}");
}
```
```

View File

@@ -7,8 +7,10 @@ using static Bullseye.Targets;
using static SimpleExec.Command;
const string Clean = "clean";
const string Restore = "restore";
const string Build = "build";
const string Test = "test";
const string Format = "format";
const string Publish = "publish";
Target(
@@ -38,10 +40,21 @@ Target(
);
Target(
Build,
Format,
() =>
{
Run("dotnet", "build src/SharpCompress/SharpCompress.csproj -c Release");
Run("dotnet", "tool restore");
Run("dotnet", "csharpier --check .");
}
);
Target(Restore, DependsOn(Format), () => Run("dotnet", "restore"));
Target(
Build,
DependsOn(Restore),
() =>
{
Run("dotnet", "build src/SharpCompress/SharpCompress.csproj -c Release --no-restore");
}
);
@@ -63,7 +76,7 @@ Target(
foreach (var file in GetFiles("**/*.Test.csproj"))
{
Run("dotnet", $"test {file} -c Release -f {framework}");
Run("dotnet", $"test {file} -c Release -f {framework} --no-restore --verbosity=normal");
}
}
);

View File

@@ -25,7 +25,8 @@ public static class ArchiveFactory
public static IWritableArchive Create(ArchiveType type)
{
var factory = Factory.Factories
var factory = Factory
.Factories
.OfType<IWriteableArchiveFactory>()
.FirstOrDefault(item => item.KnownArchiveType == type);
@@ -175,7 +176,7 @@ public static class ArchiveFactory
return IsArchive(s, out type);
}
private static bool IsArchive(Stream stream, out ArchiveType? type)
public static bool IsArchive(Stream stream, out ArchiveType? type)
{
type = null;
stream.CheckNotNull(nameof(stream));

View File

@@ -1,4 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
namespace SharpCompress.Archives;
@@ -19,4 +24,54 @@ public static class IArchiveExtensions
entry.WriteToDirectory(destinationDirectory, options);
}
}
/// <summary>
/// Extracts the archive to the destination directory. Directories will be created as needed.
/// </summary>
/// <param name="archive">The archive to extract.</param>
/// <param name="destination">The folder to extract into.</param>
/// <param name="progressReport">Optional progress report callback.</param>
/// <param name="cancellationToken">Optional cancellation token.</param>
public static void ExtractToDirectory(
this IArchive archive,
string destination,
Action<double>? progressReport = null,
CancellationToken cancellationToken = default
)
{
// Prepare for progress reporting
var totalBytes = archive.TotalUncompressSize;
var bytesRead = 0L;
// Tracking for created directories.
var seenDirectories = new HashSet<string>();
// Extract
var entries = archive.ExtractAllEntries();
while (entries.MoveToNextEntry())
{
cancellationToken.ThrowIfCancellationRequested();
var entry = entries.Entry;
if (entry.IsDirectory)
{
continue;
}
// Create each directory
var path = Path.Combine(destination, entry.Key);
if (Path.GetDirectoryName(path) is { } directory && seenDirectories.Add(path))
{
Directory.CreateDirectory(directory);
}
// Write file
using var fs = File.OpenWrite(path);
entries.WriteEntryTo(fs);
// Update progress
bytesRead += entry.Size;
progressReport?.Invoke(bytesRead / (double)totalBytes);
}
}
}

View File

@@ -40,9 +40,9 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
streams[1].Position = 0;
SrcStream.Position = 0;
return srcStream.Streams.Select(
a => new StreamRarArchiveVolume(a, ReaderOptions, idx++)
);
return srcStream
.Streams
.Select(a => new StreamRarArchiveVolume(a, ReaderOptions, idx++));
}
else //split mode or single file
{

View File

@@ -236,11 +236,13 @@ public class SevenZipArchive : AbstractArchive<SevenZipArchiveEntry, SevenZipVol
}
else
{
currentStream = archive.database.GetFolderStream(
stream,
currentFolder,
new PasswordProvider(Options.Password)
);
currentStream = archive
.database
.GetFolderStream(
stream,
currentFolder,
new PasswordProvider(Options.Password)
);
}
foreach (var entry in group)
{

View File

@@ -1,5 +1,9 @@
#nullable disable
using System;
using System.IO;
using System.Text;
using SharpCompress.IO;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
@@ -8,11 +12,6 @@ using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using SharpCompress.IO;
using System;
using System.IO;
using System.Text;
namespace SharpCompress.Common.Rar.Headers;
internal class FileHeader : RarHeader

View File

@@ -15,7 +15,7 @@ internal sealed class RarCryptoWrapper : Stream
{
_actualStream = actualStream;
_salt = salt;
_rijndael = RarRijndael.InitializeFrom(password, salt);
_rijndael = RarRijndael.InitializeFrom(password ?? "", salt);
}
public override void Flush() => throw new NotSupportedException();

View File

@@ -70,11 +70,11 @@ public abstract class RarVolume : Volume
var part = CreateFilePart(lastMarkHeader!, fh);
var buffer = new byte[fh.CompressedSize];
part.GetCompressedStream().Read(buffer, 0, buffer.Length);
Comment = System.Text.Encoding.UTF8.GetString(
buffer,
0,
buffer.Length - 1
);
Comment = System
.Text
.Encoding
.UTF8
.GetString(buffer, 0, buffer.Length - 1);
}
}
break;

View File

@@ -0,0 +1,12 @@
using System;
namespace SharpCompress.Common;
public class ReaderCancelledException : Exception
{
public ReaderCancelledException(string message)
: base(message) { }
public ReaderCancelledException(string message, Exception inner)
: base(message, inner) { }
}

View File

@@ -75,6 +75,9 @@ internal class SevenZipFilePart : FilePart
internal CompressionType GetCompression()
{
if (Header.IsDir)
return CompressionType.None;
var coder = Folder!._coders.First();
switch (coder._methodId._id)
{
@@ -97,5 +100,7 @@ internal class SevenZipFilePart : FilePart
}
internal bool IsEncrypted =>
Folder!._coders.FindIndex(c => c._methodId._id == CMethodId.K_AES_ID) != -1;
Header.IsDir
? false
: Folder!._coders.FindIndex(c => c._methodId._id == CMethodId.K_AES_ID) != -1;
}

View File

@@ -72,6 +72,10 @@ public class TarEntry : Entry
yield return new TarEntry(new TarFilePart(h, null), compressionType);
}
}
else
{
throw new IncompleteArchiveException("Unexpected EOF reading tar file");
}
}
}
}

View File

@@ -1,6 +1,6 @@
using SharpCompress.IO;
using System;
using System;
using System.IO;
using SharpCompress.IO;
namespace SharpCompress.Common.Tar;

View File

@@ -7,6 +7,7 @@ internal enum ZipCompressionMethod
Deflate64 = 9,
BZip2 = 12,
LZMA = 14,
ZStd = 93,
Xz = 95,
PPMd = 98,
WinzipAes = 0x63 //http://www.winzip.com/aes_info.htm

View File

@@ -11,6 +11,7 @@ using SharpCompress.Compressors.LZMA;
using SharpCompress.Compressors.PPMd;
using SharpCompress.Compressors.Xz;
using SharpCompress.IO;
using ZstdSharp;
namespace SharpCompress.Common.Zip;
@@ -113,6 +114,10 @@ internal abstract class ZipFilePart : FilePart
{
return new XZStream(stream);
}
case ZipCompressionMethod.ZStd:
{
return new DecompressionStream(stream);
}
case ZipCompressionMethod.PPMd:
{
Span<byte> props = stackalloc byte[2];

View File

@@ -142,9 +142,9 @@ internal class ZipHeaderFactory
if (entryHeader.CompressionMethod == ZipCompressionMethod.WinzipAes)
{
var data = entryHeader.Extra.SingleOrDefault(
x => x.Type == ExtraDataType.WinZipAes
);
var data = entryHeader
.Extra
.SingleOrDefault(x => x.Type == ExtraDataType.WinZipAes);
if (data != null)
{
var keySize = (WinzipAesKeySize)data.DataBytes[4];

View File

@@ -69,7 +69,6 @@
// -----------------------------------------------------------------------
using System;
using SharpCompress.Algorithms;
namespace SharpCompress.Compressors.Deflate;
@@ -1959,7 +1958,9 @@ internal sealed partial class DeflateManager
// returning Z_STREAM_END instead of Z_BUFF_ERROR.
}
else if (
_codec.AvailableBytesIn == 0 && (int)flush <= old_flush && flush != FlushType.Finish
_codec.AvailableBytesIn == 0
&& (int)flush <= old_flush
&& flush != FlushType.Finish
)
{
// workitem 8557

View File

@@ -64,7 +64,6 @@
// -----------------------------------------------------------------------
using System;
using SharpCompress.Algorithms;
namespace SharpCompress.Compressors.Deflate;

View File

@@ -30,8 +30,8 @@ using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Tar.Headers;
using System.Text;
using SharpCompress.Common.Tar.Headers;
namespace SharpCompress.Compressors.Deflate;

View File

@@ -4,11 +4,11 @@
#nullable disable
using SharpCompress.Common.Zip;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using SharpCompress.Common.Zip;
namespace SharpCompress.Compressors.Deflate64;

View File

@@ -0,0 +1,49 @@
using System.IO;
namespace SharpCompress.Compressors.Filters;
internal class BCJFilterARM : Filter
{
private int _pos;
public BCJFilterARM(bool isEncoder, Stream baseStream)
: base(isEncoder, baseStream, 8) => _pos = 8;
protected override int Transform(byte[] buffer, int offset, int count)
{
var end = offset + count - 4;
int i;
for (i = offset; i <= end; i += 4)
{
if ((buffer[i + 3] & 0xFF) == 0xEB)
{
int src =
((buffer[i + 2] & 0xFF) << 16)
| ((buffer[i + 1] & 0xFF) << 8)
| (buffer[i] & 0xFF);
src <<= 2;
int dest;
if (_isEncoder)
{
dest = src + (_pos + i - offset);
}
else
{
dest = src - (_pos + i - offset);
}
dest >>>= 2;
buffer[i + 2] = (byte)(dest >>> 16);
buffer[i + 1] = (byte)(dest >>> 8);
buffer[i] = (byte)dest;
}
}
i -= offset;
_pos += i;
return i;
}
}

View File

@@ -0,0 +1,47 @@
using System.IO;
namespace SharpCompress.Compressors.Filters;
internal class BCJFilterARMT : Filter
{
private int _pos;
public BCJFilterARMT(bool isEncoder, Stream baseStream)
: base(isEncoder, baseStream, 4) => _pos = 4;
protected override int Transform(byte[] buffer, int offset, int count)
{
var end = offset + count - 4;
int i;
for (i = offset; i <= end; i += 2)
{
if ((buffer[i + 1] & 0xF8) == 0xF0 && (buffer[i + 3] & 0xF8) == 0xF8)
{
int src =
((buffer[i + 1] & 0x07) << 19)
| ((buffer[i] & 0xFF) << 11)
| ((buffer[i + 3] & 0x07) << 8)
| (buffer[i + 2] & 0xFF);
src <<= 1;
int dest;
if (_isEncoder)
dest = src + (_pos + i - offset);
else
dest = src - (_pos + i - offset);
dest >>>= 1;
buffer[i + 1] = (byte)(0xF0 | ((dest >>> 19) & 0x07));
buffer[i] = (byte)(dest >>> 11);
buffer[i + 3] = (byte)(0xF8 | ((dest >>> 8) & 0x07));
buffer[i + 2] = (byte)dest;
i += 2;
}
}
i -= offset;
_pos += i;
return i;
}
}

View File

@@ -0,0 +1,107 @@
using System.IO;
namespace SharpCompress.Compressors.Filters;
internal class BCJFilterIA64 : Filter
{
private int _pos;
private static readonly int[] BRANCH_TABLE =
{
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
4,
4,
6,
6,
0,
0,
7,
7,
4,
4,
0,
0,
4,
4,
0,
0
};
public BCJFilterIA64(bool isEncoder, Stream baseStream)
: base(isEncoder, baseStream, 16) => _pos = 0;
protected override int Transform(byte[] buffer, int offset, int count)
{
var end = offset + count - 16;
int i;
for (i = offset; i <= end; i += 16)
{
int instrTemplate = buffer[i] & 0x1F;
int mask = BRANCH_TABLE[instrTemplate];
for (int slot = 0, bitPos = 5; slot < 3; ++slot, bitPos += 41)
{
if (((mask >>> slot) & 1) == 0)
continue;
int bytePos = bitPos >>> 3;
int bitRes = bitPos & 7;
long instr = 0;
for (int j = 0; j < 6; ++j)
{
instr |= (buffer[i + bytePos + j] & 0xFFL) << (8 * j);
}
long instrNorm = instr >>> bitRes;
if (((instrNorm >>> 37) & 0x0F) != 0x05 || ((instrNorm >>> 9) & 0x07) != 0x00)
continue;
int src = (int)((instrNorm >>> 13) & 0x0FFFFF);
src |= ((int)(instrNorm >>> 36) & 1) << 20;
src <<= 4;
int dest;
if (_isEncoder)
dest = src + (_pos + i - offset);
else
dest = src - (_pos + i - offset);
dest >>>= 4;
instrNorm &= ~(0x8FFFFFL << 13);
instrNorm |= (dest & 0x0FFFFFL) << 13;
instrNorm |= (dest & 0x100000L) << (36 - 20);
instr &= (1 << bitRes) - 1;
instr |= instrNorm << bitRes;
for (int j = 0; j < 6; ++j)
{
buffer[i + bytePos + j] = (byte)(instr >>> (8 * j));
}
}
}
i -= offset;
_pos += i;
return i;
}
}

View File

@@ -0,0 +1,48 @@
using System.IO;
namespace SharpCompress.Compressors.Filters;
internal class BCJFilterPPC : Filter
{
private int _pos;
public BCJFilterPPC(bool isEncoder, Stream baseStream)
: base(isEncoder, baseStream, 4) => _pos = 0;
protected override int Transform(byte[] buffer, int offset, int count)
{
var end = offset + count - 4;
int i;
for (i = offset; i <= end; i += 4)
{
if ((buffer[i] & 0xFC) == 0x48 && (buffer[i + 3] & 0x03) == 0x01)
{
int src =
((buffer[i] & 0x03) << 24)
| ((buffer[i + 1] & 0xFF) << 16)
| ((buffer[i + 2] & 0xFF) << 8)
| (buffer[i + 3] & 0xFC);
int dest;
if (_isEncoder)
{
dest = src + (_pos + i - offset);
}
else
{
dest = src - (_pos + i - offset);
}
buffer[i] = (byte)(0x48 | ((dest >>> 24) & 0x03));
buffer[i + 1] = (byte)(dest >>> 16);
buffer[i + 2] = (byte)(dest >>> 8);
buffer[i + 3] = (byte)((buffer[i + 3] & 0x03) | dest);
}
}
i -= offset;
_pos += i;
return i;
}
}

View File

@@ -0,0 +1,58 @@
using System.IO;
namespace SharpCompress.Compressors.Filters;
internal class BCJFilterSPARC : Filter
{
private int _pos;
public BCJFilterSPARC(bool isEncoder, Stream baseStream)
: base(isEncoder, baseStream, 4) => _pos = 0;
protected override int Transform(byte[] buffer, int offset, int count)
{
var end = offset + count - 4;
int i;
for (i = offset; i <= end; i += 4)
{
if (
(buffer[i] == 0x40 && (buffer[i + 1] & 0xC0) == 0x00)
|| (buffer[i] == 0x7F && (buffer[i + 1] & 0xC0) == 0xC0)
)
{
int src =
((buffer[i] & 0xFF) << 24)
| ((buffer[i + 1] & 0xFF) << 16)
| ((buffer[i + 2] & 0xFF) << 8)
| (buffer[i + 3] & 0xFF);
src <<= 2;
int dest;
if (_isEncoder)
{
dest = src + (_pos + i - offset);
}
else
{
dest = src - (_pos + i - offset);
}
dest >>>= 2;
dest =
(((0 - ((dest >>> 22) & 1)) << 22) & 0x3FFFFFFF)
| (dest & 0x3FFFFF)
| 0x40000000;
buffer[i] = (byte)(dest >>> 24);
buffer[i + 1] = (byte)(dest >>> 16);
buffer[i + 2] = (byte)(dest >>> 8);
buffer[i + 3] = (byte)dest;
}
}
i -= offset;
_pos += i;
return i;
}
}

View File

@@ -7,6 +7,7 @@ using SharpCompress.Compressors.Deflate;
using SharpCompress.Compressors.Filters;
using SharpCompress.Compressors.LZMA.Utilites;
using SharpCompress.Compressors.PPMd;
using ZstdSharp;
namespace SharpCompress.Compressors.LZMA;
@@ -19,8 +20,14 @@ internal static class DecoderRegistry
private const uint K_PPMD = 0x030401;
private const uint K_BCJ = 0x03030103;
private const uint K_BCJ2 = 0x0303011B;
private const uint K_PPC = 0x03030205;
private const uint K_IA64 = 0x03030401;
private const uint K_ARM = 0x03030501;
private const uint K_ARMT = 0x03030701;
private const uint K_SPARC = 0x03030805;
private const uint K_DEFLATE = 0x040108;
private const uint K_B_ZIP2 = 0x040202;
private const uint K_ZSTD = 0x4F71101;
internal static Stream CreateDecoderStream(
CMethodId id,
@@ -49,12 +56,24 @@ internal static class DecoderRegistry
return new BCJFilter(false, inStreams.Single());
case K_BCJ2:
return new Bcj2DecoderStream(inStreams, info, limit);
case K_PPC:
return new BCJFilterPPC(false, inStreams.Single());
case K_IA64:
return new BCJFilterIA64(false, inStreams.Single());
case K_ARM:
return new BCJFilterARM(false, inStreams.Single());
case K_ARMT:
return new BCJFilterARMT(false, inStreams.Single());
case K_SPARC:
return new BCJFilterSPARC(false, inStreams.Single());
case K_B_ZIP2:
return new BZip2Stream(inStreams.Single(), CompressionMode.Decompress, true);
case K_PPMD:
return new PpmdStream(new PpmdProperties(info), inStreams.Single(), false);
case K_DEFLATE:
return new DeflateStream(inStreams.Single(), CompressionMode.Decompress);
case K_ZSTD:
return new DecompressionStream(inStreams.Single());
default:
throw new NotSupportedException();
}

View File

@@ -866,7 +866,8 @@ internal partial class Model
);
}
else if (
(currentContext.SummaryFrequency += 4) > 128 + (4 * currentContext.NumberStatistics)
(currentContext.SummaryFrequency += 4)
> 128 + (4 * currentContext.NumberStatistics)
)
{
Refresh((uint)((currentContext.NumberStatistics + 2) >> 1), true, currentContext);

View File

@@ -1269,9 +1269,10 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
if (CurSize < DataSize + RarVM.VM_FIXEDGLOBALSIZE)
{
// StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
StackFilter.Program.GlobalData.SetSize(
DataSize + RarVM.VM_FIXEDGLOBALSIZE - CurSize
);
StackFilter
.Program
.GlobalData
.SetSize(DataSize + RarVM.VM_FIXEDGLOBALSIZE - CurSize);
}
var offset = RarVM.VM_FIXEDGLOBALSIZE;
globalData = StackFilter.Program.GlobalData;

View File

@@ -1,5 +1,4 @@
using System;
using SharpCompress.Compressors.Rar.VM;
namespace SharpCompress.Compressors.Rar.UnpackV1;

View File

@@ -1,5 +1,6 @@
#nullable disable
using System;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
@@ -7,7 +8,6 @@ using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using System;
namespace SharpCompress.Compressors.Rar.UnpackV2017;

View File

@@ -1,13 +1,13 @@
#if !Rar2017_64bit
using System;
using System.IO;
using SharpCompress.Common.Rar.Headers;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using System;
using System.IO;
using SharpCompress.Common.Rar.Headers;
namespace SharpCompress.Compressors.Rar.UnpackV2017;

View File

@@ -1,10 +1,12 @@
#if !Rar2017_64bit
using uint32 = System.UInt32;
/*#if !Rar2017_64bit
#else
using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using uint32 = System.UInt32;
#endif*/
namespace SharpCompress.Compressors.Rar.UnpackV2017;

View File

@@ -1,12 +1,14 @@
#if !Rar2017_64bit
using System;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.Unpack.Unpack20Local;
/*#if !Rar2017_64bit
#else
using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using System;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.Unpack.Unpack20Local;
#endif*/
namespace SharpCompress.Compressors.Rar.UnpackV2017;

View File

@@ -1,5 +1,9 @@
#nullable disable
using System;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
using int64 = System.Int64;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
@@ -7,11 +11,6 @@ using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using int64 = System.Int64;
using System;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
namespace SharpCompress.Compressors.Rar.UnpackV2017;

View File

@@ -1,5 +1,9 @@
#nullable disable
using System;
using SharpCompress.Common;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
@@ -8,11 +12,6 @@ using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using System;
using SharpCompress.Common;
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
namespace SharpCompress.Compressors.Rar.UnpackV2017;
internal sealed partial class Unpack : BitInput
@@ -30,12 +29,12 @@ internal sealed partial class Unpack : BitInput
Suspended = false;
UnpAllBuf = false;
UnpSomeRead = false;
#if RarV2017_RAR_SMP
MaxUserThreads = 1;
UnpThreadPool = CreateThreadPool();
ReadBufMT = null;
UnpThreadData = null;
#endif
/*#if RarV2017_RAR_SMP
MaxUserThreads = 1;
UnpThreadPool = CreateThreadPool();
ReadBufMT = null;
UnpThreadData = null;
#endif*/
MaxWinSize = 0;
MaxWinMask = 0;
@@ -199,21 +198,21 @@ internal sealed partial class Unpack : BitInput
break;
#endif
case 50: // RAR 5.0 compression algorithm.
#if RarV2017_RAR_SMP
if (MaxUserThreads > 1)
{
// We do not use the multithreaded unpack routine to repack RAR archives
// in 'suspended' mode, because unlike the single threaded code it can
// write more than one dictionary for same loop pass. So we would need
// larger buffers of unknown size. Also we do not support multithreading
// in fragmented window mode.
if (!Fragmented)
{
Unpack5MT(Solid);
break;
}
}
#endif
/*#if RarV2017_RAR_SMP
if (MaxUserThreads > 1)
{
// We do not use the multithreaded unpack routine to repack RAR archives
// in 'suspended' mode, because unlike the single threaded code it can
// write more than one dictionary for same loop pass. So we would need
// larger buffers of unknown size. Also we do not support multithreading
// in fragmented window mode.
if (!Fragmented)
{
Unpack5MT(Solid);
break;
}
}
#endif*/
Unpack5(Solid);
break;
#if !Rar2017_NOSTRICT

View File

@@ -1,10 +1,12 @@
#if !Rar2017_64bit
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
/*#if !Rar2017_64bit
#else
using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
#endif*/
namespace SharpCompress.Compressors.Rar.UnpackV2017;

View File

@@ -1,3 +1,8 @@
using System;
using System.Collections.Generic;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
using int64 = System.Int64;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
@@ -5,12 +10,6 @@ using nint = System.Int64;
using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
using int64 = System.Int64;
using System.Collections.Generic;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
using System;
// TODO: REMOVE THIS... WIP
#pragma warning disable 169
@@ -20,8 +19,6 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017;
internal static class UnpackGlobal
{
// Maximum allowed number of compressed bits processed in quick mode.
public const int MAX_QUICK_DECODE_BITS = 10;
@@ -97,11 +94,11 @@ internal struct UnpackBlockHeader
internal struct UnpackBlockTables
{
public DecodeTable LD; // Decode literals.
public DecodeTable DD; // Decode distances.
public DecodeTable LD; // Decode literals.
public DecodeTable DD; // Decode distances.
public DecodeTable LDD; // Decode lower bits of distances.
public DecodeTable RD; // Decode repeating distances.
public DecodeTable BD; // Decode bit lengths in Huffman table.
public DecodeTable RD; // Decode repeating distances.
public DecodeTable BD; // Decode bit lengths in Huffman table.
public void Init()
{
@@ -113,8 +110,7 @@ internal struct UnpackBlockTables
}
};
#if RarV2017_RAR_SMP
/*#if RarV2017_RAR_SMP
enum UNP_DEC_TYPE {
UNPDT_LITERAL,UNPDT_MATCH,UNPDT_FULLREP,UNPDT_REP,UNPDT_FILTER
};
@@ -161,7 +157,7 @@ if (Decoded!=NULL)
free(Decoded);
}
};
#endif
#endif*/
//struct UnpackFilter
@@ -171,12 +167,12 @@ internal class UnpackFilter
public uint BlockStart;
public uint BlockLength;
public byte Channels;
// uint Width;
// byte PosR;
public bool NextWindow;
};
//struct UnpackFilter30
internal class UnpackFilter30
{
@@ -195,15 +191,21 @@ internal class UnpackFilter30
internal class AudioVariables // For RAR 2.0 archives only.
{
public int K1, K2, K3, K4, K5;
public int D1, D2, D3, D4;
public int K1,
K2,
K3,
K4,
K5;
public int D1,
D2,
D3,
D4;
public int LastDelta;
public readonly uint[] Dif = new uint[11];
public uint ByteCount;
public int LastChar;
};
// We can use the fragmented dictionary in case heap does not have the single
// large enough memory block. It is slower than normal dictionary.
internal partial class FragmentedWindow
@@ -223,10 +225,8 @@ internal partial class FragmentedWindow
//size_t GetBlockSize(size_t StartPos,size_t RequiredSize);
};
internal partial class Unpack
{
//void Unpack5(bool Solid);
//void Unpack5MT(bool Solid);
//bool UnpReadBuf();
@@ -254,16 +254,16 @@ internal partial class Unpack
//BitInput Inp;
private BitInput Inp => this; // hopefully this gets inlined
#if RarV2017_RAR_SMP
void InitMT();
bool UnpackLargeBlock(UnpackThreadData &D);
bool ProcessDecoded(UnpackThreadData &D);
ThreadPool *UnpThreadPool;
UnpackThreadData *UnpThreadData;
uint MaxUserThreads;
byte *ReadBufMT;
#endif
/*#if RarV2017_RAR_SMP
void InitMT();
bool UnpackLargeBlock(UnpackThreadData &D);
bool ProcessDecoded(UnpackThreadData &D);
ThreadPool *UnpThreadPool;
UnpackThreadData *UnpThreadData;
uint MaxUserThreads;
byte *ReadBufMT;
#endif*/
private byte[] FilterSrcMemory = Array.Empty<byte>();
private byte[] FilterDstMemory = Array.Empty<byte>();
@@ -279,7 +279,8 @@ byte *ReadBufMT;
// array. In RAR3 last distance is always stored in OldDist[0].
private uint LastDist;
private size_t UnpPtr, WrPtr;
private size_t UnpPtr,
WrPtr;
// Top border of read packed data.
private int ReadTop;
@@ -307,7 +308,6 @@ byte *ReadBufMT;
private int64 WrittenFileSize;
private bool FileExtracted;
/***************************** Unpack v 1.5 *********************************/
//void Unpack15(bool Solid);
//void ShortLZ();
@@ -320,12 +320,29 @@ byte *ReadBufMT;
//void CopyString15(uint Distance,uint Length);
//uint DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab);
private readonly ushort[] ChSet = new ushort[256], ChSetA = new ushort[256], ChSetB = new ushort[256], ChSetC = new ushort[256];
private readonly byte[] NToPl = new byte[256], NToPlB = new byte[256], NToPlC = new byte[256];
private uint FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
private int Buf60, NumHuf, StMode, LCount, FlagsCnt;
private readonly ushort[] ChSet = new ushort[256],
ChSetA = new ushort[256],
ChSetB = new ushort[256],
ChSetC = new ushort[256];
private readonly byte[] NToPl = new byte[256],
NToPlB = new byte[256],
NToPlC = new byte[256];
private uint FlagBuf,
AvrPlc,
AvrPlcB,
AvrLn1,
AvrLn2,
AvrLn3;
private int Buf60,
NumHuf,
StMode,
LCount,
FlagsCnt;
private uint Nhfb,
Nlzb,
MaxDist3;
private uint Nhfb, Nlzb, MaxDist3;
/***************************** Unpack v 1.5 *********************************/
/***************************** Unpack v 2.0 *********************************/
@@ -335,9 +352,11 @@ byte *ReadBufMT;
private readonly byte[] UnpOldTable20 = new byte[MC20 * 4];
private bool UnpAudioBlock;
private uint UnpChannels, UnpCurChannel;
private uint UnpChannels,
UnpCurChannel;
private int UnpChannelDelta;
//void CopyString20(uint Length,uint Distance);
//bool ReadTables20();
//void UnpWriteBuf20();
@@ -345,6 +364,7 @@ byte *ReadBufMT;
//void ReadLastTables();
//byte DecodeAudio(int Delta);
private AudioVariables[] AudV = new AudioVariables[4];
/***************************** Unpack v 2.0 *********************************/
/***************************** Unpack v 3.0 *********************************/
@@ -363,7 +383,8 @@ byte *ReadBufMT;
// because we can have a corrupt archive with one algorithm file
// followed by another algorithm file with "solid" flag and we do not
// want to reuse tables from one algorithm in another.
private bool TablesRead2, TablesRead5;
private bool TablesRead2,
TablesRead5;
// Virtual machine to execute filters code.
/*#if !RarV2017_RAR5ONLY
@@ -385,13 +406,13 @@ byte *ReadBufMT;
// the data block length if lengths are repeating.
private readonly List<int> OldFilterLengths = new List<int>();
#if RarV2017_RAR_SMP
// More than 8 threads are unlikely to provide a noticeable gain
// for unpacking, but would use the additional memory.
void SetThreads(uint Threads) {MaxUserThreads=Min(Threads,8);}
void UnpackDecode(UnpackThreadData &D);
#endif
/*#if RarV2017_RAR_SMP
// More than 8 threads are unlikely to provide a noticeable gain
// for unpacking, but would use the additional memory.
void SetThreads(uint Threads) {MaxUserThreads=Min(Threads,8);}
void UnpackDecode(UnpackThreadData &D);
#endif*/
private size_t MaxWinSize;
private size_t MaxWinMask;

View File

@@ -6,32 +6,29 @@ namespace SharpCompress.Compressors.Xz.Filters;
public abstract class BlockFilter : ReadOnlyStream
{
[CLSCompliant(false)]
public enum FilterTypes : ulong
private enum FilterTypes : ulong
{
DELTA = 0x03,
ARCH_x86_FILTER = 0x04,
ARCH_PowerPC_FILTER = 0x05,
ARCH_IA64_FILTER = 0x06,
ARCH_ARM_FILTER = 0x07,
ARCH_ARMTHUMB_FILTER = 0x08,
ARCH_SPARC_FILTER = 0x09,
LZMA2 = 0x21
//Delta = 0x03,
ArchX86Filter = 0x04,
ArchPowerPcFilter = 0x05,
ArchIa64Filter = 0x06,
ArchArmFilter = 0x07,
ArchArmThumbFilter = 0x08,
ArchSparcFilter = 0x09,
Lzma2 = 0x21
}
private static readonly Dictionary<FilterTypes, Func<BlockFilter>> FilterMap = new Dictionary<
FilterTypes,
Func<BlockFilter>
>
{
{ FilterTypes.ARCH_x86_FILTER, () => new X86Filter() },
{ FilterTypes.ARCH_PowerPC_FILTER, () => new PowerPCFilter() },
{ FilterTypes.ARCH_IA64_FILTER, () => new IA64Filter() },
{ FilterTypes.ARCH_ARM_FILTER, () => new ArmFilter() },
{ FilterTypes.ARCH_ARMTHUMB_FILTER, () => new ArmThumbFilter() },
{ FilterTypes.ARCH_SPARC_FILTER, () => 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; }
@@ -43,12 +40,12 @@ public abstract class BlockFilter : ReadOnlyStream
public static BlockFilter Read(BinaryReader reader)
{
var filterType = (FilterTypes)reader.ReadXZInteger();
if (!FilterMap.ContainsKey(filterType))
if (!FILTER_MAP.ContainsKey(filterType))
{
throw new NotImplementedException($"Filter {filterType} has not yet been implemented");
}
var filter = FilterMap[filterType]()!;
var filter = FILTER_MAP[filterType]();
var sizeOfProperties = reader.ReadXZInteger();
if (sizeOfProperties > int.MaxValue)

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
using SharpCompress.Archives.Tar;

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.IO;
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.IO;
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using SharpCompress.Common;

View File

@@ -9,10 +9,10 @@ namespace SharpCompress.IO;
public class SourceStream : Stream
{
private long _prevSize;
private List<FileInfo> _files;
private List<Stream> _streams;
private Func<int, FileInfo?> _getFilePart;
private Func<int, Stream?> _getStreamPart;
private readonly List<FileInfo> _files;
private readonly List<Stream> _streams;
private readonly Func<int, FileInfo?> _getFilePart;
private readonly Func<int, Stream?> _getStreamPart;
private int _stream;
public SourceStream(FileInfo file, Func<int, FileInfo?> getPart, ReaderOptions options)
@@ -39,10 +39,10 @@ public class SourceStream : Stream
{
_streams.Add(stream!);
_getStreamPart = getStreamPart!;
_getFilePart = new Func<int, FileInfo>(a => null!);
if (stream is FileStream)
_getFilePart = _ => null!;
if (stream is FileStream fileStream)
{
_files.Add(new FileInfo(((FileStream)stream!).Name));
_files.Add(new FileInfo(fileStream.Name));
}
}
else
@@ -50,7 +50,7 @@ public class SourceStream : Stream
_files.Add(file!);
_streams.Add(_files[0].OpenRead());
_getFilePart = getFilePart!;
_getStreamPart = new Func<int, Stream>(a => null!);
_getStreamPart = _ => null!;
}
_stream = 0;
_prevSize = 0;
@@ -98,9 +98,9 @@ public class SourceStream : Stream
}
//throw new Exception($"Stream part {idx} not available.");
_streams.Add(s);
if (s is FileStream)
if (s is FileStream stream)
{
_files.Add(new FileInfo(((FileStream)s).Name));
_files.Add(new FileInfo(stream.Name));
}
}
}
@@ -123,11 +123,11 @@ public class SourceStream : Stream
public override bool CanWrite => false;
public override long Length => (!IsVolumes ? _streams.Sum(a => a.Length) : Current.Length);
public override long Length => !IsVolumes ? _streams.Sum(a => a.Length) : Current.Length;
public override long Position
{
get => _prevSize + Current.Position; //_prevSize is 0 for multivolume
get => _prevSize + Current.Position; //_prevSize is 0 for multi-volume
set => Seek(value, SeekOrigin.Begin);
}
@@ -222,9 +222,12 @@ public class SourceStream : Stream
{
try
{
stream?.Dispose();
stream.Dispose();
}
catch
{
// ignored
}
catch { }
}
_streams.Clear();
_files.Clear();

View File

@@ -75,7 +75,7 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader, IReaderExtracti
}
if (Cancelled)
{
throw new InvalidOperationException("Reader has been cancelled.");
throw new ReaderCancelledException("Reader has been cancelled.");
}
if (entriesForCurrentReadStream is null)
{
@@ -129,7 +129,7 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader, IReaderExtracti
{
var part = Entry.Parts.First();
if (ArchiveType != ArchiveType.Rar && !Entry.IsSolid && Entry.CompressedSize > 0)
if (!Entry.IsSolid && Entry.CompressedSize > 0)
{
//not solid and has a known compressed size then we can skip raw bytes.
var rawStream = part.GetRawStream();

View File

@@ -11,5 +11,7 @@ internal class NonSeekableStreamFilePart : RarFilePart
internal override Stream GetCompressedStream() => FileHeader.PackedStream;
internal override Stream? GetRawStream() => FileHeader.PackedStream;
internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName;
}

View File

@@ -8,9 +8,9 @@ using SharpCompress.Common.Tar;
using SharpCompress.Compressors;
using SharpCompress.Compressors.BZip2;
using SharpCompress.Compressors.Deflate;
using SharpCompress.IO;
using SharpCompress.Compressors.LZMA;
using SharpCompress.Compressors.Xz;
using SharpCompress.IO;
namespace SharpCompress.Readers.Tar;

View File

@@ -1,41 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyTitle>SharpCompress - Pure C# Decompression/Compression</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.33.0</VersionPrefix>
<AssemblyVersion>0.33.0</AssemblyVersion>
<FileVersion>0.33.0</FileVersion>
<Authors>Adam Hathcock</Authors>
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net6.0;net7.0</TargetFrameworks>
<AssemblyName>SharpCompress</AssemblyName>
<AssemblyOriginatorKeyFile>../../SharpCompress.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PackageId>SharpCompress</PackageId>
<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>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Description>SharpCompress is a compression library for NET Standard 2.0/2.1/NET 6.0/NET 7.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>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyTitle>SharpCompress - Pure C# Decompression/Compression</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.34.2</VersionPrefix>
<AssemblyVersion>0.34.2</AssemblyVersion>
<FileVersion>0.34.2</FileVersion>
<Authors>Adam Hathcock</Authors>
<TargetFrameworks>net462;netstandard2.0;netstandard2.1;net6.0;net7.0</TargetFrameworks>
<AssemblyName>SharpCompress</AssemblyName>
<AssemblyOriginatorKeyFile>../../SharpCompress.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PackageId>SharpCompress</PackageId>
<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>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Description>SharpCompress is a compression library for NET Standard 2.0/2.1/NET 6.0/NET 7.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>
<IsTrimmable>true</IsTrimmable>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup Condition=" '$(VersionlessImplicitFrameworkDefine)' == 'NETFRAMEWORK' ">
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="ZstdSharp.Port" Version="0.7.2" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup Condition=" '$(VersionlessImplicitFrameworkDefine)' == 'NETFRAMEWORK' ">
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
</Project>

View File

@@ -1,5 +1,4 @@
using System.IO;
using SharpCompress.Factories;
namespace SharpCompress.Writers;

View File

@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Linq;
using SharpCompress.Common;
namespace SharpCompress.Writers;
@@ -10,7 +9,9 @@ public static class WriterFactory
{
public static IWriter Open(Stream stream, ArchiveType archiveType, WriterOptions writerOptions)
{
var factory = Factories.Factory.Factories
var factory = Factories
.Factory
.Factories
.OfType<IWriterFactory>()
.FirstOrDefault(item => item.KnownArchiveType == archiveType);

View File

@@ -298,10 +298,10 @@ public class ArchiveTests : ReaderTests
memory.Position = 0;
for (int y = 0; y < 9; y++)
for (int x = 0; x < 256; x++)
{
Assert.Equal(x, memory.ReadByte());
}
for (int x = 0; x < 256; x++)
{
Assert.Equal(x, memory.ReadByte());
}
Assert.Equal((int)-1, memory.ReadByte());
}

View File

@@ -332,4 +332,49 @@ public class RarReaderTests : ReaderTests
}
}
}
[Fact]
public void Rar_NullReference()
{
{
var archives = new[]
{
"Rar.EncryptedParts.part01.rar",
"Rar.EncryptedParts.part02.rar",
"Rar.EncryptedParts.part03.rar",
"Rar.EncryptedParts.part04.rar",
"Rar.EncryptedParts.part05.rar",
"Rar.EncryptedParts.part06.rar"
};
using (
var reader = RarReader.Open(
archives
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
.Select(p => File.OpenRead(p)),
new ReaderOptions() { Password = "test" }
)
)
{
while (reader.MoveToNextEntry())
{
//
}
}
}
{
using var stream = File.OpenRead(
Path.Combine(TEST_ARCHIVES_PATH, "Rar.encrypted_filesOnly.rar")
);
using var reader = ReaderFactory.Open(
stream,
new ReaderOptions() { LookForHeader = true }
);
while (reader.MoveToNextEntry())
{
//
}
}
}
}

View File

@@ -1,5 +1,8 @@
using System;
using System.IO;
using System.Linq;
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Common;
using SharpCompress.Readers;
using Xunit;
@@ -111,10 +114,78 @@ public class SevenZipArchiveTests : ArchiveTests
//"7Zip.BZip2.split.006",
//"7Zip.BZip2.split.007"
[Fact]
public void SevenZipArchive_ZSTD_StreamRead() => ArchiveStreamRead("7Zip.ZSTD.7z");
[Fact]
public void SevenZipArchive_ZSTD_PathRead() => ArchiveFileRead("7Zip.ZSTD.7z");
[Fact]
public void SevenZipArchive_ZSTD_Split() =>
Assert.Throws<InvalidOperationException>(
() =>
ArchiveStreamRead(
null,
"7Zip.ZSTD.Split.7z.001",
"7Zip.ZSTD.Split.7z.002",
"7Zip.ZSTD.Split.7z.003",
"7Zip.ZSTD.Split.7z.004",
"7Zip.ZSTD.Split.7z.005",
"7Zip.ZSTD.Split.7z.006"
)
);
[Fact]
public void SevenZipArchive_Delta_FileRead() => ArchiveFileRead("7Zip.delta.7z");
[Fact]
public void SevenZipArchive_ARM_FileRead() => ArchiveFileRead("7Zip.ARM.7z");
[Fact]
public void SevenZipArchive_ARMT_FileRead() => ArchiveFileRead("7Zip.ARMT.7z");
[Fact]
public void SevenZipArchive_BCJ_FileRead() => ArchiveFileRead("7Zip.BCJ.7z");
[Fact]
public void SevenZipArchive_BCJ2_FileRead() => ArchiveFileRead("7Zip.BCJ2.7z");
[Fact]
public void SevenZipArchive_IA64_FileRead() => ArchiveFileRead("7Zip.IA64.7z");
[Fact]
public void SevenZipArchive_PPC_FileRead() => ArchiveFileRead("7Zip.PPC.7z");
[Fact]
public void SevenZipArchive_SPARC_FileRead() => ArchiveFileRead("7Zip.SPARC.7z");
[Fact]
public void SevenZipArchive_Filters_FileRead() => ArchiveFileRead("7Zip.Filters.7z");
[Fact]
public void SevenZipArchive_Delta_Distance() =>
ArchiveDeltaDistanceRead("7Zip.delta.distance.7z");
[Fact]
public void SevenZipArchive_Tar_PathRead()
{
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "7Zip.Tar.tar.7z")))
using (var archive = SevenZipArchive.Open(stream))
{
var entry = archive.Entries.First();
entry.WriteToFile(Path.Combine(SCRATCH_FILES_PATH, entry.Key));
var size = entry.Size;
var scratch = new FileInfo(Path.Combine(SCRATCH_FILES_PATH, "7Zip.Tar.tar"));
var test = new FileInfo(Path.Combine(TEST_ARCHIVES_PATH, "7Zip.Tar.tar"));
Assert.Equal(size, scratch.Length);
Assert.Equal(size, test.Length);
}
CompareArchivesByPath(
Path.Combine(SCRATCH_FILES_PATH, "7Zip.Tar.tar"),
Path.Combine(TEST_ARCHIVES_PATH, "7Zip.Tar.tar")
);
}
}

View File

@@ -1,15 +1,15 @@
using System;
using System;
using System.IO;
using System.Linq;
using System.Text;
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;
using SharpCompress.Writers;
using Xunit;
using System.Text;
using SharpCompress.Readers;
using SharpCompress.Writers.Tar;
using SharpCompress.Readers.Tar;
using SharpCompress.Writers;
using SharpCompress.Writers.Tar;
using Xunit;
namespace SharpCompress.Test.Tar;
@@ -198,9 +198,9 @@ public class TarArchiveTests : ArchiveTests
using (var archive = TarArchive.Open(unmodified))
{
var entry = archive.Entries.Single(
x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
);
var entry = archive
.Entries
.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase));
archive.RemoveEntry(entry);
archive.SaveTo(scratchPath, CompressionType.None);
}

View File

@@ -183,13 +183,34 @@ public class TarReaderTests : ReaderTests
}
}
[Fact]
public void Tar_Broken_Stream()
{
string archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar");
using (Stream stream = File.OpenRead(archiveFullPath))
using (IReader reader = ReaderFactory.Open(stream))
{
var memoryStream = new MemoryStream();
Action action = () => reader.MoveToNextEntry();
var exception = Record.Exception(action);
Assert.Null(exception);
reader.MoveToNextEntry();
reader.WriteEntryTo(memoryStream);
stream.Close();
Assert.Throws<IncompleteArchiveException>(action);
}
}
#if !NETFRAMEWORK
[Fact]
public void Tar_GZip_With_Symlink_Entries()
{
var isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
System.Runtime.InteropServices.OSPlatform.Windows
);
var isWindows = System
.Runtime
.InteropServices
.RuntimeInformation
.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows);
using (
Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "TarWithSymlink.tar.gz"))
)
@@ -232,12 +253,15 @@ public class TarReaderTests : ReaderTests
{
// need to convert the link to an absolute path for comparison
var target = reader.Entry.LinkTarget;
var realTarget = System.IO.Path.GetFullPath(
System.IO.Path.Combine(
$"{System.IO.Path.GetDirectoryName(path)}",
target
)
);
var realTarget = System
.IO
.Path
.GetFullPath(
System
.IO
.Path
.Combine($"{System.IO.Path.GetDirectoryName(path)}", target)
);
Assert.Equal(realTarget, link.GetContents().ToString());
}

View File

@@ -20,10 +20,10 @@ public class TestBase : IDisposable
public TestBase()
{
var index = AppDomain.CurrentDomain.BaseDirectory.IndexOf(
"SharpCompress.Test",
StringComparison.OrdinalIgnoreCase
);
var index = AppDomain
.CurrentDomain
.BaseDirectory
.IndexOf("SharpCompress.Test", StringComparison.OrdinalIgnoreCase);
var path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, index);
SOLUTION_BASE_PATH = Path.GetDirectoryName(path) ?? throw new ArgumentNullException();

View File

@@ -1,7 +1,7 @@
using System;
using Xunit;
using System.IO;
using SharpCompress.Compressors.Xz.Filters;
using Xunit;
namespace SharpCompress.Test.Xz.Filters;

View File

@@ -1,5 +1,5 @@
using SharpCompress.Compressors.Xz;
using System.IO;
using SharpCompress.Compressors.Xz;
using Xunit;
namespace SharpCompress.Test.Xz;

View File

@@ -1,5 +1,5 @@
using SharpCompress.Compressors.Xz;
using System.IO;
using System.IO;
using SharpCompress.Compressors.Xz;
using Xunit;
namespace SharpCompress.Test.Xz;

View File

@@ -1,5 +1,5 @@
using SharpCompress.Compressors.Xz;
using System.IO;
using System.IO;
using SharpCompress.Compressors.Xz;
using Xunit;
namespace SharpCompress.Test.Xz;

View File

@@ -184,9 +184,9 @@ public class ZipArchiveTests : ArchiveTests
using (var archive = ZipArchive.Open(unmodified))
{
var entry = archive.Entries.Single(
x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
);
var entry = archive
.Entries
.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase));
archive.RemoveEntry(entry);
WriterOptions writerOptions = new ZipWriterOptions(CompressionType.Deflate);
@@ -252,9 +252,9 @@ public class ZipArchiveTests : ArchiveTests
)
);
Assert.Null(
((IArchive)vfs).Entries.FirstOrDefault(
v => v.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
)
((IArchive)vfs)
.Entries
.FirstOrDefault(v => v.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase))
);
}
}
@@ -391,14 +391,14 @@ public class ZipArchiveTests : ArchiveTests
{
archive.AddAllFromDirectory(SCRATCH_FILES_PATH);
archive.RemoveEntry(
archive.Entries.Single(
x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
)
archive
.Entries
.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase))
);
Assert.Null(
archive.Entries.FirstOrDefault(
x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
)
archive
.Entries
.FirstOrDefault(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase))
);
}
Directory.Delete(SCRATCH_FILES_PATH, true);

View File

@@ -1,5 +1,4 @@
using System.Text;
using SharpCompress.Common;
using Xunit;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.