Compare commits

..

57 Commits
0.23 ... 0.25.1

Author SHA1 Message Date
Adam Hathcock
8bfc9ef4de Update for 0.25.1 2020-05-22 13:46:36 +01:00
Adam Hathcock
fa949e089e Merge pull request #512 from adamhathcock/fix-codepages
Attempt Windows reference fix
2020-05-22 13:44:10 +01:00
Adam Hathcock
c296ca7660 Merge pull request #513 from RealOrko/symbolic-link-default-write
Added default implementation with warning for symbolic links
2020-05-22 13:43:56 +01:00
RealOrko
538b38869f Added a warning for the writing of symbolic links with a link to the original GitHub issue for the DOTNET runtime 2020-05-21 13:00:25 +01:00
Adam Hathcock
ce328ed90b Merge branch 'master' into fix-codepages 2020-05-15 08:28:25 +01:00
Adam Hathcock
632bae725d Add braces for clarity 2020-05-14 13:47:21 +01:00
Adam Hathcock
4f824b1d9a Add build flags for Core targets 2020-05-14 13:16:00 +01:00
Adam Hathcock
120aee8039 See if windows reference is fixed 2020-05-14 13:09:17 +01:00
Adam Hathcock
3b2b341c4d Merge pull request #508 from turbedi/minor_optimizations
Minor optimizations
2020-04-11 09:08:07 +01:00
Berkan Diler
4cad40f637 Minor string optimizations 2020-04-10 12:33:40 +02:00
Berkan Diler
2c64380019 Use 3 argument Array.Copy when possible 2020-04-10 12:06:38 +02:00
Berkan Diler
ccb9593de2 Replace Span<T>.Fill(0) with Span<T>.Clear() 2020-04-10 12:03:32 +02:00
Berkan Diler
921a99fc32 Replace static readonly byte[] fields with static ReadOnlySpan<byte> properties 2020-04-10 11:54:58 +02:00
Adam Hathcock
400d2c1774 Fix usings and add braces for better merging 2020-04-03 08:47:30 +01:00
Adam Hathcock
762497b1c1 Tag for 0.25.0 and update packages 2020-04-03 08:25:43 +01:00
Adam Hathcock
be9edc7512 Merge pull request #500 from Erior/Issue_86
ZipReader/StreamingZipReaderFactory fails for archive entries which are uncompressed files in ZIP format #86
2020-01-17 09:38:19 +00:00
Lars Vahlenberg
9bf9d34d94 Issue86 Proposal 2020-01-16 22:08:48 +01:00
Adam Hathcock
df8405006c Fix workflow name 2020-01-03 09:24:08 +00:00
Adam Hathcock
d135fdce58 Give github actions build a name and use badge 2020-01-03 09:22:51 +00:00
Adam Hathcock
ba570b93bb Merge pull request #496 from Bond-009/allocations
Reduce the amount of allocations
2020-01-03 09:18:17 +00:00
Adam Hathcock
6dfe0c7a96 Merge branch 'master' into allocations 2020-01-03 09:16:46 +00:00
Adam Hathcock
73d4430a65 Merge pull request #498 from adamhathcock/build-netcore3
Build netcore3
2020-01-03 09:15:14 +00:00
Adam Hathcock
ce6fd9b976 JUst one target 2020-01-03 09:12:10 +00:00
Adam Hathcock
ae7e8c03f2 Put wrong SDK 2020-01-03 09:07:34 +00:00
Adam Hathcock
22e2526f4c Update cake and dependencies 2020-01-03 09:06:13 +00:00
Adam Hathcock
50283d9411 Add new build targets for netcore3 2020-01-03 09:02:04 +00:00
Bond-009
d2c2b58f3b Fix language version and add netstandard2.1 2020-01-02 17:43:58 +01:00
Bond_009
50d4b39ca0 Fix test 2019-12-30 22:17:45 +01:00
Bond_009
1ed675e960 Minor improvement 2019-12-30 19:19:05 +01:00
Bond_009
80b0671844 Reduce the amount of allocations
* Directly fill an array instead of filling a List and copying that to
an array
* Use own buffer when writing bytes to a stream
* Remove DataConverter class, replaced by BinaryPrimitives
2019-12-30 18:58:25 +01:00
Bond-009
6f387336c0 Use functions from System.Memory instead of selfmade ones (#495)
* Use functions from System.Memory instead of selfmade ones

* Update SharpCompress.Test.csproj
2019-12-30 15:19:46 +00:00
Adam Hathcock
9540b01bcc NET Standard 1.3 and 2.0 only (#482)
* Remove NET35, NET45 and NET Standard 1.0

* Update README and memset

* Remove NETCORE build flag

* NET 46 too?

* Update packages and usage
2019-10-10 09:24:41 +01:00
Adam Hathcock
446d6914c1 Merge pull request #483 from Bond-009/nameof
Use nameof for param names
2019-09-17 14:21:04 +01:00
Bond_009
637223aa53 Use nameof for param names 2019-09-17 13:28:44 +02:00
Adam Hathcock
17d5565120 Merge pull request #478 from Bond-009/buffers
Use System.Buffers Nuget package
2019-09-17 10:05:29 +01:00
Bond_009
4b54187b4c Fix build 2019-09-11 21:33:57 +02:00
Bond_009
cfb1421367 Use System.Buffers Nuget package 2019-09-11 20:06:50 +02:00
Adam Hathcock
5072a0f6f5 Merge pull request #471 from adamhathcock/release-024
Bump version and dependencies
2019-08-20 20:36:38 +01:00
Adam Hathcock
357dff1403 Bump version and dependencies 2019-08-20 14:29:47 -05:00
Adam Hathcock
a2bd66ded8 Merge pull request #460 from itn3000/tar-fix-garbled2
fix filename garbling in tar(#414)
2019-06-27 12:16:53 +01:00
itn3000
6bfa3c25a4 add more comments 2019-06-27 20:01:40 +09:00
itn3000
1ea9ab72c1 add comment for subtracting 2019-06-27 19:59:16 +09:00
itn3000
07c42b8725 replace magic number 2019-06-27 10:59:21 +09:00
itn3000
70392c32e2 use Buffer.BlockCopy for performance 2019-06-27 09:47:26 +09:00
itn3000
9b4b2a9f7c considering encoding in processing filename(#414)
modify test tar archive because it was not expected one.
(expected "тест.txt" in encoding 866, but actual is omitted upper byte)
2019-06-26 17:34:12 +09:00
Adam Hathcock
d3dd708b58 Merge pull request #457 from DannyBoyk/issue_456_zip_bounded_substreams_data_descriptors
Return a bounded substream when data descriptors are used in seekable zips
2019-06-04 13:42:24 +01:00
Daniel Nash
af264cdc58 Return a bounded substream when data descriptors are used in seekable zips 2019-06-04 08:31:42 -04:00
Adam Hathcock
cfd6df976f Merge pull request #455 from DannyBoyk/issue_454_zip_bad_extra_field
Handle a bad extra field in a local file header in zip files
2019-06-04 09:24:55 +01:00
Daniel Nash
b2bd20b47e Handle a bad extra field in a local file header in zip files 2019-06-03 13:02:28 -04:00
Adam Hathcock
ffea093e95 Merge pull request #453 from Lssikkes/master
Fix for clients failing on just having a 64 bit offset in ZIP64
2019-05-24 19:33:59 +01:00
Leroy Sikkes
78eb8fcf92 Fix for clients that don't support ZIP64 standard correctly in case headers are only pointed to in ZIP64 directory structure 2019-05-24 18:27:49 +02:00
Adam Hathcock
a052956881 Merge pull request #452 from Lssikkes/master
Various fixes for ZIP64 writer (zero byte entries, 32 bit where supported)
2019-05-24 16:17:48 +01:00
Lssikkes
9319ea6992 Updated ZIP64 writer to write 32 bit values to directory entries for better compatibility.
Support for zero byte files without corruption errors from WinRAR/7-zip
2019-05-24 16:14:30 +02:00
Adam Hathcock
4e5b70dbfa Merge pull request #444 from eugeny-trunin/mem-opt
Memory and speed optimization
2019-03-20 15:13:00 +00:00
evgeny
c68eaa8397 Memory and speed optimization 2019-03-20 17:46:57 +03:00
Adam Hathcock
bbb7c85ba7 Merge pull request #442 from turbolocust/master
Fix: ArchiveEncoding was ignored in TarWriterOptions
2019-03-19 08:31:31 +00:00
Matthias Fussenegger
8174359228 Fix: ArchiveEncoding was ignored in TarWriterOptions 2019-03-18 18:25:00 +01:00
153 changed files with 1578 additions and 2698 deletions

View File

@@ -1,16 +0,0 @@
version: 2
jobs:
build:
docker:
- image: microsoft/dotnet:2.2.104-sdk
steps:
- checkout
- run:
name: Install Cake
command: |
dotnet tool install -g Cake.Tool
echo 'export PATH=$PATH:/root/.dotnet/tools' >> $BASH_ENV
source $BASH_ENV
- run:
name: Build
command: dotnet cake build.cake

17
.github/workflows/dotnetcore.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: SharpCompress
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.202
- name: Run the Cake script
uses: ecampidoglio/cake-action@master

View File

@@ -1,14 +1,14 @@
# SharpCompress
SharpCompress is a compression library in pure C# for .NET 3.5, 4.5, .NET Standard 1.0, 1.3 that can unrar, un7zip, unzip, untar unbzip2 and ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip are implemented.
SharpCompress is a compression library in pure C# for .NET Standard 1.3 and 2.0 that can unrar, un7zip, unzip, untar unbzip2 and ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip are implemented.
The major feature is support for non-seekable streams so large files can be processed on the fly (i.e. download stream).
AppVeyor Build -
[![Build status](https://ci.appveyor.com/api/projects/status/voxg971oemmvxh1e/branch/master?svg=true)](https://ci.appveyor.com/project/adamhathcock/sharpcompress/branch/master)
Circle CI Build -
[![CircleCI](https://circleci.com/gh/adamhathcock/sharpcompress.svg?style=svg)](https://circleci.com/gh/adamhathcock/sharpcompress)
GitHub Actions Build -
[![GitHubActions](https://github.com/adamhathcock/sharpcompress/workflows/SharpCompress/badge.svg)](https://circleci.com/gh/adamhathcock/sharpcompress)
## Need Help?

View File

@@ -126,4 +126,7 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=6af8f80e_002D9fdd_002D4223_002D8e02_002D473db916f9b2/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="All tests from Solution" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>

View File

@@ -1,5 +1,5 @@
version: '{build}'
image: Visual Studio 2017
image: Visual Studio 2019
pull_requests:
do_not_increment_build_number: true

View File

@@ -17,24 +17,24 @@ Task("Build")
{
c.SetConfiguration("Release")
.SetVerbosity(Verbosity.Minimal)
.UseToolVersion(MSBuildToolVersion.VS2017);
.UseToolVersion(MSBuildToolVersion.VS2019);
});
}
else
{
var settings = new DotNetCoreBuildSettings
{
Framework = "netstandard1.0",
Framework = "netstandard1.3",
Configuration = "Release",
NoRestore = true
};
DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings);
settings.Framework = "netstandard1.3";
settings.Framework = "netstandard2.0";
DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings);
settings.Framework = "netstandard2.0";
settings.Framework = "netstandard2.1";
DotNetCoreBuild("./src/SharpCompress/SharpCompress.csproj", settings);
}
});
@@ -49,7 +49,7 @@ Task("Test")
var settings = new DotNetCoreTestSettings
{
Configuration = "Release",
Framework = "netcoreapp2.2"
Framework = "netcoreapp3.1"
};
DotNetCoreTest(file.ToString(), settings);
}
@@ -64,7 +64,7 @@ Task("Pack")
MSBuild("src/SharpCompress/SharpCompress.csproj", c => c
.SetConfiguration("Release")
.SetVerbosity(Verbosity.Minimal)
.UseToolVersion(MSBuildToolVersion.VS2017)
.UseToolVersion(MSBuildToolVersion.VS2019)
.WithProperty("NoBuild", "true")
.WithTarget("Pack"));
}

View File

@@ -24,7 +24,6 @@ namespace SharpCompress.Archives
private bool disposed;
#if !NO_FILE
internal AbstractArchive(ArchiveType type, FileInfo fileInfo, ReaderOptions readerOptions)
{
Type = type;
@@ -40,7 +39,6 @@ namespace SharpCompress.Archives
protected abstract IEnumerable<TVolume> LoadVolumes(FileInfo file);
#endif
internal AbstractArchive(ArchiveType type, IEnumerable<Stream> streams, ReaderOptions readerOptions)
{
@@ -142,12 +140,12 @@ namespace SharpCompress.Archives
/// <summary>
/// Use this method to extract all entries in an archive in order.
/// This is primarily for SOLID Rar Archives or 7Zip Archives as they need to be
/// This is primarily for SOLID Rar Archives or 7Zip Archives as they need to be
/// extracted sequentially for the best performance.
///
///
/// This method will load all entry information from the archive.
///
/// WARNING: this will reuse the underlying stream for the archive. Errors may
///
/// WARNING: this will reuse the underlying stream for the archive. Errors may
/// occur if this is used at the same time as other extraction methods on this instance.
/// </summary>
/// <returns></returns>
@@ -176,4 +174,4 @@ namespace SharpCompress.Archives
}
}
}
}
}

View File

@@ -28,12 +28,10 @@ namespace SharpCompress.Archives
{
}
#if !NO_FILE
internal AbstractWritableArchive(ArchiveType type, FileInfo fileInfo, ReaderOptions readerFactoryOptions)
: base(type, fileInfo, readerFactoryOptions)
{
}
#endif
public override ICollection<TEntry> Entries
{
@@ -144,4 +142,4 @@ namespace SharpCompress.Archives
modifiedEntries.Cast<Entry>().ForEach(x => x.Close());
}
}
}
}

View File

@@ -6,7 +6,6 @@ using SharpCompress.Archives.SevenZip;
using SharpCompress.Archives.Tar;
using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using SharpCompress.Compressors.LZMA;
using SharpCompress.Readers;
namespace SharpCompress.Archives
@@ -21,7 +20,7 @@ namespace SharpCompress.Archives
/// <returns></returns>
public static IArchive Open(Stream stream, ReaderOptions readerOptions = null)
{
stream.CheckNotNull("stream");
stream.CheckNotNull(nameof(stream));
if (!stream.CanRead || !stream.CanSeek)
{
throw new ArgumentException("Stream should be readable and seekable");
@@ -82,8 +81,6 @@ namespace SharpCompress.Archives
}
}
#if !NO_FILE
/// <summary>
/// Constructor expects a filepath to an existing file.
/// </summary>
@@ -91,7 +88,7 @@ namespace SharpCompress.Archives
/// <param name="options"></param>
public static IArchive Open(string filePath, ReaderOptions options = null)
{
filePath.CheckNotNullOrEmpty("filePath");
filePath.CheckNotNullOrEmpty(nameof(filePath));
return Open(new FileInfo(filePath), options);
}
@@ -102,7 +99,7 @@ namespace SharpCompress.Archives
/// <param name="options"></param>
public static IArchive Open(FileInfo fileInfo, ReaderOptions options = null)
{
fileInfo.CheckNotNull("fileInfo");
fileInfo.CheckNotNull(nameof(fileInfo));
options = options ?? new ReaderOptions { LeaveStreamOpen = false };
using (var stream = fileInfo.OpenRead())
{
@@ -148,6 +145,5 @@ namespace SharpCompress.Archives
}
}
}
#endif
}
}
}

View File

@@ -13,8 +13,6 @@ namespace SharpCompress.Archives.GZip
{
public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
{
#if !NO_FILE
/// <summary>
/// Constructor expects a filepath to an existing file.
/// </summary>
@@ -22,7 +20,7 @@ namespace SharpCompress.Archives.GZip
/// <param name="readerOptions"></param>
public static GZipArchive Open(string filePath, ReaderOptions readerOptions = null)
{
filePath.CheckNotNullOrEmpty("filePath");
filePath.CheckNotNullOrEmpty(nameof(filePath));
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
}
@@ -33,10 +31,9 @@ namespace SharpCompress.Archives.GZip
/// <param name="readerOptions"></param>
public static GZipArchive Open(FileInfo fileInfo, ReaderOptions readerOptions = null)
{
fileInfo.CheckNotNull("fileInfo");
fileInfo.CheckNotNull(nameof(fileInfo));
return new GZipArchive(fileInfo, readerOptions ?? new ReaderOptions());
}
#endif
/// <summary>
/// Takes a seekable Stream as a source
@@ -45,7 +42,7 @@ namespace SharpCompress.Archives.GZip
/// <param name="readerOptions"></param>
public static GZipArchive Open(Stream stream, ReaderOptions readerOptions = null)
{
stream.CheckNotNull("stream");
stream.CheckNotNull(nameof(stream));
return new GZipArchive(stream, readerOptions ?? new ReaderOptions());
}
@@ -54,8 +51,6 @@ namespace SharpCompress.Archives.GZip
return new GZipArchive();
}
#if !NO_FILE
/// <summary>
/// Constructor with a FileInfo object to an existing file.
/// </summary>
@@ -100,7 +95,6 @@ namespace SharpCompress.Archives.GZip
SaveTo(stream, new WriterOptions(CompressionType.GZip));
}
}
#endif
public static bool IsGZipFile(Stream stream)
{
@@ -185,4 +179,4 @@ namespace SharpCompress.Archives.GZip
return GZipReader.Open(stream);
}
}
}
}

View File

@@ -36,12 +36,10 @@ namespace SharpCompress.Archives
}
streamListener.FireEntryExtractionEnd(archiveEntry);
}
#if !NO_FILE
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteToDirectory(this IArchiveEntry entry, string destinationDirectory,
ExtractionOptions options = null)
{
@@ -65,6 +63,5 @@ namespace SharpCompress.Archives
}
});
}
#endif
}
}

View File

@@ -1,18 +1,13 @@
#if !NO_FILE
using System.Linq;
using System.Linq;
using SharpCompress.Common;
#endif
namespace SharpCompress.Archives
{
public static class IArchiveExtensions
{
#if !NO_FILE
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteToDirectory(this IArchive archive, string destinationDirectory,
ExtractionOptions options = null)
{
@@ -21,6 +16,5 @@ namespace SharpCompress.Archives
entry.WriteToDirectory(destinationDirectory, options);
}
}
#endif
}
}

View File

@@ -1,6 +1,4 @@
#if !NO_FILE
using System;
#endif
using System;
using System.IO;
using SharpCompress.Writers;
@@ -8,8 +6,6 @@ namespace SharpCompress.Archives
{
public static class IWritableArchiveExtensions
{
#if !NO_FILE
public static void AddEntry(this IWritableArchive writableArchive,
string entryPath, string filePath)
{
@@ -39,11 +35,7 @@ namespace SharpCompress.Archives
this IWritableArchive writableArchive,
string filePath, string searchPattern = "*.*", SearchOption searchOption = SearchOption.AllDirectories)
{
#if NET35
foreach (var path in Directory.GetFiles(filePath, searchPattern, searchOption))
#else
foreach (var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption))
#endif
{
var fileInfo = new FileInfo(path);
writableArchive.AddEntry(path.Substring(filePath.Length), fileInfo.OpenRead(), true, fileInfo.Length,
@@ -58,6 +50,5 @@ namespace SharpCompress.Archives
}
return writableArchive.AddEntry(key, fileInfo.OpenRead(), true, fileInfo.Length, fileInfo.LastWriteTime);
}
#endif
}
}

View File

@@ -1,7 +1,6 @@
#if !NO_FILE
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SharpCompress.Common.Rar;
using SharpCompress.Common.Rar.Headers;
using SharpCompress.IO;
@@ -18,7 +17,7 @@ namespace SharpCompress.Archives.Rar
: base(StreamingMode.Seekable, fileInfo.OpenRead(), FixOptions(options))
{
FileInfo = fileInfo;
FileParts = GetVolumeFileParts().ToReadOnly();
FileParts = GetVolumeFileParts().ToArray().ToReadOnly();
}
private static ReaderOptions FixOptions(ReaderOptions options)
@@ -43,4 +42,3 @@ namespace SharpCompress.Archives.Rar
}
}
}
#endif

View File

@@ -1,6 +1,4 @@
#if !NO_FILE
using System.IO;
using System.IO;
using SharpCompress.Common.Rar.Headers;
namespace SharpCompress.Archives.Rar
@@ -25,4 +23,3 @@ namespace SharpCompress.Archives.Rar
}
}
}
#endif

View File

@@ -15,8 +15,6 @@ namespace SharpCompress.Archives.Rar
internal Lazy<IRarUnpack> UnpackV2017 { get; } = new Lazy<IRarUnpack>(() => new SharpCompress.Compressors.Rar.UnpackV2017.Unpack());
internal Lazy<IRarUnpack> UnpackV1 { get; } = new Lazy<IRarUnpack>(() => new SharpCompress.Compressors.Rar.UnpackV1.Unpack());
#if !NO_FILE
/// <summary>
/// Constructor with a FileInfo object to an existing file.
/// </summary>
@@ -31,7 +29,6 @@ namespace SharpCompress.Archives.Rar
{
return RarArchiveVolumeFactory.GetParts(file, ReaderOptions);
}
#endif
/// <summary>
/// Takes multiple seekable Streams for a multi-part archive
@@ -63,9 +60,6 @@ namespace SharpCompress.Archives.Rar
public override bool IsSolid => Volumes.First().IsSolidArchive;
#region Creation
#if !NO_FILE
/// <summary>
/// Constructor with a FileInfo object to an existing file.
/// </summary>
@@ -73,7 +67,7 @@ namespace SharpCompress.Archives.Rar
/// <param name="options"></param>
public static RarArchive Open(string filePath, ReaderOptions options = null)
{
filePath.CheckNotNullOrEmpty("filePath");
filePath.CheckNotNullOrEmpty(nameof(filePath));
return new RarArchive(new FileInfo(filePath), options ?? new ReaderOptions());
}
@@ -84,10 +78,9 @@ namespace SharpCompress.Archives.Rar
/// <param name="options"></param>
public static RarArchive Open(FileInfo fileInfo, ReaderOptions options = null)
{
fileInfo.CheckNotNull("fileInfo");
fileInfo.CheckNotNull(nameof(fileInfo));
return new RarArchive(fileInfo, options ?? new ReaderOptions());
}
#endif
/// <summary>
/// Takes a seekable Stream as a source
@@ -96,7 +89,7 @@ namespace SharpCompress.Archives.Rar
/// <param name="options"></param>
public static RarArchive Open(Stream stream, ReaderOptions options = null)
{
stream.CheckNotNull("stream");
stream.CheckNotNull(nameof(stream));
return Open(stream.AsEnumerable(), options ?? new ReaderOptions());
}
@@ -107,11 +100,10 @@ namespace SharpCompress.Archives.Rar
/// <param name="options"></param>
public static RarArchive Open(IEnumerable<Stream> streams, ReaderOptions options = null)
{
streams.CheckNotNull("streams");
streams.CheckNotNull(nameof(streams));
return new RarArchive(streams, options ?? new ReaderOptions());
}
#if !NO_FILE
public static bool IsRarFile(string filePath)
{
return IsRarFile(new FileInfo(filePath));
@@ -128,7 +120,6 @@ namespace SharpCompress.Archives.Rar
return IsRarFile(stream);
}
}
#endif
public static bool IsRarFile(Stream stream, ReaderOptions options = null)
{
@@ -145,4 +136,4 @@ namespace SharpCompress.Archives.Rar
#endregion
}
}
}

View File

@@ -3,11 +3,9 @@ using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Rar;
using SharpCompress.Readers;
#if !NO_FILE
using System.Linq;
using System.Text;
using SharpCompress.Common.Rar.Headers;
#endif
namespace SharpCompress.Archives.Rar
{
@@ -25,8 +23,7 @@ namespace SharpCompress.Archives.Rar
yield return part;
}
}
#if !NO_FILE
internal static IEnumerable<RarVolume> GetParts(FileInfo fileInfo, ReaderOptions options)
{
FileInfoRarArchiveVolume part = new FileInfoRarArchiveVolume(fileInfo, options);
@@ -141,7 +138,5 @@ namespace SharpCompress.Archives.Rar
throw new ArgumentException("Filename invalid or next archive could not be found:"
+ fileInfo.FullName);
}
#endif
}
}

View File

@@ -19,12 +19,10 @@ namespace SharpCompress.Archives.Rar
internal override Stream GetCompressedStream()
{
stream.Position = FileHeader.DataStartPosition;
#if !NO_CRYPTO
if (FileHeader.R4Salt != null)
{
return new RarCryptoWrapper(stream, password, FileHeader.R4Salt);
}
#endif
return stream;
}

View File

@@ -13,8 +13,6 @@ namespace SharpCompress.Archives.SevenZip
public class SevenZipArchive : AbstractArchive<SevenZipArchiveEntry, SevenZipVolume>
{
private ArchiveDatabase database;
#if !NO_FILE
/// <summary>
/// Constructor expects a filepath to an existing file.
/// </summary>
@@ -36,7 +34,6 @@ namespace SharpCompress.Archives.SevenZip
fileInfo.CheckNotNull("fileInfo");
return new SevenZipArchive(fileInfo, readerOptions ?? new ReaderOptions());
}
#endif
/// <summary>
/// Takes a seekable Stream as a source
/// </summary>
@@ -48,7 +45,6 @@ namespace SharpCompress.Archives.SevenZip
return new SevenZipArchive(stream, readerOptions ?? new ReaderOptions());
}
#if !NO_FILE
internal SevenZipArchive(FileInfo fileInfo, ReaderOptions readerOptions)
: base(ArchiveType.SevenZip, fileInfo, readerOptions)
{
@@ -75,7 +71,6 @@ namespace SharpCompress.Archives.SevenZip
return IsSevenZipFile(stream);
}
}
#endif
internal SevenZipArchive(Stream stream, ReaderOptions readerOptions)
: base(ArchiveType.SevenZip, stream.AsEnumerable(), readerOptions)
@@ -134,13 +129,13 @@ namespace SharpCompress.Archives.SevenZip
}
}
private static readonly byte[] SIGNATURE = {(byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C};
private static ReadOnlySpan<byte> SIGNATURE => new byte[] {(byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C};
private static bool SignatureMatch(Stream stream)
{
BinaryReader reader = new BinaryReader(stream);
byte[] signatureBytes = reader.ReadBytes(6);
return signatureBytes.BinaryEquals(SIGNATURE);
ReadOnlySpan<byte> signatureBytes = reader.ReadBytes(6);
return signatureBytes.SequenceEqual(SIGNATURE);
}
protected override IReader CreateReaderForSolidExtraction()
@@ -206,7 +201,7 @@ namespace SharpCompress.Archives.SevenZip
return CreateEntryStream(new ReadOnlySubStream(currentStream, currentItem.Size));
}
}
private class PasswordProvider : IPasswordProvider
{
private readonly string _password;
@@ -214,7 +209,6 @@ namespace SharpCompress.Archives.SevenZip
public PasswordProvider(string password)
{
_password = password;
}
public string CryptoGetTextPassword()

View File

@@ -15,8 +15,6 @@ namespace SharpCompress.Archives.Tar
{
public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
{
#if !NO_FILE
/// <summary>
/// Constructor expects a filepath to an existing file.
/// </summary>
@@ -24,7 +22,7 @@ namespace SharpCompress.Archives.Tar
/// <param name="readerOptions"></param>
public static TarArchive Open(string filePath, ReaderOptions readerOptions = null)
{
filePath.CheckNotNullOrEmpty("filePath");
filePath.CheckNotNullOrEmpty(nameof(filePath));
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
}
@@ -35,10 +33,9 @@ namespace SharpCompress.Archives.Tar
/// <param name="readerOptions"></param>
public static TarArchive Open(FileInfo fileInfo, ReaderOptions readerOptions = null)
{
fileInfo.CheckNotNull("fileInfo");
fileInfo.CheckNotNull(nameof(fileInfo));
return new TarArchive(fileInfo, readerOptions ?? new ReaderOptions());
}
#endif
/// <summary>
/// Takes a seekable Stream as a source
@@ -47,12 +44,10 @@ namespace SharpCompress.Archives.Tar
/// <param name="readerOptions"></param>
public static TarArchive Open(Stream stream, ReaderOptions readerOptions = null)
{
stream.CheckNotNull("stream");
stream.CheckNotNull(nameof(stream));
return new TarArchive(stream, readerOptions ?? new ReaderOptions());
}
#if !NO_FILE
public static bool IsTarFile(string filePath)
{
return IsTarFile(new FileInfo(filePath));
@@ -69,7 +64,6 @@ namespace SharpCompress.Archives.Tar
return IsTarFile(stream);
}
}
#endif
public static bool IsTarFile(Stream stream)
{
@@ -85,9 +79,7 @@ namespace SharpCompress.Archives.Tar
}
return false;
}
#if !NO_FILE
/// <summary>
/// Constructor with a FileInfo object to an existing file.
/// </summary>
@@ -102,7 +94,6 @@ namespace SharpCompress.Archives.Tar
{
return new TarVolume(file.OpenRead(), ReaderOptions).AsEnumerable();
}
#endif
/// <summary>
/// Takes multiple seekable Streams for a multi-part archive
@@ -203,4 +194,4 @@ namespace SharpCompress.Archives.Tar
return TarReader.Open(stream);
}
}
}
}

View File

@@ -22,9 +22,7 @@ namespace SharpCompress.Archives.Zip
/// if the compression method is set to deflate
/// </summary>
public CompressionLevel DeflateCompressionLevel { get; set; }
#if !NO_FILE
/// <summary>
/// Constructor expects a filepath to an existing file.
/// </summary>
@@ -32,7 +30,7 @@ namespace SharpCompress.Archives.Zip
/// <param name="readerOptions"></param>
public static ZipArchive Open(string filePath, ReaderOptions readerOptions = null)
{
filePath.CheckNotNullOrEmpty("filePath");
filePath.CheckNotNullOrEmpty(nameof(filePath));
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
}
@@ -43,10 +41,9 @@ namespace SharpCompress.Archives.Zip
/// <param name="readerOptions"></param>
public static ZipArchive Open(FileInfo fileInfo, ReaderOptions readerOptions = null)
{
fileInfo.CheckNotNull("fileInfo");
fileInfo.CheckNotNull(nameof(fileInfo));
return new ZipArchive(fileInfo, readerOptions ?? new ReaderOptions());
}
#endif
/// <summary>
/// Takes a seekable Stream as a source
@@ -55,12 +52,10 @@ namespace SharpCompress.Archives.Zip
/// <param name="readerOptions"></param>
public static ZipArchive Open(Stream stream, ReaderOptions readerOptions = null)
{
stream.CheckNotNull("stream");
stream.CheckNotNull(nameof(stream));
return new ZipArchive(stream, readerOptions ?? new ReaderOptions());
}
#if !NO_FILE
public static bool IsZipFile(string filePath, string password = null)
{
return IsZipFile(new FileInfo(filePath), password);
@@ -77,7 +72,6 @@ namespace SharpCompress.Archives.Zip
return IsZipFile(stream, password);
}
}
#endif
public static bool IsZipFile(Stream stream, string password = null)
{
@@ -101,9 +95,7 @@ namespace SharpCompress.Archives.Zip
return false;
}
}
#if !NO_FILE
/// <summary>
/// Constructor with a FileInfo object to an existing file.
/// </summary>
@@ -119,7 +111,6 @@ namespace SharpCompress.Archives.Zip
{
return new ZipVolume(file.OpenRead(), ReaderOptions).AsEnumerable();
}
#endif
internal ZipArchive()
: base(ArchiveType.Zip)
@@ -211,4 +202,4 @@ namespace SharpCompress.Archives.Zip
return ZipReader.Open(stream, ReaderOptions);
}
}
}
}

View File

@@ -5,7 +5,6 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("SharpCompress")]
[assembly: AssemblyProduct("SharpCompress")]
[assembly: InternalsVisibleTo("SharpCompress.Test" + SharpCompress.AssemblyInfo.PublicKeySuffix)]
[assembly: InternalsVisibleTo("SharpCompress.Test.Portable" + SharpCompress.AssemblyInfo.PublicKeySuffix)]
[assembly: CLSCompliant(true)]
namespace SharpCompress

View File

@@ -1,119 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System.Runtime.CompilerServices;
using System.Threading;
namespace SharpCompress.Buffers
{
/// <summary>
/// Provides a resource pool that enables reusing instances of type <see cref="T:T[]"/>.
/// </summary>
/// <remarks>
/// <para>
/// Renting and returning buffers with an <see cref="ArrayPool{T}"/> can increase performance
/// in situations where arrays are created and destroyed frequently, resulting in significant
/// memory pressure on the garbage collector.
/// </para>
/// <para>
/// This class is thread-safe. All members may be used by multiple threads concurrently.
/// </para>
/// </remarks>
internal abstract class ArrayPool<T>
{
/// <summary>The lazily-initialized shared pool instance.</summary>
private static ArrayPool<T> s_sharedInstance = null;
/// <summary>
/// Retrieves a shared <see cref="ArrayPool{T}"/> instance.
/// </summary>
/// <remarks>
/// The shared pool provides a default implementation of <see cref="ArrayPool{T}"/>
/// that's intended for general applicability. It maintains arrays of multiple sizes, and
/// may hand back a larger array than was actually requested, but will never hand back a smaller
/// array than was requested. Renting a buffer from it with <see cref="Rent"/> will result in an
/// existing buffer being taken from the pool if an appropriate buffer is available or in a new
/// buffer being allocated if one is not available.
/// </remarks>
public static ArrayPool<T> Shared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated(); }
}
/// <summary>Ensures that <see cref="s_sharedInstance"/> has been initialized to a pool and returns it.</summary>
[MethodImpl(MethodImplOptions.NoInlining)]
private static ArrayPool<T> EnsureSharedCreated()
{
Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
return s_sharedInstance;
}
/// <summary>
/// Creates a new <see cref="ArrayPool{T}"/> instance using default configuration options.
/// </summary>
/// <returns>A new <see cref="ArrayPool{T}"/> instance.</returns>
public static ArrayPool<T> Create()
{
return new DefaultArrayPool<T>();
}
/// <summary>
/// Creates a new <see cref="ArrayPool{T}"/> instance using custom configuration options.
/// </summary>
/// <param name="maxArrayLength">The maximum length of array instances that may be stored in the pool.</param>
/// <param name="maxArraysPerBucket">
/// The maximum number of array instances that may be stored in each bucket in the pool. The pool
/// groups arrays of similar lengths into buckets for faster access.
/// </param>
/// <returns>A new <see cref="ArrayPool{T}"/> instance with the specified configuration options.</returns>
/// <remarks>
/// The created pool will group arrays into buckets, with no more than <paramref name="maxArraysPerBucket"/>
/// in each bucket and with those arrays not exceeding <paramref name="maxArrayLength"/> in length.
/// </remarks>
public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
{
return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
}
/// <summary>
/// Retrieves a buffer that is at least the requested length.
/// </summary>
/// <param name="minimumLength">The minimum length of the array needed.</param>
/// <returns>
/// An <see cref="T:T[]"/> that is at least <paramref name="minimumLength"/> in length.
/// </returns>
/// <remarks>
/// This buffer is loaned to the caller and should be returned to the same pool via
/// <see cref="Return"/> so that it may be reused in subsequent usage of <see cref="Rent"/>.
/// It is not a fatal error to not return a rented buffer, but failure to do so may lead to
/// decreased application performance, as the pool may need to create a new buffer to replace
/// the one lost.
/// </remarks>
public abstract T[] Rent(int minimumLength);
/// <summary>
/// Returns to the pool an array that was previously obtained via <see cref="Rent"/> on the same
/// <see cref="ArrayPool{T}"/> instance.
/// </summary>
/// <param name="array">
/// The buffer previously obtained from <see cref="Rent"/> to return to the pool.
/// </param>
/// <param name="clearArray">
/// If <c>true</c> and if the pool will store the buffer to enable subsequent reuse, <see cref="Return"/>
/// will clear <paramref name="array"/> of its contents so that a subsequent consumer via <see cref="Rent"/>
/// will not see the previous consumer's content. If <c>false</c> or if the pool will release the buffer,
/// the array's contents are left unchanged.
/// </param>
/// <remarks>
/// Once a buffer has been returned to the pool, the caller gives up all ownership of the buffer
/// and must not use it. The reference returned from a given call to <see cref="Rent"/> must only be
/// returned via <see cref="Return"/> once. The default <see cref="ArrayPool{T}"/>
/// may hold onto the returned buffer in order to rent it again, or it may release the returned buffer
/// if it's determined that the pool already has enough buffers stored.
/// </remarks>
public abstract void Return(T[] array, bool clearArray = false);
}
}
#endif

View File

@@ -1,144 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System;
namespace SharpCompress.Buffers
{
internal sealed partial class DefaultArrayPool<T> : ArrayPool<T>
{
/// <summary>The default maximum length of each array in the pool (2^20).</summary>
private const int DefaultMaxArrayLength = 1024 * 1024;
/// <summary>The default maximum number of arrays per bucket that are available for rent.</summary>
private const int DefaultMaxNumberOfArraysPerBucket = 50;
/// <summary>Lazily-allocated empty array used when arrays of length 0 are requested.</summary>
private static T[] s_emptyArray; // we support contracts earlier than those with Array.Empty<T>()
private readonly Bucket[] _buckets;
internal DefaultArrayPool() : this(DefaultMaxArrayLength, DefaultMaxNumberOfArraysPerBucket)
{
}
internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
{
if (maxArrayLength <= 0)
{
throw new ArgumentOutOfRangeException(nameof(maxArrayLength));
}
if (maxArraysPerBucket <= 0)
{
throw new ArgumentOutOfRangeException(nameof(maxArraysPerBucket));
}
// Our bucketing algorithm has a min length of 2^4 and a max length of 2^30.
// Constrain the actual max used to those values.
const int MinimumArrayLength = 0x10, MaximumArrayLength = 0x40000000;
if (maxArrayLength > MaximumArrayLength)
{
maxArrayLength = MaximumArrayLength;
}
else if (maxArrayLength < MinimumArrayLength)
{
maxArrayLength = MinimumArrayLength;
}
// Create the buckets.
int poolId = Id;
int maxBuckets = Utilities.SelectBucketIndex(maxArrayLength);
var buckets = new Bucket[maxBuckets + 1];
for (int i = 0; i < buckets.Length; i++)
{
buckets[i] = new Bucket(Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, poolId);
}
_buckets = buckets;
}
/// <summary>Gets an ID for the pool to use with events.</summary>
private int Id => GetHashCode();
public override T[] Rent(int minimumLength)
{
// Arrays can't be smaller than zero. We allow requesting zero-length arrays (even though
// pooling such an array isn't valuable) as it's a valid length array, and we want the pool
// to be usable in general instead of using `new`, even for computed lengths.
if (minimumLength < 0)
{
throw new ArgumentOutOfRangeException(nameof(minimumLength));
}
else if (minimumLength == 0)
{
// No need for events with the empty array. Our pool is effectively infinite
// and we'll never allocate for rents and never store for returns.
return s_emptyArray ?? (s_emptyArray = new T[0]);
}
T[] buffer = null;
int index = Utilities.SelectBucketIndex(minimumLength);
if (index < _buckets.Length)
{
// Search for an array starting at the 'index' bucket. If the bucket is empty, bump up to the
// next higher bucket and try that one, but only try at most a few buckets.
const int MaxBucketsToTry = 2;
int i = index;
do
{
// Attempt to rent from the bucket. If we get a buffer from it, return it.
buffer = _buckets[i].Rent();
if (buffer != null)
{
return buffer;
}
}
while (++i < _buckets.Length && i != index + MaxBucketsToTry);
// The pool was exhausted for this buffer size. Allocate a new buffer with a size corresponding
// to the appropriate bucket.
buffer = new T[_buckets[index]._bufferLength];
}
else
{
// The request was for a size too large for the pool. Allocate an array of exactly the requested length.
// When it's returned to the pool, we'll simply throw it away.
buffer = new T[minimumLength];
}
return buffer;
}
public override void Return(T[] array, bool clearArray = false)
{
if (array == null)
{
throw new ArgumentNullException(nameof(array));
}
else if (array.Length == 0)
{
// Ignore empty arrays. When a zero-length array is rented, we return a singleton
// rather than actually taking a buffer out of the lowest bucket.
return;
}
// Determine with what bucket this array length is associated
int bucket = Utilities.SelectBucketIndex(array.Length);
// If we can tell that the buffer was allocated, drop it. Otherwise, check if we have space in the pool
if (bucket < _buckets.Length)
{
// Clear the array if the user requests
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
// Return the buffer to its bucket. In the future, we might consider having Return return false
// instead of dropping a bucket, in which case we could try to return to a lower-sized bucket,
// just as how in Rent we allow renting from a higher-sized bucket.
_buckets[bucket].Return(array);
}
}
}
}
#endif

View File

@@ -1,111 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System;
using System.Diagnostics;
using System.Threading;
namespace SharpCompress.Buffers
{
internal sealed partial class DefaultArrayPool<T> : ArrayPool<T>
{
/// <summary>Provides a thread-safe bucket containing buffers that can be Rent'd and Return'd.</summary>
private sealed class Bucket
{
internal readonly int _bufferLength;
private readonly T[][] _buffers;
private readonly int _poolId;
private SpinLock _lock; // do not make this readonly; it's a mutable struct
private int _index;
/// <summary>
/// Creates the pool with numberOfBuffers arrays where each buffer is of bufferLength length.
/// </summary>
internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
{
_lock = new SpinLock(Debugger.IsAttached); // only enable thread tracking if debugger is attached; it adds non-trivial overheads to Enter/Exit
_buffers = new T[numberOfBuffers][];
_bufferLength = bufferLength;
_poolId = poolId;
}
/// <summary>Gets an ID for the bucket to use with events.</summary>
internal int Id => GetHashCode();
/// <summary>Takes an array from the bucket. If the bucket is empty, returns null.</summary>
internal T[] Rent()
{
T[][] buffers = _buffers;
T[] buffer = null;
// While holding the lock, grab whatever is at the next available index and
// update the index. We do as little work as possible while holding the spin
// lock to minimize contention with other threads. The try/finally is
// necessary to properly handle thread aborts on platforms which have them.
bool lockTaken = false, allocateBuffer = false;
try
{
_lock.Enter(ref lockTaken);
if (_index < buffers.Length)
{
buffer = buffers[_index];
buffers[_index++] = null;
allocateBuffer = buffer == null;
}
}
finally
{
if (lockTaken) _lock.Exit(false);
}
// While we were holding the lock, we grabbed whatever was at the next available index, if
// there was one. If we tried and if we got back null, that means we hadn't yet allocated
// for that slot, in which case we should do so now.
if (allocateBuffer)
{
buffer = new T[_bufferLength];
}
return buffer;
}
/// <summary>
/// Attempts to return the buffer to the bucket. If successful, the buffer will be stored
/// in the bucket and true will be returned; otherwise, the buffer won't be stored, and false
/// will be returned.
/// </summary>
internal void Return(T[] array)
{
// Check to see if the buffer is the correct size for this bucket
if (array.Length != _bufferLength)
{
throw new ArgumentException("Buffer not from pool", nameof(array));
}
// While holding the spin lock, if there's room available in the bucket,
// put the buffer into the next available slot. Otherwise, we just drop it.
// The try/finally is necessary to properly handle thread aborts on platforms
// which have them.
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
if (_index != 0)
{
_buffers[--_index] = array;
}
}
finally
{
if (lockTaken) _lock.Exit(false);
}
}
}
}
}
#endif

View File

@@ -1,38 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if NETCORE
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace SharpCompress.Buffers
{
internal static class Utilities
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int SelectBucketIndex(int bufferSize)
{
Debug.Assert(bufferSize > 0);
uint bitsRemaining = ((uint)bufferSize - 1) >> 4;
int poolIndex = 0;
if (bitsRemaining > 0xFFFF) { bitsRemaining >>= 16; poolIndex = 16; }
if (bitsRemaining > 0xFF) { bitsRemaining >>= 8; poolIndex += 8; }
if (bitsRemaining > 0xF) { bitsRemaining >>= 4; poolIndex += 4; }
if (bitsRemaining > 0x3) { bitsRemaining >>= 2; poolIndex += 2; }
if (bitsRemaining > 0x1) { bitsRemaining >>= 1; poolIndex += 1; }
return poolIndex + (int)bitsRemaining;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int GetMaxSizeForBucket(int binIndex)
{
int maxSize = 16 << binIndex;
Debug.Assert(maxSize >= 0);
return maxSize;
}
}
}
#endif

View File

@@ -28,16 +28,11 @@ namespace SharpCompress.Common
public ArchiveEncoding()
{
#if NETSTANDARD1_0
Default = Encoding.GetEncoding("cp437");
Password = Encoding.GetEncoding("cp437");
#else
Default = Encoding.GetEncoding(437);
Password = Encoding.GetEncoding(437);
#endif
}
#if NETSTANDARD1_3 || NETSTANDARD2_0
#if NETSTANDARD1_3 || NETSTANDARD2_0 || NETSTANDARD2_1
static ArchiveEncoding()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@@ -74,4 +69,4 @@ namespace SharpCompress.Common
return CustomDecoder ?? ((bytes, index, count) => GetEncoding().GetString(bytes, index, count));
}
}
}
}

View File

@@ -1,14 +1,10 @@
#if !NO_FILE
using System;
using System;
using System.IO;
#endif
namespace SharpCompress.Common
{
internal static class ExtractionMethods
{
#if !NO_FILE
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
@@ -93,6 +89,5 @@ namespace SharpCompress.Common
entry.PreserveExtractionOptions(destinationFileName, options);
}
}
#endif
}
}

View File

@@ -1,4 +1,6 @@
namespace SharpCompress.Common
using System;
namespace SharpCompress.Common
{
public class ExtractionOptions
{
@@ -29,6 +31,10 @@
/// </summary>
public delegate void SymbolicLinkWriterDelegate(string sourcePath, string targetPath);
public SymbolicLinkWriterDelegate WriteSymbolicLink;
public SymbolicLinkWriterDelegate WriteSymbolicLink =
(sourcePath, targetPath) =>
{
Console.WriteLine($"Could not write symlink {sourcePath} -> {targetPath}, for more information please see https://github.com/dotnet/runtime/issues/24271");
};
}
}

View File

@@ -10,11 +10,11 @@ namespace SharpCompress.Common
}
internal ArchiveEncoding ArchiveEncoding { get; }
internal abstract string FilePartName { get; }
internal abstract Stream GetCompressedStream();
internal abstract Stream GetRawStream();
internal bool Skipped { get; set; }
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace SharpCompress.Common.GZip
{

View File

@@ -1,11 +1,10 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Tar.Headers;
using SharpCompress.Compressors;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Converters;
using System.Text;
namespace SharpCompress.Common.GZip
{
@@ -60,7 +59,7 @@ namespace SharpCompress.Common.GZip
throw new ZlibException("Bad GZIP header.");
}
Int32 timet = DataConverter.LittleEndian.GetInt32(header, 4);
int timet = BinaryPrimitives.ReadInt32LittleEndian(header.AsSpan(4));
DateModified = TarHeader.EPOCH.AddSeconds(timet);
if ((header[3] & 0x04) == 0x04)
{
@@ -69,7 +68,7 @@ namespace SharpCompress.Common.GZip
Int16 extraLength = (Int16)(header[0] + header[1] * 256);
byte[] extra = new byte[extraLength];
if (!stream.ReadFully(extra))
{
throw new ZlibException("Unexpected end-of-file reading GZIP header.");
@@ -117,4 +116,4 @@ namespace SharpCompress.Common.GZip
return ArchiveEncoding.Decode(buffer);
}
}
}
}

View File

@@ -10,13 +10,11 @@ namespace SharpCompress.Common.GZip
{
}
#if !NO_FILE
public GZipVolume(FileInfo fileInfo, ReaderOptions options)
: base(fileInfo.OpenRead(), options)
{
options.LeaveStreamOpen = false;
}
#endif
public override bool IsFirstVolume => true;

View File

@@ -1,7 +1,4 @@
#if !NO_FILE
using System.IO;
using SharpCompress.Readers;
using System.IO;
namespace SharpCompress.Common
{
@@ -48,4 +45,3 @@ namespace SharpCompress.Common
}
}
}
#endif

View File

@@ -1,9 +1,5 @@
using System;
#if !NO_FILE
using System.IO;
#endif
namespace SharpCompress.Common
{
public interface IVolume : IDisposable

View File

@@ -7,8 +7,10 @@ namespace SharpCompress.Common.Rar.Headers
public AvHeader(RarHeader header, RarCrcBinaryReader reader)
: base(header, reader, HeaderType.Av)
{
if (IsRar5)
if (IsRar5)
{
throw new InvalidFormatException("unexpected rar5 record");
}
}
protected override void ReadFinish(MarkingBinaryReader reader)

View File

@@ -38,7 +38,11 @@ namespace SharpCompress.Common.Rar.Headers
private void ReadLocator(MarkingBinaryReader reader) {
var size = reader.ReadRarVIntUInt16();
var type = reader.ReadRarVIntUInt16();
if (type != 1) throw new InvalidFormatException("expected locator record");
if (type != 1)
{
throw new InvalidFormatException("expected locator record");
}
var flags = reader.ReadRarVIntUInt16();
const ushort hasQuickOpenOffset = 0x01;
const ushort hasRecoveryOffset = 0x02;

View File

@@ -7,7 +7,10 @@ namespace SharpCompress.Common.Rar.Headers
protected CommentHeader(RarHeader header, RarCrcBinaryReader reader)
: base(header, reader, HeaderType.Comment)
{
if (IsRar5) throw new InvalidFormatException("unexpected rar5 record");
if (IsRar5)
{
throw new InvalidFormatException("unexpected rar5 record");
}
}
protected override void ReadFinish(MarkingBinaryReader reader)

View File

@@ -195,17 +195,12 @@ namespace SharpCompress.Common.Rar.Headers
private static string ConvertPathV5(string path)
{
#if NO_FILE
// not sure what to do here
throw new NotImplementedException("TODO");
#else
if (Path.DirectorySeparatorChar == '\\')
{
// replace embedded \\ with valid filename char
return path.Replace('\\', '-').Replace('/', '\\');
}
return path;
#endif
}
@@ -361,9 +356,6 @@ namespace SharpCompress.Common.Rar.Headers
private static string ConvertPathV4(string path)
{
#if NO_FILE
return path.Replace('\\', '/');
#else
if (Path.DirectorySeparatorChar == '/')
{
return path.Replace('\\', '/');
@@ -373,7 +365,6 @@ namespace SharpCompress.Common.Rar.Headers
return path.Replace('/', '\\');
}
return path;
#endif
}
public override string ToString()

View File

@@ -46,19 +46,38 @@ namespace SharpCompress.Common.Rar.Headers
if (b == 0x61)
{
b = GetByte(stream); start++;
if (b != 0x72) continue;
if (b != 0x72)
{
continue;
}
b = GetByte(stream); start++;
if (b != 0x21) continue;
if (b != 0x21)
{
continue;
}
b = GetByte(stream); start++;
if (b != 0x1a) continue;
if (b != 0x1a)
{
continue;
}
b = GetByte(stream); start++;
if (b != 0x07) continue;
if (b != 0x07)
{
continue;
}
b = GetByte(stream); start++;
if (b == 1)
{
b = GetByte(stream); start++;
if (b != 0) continue;
if (b != 0)
{
continue;
}
return new MarkHeader(true); // Rar5
}
else if (b == 0)
@@ -69,9 +88,17 @@ namespace SharpCompress.Common.Rar.Headers
else if (b == 0x45)
{
b = GetByte(stream); start++;
if (b != 0x7e) continue;
if (b != 0x7e)
{
continue;
}
b = GetByte(stream); start++;
if (b != 0x5e) continue;
if (b != 0x5e)
{
continue;
}
throw new InvalidFormatException("Rar format version pre-4 is unsupported.");
}
}

View File

@@ -8,7 +8,10 @@ namespace SharpCompress.Common.Rar.Headers
public ProtectHeader(RarHeader header, RarCrcBinaryReader reader)
: base(header, reader, HeaderType.Protect)
{
if (IsRar5) throw new InvalidFormatException("unexpected rar5 record");
if (IsRar5)
{
throw new InvalidFormatException("unexpected rar5 record");
}
}
protected override void ReadFinish(MarkingBinaryReader reader)

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using SharpCompress.IO;
@@ -48,15 +47,11 @@ namespace SharpCompress.Common.Rar.Headers
}
else
{
#if !NO_CRYPTO
if (Options.Password == null)
{
throw new CryptographicException("Encrypted Rar archive has no password specified.");
}
reader = new RarCryptoBinaryReader(stream, Options.Password);
#else
throw new CryptographicException("Rar encryption unsupported on this platform");
#endif
}
var header = RarHeader.TryReadBase(reader, _isRar5, Options.ArchiveEncoding);
@@ -138,11 +133,7 @@ namespace SharpCompress.Common.Rar.Headers
}
else
{
#if !NO_CRYPTO
fh.PackedStream = new RarCryptoWrapper(ms, Options.Password, fh.R4Salt);
#else
throw new NotSupportedException("RarCrypto not supported");
#endif
}
}
break;

View File

@@ -7,7 +7,10 @@ namespace SharpCompress.Common.Rar.Headers
protected SignHeader(RarHeader header, RarCrcBinaryReader reader)
: base(header, reader, HeaderType.Sign)
{
if (IsRar5) throw new InvalidFormatException("unexpected rar5 record");
if (IsRar5)
{
throw new InvalidFormatException("unexpected rar5 record");
}
}
protected override void ReadFinish(MarkingBinaryReader reader)

View File

@@ -1,5 +1,4 @@
#if !NO_CRYPTO
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
namespace SharpCompress.Common.Rar
@@ -82,7 +81,9 @@ namespace SharpCompress.Common.Rar
byte[] cipherText = ReadBytesNoCrc(16);
var readBytes = _rijndael.ProcessBlock(cipherText);
foreach (var readByte in readBytes)
{
_data.Enqueue(readByte);
}
}
}
@@ -111,5 +112,4 @@ namespace SharpCompress.Common.Rar
ClearQueue();
}
}
}
#endif
}

View File

@@ -1,5 +1,3 @@
#if !NO_CRYPTO
using System;
using System.Collections.Generic;
using System.IO;
@@ -52,20 +50,23 @@ namespace SharpCompress.Common.Rar
if (sizeToRead > 0)
{
int alignedSize = sizeToRead + ((~sizeToRead + 1) & 0xf);
byte[] cipherText = new byte[RarRijndael.CRYPTO_BLOCK_SIZE];
for (int i = 0; i < alignedSize / 16; i++)
{
//long ax = System.currentTimeMillis();
byte[] cipherText = new byte[RarRijndael.CRYPTO_BLOCK_SIZE];
_actualStream.Read(cipherText, 0, RarRijndael.CRYPTO_BLOCK_SIZE);
var readBytes = _rijndael.ProcessBlock(cipherText);
foreach (var readByte in readBytes)
{
_data.Enqueue(readByte);
}
}
for (int i = 0; i < count; i++)
{
buffer[offset + i] = _data.Dequeue();
}
}
return count;
}
@@ -96,4 +97,3 @@ namespace SharpCompress.Common.Rar
}
}
}
#endif

View File

@@ -1,7 +1,4 @@
#if !NO_CRYPTO
using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Security.Cryptography;
using System.Text;
using SharpCompress.Crypto;
@@ -23,12 +20,6 @@ namespace SharpCompress.Common.Rar
_salt = salt;
}
private byte[] ComputeHash(byte[] input)
{
var sha = SHA1.Create();
return sha.ComputeHash(input);
}
private void Initialize()
{
@@ -47,28 +38,27 @@ namespace SharpCompress.Common.Rar
rawPassword[i + rawLength] = _salt[i];
}
const int noOfRounds = (1 << 18);
IList<byte> bytes = new List<byte>();
const int iblock = 3;
byte[] digest;
byte[] data = new byte[(rawPassword.Length + iblock) * noOfRounds];
//TODO slow code below, find ways to optimize
for (int i = 0; i < noOfRounds; i++)
{
bytes.AddRange(rawPassword);
rawPassword.CopyTo(data, i * (rawPassword.Length + iblock));
bytes.AddRange(new[]
data[i * (rawPassword.Length + iblock) + rawPassword.Length + 0] = (byte)i;
data[i * (rawPassword.Length + iblock) + rawPassword.Length + 1] = (byte)(i >> 8);
data[i * (rawPassword.Length + iblock) + rawPassword.Length + 2] = (byte)(i >> CRYPTO_BLOCK_SIZE);
if (i % (noOfRounds / CRYPTO_BLOCK_SIZE) == 0)
{
(byte) i, (byte) (i >> 8), (byte) (i >> CRYPTO_BLOCK_SIZE)
});
if (i%(noOfRounds/CRYPTO_BLOCK_SIZE) == 0)
{
digest = ComputeHash(bytes.ToArray());
_aesInitializationVector[i/(noOfRounds/CRYPTO_BLOCK_SIZE)] = digest[19];
digest = SHA1.Create().ComputeHash(data, 0, (i + 1) * (rawPassword.Length + iblock));
_aesInitializationVector[i / (noOfRounds / CRYPTO_BLOCK_SIZE)] = digest[19];
}
}
digest = ComputeHash(bytes.ToArray());
digest = SHA1.Create().ComputeHash(data);
//slow code ends
byte[] aesKey = new byte[CRYPTO_BLOCK_SIZE];
@@ -98,19 +88,20 @@ namespace SharpCompress.Common.Rar
public byte[] ProcessBlock(byte[] cipherText)
{
var plainText = new byte[CRYPTO_BLOCK_SIZE];
var decryptedBytes = new List<byte>();
byte[] decryptedBytes = new byte[CRYPTO_BLOCK_SIZE];
_rijndael.ProcessBlock(cipherText, 0, plainText, 0);
for (int j = 0; j < plainText.Length; j++)
for (int j = 0; j < CRYPTO_BLOCK_SIZE; j++)
{
decryptedBytes.Add((byte) (plainText[j] ^ _aesInitializationVector[j%16])); //32:114, 33:101
decryptedBytes[j] = (byte)(plainText[j] ^ _aesInitializationVector[j % 16]); //32:114, 33:101
}
for (int j = 0; j < _aesInitializationVector.Length; j++)
{
_aesInitializationVector[j] = cipherText[j];
}
return decryptedBytes.ToArray();
return decryptedBytes;
}
public void Dispose()
@@ -118,4 +109,3 @@ namespace SharpCompress.Common.Rar
}
}
}
#endif

View File

@@ -22,7 +22,7 @@ namespace SharpCompress.Common.SevenZip
internal List<long> _packStreamStartPositions = new List<long>();
internal List<int> _folderStartFileIndex = new List<int>();
internal List<int> _fileIndexToFolderIndexMap = new List<int>();
internal IPasswordProvider PasswordProvider { get; }
public ArchiveDatabase(IPasswordProvider passwordProvider)
@@ -152,13 +152,14 @@ namespace SharpCompress.Common.SevenZip
{
int packStreamIndex = folder._firstPackStreamId;
long folderStartPackPos = GetFolderStreamPos(folder, 0);
List<long> packSizes = new List<long>();
for (int j = 0; j < folder._packStreams.Count; j++)
int count = folder._packStreams.Count;
long[] packSizes = new long[count];
for (int j = 0; j < count; j++)
{
packSizes.Add(_packSizes[packStreamIndex + j]);
packSizes[j] = _packSizes[packStreamIndex + j];
}
return DecoderStreamHelper.CreateDecoderStream(stream, folderStartPackPos, packSizes.ToArray(), folder, pw);
return DecoderStreamHelper.CreateDecoderStream(stream, folderStartPackPos, packSizes, folder, pw);
}
private long GetFolderPackStreamSize(int folderIndex, int streamIndex)
@@ -179,4 +180,4 @@ namespace SharpCompress.Common.SevenZip
return 0;
}
}
}
}

View File

@@ -1449,13 +1449,14 @@ namespace SharpCompress.Common.SevenZip
CFolder folderInfo = db._folders[folderIndex];
int packStreamIndex = db._folders[folderIndex]._firstPackStreamId;
long folderStartPackPos = db.GetFolderStreamPos(folderInfo, 0);
List<long> packSizes = new List<long>();
for (int j = 0; j < folderInfo._packStreams.Count; j++)
var count = folderInfo._packStreams.Count;
long[] packSizes = new long[count];
for (int j = 0; j < count; j++)
{
packSizes.Add(db._packSizes[packStreamIndex + j]);
packSizes[j] = db._packSizes[packStreamIndex + j];
}
s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes.ToArray(), folderInfo,
s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes, folderInfo,
db.PasswordProvider);
_cachedStreams.Add(folderIndex, s);
}
@@ -1553,15 +1554,16 @@ namespace SharpCompress.Common.SevenZip
int packStreamIndex = db._folders[folderIndex]._firstPackStreamId;
long folderStartPackPos = db.GetFolderStreamPos(folderInfo, 0);
List<long> packSizes = new List<long>();
for (int j = 0; j < folderInfo._packStreams.Count; j++)
var count = folderInfo._packStreams.Count;
long[] packSizes = new long[count];
for (int j = 0; j < count; j++)
{
packSizes.Add(db._packSizes[packStreamIndex + j]);
packSizes[j] = db._packSizes[packStreamIndex + j];
}
// TODO: If the decoding fails the last file may be extracted incompletely. Delete it?
Stream s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes.ToArray(),
Stream s = DecoderStreamHelper.CreateDecoderStream(_stream, folderStartPackPos, packSizes,
folderInfo, db.PasswordProvider);
byte[] buffer = new byte[4 << 10];
for (;;)

View File

@@ -1,5 +1,4 @@
using System.IO;
using SharpCompress.Archives;
using SharpCompress.Readers;
namespace SharpCompress.Common.SevenZip

View File

@@ -1,7 +1,7 @@
using System;
using System.Buffers.Binary;
using System.IO;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Common.Tar.Headers
{
@@ -39,16 +39,17 @@ namespace SharpCompress.Common.Tar.Headers
WriteOctalBytes(0, buffer, 116, 8); // group ID
//ArchiveEncoding.UTF8.GetBytes("magic").CopyTo(buffer, 257);
if (Name.Length > 100)
var nameByteCount = ArchiveEncoding.GetEncoding().GetByteCount(Name);
if (nameByteCount > 100)
{
// Set mock filename and filetype to indicate the next block is the actual name of the file
WriteStringBytes("././@LongLink", buffer, 0, 100);
buffer[156] = (byte)EntryType.LongName;
WriteOctalBytes(Name.Length + 1, buffer, 124, 12);
WriteOctalBytes(nameByteCount + 1, buffer, 124, 12);
}
else
{
WriteStringBytes(Name, buffer, 0, 100);
WriteStringBytes(ArchiveEncoding.Encode(Name), buffer, 100);
WriteOctalBytes(Size, buffer, 124, 12);
var time = (long)(LastModifiedTime.ToUniversalTime() - EPOCH).TotalSeconds;
WriteOctalBytes(time, buffer, 136, 12);
@@ -56,11 +57,10 @@ namespace SharpCompress.Common.Tar.Headers
if (Size >= 0x1FFFFFFFF)
{
byte[] bytes = DataConverter.BigEndian.GetBytes(Size);
var bytes12 = new byte[12];
bytes.CopyTo(bytes12, 12 - bytes.Length);
Span<byte> bytes12 = stackalloc byte[12];
BinaryPrimitives.WriteInt64BigEndian(bytes12.Slice(4), Size);
bytes12[0] |= 0x80;
bytes12.CopyTo(buffer, 124);
bytes12.CopyTo(buffer.AsSpan(124));
}
}
@@ -69,10 +69,17 @@ namespace SharpCompress.Common.Tar.Headers
output.Write(buffer, 0, buffer.Length);
if (Name.Length > 100)
if (nameByteCount > 100)
{
WriteLongFilenameHeader(output);
Name = Name.Substring(0, 100);
// update to short name lower than 100 - [max bytes of one character].
// subtracting bytes is needed because preventing infinite loop(example code is here).
//
// var bytes = Encoding.UTF8.GetBytes(new string(0x3042, 100));
// var truncated = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(bytes, 0, 100));
//
// and then infinite recursion is occured in WriteLongFilenameHeader because truncated.Length is 102.
Name = ArchiveEncoding.Decode(ArchiveEncoding.Encode(Name), 0, 100 - ArchiveEncoding.GetEncoding().GetMaxByteCount(1));
Write(output);
}
}
@@ -168,8 +175,9 @@ namespace SharpCompress.Common.Tar.Headers
{
if ((buffer[124] & 0x80) == 0x80) // if size in binary
{
return DataConverter.BigEndian.GetInt64(buffer, 0x80);
return BinaryPrimitives.ReadInt64BigEndian(buffer.AsSpan(0x80));
}
return ReadAsciiInt64Base8(buffer, 124, 11);
}
@@ -184,6 +192,13 @@ namespace SharpCompress.Common.Tar.Headers
return buffer;
}
private static void WriteStringBytes(ReadOnlySpan<byte> name, Span<byte> buffer, int length)
{
name.CopyTo(buffer);
int i = Math.Min(length, name.Length);
buffer.Slice(i, length - i).Clear();
}
private static void WriteStringBytes(string name, byte[] buffer, int offset, int length)
{
int i;

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Tar.Headers;
using SharpCompress.IO;
using System.Text;
namespace SharpCompress.Common.Tar
{

View File

@@ -2,7 +2,6 @@
using System.IO;
using SharpCompress.Common.Tar.Headers;
using SharpCompress.IO;
using System.Text;
namespace SharpCompress.Common.Tar
{

View File

@@ -1,6 +1,5 @@
using System.IO;
using System.Linq;
using System.Text;
namespace SharpCompress.Common.Zip.Headers
{

View File

@@ -1,5 +1,4 @@
using System;
using System.IO;
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{

View File

@@ -1,6 +1,5 @@
using System.IO;
using System.Linq;
using System.Text;
namespace SharpCompress.Common.Zip.Headers
{

View File

@@ -1,6 +1,6 @@
using System;
using System.Buffers.Binary;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Common.Zip.Headers
{
@@ -76,34 +76,34 @@ namespace SharpCompress.Common.Zip.Headers
switch (DataBytes.Length)
{
case 4:
VolumeNumber = DataConverter.LittleEndian.GetUInt32(DataBytes, 0);
VolumeNumber = BinaryPrimitives.ReadUInt32LittleEndian(DataBytes);
return;
case 8:
RelativeOffsetOfEntryHeader = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 0);
RelativeOffsetOfEntryHeader = BinaryPrimitives.ReadInt64LittleEndian(DataBytes);
return;
case 12:
RelativeOffsetOfEntryHeader = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 0);
VolumeNumber = DataConverter.LittleEndian.GetUInt32(DataBytes, 8);
RelativeOffsetOfEntryHeader = BinaryPrimitives.ReadInt64LittleEndian(DataBytes);
VolumeNumber = BinaryPrimitives.ReadUInt32LittleEndian(DataBytes.AsSpan(8));
return;
case 16:
UncompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 0);
CompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 8);
UncompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes);
CompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes.AsSpan(8));
return;
case 20:
UncompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 0);
CompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 8);
VolumeNumber = DataConverter.LittleEndian.GetUInt32(DataBytes, 16);
UncompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes);
CompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes.AsSpan(8));
VolumeNumber = BinaryPrimitives.ReadUInt32LittleEndian(DataBytes.AsSpan(16));
return;
case 24:
UncompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 0);
CompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 8);
RelativeOffsetOfEntryHeader = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 16);
UncompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes);
CompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes.AsSpan(8));
RelativeOffsetOfEntryHeader = BinaryPrimitives.ReadInt64LittleEndian(DataBytes.AsSpan(16));
return;
case 28:
UncompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 0);
CompressedSize = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 8);
RelativeOffsetOfEntryHeader = (long)DataConverter.LittleEndian.GetUInt64(DataBytes, 16);
VolumeNumber = DataConverter.LittleEndian.GetUInt32(DataBytes, 24);
UncompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes);
CompressedSize = BinaryPrimitives.ReadInt64LittleEndian(DataBytes.AsSpan(8));
RelativeOffsetOfEntryHeader = BinaryPrimitives.ReadInt64LittleEndian(DataBytes.AsSpan(16));
VolumeNumber = BinaryPrimitives.ReadUInt32LittleEndian(DataBytes.AsSpan(24));
return;
default:
throw new ArchiveException("Unexpected size of of Zip64 extended information extra field");
@@ -132,7 +132,7 @@ namespace SharpCompress.Common.Zip.Headers
case ExtraDataType.Zip64ExtendedInformationExtraField:
return new Zip64ExtendedInformationExtraField
(
type,
type,
length,
extraData
);
@@ -146,4 +146,4 @@ namespace SharpCompress.Common.Zip.Headers
}
}
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.IO;
using System.IO;
namespace SharpCompress.Common.Zip.Headers
{

View File

@@ -1,8 +1,7 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Common.Zip.Headers
{
@@ -30,7 +29,7 @@ namespace SharpCompress.Common.Zip.Headers
&& Name.EndsWith("\\");
}
}
internal Stream PackedStream { get; set; }
internal ArchiveEncoding ArchiveEncoding { get; }
@@ -66,9 +65,7 @@ namespace SharpCompress.Common.Zip.Headers
return encryptionData;
}
#if !NO_CRYPTO
internal WinzipAesEncryptionData WinzipAesEncryptionData { get; set; }
#endif
internal ushort LastModifiedDate { get; set; }
@@ -80,13 +77,22 @@ namespace SharpCompress.Common.Zip.Headers
{
for (int i = 0; i < extra.Length - 4;)
{
ExtraDataType type = (ExtraDataType)DataConverter.LittleEndian.GetUInt16(extra, i);
ExtraDataType type = (ExtraDataType)BinaryPrimitives.ReadUInt16LittleEndian(extra.AsSpan(i));
if (!Enum.IsDefined(typeof(ExtraDataType), type))
{
type = ExtraDataType.NotImplementedExtraData;
}
ushort length = DataConverter.LittleEndian.GetUInt16(extra, i + 2);
ushort length = BinaryPrimitives.ReadUInt16LittleEndian(extra.AsSpan(i + 2));
// 7zip has this same kind of check to ignore extras blocks that don't conform to the standard 2-byte ID, 2-byte length, N-byte value.
// CPP/7Zip/Zip/ZipIn.cpp: CInArchive::ReadExtra
if (length > extra.Length)
{
// bad extras block
return;
}
byte[] data = new byte[length];
Buffer.BlockCopy(extra, i + 4, data, 0, length);
Extra.Add(LocalEntryHeaderExtraFactory.Create(type, length, data));
@@ -99,4 +105,4 @@ namespace SharpCompress.Common.Zip.Headers
internal bool IsZip64 => CompressedSize == uint.MaxValue;
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Text;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.Compressors.Deflate;

View File

@@ -1,5 +1,6 @@
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
namespace SharpCompress.Common.Zip
{
@@ -7,11 +8,13 @@ namespace SharpCompress.Common.Zip
{
private bool _isLocalHeaderLoaded;
private readonly SeekableZipHeaderFactory _headerFactory;
private readonly DirectoryEntryHeader _directoryEntryHeader;
internal SeekableZipFilePart(SeekableZipHeaderFactory headerFactory, DirectoryEntryHeader header, Stream stream)
: base(header, stream)
{
_headerFactory = headerFactory;
_directoryEntryHeader = header;
}
internal override Stream GetCompressedStream()
@@ -36,6 +39,15 @@ namespace SharpCompress.Common.Zip
protected override Stream CreateBaseStream()
{
BaseStream.Position = Header.DataStartPosition.Value;
if ((Header.CompressedSize == 0)
&& FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor)
&& (_directoryEntryHeader?.HasData == true)
&& (_directoryEntryHeader?.CompressedSize != 0))
{
return new ReadOnlySubStream(BaseStream, _directoryEntryHeader.CompressedSize);
}
return BaseStream;
}
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
using System.Text;
namespace SharpCompress.Common.Zip
{
@@ -35,7 +34,9 @@ namespace SharpCompress.Common.Zip
stream.Seek(zip64Locator.RelativeOffsetOfTheEndOfDirectoryRecord, SeekOrigin.Begin);
uint zip64Signature = reader.ReadUInt32();
if (zip64Signature != ZIP64_END_OF_CENTRAL_DIRECTORY)
{
throw new ArchiveException("Failed to locate the Zip64 Header");
}
var zip64Entry = new Zip64DirectoryEndHeader();
zip64Entry.Read(reader);
@@ -55,7 +56,9 @@ namespace SharpCompress.Common.Zip
position = stream.Position;
if (nextHeader == null)
{
yield break;
}
if (nextHeader is DirectoryEntryHeader entryHeader)
{

View File

@@ -2,7 +2,6 @@
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
using System.Text;
namespace SharpCompress.Common.Zip
{
@@ -54,14 +53,30 @@ namespace SharpCompress.Common.Zip
//entry could be zero bytes so we need to know that.
if (header.ZipHeaderType == ZipHeaderType.LocalEntry)
{
bool isRecording = rewindableStream.IsRecording;
if (!isRecording)
var local_header = ((LocalEntryHeader)header);
// If we have CompressedSize, there is data to be read
if( local_header.CompressedSize > 0 )
{
rewindableStream.StartRecording();
header.HasData = true;
} // Check if zip is streaming ( Length is 0 and is declared in PostDataDescriptor )
else if( local_header.Flags.HasFlag(HeaderFlags.UsePostDataDescriptor) )
{
bool isRecording = rewindableStream.IsRecording;
if (!isRecording)
{
rewindableStream.StartRecording();
}
uint nextHeaderBytes = reader.ReadUInt32();
// Check if next data is PostDataDescriptor, streamed file with 0 length
header.HasData = !IsHeader(nextHeaderBytes);
rewindableStream.Rewind(!isRecording);
}
else // We are not streaming and compressed size is 0, we have no data
{
header.HasData = false;
}
uint nextHeaderBytes = reader.ReadUInt32();
header.HasData = !IsHeader(nextHeaderBytes);
rewindableStream.Rewind(!isRecording);
}
yield return header;
}

View File

@@ -1,9 +1,7 @@
#if !NO_CRYPTO
using System;
using System.Buffers.Binary;
using System.IO;
using System.Security.Cryptography;
using SharpCompress.Converters;
namespace SharpCompress.Common.Zip
{
@@ -120,7 +118,7 @@ namespace SharpCompress.Common.Zip
: bytesRemaining;
// update the counter
DataConverter.LittleEndian.PutBytes(_counter, 0, _nonce++);
BinaryPrimitives.WriteInt32LittleEndian(_counter, _nonce++);
// Determine if this is the final block
if ((bytesToRead == bytesRemaining) && (_totalBytesLeftToRead == 0))
@@ -181,4 +179,3 @@ namespace SharpCompress.Common.Zip
}
}
}
#endif

View File

@@ -1,8 +1,6 @@
#if !NO_CRYPTO
using System;
using System.Buffers.Binary;
using System.Security.Cryptography;
using SharpCompress.Converters;
namespace SharpCompress.Common.Zip
{
@@ -64,10 +62,10 @@ namespace SharpCompress.Common.Zip
IvBytes = rfc2898.GetBytes(KeySizeInBytes);
_generatedVerifyValue = rfc2898.GetBytes(2);
short verify = DataConverter.LittleEndian.GetInt16(_passwordVerifyValue, 0);
short verify = BinaryPrimitives.ReadInt16LittleEndian(_passwordVerifyValue);
if (_password != null)
{
short generated = DataConverter.LittleEndian.GetInt16(_generatedVerifyValue, 0);
short generated = BinaryPrimitives.ReadInt16LittleEndian(_generatedVerifyValue);
if (verify != generated)
{
throw new InvalidFormatException("bad password");
@@ -76,4 +74,3 @@ namespace SharpCompress.Common.Zip
}
}
}
#endif

View File

@@ -1,4 +1,5 @@
using System;
using System.Buffers.Binary;
using System.IO;
using System.Linq;
using SharpCompress.Common.Zip.Headers;
@@ -8,7 +9,6 @@ using SharpCompress.Compressors.Deflate;
using SharpCompress.Compressors.Deflate64;
using SharpCompress.Compressors.LZMA;
using SharpCompress.Compressors.PPMd;
using SharpCompress.Converters;
using SharpCompress.IO;
namespace SharpCompress.Common.Zip
@@ -108,19 +108,19 @@ namespace SharpCompress.Common.Zip
{
throw new InvalidFormatException("Winzip data length is not 7.");
}
ushort compressedMethod = DataConverter.LittleEndian.GetUInt16(data.DataBytes, 0);
ushort compressedMethod = BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes);
if (compressedMethod != 0x01 && compressedMethod != 0x02)
{
throw new InvalidFormatException("Unexpected vendor version number for WinZip AES metadata");
}
ushort vendorId = DataConverter.LittleEndian.GetUInt16(data.DataBytes, 2);
ushort vendorId = BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes.AsSpan(2));
if (vendorId != 0x4541)
{
throw new InvalidFormatException("Unexpected vendor ID for WinZip AES metadata");
}
return CreateDecompressionStream(stream, (ZipCompressionMethod)DataConverter.LittleEndian.GetUInt16(data.DataBytes, 5));
return CreateDecompressionStream(stream, (ZipCompressionMethod)BinaryPrimitives.ReadUInt16LittleEndian(data.DataBytes.AsSpan(5)));
}
default:
{
@@ -142,7 +142,7 @@ namespace SharpCompress.Common.Zip
&& FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor))
|| Header.IsZip64)
{
plainStream = new NonDisposingStream(plainStream); //make sure AES doesn't close
plainStream = new NonDisposingStream(plainStream); //make sure AES doesn't close
}
else
{
@@ -165,12 +165,10 @@ namespace SharpCompress.Common.Zip
case ZipCompressionMethod.WinzipAes:
{
#if !NO_FILE
if (Header.WinzipAesEncryptionData != null)
{
return new WinzipAesCryptoStream(plainStream, Header.WinzipAesEncryptionData, Header.CompressedSize - 10);
}
#endif
return plainStream;
}
@@ -184,4 +182,4 @@ namespace SharpCompress.Common.Zip
return plainStream;
}
}
}
}

View File

@@ -1,11 +1,8 @@
using System;
using System.IO;
#if !NO_CRYPTO
using System.Linq;
#endif
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
using System.Text;
namespace SharpCompress.Common.Zip
{
@@ -132,10 +129,6 @@ namespace SharpCompress.Common.Zip
if (entryHeader.CompressionMethod == ZipCompressionMethod.WinzipAes)
{
#if NO_CRYPTO
throw new NotSupportedException("Cannot decrypt Winzip AES with Silverlight or WP7.");
#else
ExtraData data = entryHeader.Extra.SingleOrDefault(x => x.Type == ExtraDataType.WinZipAes);
if (data != null)
{
@@ -150,7 +143,6 @@ namespace SharpCompress.Common.Zip
entryHeader.CompressedSize -= (uint)(salt.Length + 2);
}
#endif
}
}

View File

@@ -65,16 +65,16 @@ namespace SharpCompress.Compressors.ADC
}
}
private static int GetOffset(byte[] chunk, int position)
private static int GetOffset(ReadOnlySpan<byte> chunk)
{
switch (GetChunkType(chunk[position]))
switch (GetChunkType(chunk[0]))
{
case PLAIN:
return 0;
case TWO_BYTE:
return ((chunk[position] & 0x03) << 8) + chunk[position + 1];
return ((chunk[0] & 0x03) << 8) + chunk[1];
case THREE_BYTE:
return (chunk[position + 1] << 8) + chunk[position + 2];
return (chunk[1] << 8) + chunk[2];
default:
return -1;
}
@@ -116,7 +116,7 @@ namespace SharpCompress.Compressors.ADC
byte[] buffer = new byte[bufferSize];
int outPosition = 0;
bool full = false;
MemoryStream tempMs;
Span<byte> temp = stackalloc byte[3];
while (position < input.Length)
{
@@ -142,11 +142,10 @@ namespace SharpCompress.Compressors.ADC
position += chunkSize + 1;
break;
case TWO_BYTE:
tempMs = new MemoryStream();
chunkSize = GetChunkSize((byte)readByte);
tempMs.WriteByte((byte)readByte);
tempMs.WriteByte((byte)input.ReadByte());
offset = GetOffset(tempMs.ToArray(), 0);
temp[0] = (byte)readByte;
temp[1] = (byte)input.ReadByte();
offset = GetOffset(temp);
if (outPosition + chunkSize > bufferSize)
{
full = true;
@@ -173,12 +172,11 @@ namespace SharpCompress.Compressors.ADC
}
break;
case THREE_BYTE:
tempMs = new MemoryStream();
chunkSize = GetChunkSize((byte)readByte);
tempMs.WriteByte((byte)readByte);
tempMs.WriteByte((byte)input.ReadByte());
tempMs.WriteByte((byte)input.ReadByte());
offset = GetOffset(tempMs.ToArray(), 0);
temp[0] = (byte)readByte;
temp[1] = (byte)input.ReadByte();
temp[2] = (byte)input.ReadByte();
offset = GetOffset(temp);
if (outPosition + chunkSize > bufferSize)
{
full = true;
@@ -213,8 +211,8 @@ namespace SharpCompress.Compressors.ADC
}
output = new byte[outPosition];
Array.Copy(buffer, 0, output, 0, outPosition);
Array.Copy(buffer, output, outPosition);
return position - start;
}
}
}
}

View File

@@ -27,9 +27,8 @@
// ------------------------------------------------------------------
using System;
using System.Buffers.Binary;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Converters;
using System.Text;
namespace SharpCompress.Compressors.Deflate
@@ -373,17 +372,16 @@ namespace SharpCompress.Compressors.Deflate
{
return;
}
if (_fileName.IndexOf("/") != -1)
if (_fileName.Contains("/"))
{
_fileName = _fileName.Replace("/", "\\");
_fileName = _fileName.Replace('/', '\\');
}
if (_fileName.EndsWith("\\"))
{
throw new InvalidOperationException("Illegal filename");
}
var index = _fileName.IndexOf("\\");
if (index != -1)
if (_fileName.Contains("\\"))
{
// trim any leading path
int length = _fileName.Length;
@@ -442,7 +440,7 @@ namespace SharpCompress.Compressors.Deflate
}
TimeSpan delta = LastModified.Value - UNIX_EPOCH;
var timet = (Int32)delta.TotalSeconds;
DataConverter.LittleEndian.PutBytes(header, i, timet);
BinaryPrimitives.WriteInt32LittleEndian(header.AsSpan(i), timet);
i += 4;
// xflg
@@ -476,4 +474,4 @@ namespace SharpCompress.Compressors.Deflate
return header.Length; // bytes written
}
}
}
}

View File

@@ -25,11 +25,10 @@
// ------------------------------------------------------------------
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Common.Tar.Headers;
using SharpCompress.Converters;
using System.Text;
namespace SharpCompress.Compressors.Deflate
@@ -244,10 +243,12 @@ namespace SharpCompress.Compressors.Deflate
if (_wantCompress)
{
// Emit the GZIP trailer: CRC32 and size mod 2^32
int c1 = crc.Crc32Result;
_stream.Write(DataConverter.LittleEndian.GetBytes(c1), 0, 4);
byte[] intBuf = new byte[4];
BinaryPrimitives.WriteInt32LittleEndian(intBuf, crc.Crc32Result);
_stream.Write(intBuf, 0, 4);
int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
_stream.Write(DataConverter.LittleEndian.GetBytes(c2), 0, 4);
BinaryPrimitives.WriteInt32LittleEndian(intBuf, c2);
_stream.Write(intBuf, 0, 4);
}
else
{
@@ -293,9 +294,9 @@ namespace SharpCompress.Compressors.Deflate
Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length);
}
Int32 crc32_expected = DataConverter.LittleEndian.GetInt32(trailer, 0);
Int32 crc32_expected = BinaryPrimitives.ReadInt32LittleEndian(trailer);
Int32 crc32_actual = crc.Crc32Result;
Int32 isize_expected = DataConverter.LittleEndian.GetInt32(trailer, 4);
Int32 isize_expected = BinaryPrimitives.ReadInt32LittleEndian(trailer.AsSpan(4));
Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF);
if (crc32_actual != crc32_expected)
@@ -446,7 +447,7 @@ namespace SharpCompress.Compressors.Deflate
throw new ZlibException("Bad GZIP header.");
}
Int32 timet = DataConverter.LittleEndian.GetInt32(header, 4);
Int32 timet = BinaryPrimitives.ReadInt32LittleEndian(header.AsSpan(4));
_GzipMtime = TarHeader.EPOCH.AddSeconds(timet);
totalBytesRead += n;
if ((header[3] & 0x04) == 0x04)
@@ -647,4 +648,4 @@ namespace SharpCompress.Compressors.Deflate
Undefined
}
}
}
}

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using SharpCompress.Common.Zip;
using SharpCompress.Compressors.Deflate;
using System;
using System.Diagnostics;
using System.IO;
@@ -23,11 +22,19 @@ namespace SharpCompress.Compressors.Deflate64
public Deflate64Stream(Stream stream, CompressionMode mode)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
if (mode != CompressionMode.Decompress)
{
throw new NotImplementedException("Deflate64: this implementation only supports decompression");
}
if (!stream.CanRead)
{
throw new ArgumentException("Deflate64: input stream is not readable", nameof(stream));
}
InitializeInflater(stream, ZipCompressionMethod.Deflate64);
}
@@ -40,7 +47,9 @@ namespace SharpCompress.Compressors.Deflate64
Debug.Assert(stream != null);
Debug.Assert(method == ZipCompressionMethod.Deflate || method == ZipCompressionMethod.Deflate64);
if (!stream.CanRead)
{
throw new ArgumentException("Deflate64: input stream is not readable", nameof(stream));
}
_inflater = new InflaterManaged(method == ZipCompressionMethod.Deflate64);
@@ -152,22 +161,32 @@ namespace SharpCompress.Compressors.Deflate64
private void ValidateParameters(byte[] array, int offset, int count)
{
if (array == null)
{
throw new ArgumentNullException(nameof(array));
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (array.Length - offset < count)
{
throw new ArgumentException("Deflate64: invalid offset/count combination");
}
}
private void EnsureNotDisposed()
{
if (_stream == null)
{
ThrowStreamClosedException();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -179,7 +198,9 @@ namespace SharpCompress.Compressors.Deflate64
private void EnsureDecompressionMode()
{
if (_mode != CompressionMode.Decompress)
{
ThrowCannotReadFromDeflateManagedStreamException();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -191,7 +212,9 @@ namespace SharpCompress.Compressors.Deflate64
private void EnsureCompressionMode()
{
if (_mode != CompressionMode.Compress)
{
ThrowCannotWriteToDeflateManagedStreamException();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -209,10 +232,14 @@ namespace SharpCompress.Compressors.Deflate64
private void PurgeBuffers(bool disposing)
{
if (!disposing)
{
return;
}
if (_stream == null)
{
return;
}
Flush();
}

View File

@@ -208,7 +208,9 @@ namespace SharpCompress.Compressors.Deflate64
for (code = 0; code < 16; code++)
{
for (int n = 0; n < (1 << EXTRA_DISTANCE_BITS[code]); n++)
{
result[dist++] = (byte)code;
}
}
dist >>= 7; // from now on, all distances are divided by 128
@@ -216,7 +218,9 @@ namespace SharpCompress.Compressors.Deflate64
for (; code < NUM_DIST_BASE_CODES; code++)
{
for (int n = 0; n < (1 << (EXTRA_DISTANCE_BITS[code] - 7)); n++)
{
result[256 + dist++] = (byte)code;
}
}
return result;

View File

@@ -82,16 +82,24 @@ namespace SharpCompress.Compressors.Deflate64
{
byte[] literalTreeLength = new byte[MAX_LITERAL_TREE_ELEMENTS];
for (int i = 0; i <= 143; i++)
{
literalTreeLength[i] = 8;
}
for (int i = 144; i <= 255; i++)
{
literalTreeLength[i] = 9;
}
for (int i = 256; i <= 279; i++)
{
literalTreeLength[i] = 7;
}
for (int i = 280; i <= 287; i++)
{
literalTreeLength[i] = 8;
}
return literalTreeLength;
}
@@ -277,9 +285,14 @@ namespace SharpCompress.Compressors.Deflate64
{
symbol = -symbol;
if ((bitBuffer & mask) == 0)
{
symbol = _left[symbol];
}
else
{
symbol = _right[symbol];
}
mask <<= 1;
} while (symbol < 0);
}

View File

@@ -37,7 +37,7 @@ namespace SharpCompress.Compressors.Deflate64
// const tables used in decoding:
// Extra bits for length code 257 - 285.
private static readonly byte[] S_EXTRA_LENGTH_BITS =
private static ReadOnlySpan<byte> S_EXTRA_LENGTH_BITS => new byte[]
{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,16 };
// The base length for length code 257 - 285.
@@ -51,9 +51,9 @@ namespace SharpCompress.Compressors.Deflate64
{ 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,32769,49153 };
// code lengths for code length alphabet is stored in following order
private static readonly byte[] S_CODE_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
private static ReadOnlySpan<byte> S_CODE_ORDER => new byte[] { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
private static readonly byte[] S_STATIC_DISTANCE_TREE_TABLE =
private static ReadOnlySpan<byte> S_STATIC_DISTANCE_TREE_TABLE => new byte[]
{
0x00,0x10,0x08,0x18,0x04,0x14,0x0c,0x1c,0x02,0x12,0x0a,0x1a,
0x06,0x16,0x0e,0x1e,0x01,0x11,0x09,0x19,0x05,0x15,0x0d,0x1d,
@@ -220,7 +220,9 @@ namespace SharpCompress.Compressors.Deflate64
// reading bfinal bit
// Need 1 bit
if (!_input.EnsureBitsAvailable(1))
{
return false;
}
_bfinal = _input.GetBits(1);
_state = InflaterState.ReadingBType;
@@ -718,7 +720,7 @@ namespace SharpCompress.Compressors.Deflate64
byte[] distanceTreeCodeLength = new byte[HuffmanTree.MAX_DIST_TREE_ELEMENTS];
// Create literal and distance tables
Array.Copy(_codeList, 0, literalTreeCodeLength, 0, _literalLengthCodeCount);
Array.Copy(_codeList, literalTreeCodeLength, _literalLengthCodeCount);
Array.Copy(_codeList, _literalLengthCodeCount, distanceTreeCodeLength, 0, _distanceCodeCount);
// Make sure there is an end-of-block code, otherwise how could we ever end?

View File

@@ -1,6 +1,4 @@
#if !NO_CRYPTO
using System;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
@@ -32,7 +30,9 @@ namespace SharpCompress.Compressors.LZMA
mLimit = limit;
if (((uint) input.Length & 15) != 0)
{
throw new NotSupportedException("AES decoder does not support padding.");
}
int numCyclesPower;
byte[] salt, seed;
@@ -92,10 +92,14 @@ namespace SharpCompress.Compressors.LZMA
{
if (count == 0
|| mWritten == mLimit)
{
return 0;
}
if (mUnderflow > 0)
{
return HandleUnderflow(buffer, offset, count);
}
// Need at least 16 bytes to proceed.
if (mEnding - mOffset < 16)
@@ -122,16 +126,22 @@ namespace SharpCompress.Compressors.LZMA
// Currently this is handled by forcing an underflow if
// the stream length is not a multiple of the block size.
if (count > mLimit - mWritten)
{
count = (int) (mLimit - mWritten);
}
// We cannot transform less than 16 bytes into the target buffer,
// but we also cannot return zero, so we need to handle this.
// We transform the data locally and use our own buffer as cache.
if (count < 16)
{
return HandleUnderflow(buffer, offset, count);
}
if (count > mEnding - mOffset)
{
count = mEnding - mOffset;
}
// Otherwise we transform directly into the target buffer.
int processed = mDecoder.TransformBlock(mBuffer, mOffset, count & ~15, buffer, offset);
@@ -159,24 +169,34 @@ namespace SharpCompress.Compressors.LZMA
int saltSize = (bt >> 7) & 1;
int ivSize = (bt >> 6) & 1;
if (info.Length == 1)
{
throw new InvalidOperationException();
}
byte bt2 = info[1];
saltSize += (bt2 >> 4);
ivSize += (bt2 & 15);
if (info.Length < 2 + saltSize + ivSize)
{
throw new InvalidOperationException();
}
salt = new byte[saltSize];
for (int i = 0; i < saltSize; i++)
{
salt[i] = info[i + 2];
}
iv = new byte[16];
for (int i = 0; i < ivSize; i++)
{
iv[i] = info[i + saltSize + 2];
}
if (numCyclesPower > 24)
{
throw new NotSupportedException();
}
}
private byte[] InitKey(int mNumCyclesPower, byte[] salt, byte[] pass)
@@ -187,15 +207,20 @@ namespace SharpCompress.Compressors.LZMA
int pos;
for (pos = 0; pos < salt.Length; pos++)
{
key[pos] = salt[pos];
}
for (int i = 0; i < pass.Length && pos < 32; i++)
{
key[pos++] = pass[i];
}
return key;
}
else
{
#if NETSTANDARD1_3
#if NETSTANDARD1_3 || NETSTANDARD2_0
using (IncrementalHash sha = IncrementalHash.CreateHash(HashAlgorithmName.SHA256))
{
byte[] counter = new byte[8];
@@ -209,8 +234,12 @@ namespace SharpCompress.Compressors.LZMA
// This mirrors the counter so we don't have to convert long to byte[] each round.
// (It also ensures the counter is little endian, which BitConverter does not.)
for (int i = 0; i < 8; i++)
{
if (++counter[i] != 0)
{
break;
}
}
}
return sha.GetHashAndReset();
}
@@ -228,8 +257,12 @@ namespace SharpCompress.Compressors.LZMA
// This mirrors the counter so we don't have to convert long to byte[] each round.
// (It also ensures the counter is little endian, which BitConverter does not.)
for (int i = 0; i < 8; i++)
{
if (++counter[i] != 0)
{
break;
}
}
}
sha.TransformFinalBlock(counter, 0, 0);
@@ -250,7 +283,9 @@ namespace SharpCompress.Compressors.LZMA
}
if (count > mUnderflow)
{
count = mUnderflow;
}
Buffer.BlockCopy(mBuffer, mOffset, buffer, offset, count);
mWritten += count;
@@ -262,5 +297,3 @@ namespace SharpCompress.Compressors.LZMA
#endregion
}
}
#endif

View File

@@ -1,6 +1,6 @@
using System;
using System.Buffers.Binary;
using System.IO;
using SharpCompress.Converters;
using SharpCompress.Crypto;
using SharpCompress.IO;
@@ -58,16 +58,17 @@ namespace SharpCompress.Compressors.LZMA
crc32Stream.WrappedStream.Dispose();
crc32Stream.Dispose();
var compressedCount = _countingWritableSubStream.Count;
var bytes = DataConverter.LittleEndian.GetBytes(crc32Stream.Crc);
_countingWritableSubStream.Write(bytes, 0, bytes.Length);
bytes = DataConverter.LittleEndian.GetBytes(_writeCount);
_countingWritableSubStream.Write(bytes, 0, bytes.Length);
byte[] intBuf = new byte[8];
BinaryPrimitives.WriteUInt32LittleEndian(intBuf, crc32Stream.Crc);
_countingWritableSubStream.Write(intBuf, 0, 4);
BinaryPrimitives.WriteInt64LittleEndian(intBuf, _writeCount);
_countingWritableSubStream.Write(intBuf, 0, 8);
//total with headers
bytes = DataConverter.LittleEndian.GetBytes(compressedCount + 6 + 20);
_countingWritableSubStream.Write(bytes, 0, bytes.Length);
BinaryPrimitives.WriteUInt64LittleEndian(intBuf, compressedCount + 6 + 20);
_countingWritableSubStream.Write(intBuf, 0, 8);
}
_finished = true;
}
@@ -101,7 +102,7 @@ namespace SharpCompress.Compressors.LZMA
{
_stream.Flush();
}
// TODO: Both Length and Position are sometimes feasible, but would require
// reading the output length when we initialize.
public override long Length => throw new NotImplementedException();

View File

@@ -34,34 +34,26 @@ namespace SharpCompress.Compressors.LZMA
if (NEEDS_INDENT)
{
NEEDS_INDENT = false;
#if !NO_FILE
Debug.Write(INDENT.Peek());
#endif
}
}
public static void Write(object value)
{
EnsureIndent();
#if !NO_FILE
Debug.Write(value);
#endif
}
public static void Write(string text)
{
EnsureIndent();
#if !NO_FILE
Debug.Write(text);
#endif
}
public static void Write(string format, params object[] args)
{
EnsureIndent();
#if !NO_FILE
Debug.Write(string.Format(format, args));
#endif
}
public static void WriteLine()

View File

@@ -996,7 +996,7 @@ namespace SharpCompress.Compressors.LZMA
}
}
UInt32 startLen = 2; // speed optimization
UInt32 startLen = 2; // speed optimization
for (UInt32 repIndex = 0; repIndex < Base.K_NUM_REP_DISTANCES; repIndex++)
{
@@ -1571,12 +1571,17 @@ namespace SharpCompress.Compressors.LZMA
public void WriteCoderProperties(Stream outStream)
{
_properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
WriteCoderProperties(_properties);
outStream.Write(_properties, 0, K_PROP_SIZE);
}
public void WriteCoderProperties(Span<byte> span)
{
span[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
for (int i = 0; i < 4; i++)
{
_properties[1 + i] = (Byte)((_dictionarySize >> (8 * i)) & 0xFF);
span[1 + i] = (byte)((_dictionarySize >> (8 * i)) & 0xFF);
}
outStream.Write(_properties, 0, K_PROP_SIZE);
}
private readonly UInt32[] _tempPrices = new UInt32[Base.K_NUM_FULL_DISTANCES];
@@ -1794,4 +1799,4 @@ namespace SharpCompress.Compressors.LZMA
_trainSize = trainSize;
}
}
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Buffers.Binary;
using System.IO;
using SharpCompress.Compressors.LZMA.LZ;
using SharpCompress.Converters;
namespace SharpCompress.Compressors.LZMA
{
@@ -56,7 +56,7 @@ namespace SharpCompress.Compressors.LZMA
if (!isLzma2)
{
_dictionarySize = DataConverter.LittleEndian.GetInt32(properties, 1);
_dictionarySize = BinaryPrimitives.ReadInt32LittleEndian(properties.AsSpan(1));
_outWindow.Create(_dictionarySize);
if (presetDictionary != null)
{
@@ -107,9 +107,9 @@ namespace SharpCompress.Compressors.LZMA
_encoder = new Encoder();
_encoder.SetCoderProperties(properties._propIDs, properties._properties);
MemoryStream propStream = new MemoryStream(5);
_encoder.WriteCoderProperties(propStream);
Properties = propStream.ToArray();
byte[] prop = new byte[5];
_encoder.WriteCoderProperties(prop);
Properties = prop;
_encoder.SetStreams(null, outputStream, -1, -1);
if (presetDictionary != null)
@@ -315,4 +315,4 @@ namespace SharpCompress.Compressors.LZMA
public byte[] Properties { get; } = new byte[5];
}
}
}

View File

@@ -36,10 +36,8 @@ namespace SharpCompress.Compressors.LZMA
case K_LZMA:
case K_LZMA2:
return new LzmaStream(info, inStreams.Single(), -1, limit);
#if !NO_CRYPTO
case CMethodId.K_AES_ID:
return new AesDecoderStream(inStreams.Single(), info, pass, limit);
#endif
case K_BCJ:
return new BCJFilter(false, inStreams.Single());
case K_BCJ2:

View File

@@ -1,6 +1,6 @@
using System;
using System.Buffers.Binary;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Compressors.PPMd.H
{
@@ -19,7 +19,11 @@ namespace SharpCompress.Compressors.PPMd.H
{
}
internal int SummFreq { get => DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff; set => DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value); }
internal int SummFreq
{
get => BinaryPrimitives.ReadInt16LittleEndian(Memory.AsSpan(Address)) & 0xffff;
set => BinaryPrimitives.WriteInt16LittleEndian(Memory.AsSpan(Address), (short)value);
}
internal FreqData Initialize(byte[] mem)
{
@@ -28,14 +32,12 @@ namespace SharpCompress.Compressors.PPMd.H
internal void IncrementSummFreq(int dSummFreq)
{
short summFreq = DataConverter.LittleEndian.GetInt16(Memory, Address);
summFreq += (short)dSummFreq;
DataConverter.LittleEndian.PutBytes(Memory, Address, summFreq);
SummFreq += (short)dSummFreq;
}
internal int GetStats()
{
return DataConverter.LittleEndian.GetInt32(Memory, Address + 2);
return BinaryPrimitives.ReadInt32LittleEndian(Memory.AsSpan(Address + 2));
}
internal virtual void SetStats(State state)
@@ -45,7 +47,7 @@ namespace SharpCompress.Compressors.PPMd.H
internal void SetStats(int state)
{
DataConverter.LittleEndian.PutBytes(Memory, Address + 2, state);
BinaryPrimitives.WriteInt32LittleEndian(Memory.AsSpan(Address + 2), state);
}
public override String ToString()
@@ -64,4 +66,4 @@ namespace SharpCompress.Compressors.PPMd.H
return buffer.ToString();
}
}
}
}

View File

@@ -137,7 +137,7 @@ namespace SharpCompress.Compressors.PPMd.H
private void RestartModelRare()
{
Utility.Fill(_charMask, 0);
new Span<int>(_charMask).Clear();
SubAlloc.InitSubAllocator();
_initRl = -(_maxOrder < 12 ? _maxOrder : 12) - 1;
int addr = SubAlloc.AllocContext();
@@ -228,7 +228,7 @@ namespace SharpCompress.Compressors.PPMd.H
private void ClearMask()
{
_escCount = 1;
Utility.Fill(_charMask, 0);
new Span<int>(_charMask).Clear();
}
internal bool DecodeInit(IRarUnpack unpackRead, int escChar)
@@ -912,4 +912,4 @@ namespace SharpCompress.Compressors.PPMd.H
}
}
}
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Buffers.Binary;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Compressors.PPMd.H
{
@@ -22,7 +22,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_numStats = DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff;
_numStats = BinaryPrimitives.ReadInt16LittleEndian(Memory.AsSpan(Address)) & 0xffff;
}
return _numStats;
}
@@ -32,7 +32,7 @@ namespace SharpCompress.Compressors.PPMd.H
_numStats = value & 0xffff;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value);
BinaryPrimitives.WriteInt16LittleEndian(Memory.AsSpan(Address), (short)value);
}
}
}
@@ -109,7 +109,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_suffix = DataConverter.LittleEndian.GetInt32(Memory, Address + 8);
_suffix = BinaryPrimitives.ReadInt32LittleEndian(Memory.AsSpan(Address + 8));
}
return _suffix;
}
@@ -124,7 +124,7 @@ namespace SharpCompress.Compressors.PPMd.H
_suffix = suffix;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address + 8, suffix);
BinaryPrimitives.WriteInt32LittleEndian(Memory.AsSpan(Address + 8), suffix);
}
}
@@ -307,7 +307,7 @@ namespace SharpCompress.Compressors.PPMd.H
// byte[] bytes = model.getSubAlloc().getHeap();
// int p1 = state1.Address;
// int p2 = state2.Address;
//
//
// for (int i = 0; i < StatePtr.size; i++) {
// byte temp = bytes[p1+i];
// bytes[p1+i] = bytes[p2+i];
@@ -564,4 +564,4 @@ namespace SharpCompress.Compressors.PPMd.H
UNION_SIZE = Math.Max(FreqData.SIZE, State.SIZE);
}
}
}
}

View File

@@ -1,4 +1,5 @@
using SharpCompress.Converters;
using System;
using System.Buffers.Binary;
namespace SharpCompress.Compressors.PPMd.H
{
@@ -21,7 +22,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_stamp = DataConverter.LittleEndian.GetInt16(Memory, Address) & 0xffff;
_stamp = BinaryPrimitives.ReadInt16LittleEndian(Memory.AsSpan(Address)) & 0xffff;
}
return _stamp;
}
@@ -31,7 +32,7 @@ namespace SharpCompress.Compressors.PPMd.H
_stamp = value;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address, (short)value);
BinaryPrimitives.WriteInt16LittleEndian(Memory.AsSpan(Address), (short)value);
}
}
}
@@ -63,7 +64,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_next = DataConverter.LittleEndian.GetInt32(Memory, Address + 4);
_next = BinaryPrimitives.ReadInt32LittleEndian(Memory.AsSpan(Address + 4));
}
return _next;
}
@@ -78,7 +79,7 @@ namespace SharpCompress.Compressors.PPMd.H
_next = next;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address + 4, next);
BinaryPrimitives.WriteInt32LittleEndian(Memory.AsSpan(Address + 4), next);
}
}
@@ -86,7 +87,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_nu = DataConverter.LittleEndian.GetInt16(Memory, Address + 2) & 0xffff;
_nu = BinaryPrimitives.ReadInt16LittleEndian(Memory.AsSpan(Address + 2)) & 0xffff;
}
return _nu;
}
@@ -96,7 +97,7 @@ namespace SharpCompress.Compressors.PPMd.H
_nu = nu & 0xffff;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address + 2, (short)nu);
BinaryPrimitives.WriteInt16LittleEndian(Memory.AsSpan(Address + 2), (short)nu);
}
}
@@ -104,7 +105,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_prev = DataConverter.LittleEndian.GetInt32(Memory, Address + 8);
_prev = BinaryPrimitives.ReadInt32LittleEndian(Memory.AsSpan(Address + 8));
}
return _prev;
}
@@ -119,8 +120,8 @@ namespace SharpCompress.Compressors.PPMd.H
_prev = prev;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address + 8, prev);
BinaryPrimitives.WriteInt32LittleEndian(Memory.AsSpan(Address + 8), prev);
}
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Buffers.Binary;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Compressors.PPMd.H
{
@@ -18,7 +19,7 @@ namespace SharpCompress.Compressors.PPMd.H
{
if (Memory != null)
{
_next = DataConverter.LittleEndian.GetInt32(Memory, Address);
_next = BinaryPrimitives.ReadInt32LittleEndian(Memory.AsSpan(Address));
}
return _next;
}
@@ -33,7 +34,7 @@ namespace SharpCompress.Compressors.PPMd.H
_next = next;
if (Memory != null)
{
DataConverter.LittleEndian.PutBytes(Memory, Address, next);
BinaryPrimitives.WriteInt32LittleEndian(Memory.AsSpan(Address), next);
}
}
@@ -51,4 +52,4 @@ namespace SharpCompress.Compressors.PPMd.H
return buffer.ToString();
}
}
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Buffers.Binary;
using System.Text;
using SharpCompress.Converters;
namespace SharpCompress.Compressors.PPMd.H
{
@@ -29,7 +29,7 @@ namespace SharpCompress.Compressors.PPMd.H
internal int GetSuccessor()
{
return DataConverter.LittleEndian.GetInt32(Memory, Address + 2);
return BinaryPrimitives.ReadInt32LittleEndian(Memory.AsSpan(Address + 2));
}
internal void SetSuccessor(PpmContext successor)
@@ -39,7 +39,7 @@ namespace SharpCompress.Compressors.PPMd.H
internal void SetSuccessor(int successor)
{
DataConverter.LittleEndian.PutBytes(Memory, Address + 2, successor);
BinaryPrimitives.WriteInt32LittleEndian(Memory.AsSpan(Address + 2), successor);
}
internal void SetValues(StateRef state)
@@ -95,4 +95,4 @@ namespace SharpCompress.Compressors.PPMd.H
return buffer.ToString();
}
}
}
}

View File

@@ -166,7 +166,7 @@ namespace SharpCompress.Compressors.PPMd.H
_freeListPos = _heapStart + allocSize;
//UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'"
//assert(realAllocSize - tempMemBlockPos == RarMemBlock.size): realAllocSize
//assert(realAllocSize - tempMemBlockPos == RarMemBlock.size): realAllocSize
//+ + tempMemBlockPos + + RarMemBlock.size;
// Init freeList
@@ -360,7 +360,7 @@ namespace SharpCompress.Compressors.PPMd.H
public virtual void InitSubAllocator()
{
int i, k;
Utility.Fill(_heap, _freeListPos, _freeListPos + SizeOfFreeList(), (byte)0);
new Span<byte>(_heap, _freeListPos, SizeOfFreeList()).Clear();
_pText = _heapStart;
@@ -448,4 +448,4 @@ namespace SharpCompress.Compressors.PPMd.H
UNIT_SIZE = Math.Max(PpmContext.SIZE, RarMemBlock.SIZE);
}
}
}
}

View File

@@ -58,7 +58,7 @@ namespace SharpCompress.Compressors.PPMd.I1
0x6051
};
private static readonly byte[] EXPONENTIAL_ESCAPES = {25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2};
private static ReadOnlySpan<byte> EXPONENTIAL_ESCAPES => new byte[] {25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2};
#region Public Methods

View File

@@ -1,5 +1,6 @@
using SharpCompress.Compressors.PPMd.I1;
using SharpCompress.Converters;
using System;
using System.Buffers.Binary;
using SharpCompress.Compressors.PPMd.I1;
namespace SharpCompress.Compressors.PPMd
{
@@ -25,7 +26,7 @@ namespace SharpCompress.Compressors.PPMd
ModelOrder = modelOrder;
RestorationMethod = modelRestorationMethod;
}
public int ModelOrder { get; }
public PpmdVersion Version { get; } = PpmdVersion.I1;
internal ModelRestorationMethod RestorationMethod { get; }
@@ -34,7 +35,7 @@ namespace SharpCompress.Compressors.PPMd
{
if (properties.Length == 2)
{
ushort props = DataConverter.LittleEndian.GetUInt16(properties, 0);
ushort props = BinaryPrimitives.ReadUInt16LittleEndian(properties);
AllocatorSize = (((props >> 4) & 0xff) + 1) << 20;
ModelOrder = (props & 0x0f) + 1;
RestorationMethod = (ModelRestorationMethod)(props >> 12);
@@ -42,7 +43,7 @@ namespace SharpCompress.Compressors.PPMd
else if (properties.Length == 5)
{
Version = PpmdVersion.H7Z;
AllocatorSize = DataConverter.LittleEndian.GetInt32(properties, 1);
AllocatorSize = BinaryPrimitives.ReadInt32LittleEndian(properties.AsSpan(1));
ModelOrder = properties[0];
}
}
@@ -64,8 +65,16 @@ namespace SharpCompress.Compressors.PPMd
}
}
public byte[] Properties => DataConverter.LittleEndian.GetBytes(
(ushort)
((ModelOrder - 1) + (((AllocatorSize >> 20) - 1) << 4) + ((ushort)RestorationMethod << 12)));
public byte[] Properties
{
get
{
byte[] bytes = new byte[2];
BinaryPrimitives.WriteUInt16LittleEndian(
bytes,
(ushort)((ModelOrder - 1) + (((AllocatorSize >> 20) - 1) << 4) + ((ushort)RestorationMethod << 12)));
return bytes;
}
}
}
}
}

View File

@@ -1,4 +1,3 @@
using System.IO;
using SharpCompress.Common;
using SharpCompress.Common.Rar.Headers;

View File

@@ -32,9 +32,9 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
}
}
public bool Suspended {
public bool Suspended {
get => suspended;
set => suspended = value;
set => suspended = value;
}
public int Char
@@ -139,12 +139,12 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
case 36: // alternative hash
Unpack29(fileHeader.IsSolid);
break;
case 50: // rar 5.x compression
Unpack5(fileHeader.IsSolid);
break;
default:
default:
throw new InvalidFormatException("unknown rar compression version " + fileHeader.CompressionAlgorithm);
}
}
@@ -729,13 +729,13 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
if (!solid)
{
tablesRead = false;
Utility.Fill(oldDist, 0); // memset(oldDist,0,sizeof(OldDist));
new Span<int>(oldDist).Clear(); // memset(oldDist,0,sizeof(OldDist));
oldDistPtr = 0;
lastDist = 0;
lastLength = 0;
Utility.Fill(unpOldTable, (byte)0); // memset(UnpOldTable,0,sizeof(UnpOldTable));
new Span<byte>(unpOldTable).Clear(); // memset(UnpOldTable,0,sizeof(UnpOldTable));
unpPtr = 0;
wrPtr = 0;
@@ -837,7 +837,7 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
if ((bitField & 0x4000) == 0)
{
Utility.Fill(unpOldTable, (byte)0); // memset(UnpOldTable,0,sizeof(UnpOldTable));
new Span<byte>(unpOldTable).Clear(); // memset(UnpOldTable,0,sizeof(UnpOldTable));
}
AddBits(2);
@@ -1109,7 +1109,7 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
oldFilterLengths[FiltPos] = StackFilter.BlockLength;
// memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
Utility.Fill(StackFilter.Program.InitR, 0);
new Span<int>(StackFilter.Program.InitR).Clear();
StackFilter.Program.InitR[3] = RarVM.VM_GLOBALMEMADDR; // StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
StackFilter.Program.InitR[4] = StackFilter.BlockLength;
@@ -1267,4 +1267,4 @@ WriteBorder=Math.Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
}
}
}
}
}

View File

@@ -3,7 +3,7 @@
* Original author: Edmund Wagner
* Creation date: 21.06.2007
*
* the unrar licence applies to all junrar source and binary distributions
* the unrar licence applies to all junrar source and binary distributions
* you are not allowed to use this source to re-create the RAR compression algorithm
*/
@@ -652,9 +652,9 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
ChSetC[I] = ((~I + 1) & 0xff) << 8;
}
Utility.Fill(NToPl, 0); // memset(NToPl,0,sizeof(NToPl));
Utility.Fill(NToPlB, 0); // memset(NToPlB,0,sizeof(NToPlB));
Utility.Fill(NToPlC, 0); // memset(NToPlC,0,sizeof(NToPlC));
new Span<int>(NToPl).Clear(); // memset(NToPl,0,sizeof(NToPl));
new Span<int>(NToPlB).Clear(); // memset(NToPlB,0,sizeof(NToPlB));
new Span<int>(NToPlC).Clear(); // memset(NToPlC,0,sizeof(NToPlC));
corrHuff(ChSetB, NToPlB);
}
@@ -670,7 +670,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
// & ~0xff) | I;
}
}
Utility.Fill(NumToPlace, 0); // memset(NumToPlace,0,sizeof(NToPl));
new Span<int>(NumToPlace).Clear(); // memset(NumToPlace,0,sizeof(NToPl));
for (I = 6; I >= 0; I--)
{
NumToPlace[I] = (7 - I) * 32;
@@ -717,4 +717,4 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
wrPtr = unpPtr;
}
}
}
}

View File

@@ -3,7 +3,7 @@
* Original author: Edmund Wagner
* Creation date: 21.06.2007
*
* the unrar licence applies to all junrar source and binary distributions
* the unrar licence applies to all junrar source and binary distributions
* you are not allowed to use this source to re-create the RAR compression algorithm
*/
@@ -38,7 +38,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
56, 64, 80, 96, 112, 128, 160, 192, 224
};
private static readonly byte[] LBits =
private static ReadOnlySpan<byte> LBits => new byte[]
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
4, 5, 5, 5, 5
@@ -263,7 +263,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
if (0 == (BitField & 0x4000))
{
// memset(UnpOldTable20,0,sizeof(UnpOldTable20));
Utility.Fill(UnpOldTable20, (byte)0);
new Span<byte>(UnpOldTable20).Clear();
}
AddBits(2);
@@ -371,7 +371,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
AudV[3] = new AudioVariables();
// memset(UnpOldTable20,0,sizeof(UnpOldTable20));
Utility.Fill(UnpOldTable20, (byte)0);
new Span<byte>(UnpOldTable20).Clear();
}
}
@@ -521,4 +521,4 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
return ((byte)Ch);
}
}
}
}

View File

@@ -2,8 +2,6 @@
using System;
using System.Collections.Generic;
using SharpCompress.Compressors.Rar.UnpackV1.Decode;
using SharpCompress.Compressors.Rar.VM;
using size_t=System.UInt32;
using UnpackBlockHeader = SharpCompress.Compressors.Rar.UnpackV1;
@@ -139,14 +137,18 @@ public bool TablePresent;
{
UnpInitData(Solid);
if (!UnpReadBuf())
return;
{
return;
}
// Check TablesRead5 to be sure that we read tables at least once
// regardless of current block header TablePresent flag.
// So we can safefly use these tables below.
if (!ReadBlockHeader() ||
!ReadTables() || !TablesRead5)
return;
{
return;
}
}
while (true)
@@ -169,17 +171,24 @@ public bool TablePresent;
break;
}
if (!ReadBlockHeader() || !ReadTables())
{
return;
}
}
if (FileDone || !UnpReadBuf())
{
break;
}
}
if (((WriteBorder-UnpPtr) & MaxWinMask)<PackDef.MAX_LZ_MATCH+3 && WriteBorder!=UnpPtr)
{
UnpWriteBuf();
if (WrittenFileSize>DestUnpSize)
{
return;
}
if (Suspended)
{
FileExtracted=false;
@@ -243,7 +252,9 @@ public bool TablePresent;
{
Length++;
if (Distance>0x40000)
{
Length++;
}
}
}
@@ -259,7 +270,10 @@ public bool TablePresent;
{
UnpackFilter Filter = new UnpackFilter();
if (!ReadFilter(Filter) || !AddFilter(Filter))
{
break;
}
continue;
}
if (MainSlot==257)
@@ -269,7 +283,10 @@ public bool TablePresent;
// FragWindow.CopyString(LastLength,OldDist[0],UnpPtr,MaxWinMask);
// else
//CopyString(LastLength,OldDist[0]);
CopyString(LastLength,OldDistN(0));
{
CopyString(LastLength,OldDistN(0));
}
continue;
}
if (MainSlot<262)
@@ -281,7 +298,10 @@ public bool TablePresent;
//for (uint I=DistNum;I>0;I--)
for (int I=DistNum;I>0;I--)
//OldDistN[I]=OldDistN(I-1);
{
SetOldDistN(I, OldDistN(I-1));
}
//OldDistN[0]=Distance;
SetOldDistN(0, Distance);
@@ -316,13 +336,19 @@ public bool TablePresent;
private bool ReadFilter(UnpackFilter Filter)
{
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-16)
{
if (!UnpReadBuf())
{
return false;
}
}
Filter.uBlockStart=ReadFilterData();
Filter.uBlockLength=ReadFilterData();
if (Filter.BlockLength>MAX_FILTER_BLOCK_SIZE)
{
Filter.BlockLength=0;
}
//Filter.Type=Inp.fgetbits()>>13;
Filter.Type=(byte)(Inp.fgetbits()>>13);
@@ -344,7 +370,9 @@ public bool TablePresent;
{
UnpWriteBuf(); // Write data, apply and flush filters.
if (Filters.Count>=MAX_UNPACK_FILTERS)
{
InitFilters(); // Still too many filters, prevent excessive memory use.
}
}
// If distance to filter start is that large that due to circular dictionary
@@ -361,7 +389,10 @@ public bool TablePresent;
{
int DataSize=ReadTop-Inp.InAddr; // Data left to process.
if (DataSize<0)
{
return false;
}
BlockHeader.BlockSize-=Inp.InAddr-BlockHeader.BlockStart;
if (Inp.InAddr>MAX_SIZE/2)
{
@@ -373,21 +404,33 @@ public bool TablePresent;
// to make it zero.
if (DataSize>0)
//memmove(Inp.InBuf,Inp.InBuf+Inp.InAddr,DataSize);
{
Array.Copy(InBuf, inAddr, InBuf, 0, DataSize);
// TODO: perf
}
// TODO: perf
//Buffer.BlockCopy(InBuf, inAddr, InBuf, 0, DataSize);
Inp.InAddr=0;
ReadTop=DataSize;
}
else
{
DataSize=ReadTop;
}
int ReadCode=0;
if (MAX_SIZE!=DataSize)
//ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput.MAX_SIZE-DataSize);
{
ReadCode = readStream.Read(InBuf, DataSize, MAX_SIZE-DataSize);
}
if (ReadCode>0) // Can be also -1.
{
ReadTop+=ReadCode;
}
ReadBorder=ReadTop-30;
BlockHeader.BlockStart=Inp.InAddr;
if (BlockHeader.BlockSize!=-1) // '-1' means not defined yet.
@@ -674,7 +717,9 @@ public bool TablePresent;
private void UnpInitData50(bool Solid)
{
if (!Solid)
{
TablesRead5=false;
}
}
private bool ReadBlockHeader()
@@ -682,8 +727,13 @@ public bool TablePresent;
Header.HeaderSize=0;
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-7)
{
if (!UnpReadBuf())
{
return false;
}
}
//Inp.faddbits((8-Inp.InBit)&7);
Inp.faddbits((uint)((8-Inp.InBit)&7));
@@ -693,7 +743,9 @@ public bool TablePresent;
uint ByteCount=(uint)(((BlockFlags>>3)&3)+1); // Block size byte count.
if (ByteCount==4)
{
return false;
}
//Header.HeaderSize=2+ByteCount;
Header.HeaderSize=(int)(2+ByteCount);
@@ -715,7 +767,9 @@ public bool TablePresent;
Header.BlockSize=BlockSize;
byte CheckSum=(byte)(0x5a^BlockFlags^BlockSize^(BlockSize>>8)^(BlockSize>>16));
if (CheckSum!=SavedCheckSum)
{
return false;
}
Header.BlockStart=Inp.InAddr;
ReadBorder=Math.Min(ReadBorder,Header.BlockStart+Header.BlockSize-1);

View File

@@ -1,4 +1,5 @@
using SharpCompress.Compressors.Rar.VM;
using System;
using SharpCompress.Compressors.Rar.VM;
namespace SharpCompress.Compressors.Rar.UnpackV1
{
@@ -186,9 +187,7 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
int i;
long M, N;
Utility.Fill(lenCount, 0); // memset(LenCount,0,sizeof(LenCount));
Utility.Fill(dec.DecodeNum, 0); // memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
new Span<int>(dec.DecodeNum).Clear(); // memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
for (i = 0; i < size; i++)
{
@@ -217,4 +216,4 @@ namespace SharpCompress.Compressors.Rar.UnpackV1
dec.MaxNum = size;
}
}
}
}

View File

@@ -30,7 +30,9 @@ public BitInput(bool AllocBuffer)
//memset(InBuf,0,BufSize);
}
else
InBuf=null;
{
InBuf=null;
}
}

View File

@@ -31,11 +31,13 @@ public FragmentedWindow()
private void Reset()
{
for (uint I=0;I<Mem.Length;I++)
{
if (Mem[I]!=null)
{
//free(Mem[I]);
Mem[I]=null;
}
}
}
@@ -60,13 +62,18 @@ public void Init(size_t WinSize)
{
NewMem=new byte[Size];
if (NewMem!=null)
{
break;
}
Size-=Size/32;
}
if (NewMem==null)
//throw std::bad_alloc();
{
throw new InvalidOperationException();
}
// Clean the window to generate the same output when unpacking corrupt
// RAR files, which may access to unused areas of sliding dictionary.
// sharpcompress: don't need this, freshly allocated above
@@ -79,17 +86,27 @@ public void Init(size_t WinSize)
}
if (TotalSize<WinSize) // Not found enough free blocks.
//throw std::bad_alloc();
{
throw new InvalidOperationException();
}
}
public byte this[size_t Item] {
get {
if (Item<MemSize[0])
{
return Mem[0][Item];
}
for (uint I=1;I<MemSize.Length;I++)
{
if (Item<MemSize[I])
{
return Mem[I][Item-MemSize[I-1]];
}
}
return Mem[0][0]; // Must never happen;
}
set {
@@ -98,10 +115,13 @@ set {
return;
}
for (uint I=1;I<MemSize.Length;I++)
{
if (Item<MemSize[I]) {
Mem[I][Item-MemSize[I-1]] = value;
return;
}
}
}
Mem[0][0] = value; // Must never happen;
}
}
@@ -138,15 +158,22 @@ public void CopyString(uint Length,uint Distance,ref size_t UnpPtr,size_t MaxWin
public void CopyData(byte[] Dest, size_t destOffset, size_t WinPos,size_t Size)
{
for (size_t I=0;I<Size;I++)
{
Dest[destOffset+I]=this[WinPos+I];
}
}
public size_t GetBlockSize(size_t StartPos,size_t RequiredSize)
{
for (uint I=0;I<MemSize.Length;I++)
{
if (StartPos<MemSize[I])
{
return Math.Min(MemSize[I]-StartPos,RequiredSize);
}
}
return 0; // Must never be here.
}

View File

@@ -12,7 +12,6 @@ using int64 = System.Int64;
using System;
using System.IO;
using SharpCompress.Common.Rar.Headers;
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
namespace SharpCompress.Compressors.Rar.UnpackV2017
{

View File

@@ -10,10 +10,6 @@ using size_t = System.UInt64;
using int64 = System.Int64;
using uint32 = System.UInt32;
using System;
using System.Collections.Generic;
using System.Text;
namespace SharpCompress.Compressors.Rar.UnpackV2017
{
internal partial class Unpack

View File

@@ -1,4 +1,5 @@
using static SharpCompress.Compressors.Rar.UnpackV2017.Unpack.Unpack15Local;
using System;
using static SharpCompress.Compressors.Rar.UnpackV2017.Unpack.Unpack15Local;
namespace SharpCompress.Compressors.Rar.UnpackV2017
{
@@ -61,7 +62,10 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
UnpPtr=0;
}
else
{
UnpPtr=WrPtr;
}
--DestUnpSize;
if (DestUnpSize>=0)
{
@@ -74,9 +78,15 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
UnpPtr&=MaxWinMask;
if (Inp.InAddr>ReadTop-30 && !UnpReadBuf())
{
break;
}
if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
{
UnpWriteBuf20();
}
if (StMode != 0)
{
HuffDecode();
@@ -93,9 +103,13 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
{
FlagBuf<<=1;
if (Nlzb > Nhfb)
{
LongLZ();
}
else
{
HuffDecode();
}
}
else
{
@@ -109,9 +123,13 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
{
FlagBuf<<=1;
if (Nlzb > Nhfb)
{
HuffDecode();
}
else
{
LongLZ();
}
}
else
{
@@ -167,15 +185,25 @@ internal static class Unpack15Local {
if (AvrLn1<37)
{
for (Length=0;;Length++)
{
if (((BitField^ShortXor1[Length]) & (~(0xff>>(int)GetShortLen1(Length))))==0)
{
break;
}
}
Inp.faddbits(GetShortLen1(Length));
}
else
{
for (Length=0;;Length++)
{
if (((BitField^ShortXor2[Length]) & (~(0xff>>(int)GetShortLen2(Length))))==0)
{
break;
}
}
Inp.faddbits(GetShortLen2(Length));
}
@@ -209,9 +237,14 @@ internal static class Unpack15Local {
return;
}
if (Distance > 256)
{
Length++;
}
if (Distance >= MaxDist3)
{
Length++;
}
OldDist[OldDistPtr++]=Distance;
OldDistPtr = OldDistPtr & 3;
@@ -259,10 +292,14 @@ internal static class Unpack15Local {
uint BitField=Inp.fgetbits();
if (AvrLn2 >= 122)
{
Length=DecodeNum(BitField,STARTL2,DecL2,PosL2);
}
else
if (AvrLn2 >= 64)
{
Length=DecodeNum(BitField,STARTL1,DecL1,PosL1);
}
else
if (BitField < 0x100)
{
@@ -272,7 +309,10 @@ internal static class Unpack15Local {
else
{
for (Length=0;((BitField<<(int)Length)&0x8000)==0;Length++)
{
;
}
Inp.faddbits(Length+1);
}
@@ -281,12 +321,18 @@ internal static class Unpack15Local {
BitField=Inp.fgetbits();
if (AvrPlcB > 0x28ff)
{
DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
}
else
if (AvrPlcB > 0x6ff)
{
DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
}
else
{
DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
}
AvrPlcB += DistancePlace;
AvrPlcB -= AvrPlcB >> 8;
@@ -295,9 +341,13 @@ internal static class Unpack15Local {
Distance = ChSetB[DistancePlace & 0xff];
NewDistancePlace = NToPlB[Distance++ & 0xff]++;
if ((Distance & 0xff) != 0)
{
CorrHuff(ChSetB,NToPlB);
}
else
{
break;
}
}
ChSetB[DistancePlace & 0xff]=ChSetB[NewDistancePlace];
@@ -308,23 +358,39 @@ internal static class Unpack15Local {
OldAvr3=AvrLn3;
if (Length!=1 && Length!=4)
{
if (Length==0 && Distance <= MaxDist3)
{
AvrLn3++;
AvrLn3 -= AvrLn3 >> 8;
}
else
if (AvrLn3 > 0)
AvrLn3--;
if (AvrLn3 > 0)
{
AvrLn3--;
}
}
Length+=3;
if (Distance >= MaxDist3)
{
Length++;
}
if (Distance <= 256)
{
Length+=8;
}
if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40)
{
MaxDist3=0x7f00;
}
else
{
MaxDist3=0x2001;
}
OldDist[OldDistPtr++]=Distance;
OldDistPtr = OldDistPtr & 3;
LastLength=Length;
@@ -342,23 +408,37 @@ internal static class Unpack15Local {
uint BitField=Inp.fgetbits();
if (AvrPlc > 0x75ff)
{
BytePlace=(int)DecodeNum(BitField,STARTHF4,DecHf4,PosHf4);
}
else
if (AvrPlc > 0x5dff)
{
BytePlace=(int)DecodeNum(BitField,STARTHF3,DecHf3,PosHf3);
}
else
if (AvrPlc > 0x35ff)
{
BytePlace=(int)DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
}
else
if (AvrPlc > 0x0dff)
{
BytePlace=(int)DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
}
else
{
BytePlace=(int)DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
}
BytePlace&=0xff;
if (StMode != 0)
{
if (BytePlace==0 && BitField > 0xfff)
{
BytePlace=0x100;
}
if (--BytePlace==-1)
{
BitField=Inp.fgetbits();
@@ -382,7 +462,10 @@ internal static class Unpack15Local {
}
else
if (NumHuf++ >= 16 && FlagsCnt==0)
{
StMode=1;
}
AvrPlc += (uint)BytePlace;
AvrPlc -= AvrPlc >> 8;
Nhfb+=16;
@@ -400,9 +483,13 @@ internal static class Unpack15Local {
CurByte=ChSet[BytePlace];
NewBytePlace=NToPl[CurByte++ & 0xff]++;
if ((CurByte & 0xff) > 0xa1)
{
CorrHuff(ChSet,NToPl);
}
else
{
break;
}
}
ChSet[BytePlace]=ChSet[NewBytePlace];
@@ -420,7 +507,9 @@ internal static class Unpack15Local {
// we need to check for value 256 when unpacking in case we unpack
// a corrupt archive.
if (FlagsPlace>=ChSetC.Length)
{
return;
}
while (true)
{
@@ -428,7 +517,10 @@ internal static class Unpack15Local {
FlagBuf=Flags>>8;
NewFlagsPlace=NToPlC[Flags++ & 0xff]++;
if ((Flags & 0xff) != 0)
{
break;
}
CorrHuff(ChSetC,NToPlC);
}
@@ -461,9 +553,9 @@ internal static class Unpack15Local {
ChSetA[I]=(ushort)I;
ChSetC[I]=(ushort)(((~I+1) & 0xff)<<8);
}
Utility.Memset(NToPl,0,NToPl.Length);
Utility.Memset(NToPlB,0,NToPlB.Length);
Utility.Memset(NToPlC,0,NToPlC.Length);
new Span<byte>(NToPl).Clear();
new Span<byte>(NToPlB).Clear();
new Span<byte>(NToPlC).Clear();
CorrHuff(ChSetB,NToPlB);
}
@@ -472,10 +564,15 @@ internal static class Unpack15Local {
int I,J;
for (I=7;I>=0;I--)
for (J=0;J<32;J++)
{
CharSet[J]=(ushort)((CharSet[J] & ~0xff) | I);
Utility.Memset(NumToPlace,0,NToPl.Length);
}
new Span<byte>(NumToPlace, 0, NToPl.Length).Clear();
for (I=6;I>=0;I--)
{
NumToPlace[I]=(byte)((7-I)*32);
}
}
private void CopyString15(uint Distance,uint Length)
@@ -492,7 +589,10 @@ internal static class Unpack15Local {
{
int I;
for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++)
{
StartPos++;
}
Inp.faddbits(StartPos);
return(((Num-(I != 0 ? DecTab[I-1]:0))>>(int)(16-StartPos))+PosTab[StartPos]);
}

View File

@@ -40,14 +40,22 @@ internal static class Unpack20Local {
uint Bits;
if (Suspended)
{
UnpPtr=WrPtr;
}
else
{
UnpInitData(Solid);
if (!UnpReadBuf())
{
return;
}
if ((!Solid || !TablesRead2) && !ReadTables20())
{
return;
}
--DestUnpSize;
}
@@ -56,13 +64,20 @@ internal static class Unpack20Local {
UnpPtr&=MaxWinMask;
if (Inp.InAddr>ReadTop-30)
{
if (!UnpReadBuf())
{
break;
}
}
if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
{
UnpWriteBuf20();
if (Suspended)
{
return;
}
}
if (UnpAudioBlock)
{
@@ -71,12 +86,18 @@ internal static class Unpack20Local {
if (AudioNumber==256)
{
if (!ReadTables20())
{
break;
}
continue;
}
Window[UnpPtr++]=DecodeAudio((int)AudioNumber);
if (++UnpCurChannel==UnpChannels)
{
UnpCurChannel=0;
}
--DestUnpSize;
continue;
}
@@ -109,7 +130,9 @@ internal static class Unpack20Local {
{
Length++;
if (Distance>=0x40000L)
{
Length++;
}
}
CopyString20(Length,Distance);
@@ -118,7 +141,10 @@ internal static class Unpack20Local {
if (Number==269)
{
if (!ReadTables20())
{
break;
}
continue;
}
if (Number==256)
@@ -143,7 +169,9 @@ internal static class Unpack20Local {
{
Length++;
if (Distance>=0x40000)
{
Length++;
}
}
}
CopyString20(Length,Distance);
@@ -168,7 +196,10 @@ internal static class Unpack20Local {
private void UnpWriteBuf20()
{
if (UnpPtr!=WrPtr)
{
UnpSomeRead=true;
}
if (UnpPtr<WrPtr)
{
UnpIO_UnpWrite(Window, WrPtr,(uint)(-(int)WrPtr & MaxWinMask));
@@ -176,7 +207,10 @@ internal static class Unpack20Local {
UnpAllBuf=true;
}
else
{
UnpIO_UnpWrite(Window,WrPtr,UnpPtr-WrPtr);
}
WrPtr=UnpPtr;
}
@@ -185,13 +219,21 @@ internal static class Unpack20Local {
byte[] BitLength = new byte[BC20];
byte[] Table = new byte[MC20*4];
if (Inp.InAddr>ReadTop-25)
{
if (!UnpReadBuf())
{
return false;
}
}
uint BitField=Inp.getbits();
UnpAudioBlock=(BitField & 0x8000)!=0;
if ((BitField & 0x4000) != 0)
Utility.Memset(UnpOldTable20,0,UnpOldTable20.Length);
{
new Span<byte>(UnpOldTable20).Clear();
}
Inp.addbits(2);
uint TableSize;
@@ -199,12 +241,17 @@ internal static class Unpack20Local {
{
UnpChannels=((BitField>>12) & 3)+1;
if (UnpCurChannel>=UnpChannels)
{
UnpCurChannel=0;
}
Inp.addbits(2);
TableSize=MC20*UnpChannels;
}
else
{
TableSize=NC20+DC20+RC20;
}
for (uint I=0;I<BC20;I++)
{
@@ -215,8 +262,13 @@ internal static class Unpack20Local {
for (uint I=0;I<TableSize;)
{
if (Inp.InAddr>ReadTop-5)
{
if (!UnpReadBuf())
{
return false;
}
}
uint Number=DecodeNumber(Inp,BlockTables.BD);
if (Number<16)
{
@@ -229,13 +281,17 @@ internal static class Unpack20Local {
uint N=(Inp.getbits() >> 14)+3;
Inp.addbits(2);
if (I==0)
{
return false; // We cannot have "repeat previous" code at the first position.
}
else
{
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
I++;
}
}
}
else
{
@@ -251,15 +307,24 @@ internal static class Unpack20Local {
Inp.addbits(7);
}
while (N-- > 0 && I<TableSize)
{
Table[I++]=0;
}
}
}
TablesRead2=true;
if (Inp.InAddr>ReadTop)
{
return true;
}
if (UnpAudioBlock)
{
for (uint I=0;I<UnpChannels;I++)
{
MakeDecodeTables(Table,(int)(I*MC20),MD[I],MC20);
}
}
else
{
MakeDecodeTables(Table,0,BlockTables.LD,NC20);
@@ -267,21 +332,27 @@ internal static class Unpack20Local {
MakeDecodeTables(Table,(int)(NC20+DC20),BlockTables.RD,RC20);
}
//x memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
Array.Copy(Table,0,UnpOldTable20,0,UnpOldTable20.Length);
Array.Copy(Table,UnpOldTable20,UnpOldTable20.Length);
return true;
}
private void ReadLastTables()
{
if (ReadTop>=Inp.InAddr+5)
{
if (UnpAudioBlock)
{
if (DecodeNumber(Inp,MD[UnpCurChannel])==256)
{
ReadTables20();
}
}
else
if (DecodeNumber(Inp,BlockTables.LD)==269)
ReadTables20();
if (DecodeNumber(Inp,BlockTables.LD)==269)
{
ReadTables20();
}
}
}
private void UnpInitData20(bool Solid)
@@ -296,7 +367,7 @@ internal static class Unpack20Local {
//memset(AudV,0,sizeof(AudV));
AudV = new AudioVariables[4];
Utility.Memset(UnpOldTable20, 0, UnpOldTable20.Length);
new Span<byte>(UnpOldTable20).Clear();
//memset(MD,0,sizeof(MD));
MD = new DecodeTable[4];
}
@@ -352,43 +423,73 @@ internal static class Unpack20Local {
{
case 1:
if (V.K1>=-16)
{
V.K1--;
}
break;
case 2:
if (V.K1<16)
{
V.K1++;
}
break;
case 3:
if (V.K2>=-16)
{
V.K2--;
}
break;
case 4:
if (V.K2<16)
{
V.K2++;
}
break;
case 5:
if (V.K3>=-16)
{
V.K3--;
}
break;
case 6:
if (V.K3<16)
{
V.K3++;
}
break;
case 7:
if (V.K4>=-16)
{
V.K4--;
}
break;
case 8:
if (V.K4<16)
{
V.K4++;
}
break;
case 9:
if (V.K5>=-16)
{
V.K5--;
}
break;
case 10:
if (V.K5<16)
{
V.K5++;
}
break;
}
}

Some files were not shown because too many files have changed in this diff Show More