diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 00b1a064..ef84a272 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"csharpier": {
- "version": "0.28.1",
+ "version": "0.25.0",
"commands": [
"dotnet-csharpier"
]
diff --git a/.editorconfig b/.editorconfig
index eab3d428..1903a97c 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -70,7 +70,7 @@ indent_style = tab
[*.{cs,csx,cake,vb,vbx}]
# Default Severity for all .NET Code Style rules below
-dotnet_analyzer_diagnostic.severity = silent
+dotnet_analyzer_diagnostic.severity = warning
##########################################
# File Header (Uncomment to support file headers)
@@ -269,8 +269,6 @@ dotnet_diagnostic.CA1305.severity = suggestion
dotnet_diagnostic.CA1307.severity = suggestion
dotnet_diagnostic.CA1309.severity = suggestion
dotnet_diagnostic.CA1310.severity = error
-dotnet_diagnostic.CA1507.severity = suggestion
-dotnet_diagnostic.CA1513.severity = suggestion
dotnet_diagnostic.CA1707.severity = suggestion
dotnet_diagnostic.CA1708.severity = suggestion
dotnet_diagnostic.CA1711.severity = suggestion
@@ -288,7 +286,6 @@ dotnet_diagnostic.CA1834.severity = error
dotnet_diagnostic.CA1845.severity = suggestion
dotnet_diagnostic.CA1848.severity = suggestion
dotnet_diagnostic.CA1852.severity = suggestion
-dotnet_diagnostic.CA1860.severity = silent
dotnet_diagnostic.CA2016.severity = suggestion
dotnet_diagnostic.CA2201.severity = error
dotnet_diagnostic.CA2206.severity = error
@@ -306,12 +303,13 @@ dotnet_diagnostic.CS1998.severity = error
dotnet_diagnostic.CS8602.severity = error
dotnet_diagnostic.CS8604.severity = error
dotnet_diagnostic.CS8618.severity = error
-dotnet_diagnostic.CS0618.severity = suggestion
+dotnet_diagnostic.CS0618.severity = error
dotnet_diagnostic.CS1998.severity = error
dotnet_diagnostic.CS4014.severity = error
dotnet_diagnostic.CS8600.severity = error
dotnet_diagnostic.CS8603.severity = error
dotnet_diagnostic.CS8625.severity = error
+dotnet_diagnostic.CS8981.severity = suggestion
dotnet_diagnostic.BL0005.severity = suggestion
@@ -320,7 +318,7 @@ dotnet_diagnostic.MVC1000.severity = suggestion
dotnet_diagnostic.RZ10012.severity = error
dotnet_diagnostic.IDE0004.severity = error # redundant cast
-dotnet_diagnostic.IDE0005.severity = suggestion
+dotnet_diagnostic.IDE0005.severity = error
dotnet_diagnostic.IDE0007.severity = error # Use var
dotnet_diagnostic.IDE0011.severity = error # Use braces on if statements
dotnet_diagnostic.IDE0010.severity = silent # populate switch
@@ -331,7 +329,7 @@ dotnet_diagnostic.IDE0023.severity = suggestion # use expression body for operat
dotnet_diagnostic.IDE0024.severity = silent # expression body for operators
dotnet_diagnostic.IDE0025.severity = suggestion # use expression body for properties
dotnet_diagnostic.IDE0027.severity = suggestion # Use expression body for accessors
-dotnet_diagnostic.IDE0028.severity = silent # expression body for accessors
+dotnet_diagnostic.IDE0028.severity = silent
dotnet_diagnostic.IDE0032.severity = suggestion # Use auto property
dotnet_diagnostic.IDE0033.severity = error # prefer tuple name
dotnet_diagnostic.IDE0037.severity = suggestion # simplify anonymous type
@@ -339,7 +337,7 @@ dotnet_diagnostic.IDE0040.severity = error # modifiers required
dotnet_diagnostic.IDE0041.severity = error # simplify null
dotnet_diagnostic.IDE0042.severity = error # deconstruct variable
dotnet_diagnostic.IDE0044.severity = suggestion # make field only when possible
-dotnet_diagnostic.IDE0047.severity = suggestion # parameter name
+dotnet_diagnostic.IDE0047.severity = suggestion # paratemeter name
dotnet_diagnostic.IDE0051.severity = error # unused field
dotnet_diagnostic.IDE0052.severity = error # unused member
dotnet_diagnostic.IDE0053.severity = suggestion # lambda not needed
@@ -353,20 +351,11 @@ dotnet_diagnostic.IDE0066.severity = suggestion # switch expression
dotnet_diagnostic.IDE0072.severity = suggestion # Populate switch - forces population of all cases even when default specified
dotnet_diagnostic.IDE0078.severity = suggestion # use pattern matching
dotnet_diagnostic.IDE0090.severity = suggestion # new can be simplified
-dotnet_diagnostic.IDE0130.severity = suggestion # namespace folder structure
+dotnet_diagnostic.IDE0130.severity = error # namespace folder structure
dotnet_diagnostic.IDE0160.severity = silent # Use block namespaces ARE NOT required
dotnet_diagnostic.IDE0161.severity = error # Please use file namespaces
dotnet_diagnostic.IDE0200.severity = suggestion # lambda not needed
dotnet_diagnostic.IDE1006.severity = suggestion # Naming rule violation: These words cannot contain lower case characters
-dotnet_diagnostic.IDE0260.severity = suggestion # Use pattern matching
-dotnet_diagnostic.IDE0270.severity = suggestion # Null check simplifcation
-dotnet_diagnostic.IDE0290.severity = error # Primary Constructor
-dotnet_diagnostic.IDE0300.severity = suggestion # Collection
-dotnet_diagnostic.IDE0305.severity = suggestion # Collection ToList
-
-dotnet_diagnostic.NX0001.severity = error
-dotnet_diagnostic.NX0002.severity = silent
-dotnet_diagnostic.NX0003.severity = silent
##########################################
# Styles
diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml
index 27d73e23..4486b23f 100644
--- a/.github/workflows/dotnetcore.yml
+++ b/.github/workflows/dotnetcore.yml
@@ -15,11 +15,18 @@ jobs:
steps:
- uses: actions/checkout@v4
- - uses: actions/setup-dotnet@v4
+ - uses: actions/setup-dotnet@v3
with:
- dotnet-version: 8.0.x
+ dotnet-version: 7.0.x
+ - name: NuGet Caching
+ uses: actions/cache@v3
+ with:
+ path: ~/.nuget/packages
+ key: ${{ runner.os }}-nuget-${{ hashFiles('packages.lock.json', '*/packages.lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-nuget-
- run: dotnet run --project build/build.csproj
- - uses: actions/upload-artifact@v4
+ - uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}-sharpcompress.nupkg
path: artifacts/*
diff --git a/Directory.Build.props b/Directory.Build.props
index b3d0b595..4b343bf8 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -10,7 +10,5 @@
true
False
False
- true
- true
diff --git a/Directory.Packages.props b/Directory.Packages.props
deleted file mode 100644
index e128f52f..00000000
--- a/Directory.Packages.props
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/NuGet.config b/NuGet.config
deleted file mode 100644
index 48259210..00000000
--- a/NuGet.config
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/README.md b/README.md
index 2ab41c09..20681105 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
# SharpCompress
-SharpCompress is a compression library in pure C# for .NET Framework 4.62, .NET Standard 2.1, .NET 6.0 and NET 8.0 that can unrar, un7zip, unzip, untar unbzip2, ungzip, unlzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip/lzip are implemented.
+SharpCompress is a compression library in pure C# for .NET Standard 2.0, 2.1, .NET Core 3.1 and .NET 5.0 that can unrar, un7zip, unzip, untar unbzip2, ungzip, unlzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip/lzip are implemented.
The major feature is support for non-seekable streams so large files can be processed on the fly (i.e. download stream).
GitHub Actions Build -
[](https://github.com/adamhathcock/sharpcompress/actions/workflows/dotnetcore.yml)
-[](https://dndocs.com/d/sharpcompress/api/index.html)
+[](https://www.robiniadocs.com/d/sharpcompress/api/SharpCompress.html)
## Need Help?
@@ -36,7 +36,7 @@ I'm always looking for help or ideas. Please submit code or email with ideas. Un
## TODOs (always lots)
-* RAR 5 decryption crc check support
+* RAR 5 decryption support
* 7Zip writing
* Zip64 (Need writing and extend Reading)
* Multi-volume Zip support.
diff --git a/SharpCompress.sln b/SharpCompress.sln
index ab4995b1..71ec294e 100644
--- a/SharpCompress.sln
+++ b/SharpCompress.sln
@@ -17,9 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{CDB425
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
global.json = global.json
- .editorconfig = .editorconfig
- Directory.Packages.props = Directory.Packages.props
- NuGet.config = NuGet.config
EndProjectSection
EndProject
Global
diff --git a/SharpCompress.sln.DotSettings b/SharpCompress.sln.DotSettings
index 4ff50910..248b4c35 100644
--- a/SharpCompress.sln.DotSettings
+++ b/SharpCompress.sln.DotSettings
@@ -79,10 +79,6 @@
<Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
<Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
<Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
- <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></Policy>
- <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy>
- <Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></Policy>
- <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></Policy>
<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
@@ -131,7 +127,6 @@
True
True
True
- True
<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">
<Solution />
</SessionState>
diff --git a/build/Program.cs b/build/Program.cs
index acafec41..9475a66b 100644
--- a/build/Program.cs
+++ b/build/Program.cs
@@ -61,7 +61,7 @@ Target(
Target(
Test,
DependsOn(Build),
- ForEach("net8.0", "net462"),
+ ForEach("net7.0", "net462"),
framework =>
{
IEnumerable GetFiles(string d)
diff --git a/build/build.csproj b/build/build.csproj
index e0dffc7f..7b478cf3 100644
--- a/build/build.csproj
+++ b/build/build.csproj
@@ -2,13 +2,13 @@
Exe
- net8.0
+ net7.0
-
-
-
+
+
+
diff --git a/build/packages.lock.json b/build/packages.lock.json
deleted file mode 100644
index 8a8fa2c0..00000000
--- a/build/packages.lock.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "version": 2,
- "dependencies": {
- "net8.0": {
- "Bullseye": {
- "type": "Direct",
- "requested": "[5.0.0, )",
- "resolved": "5.0.0",
- "contentHash": "bqyt+m17ym+5aN45C5oZRAjuLDt8jKiCm/ys1XfymIXSkrTFwvI/QsbY3ucPSHDz7SF7uON7B57kXFv5H2k1ew=="
- },
- "Glob": {
- "type": "Direct",
- "requested": "[1.1.9, )",
- "resolved": "1.1.9",
- "contentHash": "AfK5+ECWYTP7G3AAdnU8IfVj+QpGjrh9GC2mpdcJzCvtQ4pnerAGwHsxJ9D4/RnhDUz2DSzd951O/lQjQby2Sw=="
- },
- "SimpleExec": {
- "type": "Direct",
- "requested": "[12.0.0, )",
- "resolved": "12.0.0",
- "contentHash": "ptxlWtxC8vM6Y6e3h9ZTxBBkOWnWrm/Sa1HT+2i1xcXY3Hx2hmKDZP5RShPf8Xr9D+ivlrXNy57ktzyH8kyt+Q=="
- }
- }
- }
-}
\ No newline at end of file
diff --git a/global.json b/global.json
index 391ba3c2..e6e67e4e 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.100",
+ "version": "7.0.101",
"rollForward": "latestFeature"
}
}
diff --git a/src/SharpCompress/Algorithms/Adler32.cs b/src/SharpCompress/Algorithms/Adler32.cs
index 10dbfc4d..1f094c13 100644
--- a/src/SharpCompress/Algorithms/Adler32.cs
+++ b/src/SharpCompress/Algorithms/Adler32.cs
@@ -62,7 +62,7 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
public static int ReduceSum(Vector256 accumulator)
{
// Add upper lane to lower lane.
- var vsum = Sse2.Add(accumulator.GetLower(), accumulator.GetUpper());
+ Vector128 vsum = Sse2.Add(accumulator.GetLower(), accumulator.GetUpper());
// Add odd to even.
vsum = Sse2.Add(vsum, Sse2.Shuffle(vsum, 0b_11_11_01_01));
@@ -81,7 +81,7 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int EvenReduceSum(Vector256 accumulator)
{
- var vsum = Sse2.Add(accumulator.GetLower(), accumulator.GetUpper()); // add upper lane to lower lane
+ Vector128 vsum = Sse2.Add(accumulator.GetLower(), accumulator.GetUpper()); // add upper lane to lower lane
vsum = Sse2.Add(vsum, Sse2.Shuffle(vsum, 0b_11_10_11_10)); // add high to low
// Vector128.ToScalar() isn't optimized pre-net5.0 https://github.com/dotnet/runtime/pull/37882
@@ -189,29 +189,29 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
[MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)]
private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer)
{
- var s1 = adler & 0xFFFF;
- var s2 = (adler >> 16) & 0xFFFF;
+ uint s1 = adler & 0xFFFF;
+ uint s2 = (adler >> 16) & 0xFFFF;
// Process the data in blocks.
- var length = (uint)buffer.Length;
- var blocks = length / BlockSize;
+ uint length = (uint)buffer.Length;
+ uint blocks = length / BlockSize;
length -= blocks * BlockSize;
fixed (byte* bufferPtr = &MemoryMarshal.GetReference(buffer))
{
fixed (byte* tapPtr = &MemoryMarshal.GetReference(Tap1Tap2))
{
- var localBufferPtr = bufferPtr;
+ byte* localBufferPtr = bufferPtr;
// _mm_setr_epi8 on x86
- var tap1 = Sse2.LoadVector128((sbyte*)tapPtr);
- var tap2 = Sse2.LoadVector128((sbyte*)(tapPtr + 0x10));
- var zero = Vector128.Zero;
+ Vector128 tap1 = Sse2.LoadVector128((sbyte*)tapPtr);
+ Vector128 tap2 = Sse2.LoadVector128((sbyte*)(tapPtr + 0x10));
+ Vector128 zero = Vector128.Zero;
var ones = Vector128.Create((short)1);
while (blocks > 0)
{
- var n = NMAX / BlockSize; /* The NMAX constraint. */
+ uint n = NMAX / BlockSize; /* The NMAX constraint. */
if (n > blocks)
{
n = blocks;
@@ -221,15 +221,15 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
// Process n blocks of data. At most NMAX data bytes can be
// processed before s2 must be reduced modulo BASE.
- var v_ps = Vector128.CreateScalar(s1 * n);
- var v_s2 = Vector128.CreateScalar(s2);
- var v_s1 = Vector128.Zero;
+ Vector128 v_ps = Vector128.CreateScalar(s1 * n);
+ Vector128 v_s2 = Vector128.CreateScalar(s2);
+ Vector128 v_s1 = Vector128.Zero;
do
{
// Load 32 input bytes.
- var bytes1 = Sse3.LoadDquVector128(localBufferPtr);
- var bytes2 = Sse3.LoadDquVector128(localBufferPtr + 0x10);
+ Vector128 bytes1 = Sse3.LoadDquVector128(localBufferPtr);
+ Vector128 bytes2 = Sse3.LoadDquVector128(localBufferPtr + 0x10);
// Add previous block byte sum to v_ps.
v_ps = Sse2.Add(v_ps, v_s1);
@@ -237,11 +237,11 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
// Horizontally add the bytes for s1, multiply-adds the
// bytes by [ 32, 31, 30, ... ] for s2.
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes1, zero).AsUInt32());
- var mad1 = Ssse3.MultiplyAddAdjacent(bytes1, tap1);
+ Vector128 mad1 = Ssse3.MultiplyAddAdjacent(bytes1, tap1);
v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad1, ones).AsUInt32());
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes2, zero).AsUInt32());
- var mad2 = Ssse3.MultiplyAddAdjacent(bytes2, tap2);
+ Vector128 mad2 = Ssse3.MultiplyAddAdjacent(bytes2, tap2);
v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad2, ones).AsUInt32());
localBufferPtr += BlockSize;
@@ -281,15 +281,15 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
[MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)]
public static unsafe uint CalculateAvx2(uint adler, ReadOnlySpan buffer)
{
- var s1 = adler & 0xFFFF;
- var s2 = (adler >> 16) & 0xFFFF;
- var length = (uint)buffer.Length;
+ uint s1 = adler & 0xFFFF;
+ uint s2 = (adler >> 16) & 0xFFFF;
+ uint length = (uint)buffer.Length;
fixed (byte* bufferPtr = &MemoryMarshal.GetReference(buffer))
{
- var localBufferPtr = bufferPtr;
+ byte* localBufferPtr = bufferPtr;
- var zero = Vector256.Zero;
+ Vector256 zero = Vector256.Zero;
var dot3v = Vector256.Create((short)1);
var dot2v = Vector256.Create(
32,
@@ -333,29 +333,29 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
while (length >= 32)
{
- var k = length < NMAX ? (int)length : (int)NMAX;
+ int k = length < NMAX ? (int)length : (int)NMAX;
k -= k % 32;
length -= (uint)k;
- var vs10 = vs1;
- var vs3 = Vector256.Zero;
+ Vector256 vs10 = vs1;
+ Vector256 vs3 = Vector256.Zero;
while (k >= 32)
{
// Load 32 input bytes.
- var block = Avx.LoadVector256(localBufferPtr);
+ Vector256 block = Avx.LoadVector256(localBufferPtr);
// Sum of abs diff, resulting in 2 x int32's
- var vs1sad = Avx2.SumAbsoluteDifferences(block, zero);
+ Vector256 vs1sad = Avx2.SumAbsoluteDifferences(block, zero);
vs1 = Avx2.Add(vs1, vs1sad.AsUInt32());
vs3 = Avx2.Add(vs3, vs10);
// sum 32 uint8s to 16 shorts.
- var vshortsum2 = Avx2.MultiplyAddAdjacent(block, dot2v);
+ Vector256 vshortsum2 = Avx2.MultiplyAddAdjacent(block, dot2v);
// sum 16 shorts to 8 uint32s.
- var vsum2 = Avx2.MultiplyAddAdjacent(vshortsum2, dot3v);
+ Vector256 vsum2 = Avx2.MultiplyAddAdjacent(vshortsum2, dot3v);
vs2 = Avx2.Add(vsum2.AsUInt32(), vs2);
vs10 = vs1;
@@ -434,14 +434,14 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
[MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)]
private static unsafe uint CalculateScalar(uint adler, ReadOnlySpan buffer)
{
- var s1 = adler & 0xFFFF;
- var s2 = (adler >> 16) & 0xFFFF;
+ uint s1 = adler & 0xFFFF;
+ uint s2 = (adler >> 16) & 0xFFFF;
uint k;
fixed (byte* bufferPtr = buffer)
{
var localBufferPtr = bufferPtr;
- var length = (uint)buffer.Length;
+ uint length = (uint)buffer.Length;
while (length > 0)
{
diff --git a/src/SharpCompress/Archives/AbstractArchive.cs b/src/SharpCompress/Archives/AbstractArchive.cs
index df54d781..cfac55f2 100644
--- a/src/SharpCompress/Archives/AbstractArchive.cs
+++ b/src/SharpCompress/Archives/AbstractArchive.cs
@@ -12,35 +12,39 @@ public abstract class AbstractArchive : IArchive, IArchiveExtra
where TEntry : IArchiveEntry
where TVolume : IVolume
{
- private readonly LazyReadOnlyCollection _lazyVolumes;
- private readonly LazyReadOnlyCollection _lazyEntries;
- private bool _disposed;
- private readonly SourceStream? _sourceStream;
+ private readonly LazyReadOnlyCollection lazyVolumes;
+ private readonly LazyReadOnlyCollection lazyEntries;
public event EventHandler>? EntryExtractionBegin;
public event EventHandler>? EntryExtractionEnd;
public event EventHandler? CompressedBytesRead;
public event EventHandler? FilePartExtractionBegin;
+
protected ReaderOptions ReaderOptions { get; }
- internal AbstractArchive(ArchiveType type, SourceStream sourceStream)
+ private bool disposed;
+ protected SourceStream SrcStream;
+
+ internal AbstractArchive(ArchiveType type, SourceStream srcStream)
{
Type = type;
- ReaderOptions = sourceStream.ReaderOptions;
- _sourceStream = sourceStream;
- _lazyVolumes = new LazyReadOnlyCollection(LoadVolumes(_sourceStream));
- _lazyEntries = new LazyReadOnlyCollection(LoadEntries(Volumes));
+ ReaderOptions = srcStream.ReaderOptions;
+ SrcStream = srcStream;
+ lazyVolumes = new LazyReadOnlyCollection(LoadVolumes(SrcStream));
+ lazyEntries = new LazyReadOnlyCollection(LoadEntries(Volumes));
}
+#nullable disable
internal AbstractArchive(ArchiveType type)
{
Type = type;
- ReaderOptions = new();
- _lazyVolumes = new LazyReadOnlyCollection(Enumerable.Empty());
- _lazyEntries = new LazyReadOnlyCollection(Enumerable.Empty());
+ lazyVolumes = new LazyReadOnlyCollection(Enumerable.Empty());
+ lazyEntries = new LazyReadOnlyCollection(Enumerable.Empty());
}
+#nullable enable
+
public ArchiveType Type { get; }
void IArchiveExtractionListener.FireEntryExtractionBegin(IArchiveEntry entry) =>
@@ -61,12 +65,12 @@ public abstract class AbstractArchive : IArchive, IArchiveExtra
///
/// Returns an ReadOnlyCollection of all the RarArchiveEntries across the one or many parts of the RarArchive.
///
- public virtual ICollection Entries => _lazyEntries;
+ public virtual ICollection Entries => lazyEntries;
///
/// Returns an ReadOnlyCollection of all the RarArchiveVolumes across the one or many parts of the RarArchive.
///
- public ICollection Volumes => _lazyVolumes;
+ public ICollection Volumes => lazyVolumes;
///
/// The total size of the files compressed in the archive.
@@ -80,29 +84,29 @@ public abstract class AbstractArchive : IArchive, IArchiveExtra
public virtual long TotalUncompressSize =>
Entries.Aggregate(0L, (total, cf) => total + cf.Size);
- protected abstract IEnumerable LoadVolumes(SourceStream sourceStream);
+ protected abstract IEnumerable LoadVolumes(SourceStream srcStream);
protected abstract IEnumerable LoadEntries(IEnumerable volumes);
IEnumerable IArchive.Entries => Entries.Cast();
- IEnumerable IArchive.Volumes => _lazyVolumes.Cast();
+ IEnumerable IArchive.Volumes => lazyVolumes.Cast();
public virtual void Dispose()
{
- if (!_disposed)
+ if (!disposed)
{
- _lazyVolumes.ForEach(v => v.Dispose());
- _lazyEntries.GetLoaded().Cast().ForEach(x => x.Close());
- _sourceStream?.Dispose();
+ lazyVolumes.ForEach(v => v.Dispose());
+ lazyEntries.GetLoaded().Cast().ForEach(x => x.Close());
+ SrcStream?.Dispose();
- _disposed = true;
+ disposed = true;
}
}
void IArchiveExtractionListener.EnsureEntriesLoaded()
{
- _lazyEntries.EnsureFullyLoaded();
- _lazyVolumes.EnsureFullyLoaded();
+ lazyEntries.EnsureFullyLoaded();
+ lazyVolumes.EnsureFullyLoaded();
}
void IExtractionListener.FireCompressedBytesRead(
diff --git a/src/SharpCompress/Archives/AbstractWritableArchive.cs b/src/SharpCompress/Archives/AbstractWritableArchive.cs
index 614489fe..30083ec7 100644
--- a/src/SharpCompress/Archives/AbstractWritableArchive.cs
+++ b/src/SharpCompress/Archives/AbstractWritableArchive.cs
@@ -31,18 +31,18 @@ public abstract class AbstractWritableArchive
}
}
- private readonly List newEntries = new();
- private readonly List removedEntries = new();
+ private readonly List newEntries = new List();
+ private readonly List removedEntries = new List();
- private readonly List modifiedEntries = new();
+ private readonly List modifiedEntries = new List();
private bool hasModifications;
private bool pauseRebuilding;
internal AbstractWritableArchive(ArchiveType type)
: base(type) { }
- internal AbstractWritableArchive(ArchiveType type, SourceStream sourceStream)
- : base(type, sourceStream) { }
+ internal AbstractWritableArchive(ArchiveType type, SourceStream srcStream)
+ : base(type, srcStream) { }
public override ICollection Entries
{
@@ -120,10 +120,6 @@ public abstract class AbstractWritableArchive
{
foreach (var path in Entries.Select(x => x.Key))
{
- if (path is null)
- {
- continue;
- }
var p = path.Replace('/', '\\');
if (p.Length > 0 && p[0] == '\\')
{
diff --git a/src/SharpCompress/Archives/ArchiveFactory.cs b/src/SharpCompress/Archives/ArchiveFactory.cs
index 3f479327..cd0952f1 100644
--- a/src/SharpCompress/Archives/ArchiveFactory.cs
+++ b/src/SharpCompress/Archives/ArchiveFactory.cs
@@ -25,8 +25,8 @@ public static class ArchiveFactory
public static IWritableArchive Create(ArchiveType type)
{
- var factory = Factory
- .Factories.OfType()
+ var factory = Factory.Factories
+ .OfType()
.FirstOrDefault(item => item.KnownArchiveType == type);
if (factory != null)
diff --git a/src/SharpCompress/Archives/ArchiveVolumeFactory.cs b/src/SharpCompress/Archives/ArchiveVolumeFactory.cs
index 81a5d4fd..d8f5535f 100644
--- a/src/SharpCompress/Archives/ArchiveVolumeFactory.cs
+++ b/src/SharpCompress/Archives/ArchiveVolumeFactory.cs
@@ -11,7 +11,7 @@ internal abstract class ArchiveVolumeFactory
FileInfo? item = null;
//split 001, 002 ...
- var m = Regex.Match(part1.Name, @"^(.*\.)([0-9]+)$", RegexOptions.IgnoreCase);
+ Match m = Regex.Match(part1.Name, @"^(.*\.)([0-9]+)$", RegexOptions.IgnoreCase);
if (m.Success)
item = new FileInfo(
Path.Combine(
diff --git a/src/SharpCompress/Archives/GZip/GZipArchive.cs b/src/SharpCompress/Archives/GZip/GZipArchive.cs
index ea46e8d0..fb2f7691 100644
--- a/src/SharpCompress/Archives/GZip/GZipArchive.cs
+++ b/src/SharpCompress/Archives/GZip/GZipArchive.cs
@@ -90,23 +90,25 @@ public class GZipArchive : AbstractWritableArchive
{
stream.CheckNotNull(nameof(stream));
return new GZipArchive(
- new SourceStream(stream, _ => null, readerOptions ?? new ReaderOptions())
+ new SourceStream(stream, i => null, readerOptions ?? new ReaderOptions())
);
}
- public static GZipArchive Create() => new();
+ public static GZipArchive Create() => new GZipArchive();
///
/// Constructor with a SourceStream able to handle FileInfo and Streams.
///
- ///
- private GZipArchive(SourceStream sourceStream)
- : base(ArchiveType.GZip, sourceStream) { }
+ ///
+ ///
+ internal GZipArchive(SourceStream srcStream)
+ : base(ArchiveType.Tar, srcStream) { }
- protected override IEnumerable LoadVolumes(SourceStream sourceStream)
+ protected override IEnumerable LoadVolumes(SourceStream srcStream)
{
- sourceStream.LoadAllParts();
- return sourceStream.Streams.Select(a => new GZipVolume(a, ReaderOptions, 0));
+ srcStream.LoadAllParts();
+ var idx = 0;
+ return srcStream.Streams.Select(a => new GZipVolume(a, ReaderOptions, idx++));
}
public static bool IsGZipFile(string filePath) => IsGZipFile(new FileInfo(filePath));
@@ -182,11 +184,7 @@ public class GZipArchive : AbstractWritableArchive
foreach (var entry in oldEntries.Concat(newEntries).Where(x => !x.IsDirectory))
{
using var entryStream = entry.OpenEntryStream();
- writer.Write(
- entry.Key.NotNull("Entry Key is null"),
- entryStream,
- entry.LastModifiedTime
- );
+ writer.Write(entry.Key, entryStream, entry.LastModifiedTime);
}
}
diff --git a/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs b/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs
index 459d042d..be872e80 100644
--- a/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs
+++ b/src/SharpCompress/Archives/GZip/GZipArchiveEntry.cs
@@ -6,7 +6,7 @@ namespace SharpCompress.Archives.GZip;
public class GZipArchiveEntry : GZipEntry, IArchiveEntry
{
- internal GZipArchiveEntry(GZipArchive archive, GZipFilePart? part)
+ internal GZipArchiveEntry(GZipArchive archive, GZipFilePart part)
: base(part) => Archive = archive;
public virtual Stream OpenEntryStream()
diff --git a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs
index 90f6f16f..27dfc2bf 100644
--- a/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs
+++ b/src/SharpCompress/Archives/GZip/GZipWritableArchiveEntry.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -30,7 +32,7 @@ internal sealed class GZipWritableArchiveEntry : GZipArchiveEntry, IWritableArch
public override long Crc => 0;
- public override string? Key { get; }
+ public override string Key { get; }
public override long CompressedSize => 0;
diff --git a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs
index 3d1daa1a..0992f152 100644
--- a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs
+++ b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs
@@ -17,11 +17,15 @@ public static class IArchiveEntryExtensions
streamListener.EnsureEntriesLoaded();
streamListener.FireEntryExtractionBegin(archiveEntry);
streamListener.FireFilePartExtractionBegin(
- archiveEntry.Key ?? "Key",
+ archiveEntry.Key,
archiveEntry.Size,
archiveEntry.CompressedSize
);
var entryStream = archiveEntry.OpenEntryStream();
+ if (entryStream is null)
+ {
+ return;
+ }
using (entryStream)
{
using Stream s = new ListeningStream(streamListener, entryStream);
diff --git a/src/SharpCompress/Archives/IArchiveExtensions.cs b/src/SharpCompress/Archives/IArchiveExtensions.cs
index 382c3ddf..56ea0d9f 100644
--- a/src/SharpCompress/Archives/IArchiveExtensions.cs
+++ b/src/SharpCompress/Archives/IArchiveExtensions.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
+using System.Threading.Tasks;
using SharpCompress.Common;
namespace SharpCompress.Archives;
@@ -58,7 +59,7 @@ public static class IArchiveExtensions
}
// Create each directory
- var path = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
+ var path = Path.Combine(destination, entry.Key);
if (Path.GetDirectoryName(path) is { } directory && seenDirectories.Add(path))
{
Directory.CreateDirectory(directory);
diff --git a/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs b/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
index 6d9b44fd..3e576db3 100644
--- a/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
+++ b/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
@@ -13,7 +13,7 @@ namespace SharpCompress.Archives.Rar;
///
internal class FileInfoRarArchiveVolume : RarVolume
{
- internal FileInfoRarArchiveVolume(FileInfo fileInfo, ReaderOptions options, int index)
+ internal FileInfoRarArchiveVolume(FileInfo fileInfo, ReaderOptions options, int index = 0)
: base(StreamingMode.Seekable, fileInfo.OpenRead(), FixOptions(options), index)
{
FileInfo = fileInfo;
diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs
index a05ad417..29d733f6 100644
--- a/src/SharpCompress/Archives/Rar/RarArchive.cs
+++ b/src/SharpCompress/Archives/Rar/RarArchive.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -15,39 +14,40 @@ namespace SharpCompress.Archives.Rar;
public class RarArchive : AbstractArchive
{
internal Lazy UnpackV2017 { get; } =
- new(() => new Compressors.Rar.UnpackV2017.Unpack());
- internal Lazy UnpackV1 { get; } = new(() => new Compressors.Rar.UnpackV1.Unpack());
+ new Lazy(() => new Compressors.Rar.UnpackV2017.Unpack());
+ internal Lazy UnpackV1 { get; } =
+ new Lazy(() => new Compressors.Rar.UnpackV1.Unpack());
///
/// Constructor with a SourceStream able to handle FileInfo and Streams.
///
- ///
- private RarArchive(SourceStream sourceStream)
- : base(ArchiveType.Rar, sourceStream) { }
+ ///
+ ///
+ internal RarArchive(SourceStream srcStream)
+ : base(ArchiveType.Rar, srcStream) { }
protected override IEnumerable LoadEntries(IEnumerable volumes) =>
RarArchiveEntryFactory.GetEntries(this, volumes, ReaderOptions);
- protected override IEnumerable LoadVolumes(SourceStream sourceStream)
+ protected override IEnumerable LoadVolumes(SourceStream srcStream)
{
- sourceStream.LoadAllParts(); //request all streams
- var streams = sourceStream.Streams.ToArray();
- var i = 0;
+ SrcStream.LoadAllParts(); //request all streams
+ var streams = SrcStream.Streams.ToArray();
+ var idx = 0;
if (streams.Length > 1 && IsRarFile(streams[1], ReaderOptions)) //test part 2 - true = multipart not split
{
- sourceStream.IsVolumes = true;
+ SrcStream.IsVolumes = true;
streams[1].Position = 0;
- sourceStream.Position = 0;
+ SrcStream.Position = 0;
- return sourceStream.Streams.Select(a => new StreamRarArchiveVolume(
- a,
- ReaderOptions,
- i++
- ));
+ return srcStream.Streams.Select(
+ a => new StreamRarArchiveVolume(a, ReaderOptions, idx++)
+ );
+ }
+ else //split mode or single file
+ {
+ return new StreamRarArchiveVolume(SrcStream, ReaderOptions, idx++).AsEnumerable();
}
-
- //split mode or single file
- return new StreamRarArchiveVolume(sourceStream, ReaderOptions, i++).AsEnumerable();
}
protected override IReader CreateReaderForSolidExtraction()
@@ -106,7 +106,7 @@ public class RarArchive : AbstractArchive
public static RarArchive Open(Stream stream, ReaderOptions? options = null)
{
stream.CheckNotNull(nameof(stream));
- return new RarArchive(new SourceStream(stream, _ => null, options ?? new ReaderOptions()));
+ return new RarArchive(new SourceStream(stream, i => null, options ?? new ReaderOptions()));
}
///
diff --git a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs
index fa59b295..5885210a 100644
--- a/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs
+++ b/src/SharpCompress/Archives/Rar/RarArchiveEntry.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -41,10 +40,7 @@ public class RarArchiveEntry : RarEntry, IArchiveEntry
get
{
CheckIncomplete();
- return BitConverter.ToUInt32(
- parts.Select(fp => fp.FileHeader).Single(fh => !fh.IsSplitAfter).FileCrc,
- 0
- );
+ return parts.Select(fp => fp.FileHeader).Single(fh => !fh.IsSplitAfter).FileCrc;
}
}
diff --git a/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs b/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs
index f5ce89b8..72ccf60f 100644
--- a/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs
+++ b/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs
@@ -11,7 +11,7 @@ internal static class RarArchiveVolumeFactory
FileInfo? item = null;
//new style rar - ..part1 | /part01 | part001 ....
- var m = Regex.Match(part1.Name, @"^(.*\.part)([0-9]+)(\.rar)$", RegexOptions.IgnoreCase);
+ Match m = Regex.Match(part1.Name, @"^(.*\.part)([0-9]+)(\.rar)$", RegexOptions.IgnoreCase);
if (m.Success)
item = new FileInfo(
Path.Combine(
diff --git a/src/SharpCompress/Archives/Rar/SeekableFilePart.cs b/src/SharpCompress/Archives/Rar/SeekableFilePart.cs
index 97822d90..08aceb13 100644
--- a/src/SharpCompress/Archives/Rar/SeekableFilePart.cs
+++ b/src/SharpCompress/Archives/Rar/SeekableFilePart.cs
@@ -6,8 +6,8 @@ namespace SharpCompress.Archives.Rar;
internal class SeekableFilePart : RarFilePart
{
- private readonly Stream _stream;
- private readonly string? _password;
+ private readonly Stream stream;
+ private readonly string? password;
internal SeekableFilePart(
MarkHeader mh,
@@ -18,27 +18,18 @@ internal class SeekableFilePart : RarFilePart
)
: base(mh, fh, index)
{
- _stream = stream;
- _password = password;
+ this.stream = stream;
+ this.password = password;
}
internal override Stream GetCompressedStream()
{
- _stream.Position = FileHeader.DataStartPosition;
-
+ stream.Position = FileHeader.DataStartPosition;
if (FileHeader.R4Salt != null)
{
- var cryptKey = new CryptKey3(_password!);
- return new RarCryptoWrapper(_stream, FileHeader.R4Salt, cryptKey);
+ return new RarCryptoWrapper(stream, password!, FileHeader.R4Salt);
}
-
- if (FileHeader.Rar5CryptoInfo != null)
- {
- var cryptKey = new CryptKey5(_password!, FileHeader.Rar5CryptoInfo);
- return new RarCryptoWrapper(_stream, FileHeader.Rar5CryptoInfo.Salt, cryptKey);
- }
-
- return _stream;
+ return stream;
}
internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName;
diff --git a/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs b/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs
index 60cbab9a..3eb5095c 100644
--- a/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs
+++ b/src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs
@@ -9,7 +9,7 @@ namespace SharpCompress.Archives.Rar;
internal class StreamRarArchiveVolume : RarVolume
{
- internal StreamRarArchiveVolume(Stream stream, ReaderOptions options, int index)
+ internal StreamRarArchiveVolume(Stream stream, ReaderOptions options, int index = 0)
: base(StreamingMode.Seekable, stream, options, index) { }
internal override IEnumerable ReadFileParts() => GetVolumeFileParts();
diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
index ee165982..7577b43d 100644
--- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
+++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -12,14 +14,14 @@ namespace SharpCompress.Archives.SevenZip;
public class SevenZipArchive : AbstractArchive
{
- private ArchiveDatabase? _database;
+ private ArchiveDatabase database;
///
/// Constructor expects a filepath to an existing file.
///
///
///
- public static SevenZipArchive Open(string filePath, ReaderOptions? readerOptions = null)
+ public static SevenZipArchive Open(string filePath, ReaderOptions readerOptions = null)
{
filePath.CheckNotNullOrEmpty("filePath");
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
@@ -30,7 +32,7 @@ public class SevenZipArchive : AbstractArchive
///
///
- public static SevenZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
+ public static SevenZipArchive Open(FileInfo fileInfo, ReaderOptions readerOptions = null)
{
fileInfo.CheckNotNull("fileInfo");
return new SevenZipArchive(
@@ -49,7 +51,7 @@ public class SevenZipArchive : AbstractArchive
public static SevenZipArchive Open(
IEnumerable fileInfos,
- ReaderOptions? readerOptions = null
+ ReaderOptions readerOptions = null
)
{
fileInfos.CheckNotNull(nameof(fileInfos));
@@ -70,7 +72,7 @@ public class SevenZipArchive : AbstractArchive
public static SevenZipArchive Open(
IEnumerable streams,
- ReaderOptions? readerOptions = null
+ ReaderOptions readerOptions = null
)
{
streams.CheckNotNull(nameof(streams));
@@ -89,25 +91,27 @@ public class SevenZipArchive : AbstractArchive
///
///
- public static SevenZipArchive Open(Stream stream, ReaderOptions? readerOptions = null)
+ public static SevenZipArchive Open(Stream stream, ReaderOptions readerOptions = null)
{
stream.CheckNotNull("stream");
return new SevenZipArchive(
- new SourceStream(stream, _ => null, readerOptions ?? new ReaderOptions())
+ new SourceStream(stream, i => null, readerOptions ?? new ReaderOptions())
);
}
///
/// Constructor with a SourceStream able to handle FileInfo and Streams.
///
- ///
- private SevenZipArchive(SourceStream sourceStream)
- : base(ArchiveType.SevenZip, sourceStream) { }
+ ///
+ ///
+ internal SevenZipArchive(SourceStream srcStream)
+ : base(ArchiveType.SevenZip, srcStream) { }
- protected override IEnumerable LoadVolumes(SourceStream sourceStream)
+ protected override IEnumerable LoadVolumes(SourceStream srcStream)
{
- sourceStream.NotNull("SourceStream is null").LoadAllParts(); //request all streams
- return new SevenZipVolume(sourceStream, ReaderOptions, 0).AsEnumerable(); //simple single volume or split, multivolume not supported
+ SrcStream.LoadAllParts(); //request all streams
+ var idx = 0;
+ return new SevenZipVolume(srcStream, ReaderOptions, idx++).AsEnumerable(); //simple single volume or split, multivolume not supported
}
public static bool IsSevenZipFile(string filePath) => IsSevenZipFile(new FileInfo(filePath));
@@ -131,17 +135,13 @@ public class SevenZipArchive : AbstractArchive();
- }
- var entries = new SevenZipArchiveEntry[_database._files.Count];
- for (var i = 0; i < _database._files.Count; i++)
- {
- var file = _database._files[i];
+ var file = database._files[i];
entries[i] = new SevenZipArchiveEntry(
this,
- new SevenZipFilePart(stream, _database, i, file, ReaderOptions.ArchiveEncoding)
+ new SevenZipFilePart(stream, database, i, file, ReaderOptions.ArchiveEncoding)
);
}
foreach (var group in entries.Where(x => !x.IsDirectory).GroupBy(x => x.FilePart.Folder))
@@ -159,12 +159,12 @@ public class SevenZipArchive : AbstractArchive Signature =>
+ private static ReadOnlySpan SIGNATURE =>
new byte[] { (byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C };
private static bool SignatureMatch(Stream stream)
{
var reader = new BinaryReader(stream);
ReadOnlySpan signatureBytes = reader.ReadBytes(6);
- return signatureBytes.SequenceEqual(Signature);
+ return signatureBytes.SequenceEqual(SIGNATURE);
}
protected override IReader CreateReaderForSolidExtraction() =>
@@ -196,24 +196,30 @@ public class SevenZipArchive : AbstractArchive
Entries.Where(x => !x.IsDirectory).GroupBy(x => x.FilePart.Folder).Count() > 1;
- public override long TotalSize =>
- _database?._packSizes.Aggregate(0L, (total, packSize) => total + packSize) ?? 0;
+ public override long TotalSize
+ {
+ get
+ {
+ var i = Entries.Count;
+ return database._packSizes.Aggregate(0L, (total, packSize) => total + packSize);
+ }
+ }
private sealed class SevenZipReader : AbstractReader
{
- private readonly SevenZipArchive _archive;
- private CFolder? _currentFolder;
- private Stream? _currentStream;
- private CFileItem? _currentItem;
+ private readonly SevenZipArchive archive;
+ private CFolder currentFolder;
+ private Stream currentStream;
+ private CFileItem currentItem;
internal SevenZipReader(ReaderOptions readerOptions, SevenZipArchive archive)
- : base(readerOptions, ArchiveType.SevenZip) => this._archive = archive;
+ : base(readerOptions, ArchiveType.SevenZip) => this.archive = archive;
- public override SevenZipVolume Volume => _archive.Volumes.Single();
+ public override SevenZipVolume Volume => archive.Volumes.Single();
protected override IEnumerable GetEntries(Stream stream)
{
- var entries = _archive.Entries.ToList();
+ var entries = archive.Entries.ToList();
stream.Position = 0;
foreach (var dir in entries.Where(x => x.IsDirectory))
{
@@ -223,42 +229,37 @@ public class SevenZipArchive : AbstractArchive !x.IsDirectory).GroupBy(x => x.FilePart.Folder)
)
{
- _currentFolder = group.Key;
+ currentFolder = group.Key;
if (group.Key is null)
{
- _currentStream = Stream.Null;
+ currentStream = Stream.Null;
}
else
{
- _currentStream = _archive._database?.GetFolderStream(
+ currentStream = archive.database.GetFolderStream(
stream,
- _currentFolder,
+ currentFolder,
new PasswordProvider(Options.Password)
);
}
foreach (var entry in group)
{
- _currentItem = entry.FilePart.Header;
+ currentItem = entry.FilePart.Header;
yield return entry;
}
}
}
protected override EntryStream GetEntryStream() =>
- CreateEntryStream(
- new ReadOnlySubStream(
- _currentStream.NotNull("currentStream is not null"),
- _currentItem?.Size ?? 0
- )
- );
+ CreateEntryStream(new ReadOnlySubStream(currentStream, currentItem.Size));
}
private class PasswordProvider : IPasswordProvider
{
- private readonly string? _password;
+ private readonly string _password;
- public PasswordProvider(string? password) => _password = password;
+ public PasswordProvider(string password) => _password = password;
- public string? CryptoGetTextPassword() => _password;
+ public string CryptoGetTextPassword() => _password;
}
}
diff --git a/src/SharpCompress/Archives/Tar/TarArchive.cs b/src/SharpCompress/Archives/Tar/TarArchive.cs
index fdf8cd42..43184b66 100644
--- a/src/SharpCompress/Archives/Tar/TarArchive.cs
+++ b/src/SharpCompress/Archives/Tar/TarArchive.cs
@@ -114,7 +114,7 @@ public class TarArchive : AbstractWritableArchive
var tarHeader = new TarHeader(new ArchiveEncoding());
var readSucceeded = tarHeader.Read(new BinaryReader(stream));
var isEmptyArchive =
- tarHeader.Name?.Length == 0
+ tarHeader.Name.Length == 0
&& tarHeader.Size == 0
&& Enum.IsDefined(typeof(EntryType), tarHeader.EntryType);
return readSucceeded || isEmptyArchive;
@@ -123,20 +123,22 @@ public class TarArchive : AbstractWritableArchive
return false;
}
- protected override IEnumerable LoadVolumes(SourceStream sourceStream)
+ protected override IEnumerable LoadVolumes(SourceStream srcStream)
{
- sourceStream.NotNull("SourceStream is null").LoadAllParts(); //request all streams
- return new TarVolume(sourceStream, ReaderOptions, 1).AsEnumerable(); //simple single volume or split, multivolume not supported
+ SrcStream.LoadAllParts(); //request all streams
+ var idx = 0;
+ return new TarVolume(srcStream, ReaderOptions, idx++).AsEnumerable(); //simple single volume or split, multivolume not supported
}
///
/// Constructor with a SourceStream able to handle FileInfo and Streams.
///
- ///
- private TarArchive(SourceStream sourceStream)
- : base(ArchiveType.Tar, sourceStream) { }
+ ///
+ ///
+ internal TarArchive(SourceStream srcStream)
+ : base(ArchiveType.Tar, srcStream) { }
- private TarArchive()
+ internal TarArchive()
: base(ArchiveType.Tar) { }
protected override IEnumerable LoadEntries(IEnumerable volumes)
@@ -190,14 +192,10 @@ public class TarArchive : AbstractWritableArchive
);
}
}
- else
- {
- throw new IncompleteArchiveException("Failed to read TAR header");
- }
}
}
- public static TarArchive Create() => new();
+ public static TarArchive Create() => new TarArchive();
protected override TarArchiveEntry CreateEntryInternal(
string filePath,
@@ -227,12 +225,7 @@ public class TarArchive : AbstractWritableArchive
foreach (var entry in oldEntries.Concat(newEntries).Where(x => !x.IsDirectory))
{
using var entryStream = entry.OpenEntryStream();
- writer.Write(
- entry.Key.NotNull("Entry Key is null"),
- entryStream,
- entry.LastModifiedTime,
- entry.Size
- );
+ writer.Write(entry.Key, entryStream, entry.LastModifiedTime, entry.Size);
}
}
diff --git a/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs b/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs
index d04c4ef8..2da84d71 100644
--- a/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs
+++ b/src/SharpCompress/Archives/Tar/TarArchiveEntry.cs
@@ -7,7 +7,7 @@ namespace SharpCompress.Archives.Tar;
public class TarArchiveEntry : TarEntry, IArchiveEntry
{
- internal TarArchiveEntry(TarArchive archive, TarFilePart? part, CompressionType compressionType)
+ internal TarArchiveEntry(TarArchive archive, TarFilePart part, CompressionType compressionType)
: base(part, compressionType) => Archive = archive;
public virtual Stream OpenEntryStream() => Parts.Single().GetCompressedStream();
diff --git a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs
index 32be7d9b..0bbea709 100644
--- a/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs
+++ b/src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/src/SharpCompress/Archives/Zip/ZipArchive.cs b/src/SharpCompress/Archives/Zip/ZipArchive.cs
index 85130f70..14e4a93e 100644
--- a/src/SharpCompress/Archives/Zip/ZipArchive.cs
+++ b/src/SharpCompress/Archives/Zip/ZipArchive.cs
@@ -16,7 +16,10 @@ namespace SharpCompress.Archives.Zip;
public class ZipArchive : AbstractWritableArchive
{
- private readonly SeekableZipHeaderFactory? headerFactory;
+#nullable disable
+ private readonly SeekableZipHeaderFactory headerFactory;
+
+#nullable enable
///
/// Gets or sets the compression level applied to files added to the archive,
@@ -27,13 +30,13 @@ public class ZipArchive : AbstractWritableArchive
///
/// Constructor with a SourceStream able to handle FileInfo and Streams.
///
- ///
+ ///
///
- internal ZipArchive(SourceStream sourceStream)
- : base(ArchiveType.Zip, sourceStream) =>
+ internal ZipArchive(SourceStream srcStream)
+ : base(ArchiveType.Zip, srcStream) =>
headerFactory = new SeekableZipHeaderFactory(
- sourceStream.ReaderOptions.Password,
- sourceStream.ReaderOptions.ArchiveEncoding
+ srcStream.ReaderOptions.Password,
+ srcStream.ReaderOptions.ArchiveEncoding
);
///
@@ -186,21 +189,21 @@ public class ZipArchive : AbstractWritableArchive
}
}
- protected override IEnumerable LoadVolumes(SourceStream stream)
+ protected override IEnumerable LoadVolumes(SourceStream srcStream)
{
- stream.LoadAllParts(); //request all streams
- stream.Position = 0;
+ SrcStream.LoadAllParts(); //request all streams
+ SrcStream.Position = 0;
- var streams = stream.Streams.ToList();
+ var streams = SrcStream.Streams.ToList();
var idx = 0;
- if (streams.Count() > 1) //test part 2 - true = multipart not split
+ if (streams.Count > 1) //test part 2 - true = multipart not split
{
streams[1].Position += 4; //skip the POST_DATA_DESCRIPTOR to prevent an exception
var isZip = IsZipFile(streams[1], ReaderOptions.Password);
streams[1].Position -= 4;
if (isZip)
{
- stream.IsVolumes = true;
+ SrcStream.IsVolumes = true;
var tmp = streams[0]; //arcs as zip, z01 ... swap the zip the end
streams.RemoveAt(0);
@@ -212,7 +215,7 @@ public class ZipArchive : AbstractWritableArchive
}
//split mode or single file
- return new ZipVolume(stream, ReaderOptions, idx++).AsEnumerable();
+ return new ZipVolume(SrcStream, ReaderOptions, idx++).AsEnumerable();
}
internal ZipArchive()
@@ -221,13 +224,14 @@ public class ZipArchive : AbstractWritableArchive
protected override IEnumerable LoadEntries(IEnumerable volumes)
{
var vols = volumes.ToArray();
- foreach (var h in headerFactory.NotNull().ReadSeekableHeader(vols.Last().Stream))
+ foreach (var h in headerFactory.ReadSeekableHeader(vols.Last().Stream))
{
if (h != null)
{
switch (h.ZipHeaderType)
{
case ZipHeaderType.DirectoryEntry:
+
{
var deh = (DirectoryEntryHeader)h;
Stream s;
@@ -250,14 +254,14 @@ public class ZipArchive : AbstractWritableArchive
yield return new ZipArchiveEntry(
this,
- new SeekableZipFilePart(headerFactory.NotNull(), deh, s)
+ new SeekableZipFilePart(headerFactory, deh, s)
);
}
break;
case ZipHeaderType.DirectoryEnd:
{
var bytes = ((DirectoryEndHeader)h).Comment ?? Array.Empty();
- vols.Last().Comment = ReaderOptions.ArchiveEncoding.Decode(bytes);
+ volumes.Last().Comment = ReaderOptions.ArchiveEncoding.Decode(bytes);
yield break;
}
}
@@ -278,11 +282,7 @@ public class ZipArchive : AbstractWritableArchive
foreach (var entry in oldEntries.Concat(newEntries).Where(x => !x.IsDirectory))
{
using var entryStream = entry.OpenEntryStream();
- writer.Write(
- entry.Key.NotNull("Entry Key is null"),
- entryStream,
- entry.LastModifiedTime
- );
+ writer.Write(entry.Key, entryStream, entry.LastModifiedTime);
}
}
@@ -294,7 +294,7 @@ public class ZipArchive : AbstractWritableArchive
bool closeStream
) => new ZipWritableArchiveEntry(this, source, filePath, size, modified, closeStream);
- public static ZipArchive Create() => new();
+ public static ZipArchive Create() => new ZipArchive();
protected override IReader CreateReaderForSolidExtraction()
{
diff --git a/src/SharpCompress/Archives/Zip/ZipArchiveVolumeFactory.cs b/src/SharpCompress/Archives/Zip/ZipArchiveVolumeFactory.cs
index 1b2f093d..fdaa85b9 100644
--- a/src/SharpCompress/Archives/Zip/ZipArchiveVolumeFactory.cs
+++ b/src/SharpCompress/Archives/Zip/ZipArchiveVolumeFactory.cs
@@ -12,7 +12,7 @@ internal static class ZipArchiveVolumeFactory
//load files with zip/zipx first. Swapped to end once loaded in ZipArchive
//new style .zip, z01.. | .zipx, zx01 - if the numbers go beyond 99 then they use 100 ...1000 etc
- var m = Regex.Match(part1.Name, @"^(.*\.)(zipx?|zx?[0-9]+)$", RegexOptions.IgnoreCase);
+ Match m = Regex.Match(part1.Name, @"^(.*\.)(zipx?|zx?[0-9]+)$", RegexOptions.IgnoreCase);
if (m.Success)
item = new FileInfo(
Path.Combine(
diff --git a/src/SharpCompress/BufferPool.cs b/src/SharpCompress/BufferPool.cs
deleted file mode 100644
index b11dbe6f..00000000
--- a/src/SharpCompress/BufferPool.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Buffers;
-
-namespace SharpCompress;
-
-internal static class BufferPool
-{
- ///
- /// gets a buffer from the pool
- ///
- /// size of the buffer
- /// the buffer
- public static byte[] Rent(int bufferSize)
- {
-#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
- return ArrayPool.Shared.Rent(bufferSize);
-#else
- return new byte[bufferSize];
-#endif
- }
-
- ///
- /// returns a buffer to the pool
- ///
- /// the buffer to return
- public static void Return(byte[] buffer)
- {
-#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
- ArrayPool.Shared.Return(buffer);
-#else
- // no-op
-#endif
- }
-}
diff --git a/src/SharpCompress/Common/ArchiveEncoding.cs b/src/SharpCompress/Common/ArchiveEncoding.cs
index 3701a93b..f66044d3 100644
--- a/src/SharpCompress/Common/ArchiveEncoding.cs
+++ b/src/SharpCompress/Common/ArchiveEncoding.cs
@@ -8,12 +8,12 @@ public class ArchiveEncoding
///
/// Default encoding to use when archive format doesn't specify one.
///
- public Encoding? Default { get; set; }
+ public Encoding Default { get; set; }
///
/// ArchiveEncoding used by encryption schemes which don't comply with RFC 2898.
///
- public Encoding? Password { get; set; }
+ public Encoding Password { get; set; }
///
/// Set this encoding when you want to force it for all encoding operations.
@@ -50,8 +50,6 @@ public class ArchiveEncoding
public Encoding GetEncoding() => Forced ?? Default ?? Encoding.UTF8;
- public Encoding GetPasswordEncoding() => Password ?? Encoding.UTF8;
-
public Func GetDecoder() =>
CustomDecoder ?? ((bytes, index, count) => GetEncoding().GetString(bytes, index, count));
}
diff --git a/src/SharpCompress/Common/CompressionType.cs b/src/SharpCompress/Common/CompressionType.cs
index 20f166c4..11263245 100644
--- a/src/SharpCompress/Common/CompressionType.cs
+++ b/src/SharpCompress/Common/CompressionType.cs
@@ -14,7 +14,5 @@ public enum CompressionType
LZip,
Xz,
Unknown,
- Deflate64,
- Shrink,
- Lzw
+ Deflate64
}
diff --git a/src/SharpCompress/Common/Entry.cs b/src/SharpCompress/Common/Entry.cs
index 6209b3de..85219a43 100644
--- a/src/SharpCompress/Common/Entry.cs
+++ b/src/SharpCompress/Common/Entry.cs
@@ -14,7 +14,7 @@ public abstract class Entry : IEntry
///
/// The string key of the file internal to the Archive.
///
- public abstract string? Key { get; }
+ public abstract string Key { get; }
///
/// The target of a symlink entry internal to the Archive. Will be null if not a symlink.
@@ -71,11 +71,11 @@ public abstract class Entry : IEntry
///
public abstract bool IsSplitAfter { get; }
- public int VolumeIndexFirst => Parts.FirstOrDefault()?.Index ?? 0;
- public int VolumeIndexLast => Parts.LastOrDefault()?.Index ?? 0;
+ public int VolumeIndexFirst => Parts?.FirstOrDefault()?.Index ?? 0;
+ public int VolumeIndexLast => Parts?.LastOrDefault()?.Index ?? 0;
///
- public override string ToString() => Key ?? "Entry";
+ public override string ToString() => Key;
internal abstract IEnumerable Parts { get; }
diff --git a/src/SharpCompress/Common/ExtractionMethods.cs b/src/SharpCompress/Common/ExtractionMethods.cs
index 27d41648..c8e5896e 100644
--- a/src/SharpCompress/Common/ExtractionMethods.cs
+++ b/src/SharpCompress/Common/ExtractionMethods.cs
@@ -16,7 +16,7 @@ internal static class ExtractionMethods
)
{
string destinationFileName;
- var fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory);
+ string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory);
//check for trailing slash.
if (
@@ -36,12 +36,11 @@ internal static class ExtractionMethods
options ??= new ExtractionOptions() { Overwrite = true };
- var file = Path.GetFileName(entry.Key.NotNull("Entry Key is null")).NotNull("File is null");
+ string file = Path.GetFileName(entry.Key);
if (options.ExtractFullPath)
{
- var folder = Path.GetDirectoryName(entry.Key.NotNull("Entry Key is null"))
- .NotNull("Directory is null");
- var destdir = Path.GetFullPath(Path.Combine(fullDestinationDirectoryPath, folder));
+ string folder = Path.GetDirectoryName(entry.Key)!;
+ string destdir = Path.GetFullPath(Path.Combine(fullDestinationDirectoryPath, folder));
if (!Directory.Exists(destdir))
{
@@ -103,7 +102,7 @@ internal static class ExtractionMethods
}
else
{
- var fm = FileMode.Create;
+ FileMode fm = FileMode.Create;
options ??= new ExtractionOptions() { Overwrite = true };
if (!options.Overwrite)
diff --git a/src/SharpCompress/Common/FilePart.cs b/src/SharpCompress/Common/FilePart.cs
index 23b8b400..3c286d54 100644
--- a/src/SharpCompress/Common/FilePart.cs
+++ b/src/SharpCompress/Common/FilePart.cs
@@ -8,7 +8,7 @@ public abstract class FilePart
internal ArchiveEncoding ArchiveEncoding { get; }
- internal abstract string? FilePartName { get; }
+ internal abstract string FilePartName { get; }
public int Index { get; set; }
internal abstract Stream GetCompressedStream();
diff --git a/src/SharpCompress/Common/GZip/GZipEntry.cs b/src/SharpCompress/Common/GZip/GZipEntry.cs
index 9a551d07..bb9a22da 100644
--- a/src/SharpCompress/Common/GZip/GZipEntry.cs
+++ b/src/SharpCompress/Common/GZip/GZipEntry.cs
@@ -6,23 +6,23 @@ namespace SharpCompress.Common.GZip;
public class GZipEntry : Entry
{
- private readonly GZipFilePart? _filePart;
+ private readonly GZipFilePart _filePart;
- internal GZipEntry(GZipFilePart? filePart) => _filePart = filePart;
+ internal GZipEntry(GZipFilePart filePart) => _filePart = filePart;
public override CompressionType CompressionType => CompressionType.GZip;
- public override long Crc => _filePart?.Crc ?? 0;
+ public override long Crc => _filePart.Crc ?? 0;
- public override string? Key => _filePart?.FilePartName;
+ public override string Key => _filePart.FilePartName;
public override string? LinkTarget => null;
public override long CompressedSize => 0;
- public override long Size => _filePart?.UncompressedSize ?? 0;
+ public override long Size => _filePart.UncompressedSize ?? 0;
- public override DateTime? LastModifiedTime => _filePart?.DateModified;
+ public override DateTime? LastModifiedTime => _filePart.DateModified;
public override DateTime? CreatedTime => null;
@@ -36,7 +36,7 @@ public class GZipEntry : Entry
public override bool IsSplitAfter => false;
- internal override IEnumerable Parts => _filePart.Empty();
+ internal override IEnumerable Parts => _filePart.AsEnumerable();
internal static IEnumerable GetEntries(Stream stream, OptionsBase options)
{
diff --git a/src/SharpCompress/Common/GZip/GZipFilePart.cs b/src/SharpCompress/Common/GZip/GZipFilePart.cs
index 4a1c9515..fbf4ee45 100644
--- a/src/SharpCompress/Common/GZip/GZipFilePart.cs
+++ b/src/SharpCompress/Common/GZip/GZipFilePart.cs
@@ -34,7 +34,7 @@ internal sealed class GZipFilePart : FilePart
internal uint? Crc { get; private set; }
internal uint? UncompressedSize { get; private set; }
- internal override string? FilePartName => _name;
+ internal override string FilePartName => _name!;
internal override Stream GetCompressedStream() =>
new DeflateStream(_stream, CompressionMode.Decompress, CompressionLevel.Default);
diff --git a/src/SharpCompress/Common/GZip/GZipVolume.cs b/src/SharpCompress/Common/GZip/GZipVolume.cs
index 600ba8e3..0dd9b8d9 100644
--- a/src/SharpCompress/Common/GZip/GZipVolume.cs
+++ b/src/SharpCompress/Common/GZip/GZipVolume.cs
@@ -5,7 +5,7 @@ namespace SharpCompress.Common.GZip;
public class GZipVolume : Volume
{
- public GZipVolume(Stream stream, ReaderOptions? options, int index)
+ public GZipVolume(Stream stream, ReaderOptions options, int index = 0)
: base(stream, options, index) { }
public GZipVolume(FileInfo fileInfo, ReaderOptions options)
diff --git a/src/SharpCompress/Common/IEntry.cs b/src/SharpCompress/Common/IEntry.cs
index 56e1db81..df1fa603 100644
--- a/src/SharpCompress/Common/IEntry.cs
+++ b/src/SharpCompress/Common/IEntry.cs
@@ -9,7 +9,7 @@ public interface IEntry
long CompressedSize { get; }
long Crc { get; }
DateTime? CreatedTime { get; }
- string? Key { get; }
+ string Key { get; }
string? LinkTarget { get; }
bool IsDirectory { get; }
bool IsEncrypted { get; }
diff --git a/src/SharpCompress/Common/IVolume.cs b/src/SharpCompress/Common/IVolume.cs
index aed35fd0..abbc0406 100644
--- a/src/SharpCompress/Common/IVolume.cs
+++ b/src/SharpCompress/Common/IVolume.cs
@@ -6,5 +6,5 @@ public interface IVolume : IDisposable
{
int Index { get; }
- string? FileName { get; }
+ string FileName { get; }
}
diff --git a/src/SharpCompress/Common/OptionsBase.cs b/src/SharpCompress/Common/OptionsBase.cs
index 8d1cbd1c..61a6cb55 100644
--- a/src/SharpCompress/Common/OptionsBase.cs
+++ b/src/SharpCompress/Common/OptionsBase.cs
@@ -7,5 +7,5 @@ public class OptionsBase
///
public bool LeaveStreamOpen { get; set; } = true;
- public ArchiveEncoding ArchiveEncoding { get; set; } = new();
+ public ArchiveEncoding ArchiveEncoding { get; set; } = new ArchiveEncoding();
}
diff --git a/src/SharpCompress/Common/PasswordProtectedException.cs b/src/SharpCompress/Common/PasswordProtectedException.cs
new file mode 100644
index 00000000..9ebe3d65
--- /dev/null
+++ b/src/SharpCompress/Common/PasswordProtectedException.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace SharpCompress.Common;
+
+public class PasswordProtectedException : ExtractionException
+{
+ public PasswordProtectedException(string message)
+ : base(message) { }
+
+ public PasswordProtectedException(string message, Exception inner)
+ : base(message, inner) { }
+}
diff --git a/src/SharpCompress/Common/Rar/CryptKey3.cs b/src/SharpCompress/Common/Rar/CryptKey3.cs
deleted file mode 100644
index 93e451b1..00000000
--- a/src/SharpCompress/Common/Rar/CryptKey3.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-#nullable disable
-
-using System.Security.Cryptography;
-using System.Text;
-using SharpCompress.Common.Rar.Headers;
-
-namespace SharpCompress.Common.Rar;
-
-internal class CryptKey3 : ICryptKey
-{
- const int AES_128 = 128;
-
- private string _password;
-
- public CryptKey3(string password) => _password = password ?? "";
-
- public ICryptoTransform Transformer(byte[] salt)
- {
- var aesIV = new byte[EncryptionConstV5.SIZE_INITV];
-
- var rawLength = 2 * _password.Length;
- var rawPassword = new byte[rawLength + EncryptionConstV5.SIZE_SALT30];
- var passwordBytes = Encoding.UTF8.GetBytes(_password);
- for (var i = 0; i < _password.Length; i++)
- {
- rawPassword[i * 2] = passwordBytes[i];
- rawPassword[(i * 2) + 1] = 0;
- }
-
- for (var i = 0; i < salt.Length; i++)
- {
- rawPassword[i + rawLength] = salt[i];
- }
-
- var msgDigest = SHA1.Create();
- const int noOfRounds = (1 << 18);
- const int iblock = 3;
-
- byte[] digest;
- var data = new byte[(rawPassword.Length + iblock) * noOfRounds];
-
- //TODO slow code below, find ways to optimize
- for (var i = 0; i < noOfRounds; i++)
- {
- rawPassword.CopyTo(data, i * (rawPassword.Length + iblock));
-
- 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 >> 16);
-
- if (i % (noOfRounds / EncryptionConstV5.SIZE_INITV) == 0)
- {
- digest = msgDigest.ComputeHash(data, 0, (i + 1) * (rawPassword.Length + iblock));
- aesIV[i / (noOfRounds / EncryptionConstV5.SIZE_INITV)] = digest[19];
- }
- }
- digest = msgDigest.ComputeHash(data);
- //slow code ends
-
- var aesKey = new byte[EncryptionConstV5.SIZE_INITV];
- for (var i = 0; i < 4; i++)
- {
- for (var j = 0; j < 4; j++)
- {
- aesKey[(i * 4) + j] = (byte)(
- (
- ((digest[i * 4] * 0x1000000) & 0xff000000)
- | (uint)((digest[(i * 4) + 1] * 0x10000) & 0xff0000)
- | (uint)((digest[(i * 4) + 2] * 0x100) & 0xff00)
- | (uint)(digest[(i * 4) + 3] & 0xff)
- ) >> (j * 8)
- );
- }
- }
-
- var aes = Aes.Create();
- aes.KeySize = AES_128;
- aes.Mode = CipherMode.CBC;
- aes.Padding = PaddingMode.None;
- aes.Key = aesKey;
- aes.IV = aesIV;
- return aes.CreateDecryptor();
- }
-}
diff --git a/src/SharpCompress/Common/Rar/CryptKey5.cs b/src/SharpCompress/Common/Rar/CryptKey5.cs
deleted file mode 100644
index 0b802691..00000000
--- a/src/SharpCompress/Common/Rar/CryptKey5.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using SharpCompress.Common.Rar.Headers;
-
-namespace SharpCompress.Common.Rar;
-
-internal class CryptKey5 : ICryptKey
-{
- const int AES_256 = 256;
- const int DERIVED_KEY_LENGTH = 0x10;
- const int SHA256_DIGEST_SIZE = 32;
-
- private string _password;
- private Rar5CryptoInfo _cryptoInfo;
- private byte[] _pswCheck = { };
- private byte[] _hashKey = { };
-
- public CryptKey5(string password, Rar5CryptoInfo rar5CryptoInfo)
- {
- _password = password ?? "";
- _cryptoInfo = rar5CryptoInfo;
- }
-
- public byte[] PswCheck => _pswCheck;
-
- public byte[] HashKey => _hashKey;
-
- private static List GenerateRarPBKDF2Key(
- string password,
- byte[] salt,
- int iterations,
- int keyLength
- )
- {
- using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(password));
- var block = hmac.ComputeHash(salt);
- var finalHash = (byte[])block.Clone();
-
- var loop = new int[] { iterations, 17, 17 };
- var res = new List { };
-
- for (var x = 0; x < 3; x++)
- {
- for (var i = 1; i < loop[x]; i++)
- {
- block = hmac.ComputeHash(block);
- for (var j = 0; j < finalHash.Length; j++)
- {
- finalHash[j] ^= block[j];
- }
- }
-
- res.Add((byte[])finalHash.Clone());
- }
-
- return res;
- }
-
- public ICryptoTransform Transformer(byte[] salt)
- {
- var iterations = (1 << _cryptoInfo.LG2Count); // Adjust the number of iterations as needed
-
- var salt_rar5 = salt.Concat(new byte[] { 0, 0, 0, 1 });
- var derivedKey = GenerateRarPBKDF2Key(
- _password,
- salt_rar5.ToArray(),
- iterations,
- DERIVED_KEY_LENGTH
- );
-
- _hashKey = derivedKey[1];
-
- _pswCheck = new byte[EncryptionConstV5.SIZE_PSWCHECK];
-
- for (var i = 0; i < SHA256_DIGEST_SIZE; i++)
- {
- _pswCheck[i % EncryptionConstV5.SIZE_PSWCHECK] ^= derivedKey[2][i];
- }
-
- if (_cryptoInfo.UsePswCheck && !_cryptoInfo.PswCheck.SequenceEqual(_pswCheck))
- {
- throw new CryptographicException("The password did not match.");
- }
-
- var aes = Aes.Create();
- aes.KeySize = AES_256;
- aes.Mode = CipherMode.CBC;
- aes.Padding = PaddingMode.None;
- aes.Key = derivedKey[0];
- aes.IV = _cryptoInfo.InitV;
- return aes.CreateDecryptor();
- }
-}
diff --git a/src/SharpCompress/Common/Rar/Headers/ArchiveCryptHeader.cs b/src/SharpCompress/Common/Rar/Headers/ArchiveCryptHeader.cs
index 5aa29d49..619e8fc9 100644
--- a/src/SharpCompress/Common/Rar/Headers/ArchiveCryptHeader.cs
+++ b/src/SharpCompress/Common/Rar/Headers/ArchiveCryptHeader.cs
@@ -1,19 +1,50 @@
#nullable disable
-using System;
-using System.Security.Cryptography;
-using SharpCompress.Common.Rar.Headers;
using SharpCompress.IO;
namespace SharpCompress.Common.Rar.Headers;
internal class ArchiveCryptHeader : RarHeader
{
+ private const int CRYPT_VERSION = 0; // Supported encryption version.
+ private const int SIZE_SALT50 = 16;
+ private const int SIZE_PSWCHECK = 8;
+ private const int SIZE_PSWCHECK_CSUM = 4;
+ private const int CRYPT5_KDF_LG2_COUNT_MAX = 24; // LOG2 of maximum accepted iteration count.
+
+ private bool _usePswCheck;
+ private uint _lg2Count; // Log2 of PBKDF2 repetition count.
+ private byte[] _salt;
+ private byte[] _pswCheck;
+ private byte[] _pswCheckCsm;
+
public ArchiveCryptHeader(RarHeader header, RarCrcBinaryReader reader)
: base(header, reader, HeaderType.Crypt) { }
- public Rar5CryptoInfo CryptInfo = new();
+ protected override void ReadFinish(MarkingBinaryReader reader)
+ {
+ var cryptVersion = reader.ReadRarVIntUInt32();
+ if (cryptVersion > CRYPT_VERSION)
+ {
+ //error?
+ return;
+ }
+ var encryptionFlags = reader.ReadRarVIntUInt32();
+ _usePswCheck = FlagUtility.HasFlag(encryptionFlags, EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
+ _lg2Count = reader.ReadRarVIntByte(1);
- protected override void ReadFinish(MarkingBinaryReader reader) =>
- CryptInfo = new Rar5CryptoInfo(reader, false);
+ //UsePswCheck = HasHeaderFlag(EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
+ if (_lg2Count > CRYPT5_KDF_LG2_COUNT_MAX)
+ {
+ //error?
+ return;
+ }
+
+ _salt = reader.ReadBytes(SIZE_SALT50);
+ if (_usePswCheck)
+ {
+ _pswCheck = reader.ReadBytes(SIZE_PSWCHECK);
+ _pswCheckCsm = reader.ReadBytes(SIZE_PSWCHECK_CSUM);
+ }
+ }
}
diff --git a/src/SharpCompress/Common/Rar/Headers/FileHeader.cs b/src/SharpCompress/Common/Rar/Headers/FileHeader.cs
index eea8293d..e95052ef 100644
--- a/src/SharpCompress/Common/Rar/Headers/FileHeader.cs
+++ b/src/SharpCompress/Common/Rar/Headers/FileHeader.cs
@@ -1,11 +1,5 @@
#nullable disable
-using System;
-using System.IO;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using SharpCompress.IO;
#if !Rar2017_64bit
using size_t = System.UInt32;
#else
@@ -14,11 +8,16 @@ using nuint = System.UInt64;
using size_t = System.UInt64;
#endif
+using SharpCompress.IO;
+using System;
+using System.IO;
+using System.Text;
+
namespace SharpCompress.Common.Rar.Headers;
internal class FileHeader : RarHeader
{
- private byte[] _hash;
+ private uint _fileCrc;
public FileHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
: base(header, reader, headerType) { }
@@ -53,7 +52,7 @@ internal class FileHeader : RarHeader
if (HasFlag(FileFlagsV5.HAS_CRC32))
{
- FileCrc = reader.ReadBytes(4);
+ FileCrc = reader.ReadUInt32();
}
var compressionInfo = reader.ReadRarVIntUInt16();
@@ -105,13 +104,7 @@ internal class FileHeader : RarHeader
throw new InvalidFormatException("rar5 header size / extra size inconsistency");
}
- const ushort FHEXTRA_CRYPT = 0x01;
- const ushort FHEXTRA_HASH = 0x02;
- const ushort FHEXTRA_HTIME = 0x03;
- // const ushort FHEXTRA_VERSION = 0x04;
- const ushort FHEXTRA_REDIR = 0x05;
- // const ushort FHEXTRA_UOWNER = 0x06;
- // const ushort FHEXTRA_SUBDATA = 0x07;
+ isEncryptedRar5 = false;
while (RemainingHeaderBytes(reader) > 0)
{
@@ -120,30 +113,23 @@ internal class FileHeader : RarHeader
var type = reader.ReadRarVIntUInt16();
switch (type)
{
- case FHEXTRA_CRYPT: // file encryption
- {
- Rar5CryptoInfo = new Rar5CryptoInfo(reader, true);
+ //TODO
+ case 1: // file encryption
- if (Rar5CryptoInfo.PswCheck.All(singleByte => singleByte == 0))
- {
- Rar5CryptoInfo = null;
- }
- }
- break;
- case FHEXTRA_HASH:
{
- const uint FHEXTRA_HASH_BLAKE2 = 0x0;
- // const uint HASH_BLAKE2 = 0x03;
- const int BLAKE2_DIGEST_SIZE = 0x20;
- if ((uint)reader.ReadRarVInt() == FHEXTRA_HASH_BLAKE2)
- {
- // var hash = HASH_BLAKE2;
- _hash = reader.ReadBytes(BLAKE2_DIGEST_SIZE);
- }
- // enum HASH_TYPE {HASH_NONE,HASH_RAR14,HASH_CRC32,HASH_BLAKE2};
+ isEncryptedRar5 = true;
+
+ //var version = reader.ReadRarVIntByte();
+ //if (version != 0) throw new InvalidFormatException("unknown encryption algorithm " + version);
}
break;
- case FHEXTRA_HTIME: // file time
+ // case 2: // file hash
+ // {
+ //
+ // }
+ // break;
+ case 3: // file time
+
{
var flags = reader.ReadRarVIntUInt16();
var isWindowsTime = (flags & 1) == 0;
@@ -162,27 +148,22 @@ internal class FileHeader : RarHeader
}
break;
//TODO
- // case FHEXTRA_VERSION: // file version
+ // case 4: // file version
// {
//
// }
// break;
- case FHEXTRA_REDIR: // file system redirection
- {
- RedirType = reader.ReadRarVIntByte();
- RedirFlags = reader.ReadRarVIntByte();
- var nn = reader.ReadRarVIntUInt16();
- var bb = reader.ReadBytes(nn);
- RedirTargetName = ConvertPathV5(Encoding.UTF8.GetString(bb, 0, bb.Length));
- }
- break;
- //TODO
- // case FHEXTRA_UOWNER: // unix owner
+ // case 5: // file system redirection
// {
//
// }
// break;
- // case FHEXTRA_SUBDATA: // service data
+ // case 6: // unix owner
+ // {
+ //
+ // }
+ // break;
+ // case 7: // service data
// {
//
// }
@@ -190,7 +171,6 @@ internal class FileHeader : RarHeader
default:
// skip unknown record types to allow new record types to be added in the future
- //Console.WriteLine($"unhandled rar header field type {type}");
break;
}
// drain any trailing bytes of extra record
@@ -242,7 +222,7 @@ internal class FileHeader : RarHeader
HostOs = reader.ReadByte();
- FileCrc = reader.ReadBytes(4);
+ FileCrc = reader.ReadUInt32();
FileLastModifiedTime = Utility.DosDateToDateTime(reader.ReadUInt32());
@@ -275,11 +255,13 @@ internal class FileHeader : RarHeader
var fileNameBytes = reader.ReadBytes(nameSize);
+ const int saltSize = 8;
const int newLhdSize = 32;
switch (HeaderCode)
{
case HeaderCodeV.RAR4_FILE_HEADER:
+
{
if (HasFlag(FileFlagsV4.UNICODE))
{
@@ -306,11 +288,12 @@ internal class FileHeader : RarHeader
}
break;
case HeaderCodeV.RAR4_NEW_SUB_HEADER:
+
{
var datasize = HeaderSize - newLhdSize - nameSize;
if (HasFlag(FileFlagsV4.SALT))
{
- datasize -= EncryptionConstV5.SIZE_SALT30;
+ datasize -= saltSize;
}
if (datasize > 0)
{
@@ -331,7 +314,7 @@ internal class FileHeader : RarHeader
if (HasFlag(FileFlagsV4.SALT))
{
- R4Salt = reader.ReadBytes(EncryptionConstV5.SIZE_SALT30);
+ R4Salt = reader.ReadBytes(saltSize);
}
if (HasFlag(FileFlagsV4.EXT_TIME))
{
@@ -412,10 +395,18 @@ internal class FileHeader : RarHeader
private bool HasFlag(ushort flag) => (Flags & flag) == flag;
- internal byte[] FileCrc
+ internal uint FileCrc
{
- get => _hash;
- private set => _hash = value;
+ get
+ {
+ if (IsRar5 && !HasFlag(FileFlagsV5.HAS_CRC32))
+ {
+ //!!! rar5:
+ throw new InvalidOperationException("TODO rar5");
+ }
+ return _fileCrc;
+ }
+ private set => _fileCrc = value;
}
// 0 - storing
@@ -437,17 +428,11 @@ internal class FileHeader : RarHeader
public bool IsSolid { get; private set; }
- public byte RedirType { get; private set; }
- public bool IsRedir => RedirType != 0;
- public byte RedirFlags { get; private set; }
- public bool IsRedirDirectory => (RedirFlags & RedirFlagV5.DIRECTORY) != 0;
- public string RedirTargetName { get; private set; }
-
// unused for UnpackV1 implementation (limitation)
internal size_t WindowSize { get; private set; }
internal byte[] R4Salt { get; private set; }
- internal Rar5CryptoInfo Rar5CryptoInfo { get; private set; }
+
private byte HostOs { get; set; }
internal uint FileAttributes { get; private set; }
internal long CompressedSize { get; private set; }
@@ -465,7 +450,8 @@ internal class FileHeader : RarHeader
public bool IsDirectory => HasFlag(IsRar5 ? FileFlagsV5.DIRECTORY : FileFlagsV4.DIRECTORY);
- public bool IsEncrypted => IsRar5 ? Rar5CryptoInfo != null : HasFlag(FileFlagsV4.PASSWORD);
+ private bool isEncryptedRar5 = false;
+ public bool IsEncrypted => IsRar5 ? isEncryptedRar5 : HasFlag(FileFlagsV4.PASSWORD);
internal DateTime? FileLastModifiedTime { get; private set; }
diff --git a/src/SharpCompress/Common/Rar/Headers/Flags.cs b/src/SharpCompress/Common/Rar/Headers/Flags.cs
index 990dbc99..5a52f001 100644
--- a/src/SharpCompress/Common/Rar/Headers/Flags.cs
+++ b/src/SharpCompress/Common/Rar/Headers/Flags.cs
@@ -50,17 +50,6 @@ internal static class EncryptionFlagsV5
public const uint FHEXTRA_CRYPT_HASHMAC = 0x02;
}
-internal static class EncryptionConstV5
-{
- public const int VERSION = 0;
- public const uint CRYPT5_KDF_LG2_COUNT_MAX = 0x24;
- public const int SIZE_SALT30 = 0x08;
- public const int SIZE_SALT50 = 0x10;
- public const int SIZE_INITV = 0x10;
- public const int SIZE_PSWCHECK = 0x08;
- public const int SIZE_PSWCHECK_CSUM = 0x04;
-}
-
internal static class HeaderFlagsV5
{
public const ushort HAS_EXTRA = 0x0001;
@@ -157,17 +146,3 @@ internal static class EndArchiveFlagsV5
{
public const ushort HAS_NEXT_VOLUME = 0x0001;
}
-
-internal static class RedirTypeV5
-{
- public const byte UNIX_SYMLINK = 0x0001;
- public const byte WIN_SYMLINK = 0x0002;
- public const byte WIN_JUNCTION = 0x0003;
- public const byte HARD_LINK = 0x0004;
- public const byte FILE_COPY = 0x0005;
-}
-
-internal static class RedirFlagV5
-{
- public const byte DIRECTORY = 0x0001;
-}
diff --git a/src/SharpCompress/Common/Rar/Headers/RarHeader.cs b/src/SharpCompress/Common/Rar/Headers/RarHeader.cs
index 0d8648e8..81002fc4 100644
--- a/src/SharpCompress/Common/Rar/Headers/RarHeader.cs
+++ b/src/SharpCompress/Common/Rar/Headers/RarHeader.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using SharpCompress.IO;
diff --git a/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs b/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs
index 74d68fc7..d371166d 100644
--- a/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs
+++ b/src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs
@@ -1,7 +1,5 @@
using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using SharpCompress.Common.Rar;
using SharpCompress.IO;
using SharpCompress.Readers;
@@ -11,8 +9,6 @@ public class RarHeaderFactory
{
private bool _isRar5;
- private Rar5CryptoInfo? _cryptInfo;
-
public RarHeaderFactory(StreamingMode mode, ReaderOptions options)
{
StreamingMode = mode;
@@ -57,19 +53,7 @@ public class RarHeaderFactory
"Encrypted Rar archive has no password specified."
);
}
-
- if (_isRar5 && _cryptInfo != null)
- {
- _cryptInfo.ReadInitV(new MarkingBinaryReader(stream));
- var _headerKey = new CryptKey5(Options.Password!, _cryptInfo);
-
- reader = new RarCryptoBinaryReader(stream, _headerKey, _cryptInfo.Salt);
- }
- else
- {
- var key = new CryptKey3(Options.Password);
- reader = new RarCryptoBinaryReader(stream, key);
- }
+ reader = new RarCryptoBinaryReader(stream, Options.Password);
}
var header = RarHeader.TryReadBase(reader, _isRar5, Options.ArchiveEncoding);
@@ -98,11 +82,13 @@ public class RarHeaderFactory
switch (StreamingMode)
{
case StreamingMode.Seekable:
+
{
reader.BaseStream.Position += ph.DataSize;
}
break;
case StreamingMode.Streaming:
+
{
reader.BaseStream.Skip(ph.DataSize);
}
@@ -119,14 +105,7 @@ public class RarHeaderFactory
case HeaderCodeV.RAR5_SERVICE_HEADER:
{
var fh = new FileHeader(header, reader, HeaderType.Service);
- if (fh.FileName == "CMT")
- {
- fh.PackedStream = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
- }
- else
- {
- SkipData(fh, reader);
- }
+ SkipData(fh, reader);
return fh;
}
@@ -144,15 +123,17 @@ public class RarHeaderFactory
switch (StreamingMode)
{
case StreamingMode.Seekable:
+
{
fh.DataStartPosition = reader.BaseStream.Position;
reader.BaseStream.Position += fh.CompressedSize;
}
break;
case StreamingMode.Streaming:
+
{
var ms = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
- if (fh.R4Salt is null && fh.Rar5CryptoInfo is null)
+ if (fh.R4Salt is null)
{
fh.PackedStream = ms;
}
@@ -160,10 +141,8 @@ public class RarHeaderFactory
{
fh.PackedStream = new RarCryptoWrapper(
ms,
- fh.R4Salt is null ? fh.Rar5CryptoInfo.Salt : fh.R4Salt,
- fh.R4Salt is null
- ? new CryptKey5(Options.Password!, fh.Rar5CryptoInfo)
- : new CryptKey3(Options.Password!)
+ Options.Password!,
+ fh.R4Salt
);
}
}
@@ -182,11 +161,9 @@ public class RarHeaderFactory
}
case HeaderCodeV.RAR5_ARCHIVE_ENCRYPTION_HEADER:
{
- var cryptoHeader = new ArchiveCryptHeader(header, reader);
+ var ch = new ArchiveCryptHeader(header, reader);
IsEncrypted = true;
- _cryptInfo = cryptoHeader.CryptInfo;
-
- return cryptoHeader;
+ return ch;
}
default:
{
@@ -200,12 +177,14 @@ public class RarHeaderFactory
switch (StreamingMode)
{
case StreamingMode.Seekable:
+
{
fh.DataStartPosition = reader.BaseStream.Position;
reader.BaseStream.Position += fh.CompressedSize;
}
break;
case StreamingMode.Streaming:
+
{
//skip the data because it's useless?
reader.BaseStream.Skip(fh.CompressedSize);
diff --git a/src/SharpCompress/Common/Rar/ICryptKey.cs b/src/SharpCompress/Common/Rar/ICryptKey.cs
deleted file mode 100644
index 94f068f5..00000000
--- a/src/SharpCompress/Common/Rar/ICryptKey.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System.Security.Cryptography;
-
-namespace SharpCompress.Common.Rar;
-
-internal interface ICryptKey
-{
- ICryptoTransform Transformer(byte[] salt);
-}
diff --git a/src/SharpCompress/Common/Rar/Rar5CryptoInfo.cs b/src/SharpCompress/Common/Rar/Rar5CryptoInfo.cs
deleted file mode 100644
index 7b8edff9..00000000
--- a/src/SharpCompress/Common/Rar/Rar5CryptoInfo.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Security.Cryptography;
-using SharpCompress.Common.Rar.Headers;
-using SharpCompress.IO;
-
-namespace SharpCompress.Common.Rar;
-
-internal class Rar5CryptoInfo
-{
- public Rar5CryptoInfo() { }
-
- public Rar5CryptoInfo(MarkingBinaryReader reader, bool readInitV)
- {
- var cryptVersion = reader.ReadRarVIntUInt32();
- if (cryptVersion > EncryptionConstV5.VERSION)
- {
- throw new CryptographicException($"Unsupported crypto version of {cryptVersion}");
- }
- var encryptionFlags = reader.ReadRarVIntUInt32();
- UsePswCheck = FlagUtility.HasFlag(encryptionFlags, EncryptionFlagsV5.CHFL_CRYPT_PSWCHECK);
- LG2Count = reader.ReadRarVIntByte(1);
-
- if (LG2Count > EncryptionConstV5.CRYPT5_KDF_LG2_COUNT_MAX)
- {
- throw new CryptographicException($"Unsupported LG2 count of {LG2Count}.");
- }
-
- Salt = reader.ReadBytes(EncryptionConstV5.SIZE_SALT50);
-
- if (readInitV) // File header needs to read IV here
- {
- ReadInitV(reader);
- }
-
- if (UsePswCheck)
- {
- PswCheck = reader.ReadBytes(EncryptionConstV5.SIZE_PSWCHECK);
- var _pswCheckCsm = reader.ReadBytes(EncryptionConstV5.SIZE_PSWCHECK_CSUM);
-
- var sha = SHA256.Create();
- UsePswCheck = sha.ComputeHash(PswCheck).AsSpan().StartsWith(_pswCheckCsm.AsSpan());
- }
- }
-
- public void ReadInitV(MarkingBinaryReader reader) =>
- InitV = reader.ReadBytes(EncryptionConstV5.SIZE_INITV);
-
- public bool UsePswCheck = false;
-
- public int LG2Count = 0;
-
- public byte[] InitV = { };
-
- public byte[] Salt = { };
-
- public byte[] PswCheck = { };
-}
diff --git a/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs b/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs
index 6e44286b..0be6e74e 100644
--- a/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs
+++ b/src/SharpCompress/Common/Rar/RarCryptoBinaryReader.cs
@@ -1,28 +1,28 @@
-#nullable disable
-
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
-using SharpCompress.Common.Rar.Headers;
-using SharpCompress.Crypto;
namespace SharpCompress.Common.Rar;
internal sealed class RarCryptoBinaryReader : RarCrcBinaryReader
{
- private BlockTransformer _rijndael;
- private readonly Queue _data = new();
+ private RarRijndael _rijndael;
+ private byte[] _salt;
+ private readonly string _password;
+ private readonly Queue _data = new Queue();
private long _readCount;
- public RarCryptoBinaryReader(Stream stream, ICryptKey cryptKey)
+ public RarCryptoBinaryReader(Stream stream, string password)
: base(stream)
{
- var salt = base.ReadBytes(EncryptionConstV5.SIZE_SALT30);
- _readCount += EncryptionConstV5.SIZE_SALT30;
- _rijndael = new BlockTransformer(cryptKey.Transformer(salt));
- }
+ _password = password;
- public RarCryptoBinaryReader(Stream stream, ICryptKey cryptKey, byte[] salt)
- : base(stream) => _rijndael = new BlockTransformer(cryptKey.Transformer(salt));
+ // coderb: not sure why this was being done at this logical point
+ //SkipQueue();
+ var salt = ReadBytes(8);
+
+ _salt = salt;
+ _rijndael = RarRijndael.InitializeFrom(_password, salt);
+ }
// track read count ourselves rather than using the underlying stream since we buffer
public override long CurrentReadByteCount
@@ -36,9 +36,29 @@ internal sealed class RarCryptoBinaryReader : RarCrcBinaryReader
public override void Mark() => _readCount = 0;
- public override byte ReadByte() => ReadAndDecryptBytes(1)[0];
+ private bool UseEncryption => _salt != null;
- public override byte[] ReadBytes(int count) => ReadAndDecryptBytes(count);
+ public override byte ReadByte()
+ {
+ if (UseEncryption)
+ {
+ return ReadAndDecryptBytes(1)[0];
+ }
+
+ _readCount++;
+ return base.ReadByte();
+ }
+
+ public override byte[] ReadBytes(int count)
+ {
+ if (UseEncryption)
+ {
+ return ReadAndDecryptBytes(count);
+ }
+
+ _readCount += count;
+ return base.ReadBytes(count);
+ }
private byte[] ReadAndDecryptBytes(int count)
{
diff --git a/src/SharpCompress/Common/Rar/RarCryptoWrapper.cs b/src/SharpCompress/Common/Rar/RarCryptoWrapper.cs
index 5500af8d..a1cee046 100644
--- a/src/SharpCompress/Common/Rar/RarCryptoWrapper.cs
+++ b/src/SharpCompress/Common/Rar/RarCryptoWrapper.cs
@@ -1,30 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
-using SharpCompress.Crypto;
namespace SharpCompress.Common.Rar;
internal sealed class RarCryptoWrapper : Stream
{
private readonly Stream _actualStream;
- private BlockTransformer _rijndael;
- private readonly Queue _data = new();
+ private readonly byte[] _salt;
+ private RarRijndael _rijndael;
+ private readonly Queue _data = new Queue();
- public RarCryptoWrapper(Stream actualStream, byte[] salt, ICryptKey key)
+ public RarCryptoWrapper(Stream actualStream, string password, byte[] salt)
{
_actualStream = actualStream;
- _rijndael = new BlockTransformer(key.Transformer(salt));
+ _salt = salt;
+ _rijndael = RarRijndael.InitializeFrom(password ?? "", salt);
}
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
- public override int Read(byte[] buffer, int offset, int count) =>
- ReadAndDecrypt(buffer, offset, count);
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ if (_salt is null)
+ {
+ return _actualStream.Read(buffer, offset, count);
+ }
+ return ReadAndDecrypt(buffer, offset, count);
+ }
public int ReadAndDecrypt(byte[] buffer, int offset, int count)
{
@@ -34,7 +41,7 @@ internal sealed class RarCryptoWrapper : Stream
if (sizeToRead > 0)
{
var alignedSize = sizeToRead + ((~sizeToRead + 1) & 0xf);
- Span cipherText = stackalloc byte[16];
+ Span cipherText = stackalloc byte[RarRijndael.CRYPTO_BLOCK_SIZE];
for (var i = 0; i < alignedSize / 16; i++)
{
//long ax = System.currentTimeMillis();
@@ -70,11 +77,11 @@ internal sealed class RarCryptoWrapper : Stream
protected override void Dispose(bool disposing)
{
- if (disposing)
+ if (_rijndael != null)
{
_rijndael.Dispose();
+ _rijndael = null!;
}
-
base.Dispose(disposing);
}
}
diff --git a/src/SharpCompress/Common/Rar/RarEntry.cs b/src/SharpCompress/Common/Rar/RarEntry.cs
index a064c2f8..7f280e4a 100644
--- a/src/SharpCompress/Common/Rar/RarEntry.cs
+++ b/src/SharpCompress/Common/Rar/RarEntry.cs
@@ -20,12 +20,12 @@ public abstract class RarEntry : Entry
///
/// The File's 32 bit CRC Hash
///
- public override long Crc => BitConverter.ToUInt32(FileHeader.FileCrc, 0);
+ public override long Crc => FileHeader.FileCrc;
///
/// The path of the file internal to the Rar Archive.
///
- public override string? Key => FileHeader.FileName;
+ public override string Key => FileHeader.FileName;
public override string? LinkTarget => null;
@@ -55,21 +55,12 @@ public abstract class RarEntry : Entry
public override bool IsEncrypted => FileHeader.IsEncrypted;
///
- /// Entry Windows file attributes
- ///
- public override int? Attrib => (int)FileHeader.FileAttributes;
-
- ///
- /// Entry is a directory
+ /// Entry is password protected and encrypted and cannot be extracted.
///
public override bool IsDirectory => FileHeader.IsDirectory;
public override bool IsSplitAfter => FileHeader.IsSplitAfter;
- public bool IsRedir => FileHeader.IsRedir;
-
- public string RedirTargetName => FileHeader.RedirTargetName;
-
public override string ToString() =>
string.Format(
"Entry Path: {0} Compressed Size: {1} Uncompressed Size: {2} CRC: {3}",
diff --git a/src/SharpCompress/Common/Rar/RarRijndael.cs b/src/SharpCompress/Common/Rar/RarRijndael.cs
new file mode 100644
index 00000000..94592639
--- /dev/null
+++ b/src/SharpCompress/Common/Rar/RarRijndael.cs
@@ -0,0 +1,114 @@
+#nullable disable
+
+using System;
+using System.Security.Cryptography;
+using System.Text;
+using SharpCompress.Crypto;
+
+namespace SharpCompress.Common.Rar;
+
+internal class RarRijndael : IDisposable
+{
+ internal const int CRYPTO_BLOCK_SIZE = 16;
+
+ private readonly string _password;
+ private readonly byte[] _salt;
+ private byte[] _aesInitializationVector;
+ private RijndaelEngine _rijndael;
+
+ private RarRijndael(string password, byte[] salt)
+ {
+ _password = password;
+ _salt = salt;
+ }
+
+ private void Initialize()
+ {
+ _rijndael = new RijndaelEngine();
+ _aesInitializationVector = new byte[CRYPTO_BLOCK_SIZE];
+ var rawLength = 2 * _password.Length;
+ var rawPassword = new byte[rawLength + 8];
+ var passwordBytes = Encoding.UTF8.GetBytes(_password);
+ for (var i = 0; i < _password.Length; i++)
+ {
+ rawPassword[i * 2] = passwordBytes[i];
+ rawPassword[(i * 2) + 1] = 0;
+ }
+ for (var i = 0; i < _salt.Length; i++)
+ {
+ rawPassword[i + rawLength] = _salt[i];
+ }
+
+ const int noOfRounds = (1 << 18);
+ const int iblock = 3;
+ byte[] digest;
+ var data = new byte[(rawPassword.Length + iblock) * noOfRounds];
+
+ //TODO slow code below, find ways to optimize
+ for (var i = 0; i < noOfRounds; i++)
+ {
+ rawPassword.CopyTo(data, i * (rawPassword.Length + iblock));
+
+ 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)
+ {
+ digest = SHA1.Create()
+ .ComputeHash(data, 0, (i + 1) * (rawPassword.Length + iblock));
+ _aesInitializationVector[i / (noOfRounds / CRYPTO_BLOCK_SIZE)] = digest[19];
+ }
+ }
+ digest = SHA1.Create().ComputeHash(data);
+ //slow code ends
+
+ var aesKey = new byte[CRYPTO_BLOCK_SIZE];
+ for (var i = 0; i < 4; i++)
+ {
+ for (var j = 0; j < 4; j++)
+ {
+ aesKey[(i * 4) + j] = (byte)(
+ (
+ ((digest[i * 4] * 0x1000000) & 0xff000000)
+ | (uint)((digest[(i * 4) + 1] * 0x10000) & 0xff0000)
+ | (uint)((digest[(i * 4) + 2] * 0x100) & 0xff00)
+ | (uint)(digest[(i * 4) + 3] & 0xff)
+ ) >> (j * 8)
+ );
+ }
+ }
+
+ _rijndael.Init(false, new KeyParameter(aesKey));
+ }
+
+ public static RarRijndael InitializeFrom(string password, byte[] salt)
+ {
+ var rijndael = new RarRijndael(password, salt);
+ rijndael.Initialize();
+ return rijndael;
+ }
+
+ public byte[] ProcessBlock(ReadOnlySpan cipherText)
+ {
+ Span plainText = stackalloc byte[CRYPTO_BLOCK_SIZE]; // 16 bytes
+ var decryptedBytes = new byte[CRYPTO_BLOCK_SIZE];
+ _rijndael.ProcessBlock(cipherText, plainText);
+
+ for (var j = 0; j < CRYPTO_BLOCK_SIZE; j++)
+ {
+ decryptedBytes[j] = (byte)(plainText[j] ^ _aesInitializationVector[j % 16]); //32:114, 33:101
+ }
+
+ for (var j = 0; j < _aesInitializationVector.Length; j++)
+ {
+ _aesInitializationVector[j] = cipherText[j];
+ }
+
+ return decryptedBytes;
+ }
+
+ public void Dispose() { }
+}
diff --git a/src/SharpCompress/Common/Rar/RarVolume.cs b/src/SharpCompress/Common/Rar/RarVolume.cs
index d05e16c2..7be719ec 100644
--- a/src/SharpCompress/Common/Rar/RarVolume.cs
+++ b/src/SharpCompress/Common/Rar/RarVolume.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
using SharpCompress.Common.Rar.Headers;
using SharpCompress.IO;
using SharpCompress.Readers;
@@ -15,14 +14,17 @@ namespace SharpCompress.Common.Rar;
public abstract class RarVolume : Volume
{
private readonly RarHeaderFactory _headerFactory;
- private int _maxCompressionAlgorithm;
+ internal int _maxCompressionAlgorithm;
- internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options, int index)
+ internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options, int index = 0)
: base(stream, options, index) => _headerFactory = new RarHeaderFactory(mode, options);
- private ArchiveHeader? ArchiveHeader { get; set; }
+#nullable disable
+ internal ArchiveHeader ArchiveHeader { get; private set; }
- private StreamingMode Mode => _headerFactory.StreamingMode;
+#nullable enable
+
+ internal StreamingMode Mode => _headerFactory.StreamingMode;
internal abstract IEnumerable ReadFileParts();
@@ -36,16 +38,19 @@ public abstract class RarVolume : Volume
switch (header.HeaderType)
{
case HeaderType.Mark:
+
{
lastMarkHeader = (MarkHeader)header;
}
break;
case HeaderType.Archive:
+
{
ArchiveHeader = (ArchiveHeader)header;
}
break;
case HeaderType.File:
+
{
var fh = (FileHeader)header;
if (_maxCompressionAlgorithm < fh.CompressionAlgorithm)
@@ -57,13 +62,19 @@ public abstract class RarVolume : Volume
}
break;
case HeaderType.Service:
+
{
var fh = (FileHeader)header;
if (fh.FileName == "CMT")
{
+ var part = CreateFilePart(lastMarkHeader!, fh);
var buffer = new byte[fh.CompressedSize];
- fh.PackedStream.Read(buffer, 0, buffer.Length);
- Comment = Encoding.UTF8.GetString(buffer, 0, buffer.Length - 1);
+ part.GetCompressedStream().Read(buffer, 0, buffer.Length);
+ Comment = System.Text.Encoding.UTF8.GetString(
+ buffer,
+ 0,
+ buffer.Length - 1
+ );
}
}
break;
@@ -97,7 +108,7 @@ public abstract class RarVolume : Volume
get
{
EnsureArchiveHeaderLoaded();
- return ArchiveHeader?.IsFirstVolume ?? false;
+ return ArchiveHeader.IsFirstVolume;
}
}
@@ -109,7 +120,7 @@ public abstract class RarVolume : Volume
get
{
EnsureArchiveHeaderLoaded();
- return ArchiveHeader?.IsVolume ?? false;
+ return ArchiveHeader.IsVolume;
}
}
@@ -122,7 +133,7 @@ public abstract class RarVolume : Volume
get
{
EnsureArchiveHeaderLoaded();
- return ArchiveHeader?.IsSolid ?? false;
+ return ArchiveHeader.IsSolid;
}
}
diff --git a/src/SharpCompress/Common/ReaderCancelledException.cs b/src/SharpCompress/Common/ReaderCancelledException.cs
deleted file mode 100644
index 918e5abb..00000000
--- a/src/SharpCompress/Common/ReaderCancelledException.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace SharpCompress.Common;
-
-public class ReaderCancelledException : Exception
-{
- public ReaderCancelledException(string message)
- : base(message) { }
-
- public ReaderCancelledException(string message, Exception inner)
- : base(message, inner) { }
-}
diff --git a/src/SharpCompress/Common/SevenZip/ArchiveDatabase.cs b/src/SharpCompress/Common/SevenZip/ArchiveDatabase.cs
index 4bac08ad..5e42494a 100644
--- a/src/SharpCompress/Common/SevenZip/ArchiveDatabase.cs
+++ b/src/SharpCompress/Common/SevenZip/ArchiveDatabase.cs
@@ -15,15 +15,15 @@ internal class ArchiveDatabase
internal long _startPositionAfterHeader;
internal long _dataStartPosition;
- internal List _packSizes = new();
- internal List _packCrCs = new();
- internal List _folders = new();
+ internal List _packSizes = new List();
+ internal List _packCrCs = new List();
+ internal List _folders = new List();
internal List _numUnpackStreamsVector;
- internal List _files = new();
+ internal List _files = new List();
- internal List _packStreamStartPositions = new();
- internal List _folderStartFileIndex = new();
- internal List _fileIndexToFolderIndexMap = new();
+ internal List _packStreamStartPositions = new List();
+ internal List _folderStartFileIndex = new List();
+ internal List _fileIndexToFolderIndexMap = new List();
internal IPasswordProvider PasswordProvider { get; }
@@ -35,7 +35,7 @@ internal class ArchiveDatabase
_packSizes.Clear();
_packCrCs.Clear();
_folders.Clear();
- _numUnpackStreamsVector = null;
+ _numUnpackStreamsVector = null!;
_files.Clear();
_packStreamStartPositions.Clear();
diff --git a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
index 3e506e0e..42b5b6b2 100644
--- a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
+++ b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
@@ -14,13 +14,13 @@ namespace SharpCompress.Common.SevenZip;
internal class ArchiveReader
{
internal Stream _stream;
- internal Stack _readerStack = new();
+ internal Stack _readerStack = new Stack();
internal DataReader _currentReader;
internal long _streamOrigin;
internal long _streamEnding;
internal byte[] _header;
- private readonly Dictionary _cachedStreams = new();
+ private readonly Dictionary _cachedStreams = new Dictionary();
internal void AddByteStream(byte[] buffer, int offset, int length)
{
@@ -1359,7 +1359,7 @@ internal class ArchiveReader
{
internal int _fileIndex;
internal int _folderIndex;
- internal List _extractStatuses = new();
+ internal List _extractStatuses = new List();
internal CExtractFolderInfo(int fileIndex, int folderIndex)
{
@@ -1393,7 +1393,7 @@ internal class ArchiveReader
public override bool CanWrite => false;
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override long Length => throw new NotSupportedException();
diff --git a/src/SharpCompress/Common/SevenZip/CFolder.cs b/src/SharpCompress/Common/SevenZip/CFolder.cs
index 8b0123da..9d3516b1 100644
--- a/src/SharpCompress/Common/SevenZip/CFolder.cs
+++ b/src/SharpCompress/Common/SevenZip/CFolder.cs
@@ -6,11 +6,11 @@ namespace SharpCompress.Common.SevenZip;
internal class CFolder
{
- internal List _coders = new();
- internal List _bindPairs = new();
- internal List _packStreams = new();
+ internal List _coders = new List();
+ internal List _bindPairs = new List();
+ internal List _packStreams = new List();
internal int _firstPackStreamId;
- internal List _unpackSizes = new();
+ internal List _unpackSizes = new List();
internal uint? _unpackCrc;
internal bool UnpackCrcDefined => _unpackCrc != null;
diff --git a/src/SharpCompress/Common/SevenZip/CMethodId.cs b/src/SharpCompress/Common/SevenZip/CMethodId.cs
index 8494aad5..6dce5773 100644
--- a/src/SharpCompress/Common/SevenZip/CMethodId.cs
+++ b/src/SharpCompress/Common/SevenZip/CMethodId.cs
@@ -7,10 +7,10 @@ internal readonly struct CMethodId
public const ulong K_LZMA2_ID = 0x21;
public const ulong K_AES_ID = 0x06F10701;
- public static readonly CMethodId K_COPY = new(K_COPY_ID);
- public static readonly CMethodId K_LZMA = new(K_LZMA_ID);
- public static readonly CMethodId K_LZMA2 = new(K_LZMA2_ID);
- public static readonly CMethodId K_AES = new(K_AES_ID);
+ public static readonly CMethodId K_COPY = new CMethodId(K_COPY_ID);
+ public static readonly CMethodId K_LZMA = new CMethodId(K_LZMA_ID);
+ public static readonly CMethodId K_LZMA2 = new CMethodId(K_LZMA2_ID);
+ public static readonly CMethodId K_AES = new CMethodId(K_AES_ID);
public readonly ulong _id;
diff --git a/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs b/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs
index fbcb3d00..66170ba8 100644
--- a/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs
+++ b/src/SharpCompress/Common/SevenZip/SevenZipEntry.cs
@@ -13,7 +13,7 @@ public class SevenZipEntry : Entry
public override long Crc => FilePart.Header.Crc ?? 0;
- public override string? Key => FilePart.Header.Name;
+ public override string Key => FilePart.Header.Name;
public override string? LinkTarget => null;
diff --git a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs
index fe221b53..aad191c9 100644
--- a/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs
+++ b/src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs
@@ -41,7 +41,7 @@ internal class SevenZipFilePart : FilePart
{
if (!Header.HasStream)
{
- throw new InvalidOperationException("File does not have a stream.");
+ return null!;
}
var folderStream = _database.GetFolderStream(_stream, Folder!, _database.PasswordProvider);
@@ -73,24 +73,34 @@ internal class SevenZipFilePart : FilePart
private const uint K_PPMD = 0x030401;
private const uint K_B_ZIP2 = 0x040202;
- private CompressionType GetCompression()
+ internal CompressionType GetCompression()
{
if (Header.IsDir)
- {
return CompressionType.None;
- }
- var coder = Folder.NotNull()._coders.First();
- return coder._methodId._id switch
+ var coder = Folder!._coders.First();
+ switch (coder._methodId._id)
{
- K_LZMA or K_LZMA2 => CompressionType.LZMA,
- K_PPMD => CompressionType.PPMd,
- K_B_ZIP2 => CompressionType.BZip2,
- _ => throw new NotImplementedException()
- };
+ case K_LZMA:
+ case K_LZMA2:
+ {
+ return CompressionType.LZMA;
+ }
+ case K_PPMD:
+ {
+ return CompressionType.PPMd;
+ }
+ case K_B_ZIP2:
+ {
+ return CompressionType.BZip2;
+ }
+ default:
+ throw new NotImplementedException();
+ }
}
internal bool IsEncrypted =>
- !Header.IsDir
- && Folder?._coders.FindIndex(c => c._methodId._id == CMethodId.K_AES_ID) != -1;
+ Header.IsDir
+ ? false
+ : Folder!._coders.FindIndex(c => c._methodId._id == CMethodId.K_AES_ID) != -1;
}
diff --git a/src/SharpCompress/Common/Tar/Headers/TarHeader.cs b/src/SharpCompress/Common/Tar/Headers/TarHeader.cs
index e9aa343c..ef86ab00 100644
--- a/src/SharpCompress/Common/Tar/Headers/TarHeader.cs
+++ b/src/SharpCompress/Common/Tar/Headers/TarHeader.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Buffers.Binary;
using System.IO;
@@ -7,12 +9,12 @@ namespace SharpCompress.Common.Tar.Headers;
internal sealed class TarHeader
{
- internal static readonly DateTime EPOCH = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ internal static readonly DateTime EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public TarHeader(ArchiveEncoding archiveEncoding) => ArchiveEncoding = archiveEncoding;
- internal string? Name { get; set; }
- internal string? LinkName { get; set; }
+ internal string Name { get; set; }
+ internal string LinkName { get; set; }
internal long Mode { get; set; }
internal long UserId { get; set; }
@@ -20,7 +22,7 @@ internal sealed class TarHeader
internal long Size { get; set; }
internal DateTime LastModifiedTime { get; set; }
internal EntryType EntryType { get; set; }
- internal Stream? PackedStream { get; set; }
+ internal Stream PackedStream { get; set; }
internal ArchiveEncoding ArchiveEncoding { get; }
internal const int BLOCK_SIZE = 512;
@@ -34,9 +36,7 @@ internal sealed class TarHeader
WriteOctalBytes(0, buffer, 116, 8); // group ID
//ArchiveEncoding.UTF8.GetBytes("magic").CopyTo(buffer, 257);
- var nameByteCount = ArchiveEncoding
- .GetEncoding()
- .GetByteCount(Name.NotNull("Name is null"));
+ 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
@@ -46,7 +46,7 @@ internal sealed class TarHeader
}
else
{
- WriteStringBytes(ArchiveEncoding.Encode(Name.NotNull("Name is null")), buffer, 100);
+ WriteStringBytes(ArchiveEncoding.Encode(Name), buffer, 100);
WriteOctalBytes(Size, buffer, 124, 12);
var time = (long)(LastModifiedTime.ToUniversalTime() - EPOCH).TotalSeconds;
WriteOctalBytes(time, buffer, 136, 12);
@@ -77,7 +77,7 @@ internal sealed class TarHeader
//
// and then infinite recursion is occured in WriteLongFilenameHeader because truncated.Length is 102.
Name = ArchiveEncoding.Decode(
- ArchiveEncoding.Encode(Name.NotNull("Name is null")),
+ ArchiveEncoding.Encode(Name),
0,
100 - ArchiveEncoding.GetEncoding().GetMaxByteCount(1)
);
@@ -87,7 +87,7 @@ internal sealed class TarHeader
private void WriteLongFilenameHeader(Stream output)
{
- var nameBytes = ArchiveEncoding.Encode(Name.NotNull("Name is null"));
+ var nameBytes = ArchiveEncoding.Encode(Name);
output.Write(nameBytes, 0, nameBytes.Length);
// pad to multiple of BlockSize bytes, and make sure a terminating null is added
@@ -101,79 +101,57 @@ internal sealed class TarHeader
internal bool Read(BinaryReader reader)
{
- string? longName = null;
- string? longLinkName = null;
- var hasLongValue = true;
- byte[] buffer;
- EntryType entryType;
-
- do
+ var buffer = ReadBlock(reader);
+ if (buffer.Length == 0)
{
- buffer = ReadBlock(reader);
-
- if (buffer.Length == 0)
- {
- return false;
- }
-
- entryType = ReadEntryType(buffer);
-
- // LongName and LongLink headers can follow each other and need
- // to apply to the header that follows them.
- if (entryType == EntryType.LongName)
- {
- longName = ReadLongName(reader, buffer);
- continue;
- }
- else if (entryType == EntryType.LongLink)
- {
- longLinkName = ReadLongName(reader, buffer);
- continue;
- }
-
- hasLongValue = false;
- } while (hasLongValue);
-
- Name = longName ?? ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
- EntryType = entryType;
- Size = ReadSize(buffer);
-
- // for symlinks, additionally read the linkname
- if (entryType == EntryType.SymLink || entryType == EntryType.HardLink)
- {
- LinkName = longLinkName ?? ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
+ return false;
}
- Mode = ReadAsciiInt64Base8(buffer, 100, 7);
+ // for symlinks, additionally read the linkname
+ if (ReadEntryType(buffer) == EntryType.SymLink)
+ {
+ LinkName = ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
+ }
- if (entryType == EntryType.Directory)
+ if (ReadEntryType(buffer) == EntryType.LongName)
+ {
+ Name = ReadLongName(reader, buffer);
+ buffer = ReadBlock(reader);
+ }
+ else
+ {
+ Name = ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
+ }
+
+ EntryType = ReadEntryType(buffer);
+ Size = ReadSize(buffer);
+
+ Mode = ReadAsciiInt64Base8(buffer, 100, 7);
+ if (EntryType == EntryType.Directory)
{
Mode |= 0b1_000_000_000;
}
- UserId = ReadAsciiInt64Base8oldGnu(buffer, 108, 7);
- GroupId = ReadAsciiInt64Base8oldGnu(buffer, 116, 7);
-
+ UserId = ReadAsciiInt64Base8(buffer, 108, 7);
+ GroupId = ReadAsciiInt64Base8(buffer, 116, 7);
var unixTimeStamp = ReadAsciiInt64Base8(buffer, 136, 11);
-
LastModifiedTime = EPOCH.AddSeconds(unixTimeStamp).ToLocalTime();
+
Magic = ArchiveEncoding.Decode(buffer, 257, 6).TrimNulls();
if (!string.IsNullOrEmpty(Magic) && "ustar".Equals(Magic))
{
- var namePrefix = ArchiveEncoding.Decode(buffer, 345, 157).TrimNulls();
-
+ var namePrefix = ArchiveEncoding.Decode(buffer, 345, 157);
+ namePrefix = namePrefix.TrimNulls();
if (!string.IsNullOrEmpty(namePrefix))
{
Name = namePrefix + "/" + Name;
}
}
-
- if (entryType != EntryType.LongName && Name.Length == 0)
+ if (EntryType != EntryType.LongName && Name.Length == 0)
{
return false;
}
-
return true;
}
@@ -271,24 +249,6 @@ internal sealed class TarHeader
return Convert.ToInt64(s, 8);
}
- private static long ReadAsciiInt64Base8oldGnu(byte[] buffer, int offset, int count)
- {
- if (buffer[offset] == 0x80 && buffer[offset + 1] == 0x00)
- {
- return buffer[offset + 4] << 24
- | buffer[offset + 5] << 16
- | buffer[offset + 6] << 8
- | buffer[offset + 7];
- }
- var s = Encoding.UTF8.GetString(buffer, offset, count).TrimNulls();
-
- if (string.IsNullOrEmpty(s))
- {
- return 0;
- }
- return Convert.ToInt64(s, 8);
- }
-
private static long ReadAsciiInt64(byte[] buffer, int offset, int count)
{
var s = Encoding.UTF8.GetString(buffer, offset, count).TrimNulls();
@@ -345,5 +305,5 @@ internal sealed class TarHeader
public long? DataStartPosition { get; set; }
- public string? Magic { get; set; }
+ public string Magic { get; set; }
}
diff --git a/src/SharpCompress/Common/Tar/TarEntry.cs b/src/SharpCompress/Common/Tar/TarEntry.cs
index 2597b837..59743070 100644
--- a/src/SharpCompress/Common/Tar/TarEntry.cs
+++ b/src/SharpCompress/Common/Tar/TarEntry.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -8,9 +10,9 @@ namespace SharpCompress.Common.Tar;
public class TarEntry : Entry
{
- private readonly TarFilePart? _filePart;
+ private readonly TarFilePart _filePart;
- internal TarEntry(TarFilePart? filePart, CompressionType type)
+ internal TarEntry(TarFilePart filePart, CompressionType type)
{
_filePart = filePart;
CompressionType = type;
@@ -20,15 +22,15 @@ public class TarEntry : Entry
public override long Crc => 0;
- public override string? Key => _filePart?.Header.Name;
+ public override string Key => _filePart.Header.Name;
- public override string? LinkTarget => _filePart?.Header.LinkName;
+ public override string LinkTarget => _filePart.Header.LinkName;
- public override long CompressedSize => _filePart?.Header.Size ?? 0;
+ public override long CompressedSize => _filePart.Header.Size;
- public override long Size => _filePart?.Header.Size ?? 0;
+ public override long Size => _filePart.Header.Size;
- public override DateTime? LastModifiedTime => _filePart?.Header.LastModifiedTime;
+ public override DateTime? LastModifiedTime => _filePart.Header.LastModifiedTime;
public override DateTime? CreatedTime => null;
@@ -38,17 +40,17 @@ public class TarEntry : Entry
public override bool IsEncrypted => false;
- public override bool IsDirectory => _filePart?.Header.EntryType == EntryType.Directory;
+ public override bool IsDirectory => _filePart.Header.EntryType == EntryType.Directory;
public override bool IsSplitAfter => false;
- public long Mode => _filePart?.Header.Mode ?? 0;
+ public long Mode => _filePart.Header.Mode;
- public long UserID => _filePart?.Header.UserId ?? 0;
+ public long UserID => _filePart.Header.UserId;
- public long GroupId => _filePart?.Header.GroupId ?? 0;
+ public long GroupId => _filePart.Header.GroupId;
- internal override IEnumerable Parts => _filePart.Empty();
+ internal override IEnumerable Parts => _filePart.AsEnumerable();
internal static IEnumerable GetEntries(
StreamingMode mode,
@@ -57,17 +59,17 @@ public class TarEntry : Entry
ArchiveEncoding archiveEncoding
)
{
- foreach (var header in TarHeaderFactory.ReadHeader(mode, stream, archiveEncoding))
+ foreach (var h in TarHeaderFactory.ReadHeader(mode, stream, archiveEncoding))
{
- if (header != null)
+ if (h != null)
{
if (mode == StreamingMode.Seekable)
{
- yield return new TarEntry(new TarFilePart(header, stream), compressionType);
+ yield return new TarEntry(new TarFilePart(h, stream), compressionType);
}
else
{
- yield return new TarEntry(new TarFilePart(header, null), compressionType);
+ yield return new TarEntry(new TarFilePart(h, null), compressionType);
}
}
else
diff --git a/src/SharpCompress/Common/Tar/TarFilePart.cs b/src/SharpCompress/Common/Tar/TarFilePart.cs
index 06516114..bfd2fe29 100644
--- a/src/SharpCompress/Common/Tar/TarFilePart.cs
+++ b/src/SharpCompress/Common/Tar/TarFilePart.cs
@@ -5,9 +5,9 @@ namespace SharpCompress.Common.Tar;
internal sealed class TarFilePart : FilePart
{
- private readonly Stream? _seekableStream;
+ private readonly Stream _seekableStream;
- internal TarFilePart(TarHeader header, Stream? seekableStream)
+ internal TarFilePart(TarHeader header, Stream seekableStream)
: base(header.ArchiveEncoding)
{
_seekableStream = seekableStream;
@@ -16,16 +16,16 @@ internal sealed class TarFilePart : FilePart
internal TarHeader Header { get; }
- internal override string? FilePartName => Header?.Name;
+ internal override string FilePartName => Header.Name;
internal override Stream GetCompressedStream()
{
if (_seekableStream != null)
{
- _seekableStream.Position = Header.DataStartPosition ?? 0;
+ _seekableStream.Position = Header.DataStartPosition!.Value;
return new TarReadOnlySubStream(_seekableStream, Header.Size);
}
- return Header.PackedStream.NotNull();
+ return Header.PackedStream;
}
internal override Stream? GetRawStream() => null;
diff --git a/src/SharpCompress/Common/Tar/TarHeaderFactory.cs b/src/SharpCompress/Common/Tar/TarHeaderFactory.cs
index 13813353..85eec5b4 100644
--- a/src/SharpCompress/Common/Tar/TarHeaderFactory.cs
+++ b/src/SharpCompress/Common/Tar/TarHeaderFactory.cs
@@ -28,6 +28,7 @@ internal static class TarHeaderFactory
switch (mode)
{
case StreamingMode.Seekable:
+
{
header.DataStartPosition = reader.BaseStream.Position;
@@ -36,6 +37,7 @@ internal static class TarHeaderFactory
}
break;
case StreamingMode.Streaming:
+
{
header.PackedStream = new TarReadOnlySubStream(stream, header.Size);
}
diff --git a/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs b/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs
index 09a2fdb8..7ccfd238 100644
--- a/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs
+++ b/src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs
@@ -1,6 +1,6 @@
+using SharpCompress.IO;
using System;
using System.IO;
-using SharpCompress.IO;
namespace SharpCompress.Common.Tar;
@@ -47,7 +47,7 @@ internal class TarReadOnlySubStream : NonDisposingStream
public override bool CanWrite => false;
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override long Length => throw new NotSupportedException();
@@ -63,7 +63,7 @@ internal class TarReadOnlySubStream : NonDisposingStream
{
count = (int)BytesLeftToRead;
}
- var read = Stream.Read(buffer, offset, count);
+ int read = Stream.Read(buffer, offset, count);
if (read > 0)
{
BytesLeftToRead -= read;
@@ -78,7 +78,7 @@ internal class TarReadOnlySubStream : NonDisposingStream
{
return -1;
}
- var value = Stream.ReadByte();
+ int value = Stream.ReadByte();
if (value != -1)
{
--BytesLeftToRead;
diff --git a/src/SharpCompress/Common/Volume.cs b/src/SharpCompress/Common/Volume.cs
index 7be161ec..1f259257 100644
--- a/src/SharpCompress/Common/Volume.cs
+++ b/src/SharpCompress/Common/Volume.cs
@@ -9,11 +9,11 @@ public abstract class Volume : IVolume
{
private readonly Stream _actualStream;
- internal Volume(Stream stream, ReaderOptions? readerOptions, int index = 0)
+ internal Volume(Stream stream, ReaderOptions readerOptions, int index = 0)
{
Index = index;
- ReaderOptions = readerOptions ?? new ReaderOptions();
- if (ReaderOptions.LeaveStreamOpen)
+ ReaderOptions = readerOptions;
+ if (readerOptions.LeaveStreamOpen)
{
stream = NonDisposingStream.Create(stream);
}
@@ -32,7 +32,7 @@ public abstract class Volume : IVolume
public virtual int Index { get; internal set; }
- public string? FileName => (_actualStream as FileStream)?.Name;
+ public string FileName => (_actualStream as FileStream)?.Name!;
///
/// RarArchive is part of a multi-part archive.
diff --git a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs
index 2b26d298..fc2cb262 100644
--- a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs
+++ b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs
@@ -14,8 +14,8 @@ internal class DirectoryEntryHeader : ZipFileEntry
VersionNeededToExtract = reader.ReadUInt16();
Flags = (HeaderFlags)reader.ReadUInt16();
CompressionMethod = (ZipCompressionMethod)reader.ReadUInt16();
- OriginalLastModifiedTime = LastModifiedTime = reader.ReadUInt16();
- OriginalLastModifiedDate = LastModifiedDate = reader.ReadUInt16();
+ LastModifiedTime = reader.ReadUInt16();
+ LastModifiedDate = reader.ReadUInt16();
Crc = reader.ReadUInt32();
CompressedSize = reader.ReadUInt32();
UncompressedSize = reader.ReadUInt32();
@@ -52,8 +52,8 @@ internal class DirectoryEntryHeader : ZipFileEntry
LoadExtra(extra);
- var unicodePathExtra = Extra.FirstOrDefault(u =>
- u.Type == ExtraDataType.UnicodePathExtraField
+ var unicodePathExtra = Extra.FirstOrDefault(
+ u => u.Type == ExtraDataType.UnicodePathExtraField
);
if (unicodePathExtra != null && ArchiveEncoding.Forced == null)
{
@@ -85,36 +85,6 @@ internal class DirectoryEntryHeader : ZipFileEntry
RelativeOffsetOfEntryHeader = zip64ExtraData.RelativeOffsetOfEntryHeader;
}
}
-
- var unixTimeExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnixTimeExtraField);
-
- if (unixTimeExtra is not null)
- {
- // Tuple order is last modified time, last access time, and creation time.
- var unixTimeTuple = ((UnixTimeExtraField)unixTimeExtra).UnicodeTimes;
-
- if (unixTimeTuple.Item1.HasValue)
- {
- var dosTime = Utility.DateTimeToDosTime(unixTimeTuple.Item1.Value);
-
- LastModifiedDate = (ushort)(dosTime >> 16);
- LastModifiedTime = (ushort)(dosTime & 0x0FFFF);
- }
- else if (unixTimeTuple.Item2.HasValue)
- {
- var dosTime = Utility.DateTimeToDosTime(unixTimeTuple.Item2.Value);
-
- LastModifiedDate = (ushort)(dosTime >> 16);
- LastModifiedTime = (ushort)(dosTime & 0x0FFFF);
- }
- else if (unixTimeTuple.Item3.HasValue)
- {
- var dosTime = Utility.DateTimeToDosTime(unixTimeTuple.Item3.Value);
-
- LastModifiedDate = (ushort)(dosTime >> 16);
- LastModifiedTime = (ushort)(dosTime & 0x0FFFF);
- }
- }
}
internal ushort Version { get; private set; }
diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs
index 1e3dc62d..93cc55ac 100644
--- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs
+++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs
@@ -13,8 +13,8 @@ internal class LocalEntryHeader : ZipFileEntry
Version = reader.ReadUInt16();
Flags = (HeaderFlags)reader.ReadUInt16();
CompressionMethod = (ZipCompressionMethod)reader.ReadUInt16();
- OriginalLastModifiedTime = LastModifiedTime = reader.ReadUInt16();
- OriginalLastModifiedDate = LastModifiedDate = reader.ReadUInt16();
+ LastModifiedTime = reader.ReadUInt16();
+ LastModifiedDate = reader.ReadUInt16();
Crc = reader.ReadUInt32();
CompressedSize = reader.ReadUInt32();
UncompressedSize = reader.ReadUInt32();
@@ -42,8 +42,8 @@ internal class LocalEntryHeader : ZipFileEntry
LoadExtra(extra);
- var unicodePathExtra = Extra.FirstOrDefault(u =>
- u.Type == ExtraDataType.UnicodePathExtraField
+ var unicodePathExtra = Extra.FirstOrDefault(
+ u => u.Type == ExtraDataType.UnicodePathExtraField
);
if (unicodePathExtra != null && ArchiveEncoding.Forced == null)
{
@@ -64,36 +64,6 @@ internal class LocalEntryHeader : ZipFileEntry
UncompressedSize = zip64ExtraData.UncompressedSize;
}
}
-
- var unixTimeExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnixTimeExtraField);
-
- if (unixTimeExtra is not null)
- {
- // Tuple order is last modified time, last access time, and creation time.
- var unixTimeTuple = ((UnixTimeExtraField)unixTimeExtra).UnicodeTimes;
-
- if (unixTimeTuple.Item1.HasValue)
- {
- var dosTime = Utility.DateTimeToDosTime(unixTimeTuple.Item1.Value);
-
- LastModifiedDate = (ushort)(dosTime >> 16);
- LastModifiedTime = (ushort)(dosTime & 0x0FFFF);
- }
- else if (unixTimeTuple.Item2.HasValue)
- {
- var dosTime = Utility.DateTimeToDosTime(unixTimeTuple.Item2.Value);
-
- LastModifiedDate = (ushort)(dosTime >> 16);
- LastModifiedTime = (ushort)(dosTime & 0x0FFFF);
- }
- else if (unixTimeTuple.Item3.HasValue)
- {
- var dosTime = Utility.DateTimeToDosTime(unixTimeTuple.Item3.Value);
-
- LastModifiedDate = (ushort)(dosTime >> 16);
- LastModifiedTime = (ushort)(dosTime & 0x0FFFF);
- }
- }
}
internal ushort Version { get; private set; }
diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs
index 88e4a187..80ec9b8f 100644
--- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs
+++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Buffers.Binary;
using System.Text;
@@ -13,8 +13,7 @@ internal enum ExtraDataType : ushort
// Third Party Mappings
// -Info-ZIP Unicode Path Extra Field
UnicodePathExtraField = 0x7075,
- Zip64ExtendedInformationExtraField = 0x0001,
- UnixTimeExtraField = 0x5455
+ Zip64ExtendedInformationExtraField = 0x0001
}
internal class ExtraData
@@ -146,84 +145,6 @@ internal sealed class Zip64ExtendedInformationExtraField : ExtraData
public uint VolumeNumber { get; private set; }
}
-internal sealed class UnixTimeExtraField : ExtraData
-{
- public UnixTimeExtraField(ExtraDataType type, ushort length, byte[] dataBytes)
- : base(type, length, dataBytes) { }
-
- ///
- /// The unix modified time, last access time, and creation time, if set.
- ///
- /// Must return Tuple explicitly due to net462 support.
- internal Tuple UnicodeTimes
- {
- get
- {
- // There has to be at least 5 byte for there to be a timestamp.
- // 1 byte for flags and 4 bytes for a timestamp.
- if (DataBytes is null || DataBytes.Length < 5)
- {
- return Tuple.Create(null, null, null);
- }
-
- var flags = DataBytes[0];
- var isModifiedTimeSpecified = (flags & 0x01) == 1;
- var isLastAccessTimeSpecified = (flags & 0x02) == 1;
- var isCreationTimeSpecified = (flags & 0x04) == 1;
- var currentIndex = 1;
- DateTime? modifiedTime = null;
- DateTime? lastAccessTime = null;
- DateTime? creationTime = null;
-
- if (isModifiedTimeSpecified)
- {
- var modifiedEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
- DataBytes.AsSpan(currentIndex, 4)
- );
-
- currentIndex += 4;
- modifiedTime = DateTimeOffset.FromUnixTimeSeconds(modifiedEpochTime).UtcDateTime;
- }
-
- if (isLastAccessTimeSpecified)
- {
- if (currentIndex + 4 > DataBytes.Length)
- {
- throw new ArchiveException("Invalid UnicodeExtraTime field");
- }
-
- var lastAccessEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
- DataBytes.AsSpan(currentIndex, 4)
- );
-
- currentIndex += 4;
- lastAccessTime = DateTimeOffset
- .FromUnixTimeSeconds(lastAccessEpochTime)
- .UtcDateTime;
- }
-
- if (isCreationTimeSpecified)
- {
- if (currentIndex + 4 > DataBytes.Length)
- {
- throw new ArchiveException("Invalid UnicodeExtraTime field");
- }
-
- var creationTimeEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
- DataBytes.AsSpan(currentIndex, 4)
- );
-
- currentIndex += 4;
- creationTime = DateTimeOffset
- .FromUnixTimeSeconds(creationTimeEpochTime)
- .UtcDateTime;
- }
-
- return Tuple.Create(modifiedTime, lastAccessTime, creationTime);
- }
- }
-}
-
internal static class LocalEntryHeaderExtraFactory
{
internal static ExtraData Create(ExtraDataType type, ushort length, byte[] extraData) =>
@@ -233,7 +154,6 @@ internal static class LocalEntryHeaderExtraFactory
=> new ExtraUnicodePathExtraField(type, length, extraData),
ExtraDataType.Zip64ExtendedInformationExtraField
=> new Zip64ExtendedInformationExtraField(type, length, extraData),
- ExtraDataType.UnixTimeExtraField => new UnixTimeExtraField(type, length, extraData),
_ => new ExtraData(type, length, extraData)
};
}
diff --git a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs
index 0570bf6d..98d230f5 100644
--- a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs
+++ b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
@@ -18,21 +20,21 @@ internal abstract class ZipFileEntry : ZipHeader
{
get
{
- if (Name?.EndsWith('/') ?? false)
+ if (Name.EndsWith('/'))
{
return true;
}
//.NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers
- return CompressedSize == 0 && UncompressedSize == 0 && (Name?.EndsWith('\\') ?? false);
+ return CompressedSize == 0 && UncompressedSize == 0 && Name.EndsWith('\\');
}
}
- internal Stream? PackedStream { get; set; }
+ internal Stream PackedStream { get; set; }
internal ArchiveEncoding ArchiveEncoding { get; }
- internal string? Name { get; set; }
+ internal string Name { get; set; }
internal HeaderFlags Flags { get; set; }
@@ -46,7 +48,7 @@ internal abstract class ZipFileEntry : ZipHeader
internal List Extra { get; set; }
- public string? Password { get; set; }
+ public string Password { get; set; }
internal PkwareTraditionalEncryptionData ComposeEncryptionData(Stream archiveStream)
{
@@ -63,28 +65,10 @@ internal abstract class ZipFileEntry : ZipHeader
return encryptionData;
}
- internal WinzipAesEncryptionData? WinzipAesEncryptionData { get; set; }
+ internal WinzipAesEncryptionData WinzipAesEncryptionData { get; set; }
- ///
- /// The last modified date as read from the Local or Central Directory header.
- ///
- internal ushort OriginalLastModifiedDate { get; set; }
-
- ///
- /// The last modified date from the UnixTimeExtraField, if present, or the
- /// Local or Cental Directory header, if not.
- ///
internal ushort LastModifiedDate { get; set; }
- ///
- /// The last modified time as read from the Local or Central Directory header.
- ///
- internal ushort OriginalLastModifiedTime { get; set; }
-
- ///
- /// The last modified time from the UnixTimeExtraField, if present, or the
- /// Local or Cental Directory header, if not.
- ///
internal ushort LastModifiedTime { get; set; }
internal uint Crc { get; set; }
@@ -117,7 +101,7 @@ internal abstract class ZipFileEntry : ZipHeader
}
}
- internal ZipFilePart? Part { get; set; }
+ internal ZipFilePart Part { get; set; }
internal bool IsZip64 => CompressedSize >= uint.MaxValue;
}
diff --git a/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs b/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
index 6ac48c6f..273a7a3c 100644
--- a/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
+++ b/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
namespace SharpCompress.Common.Zip;
@@ -87,7 +87,10 @@ internal class PkwareTraditionalCryptoStream : Stream
_stream.Write(encrypted, 0, encrypted.Length);
}
- public override void Flush() { }
+ public override void Flush()
+ {
+ //throw new NotSupportedException();
+ }
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
diff --git a/src/SharpCompress/Common/Zip/PkwareTraditionalEncryptionData.cs b/src/SharpCompress/Common/Zip/PkwareTraditionalEncryptionData.cs
index 7b517857..353000d8 100644
--- a/src/SharpCompress/Common/Zip/PkwareTraditionalEncryptionData.cs
+++ b/src/SharpCompress/Common/Zip/PkwareTraditionalEncryptionData.cs
@@ -6,7 +6,7 @@ namespace SharpCompress.Common.Zip;
internal class PkwareTraditionalEncryptionData
{
- private static readonly CRC32 CRC32 = new();
+ private static readonly CRC32 CRC32 = new CRC32();
private readonly uint[] _keys = { 0x12345678, 0x23456789, 0x34567890 };
private readonly ArchiveEncoding _archiveEncoding;
@@ -39,7 +39,7 @@ internal class PkwareTraditionalEncryptionData
{
throw new CryptographicException("The password did not match.");
}
- if (plainTextHeader[11] != (byte)((header.OriginalLastModifiedTime >> 8) & 0xff))
+ if (plainTextHeader[11] != (byte)((header.LastModifiedTime >> 8) & 0xff))
{
throw new CryptographicException("The password did not match.");
}
@@ -103,7 +103,7 @@ internal class PkwareTraditionalEncryptionData
internal byte[] StringToByteArray(string value)
{
- var a = _archiveEncoding.GetPasswordEncoding().GetBytes(value);
+ var a = _archiveEncoding.Password.GetBytes(value);
return a;
}
diff --git a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
index e37008e5..63fdc933 100644
--- a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
+++ b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
@@ -42,16 +42,16 @@ internal class SeekableZipFilePart : ZipFilePart
protected override Stream CreateBaseStream()
{
- BaseStream.Position = Header.DataStartPosition.NotNull();
+ BaseStream.Position = Header.DataStartPosition!.Value;
if (
(Header.CompressedSize == 0)
&& FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor)
- && _directoryEntryHeader.HasData
- && (_directoryEntryHeader.CompressedSize != 0)
+ && (_directoryEntryHeader?.HasData == true)
+ && (_directoryEntryHeader?.CompressedSize != 0)
)
{
- return new ReadOnlySubStream(BaseStream, _directoryEntryHeader.CompressedSize);
+ return new ReadOnlySubStream(BaseStream, _directoryEntryHeader!.CompressedSize);
}
return BaseStream;
diff --git a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
index 97e44b6b..1cd1f61f 100644
--- a/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
+++ b/src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
@@ -13,7 +13,7 @@ internal sealed class StreamingZipFilePart : ZipFilePart
internal StreamingZipFilePart(ZipFileEntry header, Stream stream)
: base(header, stream) { }
- protected override Stream CreateBaseStream() => Header.PackedStream.NotNull();
+ protected override Stream CreateBaseStream() => Header.PackedStream;
internal override Stream GetCompressedStream()
{
diff --git a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
index 508dfd1a..e76a2856 100644
--- a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
+++ b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
@@ -15,7 +15,10 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
ArchiveEncoding archiveEncoding,
IEnumerable? entries
)
- : base(StreamingMode.Streaming, password, archiveEncoding) => _entries = entries;
+ : base(StreamingMode.Streaming, password, archiveEncoding)
+ {
+ _entries = entries;
+ }
internal IEnumerable ReadStreamHeader(Stream stream)
{
@@ -36,19 +39,16 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
uint headerBytes = 0;
if (
_lastEntryHeader != null
- && FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)
+ && (
+ FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)
+ || _lastEntryHeader.IsZip64
+ )
)
{
- if (_lastEntryHeader.Part is null)
- {
- continue;
- }
reader = ((StreamingZipFilePart)_lastEntryHeader.Part).FixStreamedFileLocation(
ref rewindableStream
);
-
var pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
-
var crc = reader.ReadUInt32();
if (crc == POST_DATA_DESCRIPTOR)
{
@@ -81,60 +81,6 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
_lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
}
}
- else if (_lastEntryHeader != null && _lastEntryHeader.IsZip64)
- {
- if (_lastEntryHeader.Part is null)
- continue;
-
- reader = ((StreamingZipFilePart)_lastEntryHeader.Part).FixStreamedFileLocation(
- ref rewindableStream
- );
-
- var pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
-
- headerBytes = reader.ReadUInt32();
-
- var version = reader.ReadUInt16();
- var flags = (HeaderFlags)reader.ReadUInt16();
- var compressionMethod = (ZipCompressionMethod)reader.ReadUInt16();
- var lastModifiedDate = reader.ReadUInt16();
- var lastModifiedTime = reader.ReadUInt16();
-
- var crc = reader.ReadUInt32();
-
- if (crc == POST_DATA_DESCRIPTOR)
- {
- crc = reader.ReadUInt32();
- }
- _lastEntryHeader.Crc = crc;
-
- // The DataDescriptor can be either 64bit or 32bit
- var compressed_size = reader.ReadUInt32();
- var uncompressed_size = reader.ReadUInt32();
-
- // Check if we have header or 64bit DataDescriptor
- var test_header = !(headerBytes == 0x04034b50 || headerBytes == 0x02014b50);
-
- var test_64bit = ((long)uncompressed_size << 32) | compressed_size;
- if (test_64bit == _lastEntryHeader.CompressedSize && test_header)
- {
- _lastEntryHeader.UncompressedSize =
- ((long)reader.ReadUInt32() << 32) | headerBytes;
- headerBytes = reader.ReadUInt32();
- }
- else
- {
- _lastEntryHeader.UncompressedSize = uncompressed_size;
- }
-
- if (pos.HasValue)
- {
- _lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
-
- // 4 = First 4 bytes of the entry header (i.e. 50 4B 03 04)
- rewindableStream.Position = pos.Value + 4;
- }
- }
else
{
headerBytes = reader.ReadUInt32();
@@ -151,12 +97,13 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
if (header.ZipHeaderType == ZipHeaderType.LocalEntry)
{
var local_header = ((LocalEntryHeader)header);
- var dir_header = _entries?.FirstOrDefault(entry =>
- entry.Key == local_header.Name
- && local_header.CompressedSize == 0
- && local_header.UncompressedSize == 0
- && local_header.Crc == 0
- && local_header.IsDirectory == false
+ var dir_header = _entries?.FirstOrDefault(
+ entry =>
+ entry.Key == local_header.Name
+ && local_header.CompressedSize == 0
+ && local_header.UncompressedSize == 0
+ && local_header.Crc == 0
+ && local_header.IsDirectory == false
);
if (dir_header != null)
diff --git a/src/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs b/src/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs
index 5742458a..093ac034 100644
--- a/src/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs
+++ b/src/SharpCompress/Common/Zip/WinzipAesCryptoStream.cs
@@ -73,7 +73,7 @@ internal class WinzipAesCryptoStream : Stream
}
}
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override int Read(byte[] buffer, int offset, int count)
{
diff --git a/src/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs b/src/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs
index 31322019..251b919e 100644
--- a/src/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs
+++ b/src/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Buffers.Binary;
using System.Security.Cryptography;
@@ -8,7 +10,12 @@ internal class WinzipAesEncryptionData
{
private const int RFC2898_ITERATIONS = 1000;
+ private readonly byte[] _salt;
private readonly WinzipAesKeySize _keySize;
+ private readonly byte[] _passwordVerifyValue;
+ private readonly string _password;
+
+ private byte[] _generatedVerifyValue;
internal WinzipAesEncryptionData(
WinzipAesKeySize keySize,
@@ -18,28 +25,10 @@ internal class WinzipAesEncryptionData
)
{
_keySize = keySize;
-
-#if NETFRAMEWORK || NETSTANDARD2_0
- var rfc2898 = new Rfc2898DeriveBytes(password, salt, RFC2898_ITERATIONS);
-#else
- var rfc2898 = new Rfc2898DeriveBytes(
- password,
- salt,
- RFC2898_ITERATIONS,
- HashAlgorithmName.SHA1
- );
-#endif
-
- KeyBytes = rfc2898.GetBytes(KeySizeInBytes); // 16 or 24 or 32 ???
- IvBytes = rfc2898.GetBytes(KeySizeInBytes);
- var generatedVerifyValue = rfc2898.GetBytes(2);
-
- var verify = BinaryPrimitives.ReadInt16LittleEndian(passwordVerifyValue);
- var generated = BinaryPrimitives.ReadInt16LittleEndian(generatedVerifyValue);
- if (verify != generated)
- {
- throw new InvalidFormatException("bad password");
- }
+ _salt = salt;
+ _passwordVerifyValue = passwordVerifyValue;
+ _password = password;
+ Initialize();
}
internal byte[] IvBytes { get; set; }
@@ -56,4 +45,32 @@ internal class WinzipAesEncryptionData
WinzipAesKeySize.KeySize256 => 32,
_ => throw new InvalidOperationException(),
};
+
+ private void Initialize()
+ {
+#if NET7_0
+ var rfc2898 = new Rfc2898DeriveBytes(
+ _password,
+ _salt,
+ RFC2898_ITERATIONS,
+ HashAlgorithmName.SHA1
+ );
+#else
+ var rfc2898 = new Rfc2898DeriveBytes(_password, _salt, RFC2898_ITERATIONS);
+#endif
+
+ KeyBytes = rfc2898.GetBytes(KeySizeInBytes); // 16 or 24 or 32 ???
+ IvBytes = rfc2898.GetBytes(KeySizeInBytes);
+ _generatedVerifyValue = rfc2898.GetBytes(2);
+
+ var verify = BinaryPrimitives.ReadInt16LittleEndian(_passwordVerifyValue);
+ if (_password != null)
+ {
+ var generated = BinaryPrimitives.ReadInt16LittleEndian(_generatedVerifyValue);
+ if (verify != generated)
+ {
+ throw new InvalidFormatException("bad password");
+ }
+ }
+ }
}
diff --git a/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs b/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
index a98ed667..13c2dbe7 100644
--- a/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
+++ b/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
@@ -3,7 +3,6 @@ namespace SharpCompress.Common.Zip;
internal enum ZipCompressionMethod
{
None = 0,
- Shrink = 1,
Deflate = 8,
Deflate64 = 9,
BZip2 = 12,
diff --git a/src/SharpCompress/Common/Zip/ZipEntry.cs b/src/SharpCompress/Common/Zip/ZipEntry.cs
index c2cecf39..2c544b94 100644
--- a/src/SharpCompress/Common/Zip/ZipEntry.cs
+++ b/src/SharpCompress/Common/Zip/ZipEntry.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Generic;
using SharpCompress.Common.Zip.Headers;
@@ -6,43 +8,67 @@ namespace SharpCompress.Common.Zip;
public class ZipEntry : Entry
{
- private readonly ZipFilePart? _filePart;
+ private readonly ZipFilePart _filePart;
- internal ZipEntry(ZipFilePart? filePart)
+ internal ZipEntry(ZipFilePart filePart)
{
- if (filePart == null)
+ if (filePart != null)
{
- return;
+ _filePart = filePart;
+ LastModifiedTime = Utility.DosDateToDateTime(
+ filePart.Header.LastModifiedDate,
+ filePart.Header.LastModifiedTime
+ );
}
- _filePart = filePart;
- LastModifiedTime = Utility.DosDateToDateTime(
- filePart.Header.LastModifiedDate,
- filePart.Header.LastModifiedTime
- );
}
- public override CompressionType CompressionType =>
- _filePart?.Header.CompressionMethod switch
+ public override CompressionType CompressionType
+ {
+ get
{
- ZipCompressionMethod.BZip2 => CompressionType.BZip2,
- ZipCompressionMethod.Deflate => CompressionType.Deflate,
- ZipCompressionMethod.Deflate64 => CompressionType.Deflate64,
- ZipCompressionMethod.LZMA => CompressionType.LZMA,
- ZipCompressionMethod.PPMd => CompressionType.PPMd,
- ZipCompressionMethod.None => CompressionType.None,
- ZipCompressionMethod.Shrink => CompressionType.Shrink,
- _ => CompressionType.Unknown
- };
+ switch (_filePart.Header.CompressionMethod)
+ {
+ case ZipCompressionMethod.BZip2:
+ {
+ return CompressionType.BZip2;
+ }
+ case ZipCompressionMethod.Deflate:
+ {
+ return CompressionType.Deflate;
+ }
+ case ZipCompressionMethod.Deflate64:
+ {
+ return CompressionType.Deflate64;
+ }
+ case ZipCompressionMethod.LZMA:
+ {
+ return CompressionType.LZMA;
+ }
+ case ZipCompressionMethod.PPMd:
+ {
+ return CompressionType.PPMd;
+ }
+ case ZipCompressionMethod.None:
+ {
+ return CompressionType.None;
+ }
+ default:
+ {
+ return CompressionType.Unknown;
+ }
+ }
+ }
+ }
- public override long Crc => _filePart?.Header.Crc ?? 0;
+ public override long Crc => _filePart.Header.Crc;
- public override string? Key => _filePart?.Header.Name;
+ public override string Key => _filePart.Header.Name;
- public override string? LinkTarget => null;
+ public override string LinkTarget => null;
- public override long CompressedSize => _filePart?.Header.CompressedSize ?? 0;
+ public override long CompressedSize => _filePart.Header.CompressedSize;
- public override long Size => _filePart?.Header.UncompressedSize ?? 0;
+ public override long Size => _filePart.Header.UncompressedSize;
public override DateTime? LastModifiedTime { get; }
@@ -53,11 +79,11 @@ public class ZipEntry : Entry
public override DateTime? ArchivedTime => null;
public override bool IsEncrypted =>
- FlagUtility.HasFlag(_filePart?.Header.Flags ?? HeaderFlags.None, HeaderFlags.Encrypted);
+ FlagUtility.HasFlag(_filePart.Header.Flags, HeaderFlags.Encrypted);
- public override bool IsDirectory => _filePart?.Header.IsDirectory ?? false;
+ public override bool IsDirectory => _filePart.Header.IsDirectory;
public override bool IsSplitAfter => false;
- internal override IEnumerable Parts => _filePart.Empty();
+ internal override IEnumerable Parts => _filePart.AsEnumerable();
}
diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs
index e8516150..faefdf15 100644
--- a/src/SharpCompress/Common/Zip/ZipFilePart.cs
+++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs
@@ -9,7 +9,6 @@ using SharpCompress.Compressors.Deflate;
using SharpCompress.Compressors.Deflate64;
using SharpCompress.Compressors.LZMA;
using SharpCompress.Compressors.PPMd;
-using SharpCompress.Compressors.Shrink;
using SharpCompress.Compressors.Xz;
using SharpCompress.IO;
using ZstdSharp;
@@ -29,7 +28,7 @@ internal abstract class ZipFilePart : FilePart
internal Stream BaseStream { get; }
internal ZipFileEntry Header { get; set; }
- internal override string? FilePartName => Header.Name;
+ internal override string FilePartName => Header.Name;
internal override Stream GetCompressedStream()
{
@@ -80,15 +79,6 @@ internal abstract class ZipFilePart : FilePart
return new DataDescriptorStream(stream);
}
- case ZipCompressionMethod.Shrink:
- {
- return new ShrinkStream(
- stream,
- CompressionMode.Decompress,
- Header.CompressedSize,
- Header.UncompressedSize
- );
- }
case ZipCompressionMethod.Deflate:
{
return new DeflateStream(stream, CompressionMode.Decompress);
@@ -202,7 +192,6 @@ internal abstract class ZipFilePart : FilePart
switch (Header.CompressionMethod)
{
case ZipCompressionMethod.None:
- case ZipCompressionMethod.Shrink:
case ZipCompressionMethod.Deflate:
case ZipCompressionMethod.Deflate64:
case ZipCompressionMethod.BZip2:
diff --git a/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs
index 45869ff6..8a58e220 100644
--- a/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs
+++ b/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs
@@ -55,13 +55,7 @@ internal class ZipHeaderFactory
}
case POST_DATA_DESCRIPTOR:
{
- if (
- _lastEntryHeader != null
- && FlagUtility.HasFlag(
- _lastEntryHeader.NotNull().Flags,
- HeaderFlags.UsePostDataDescriptor
- )
- )
+ if (FlagUtility.HasFlag(_lastEntryHeader!.Flags, HeaderFlags.UsePostDataDescriptor))
{
_lastEntryHeader.Crc = reader.ReadUInt32();
_lastEntryHeader.CompressedSize = zip64
@@ -148,8 +142,8 @@ internal class ZipHeaderFactory
if (entryHeader.CompressionMethod == ZipCompressionMethod.WinzipAes)
{
- var data = entryHeader.Extra.SingleOrDefault(x =>
- x.Type == ExtraDataType.WinZipAes
+ var data = entryHeader.Extra.SingleOrDefault(
+ x => x.Type == ExtraDataType.WinZipAes
);
if (data != null)
{
diff --git a/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs b/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs
index 2c00ea71..feea12d1 100644
--- a/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs
+++ b/src/SharpCompress/Compressors/BZip2/BZip2Stream.cs
@@ -69,7 +69,7 @@ public sealed class BZip2Stream : Stream
public override void SetLength(long value) => stream.SetLength(value);
-#if !NETFRAMEWORK&& !NETSTANDARD2_0
+#if !NETFRAMEWORK && !NETSTANDARD2_0
public override int Read(Span buffer) => stream.Read(buffer);
diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
index a467942f..e03a5096 100644
--- a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
+++ b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
@@ -1,4 +1,4 @@
-#nullable disable
+#nullable disable
using System;
using System.IO;
@@ -42,17 +42,14 @@ internal class CBZip2InputStream : Stream
private static void Cadvise()
{
//System.out.Println("CRC Error");
- throw new InvalidOperationException("BZip2 error");
+ //throw new CCoruptionError();
}
private static void BadBGLengths() => Cadvise();
private static void BitStreamEOF() => Cadvise();
- private static void CompressedStreamEOF()
- {
- throw new InvalidOperationException("BZip2 compressed file ends unexpectedly");
- }
+ private static void CompressedStreamEOF() => Cadvise();
private void MakeMaps()
{
@@ -90,7 +87,7 @@ internal class CBZip2InputStream : Stream
private int bsBuff;
private int bsLive;
- private readonly CRC mCrc = new();
+ private readonly CRC mCrc = new CRC();
private readonly bool[] inUse = new bool[256];
private int nInUse;
diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs
index bf01c2c3..a975ffbd 100644
--- a/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs
+++ b/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs
@@ -284,7 +284,7 @@ internal sealed class CBZip2OutputStream : Stream
private int bytesOut;
private int bsBuff;
private int bsLive;
- private readonly CRC mCrc = new();
+ private readonly CRC mCrc = new CRC();
private readonly bool[] inUse = new bool[256];
private int nInUse;
diff --git a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs
index cccd0237..27ad4018 100644
--- a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs
+++ b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs
@@ -69,6 +69,7 @@
// -----------------------------------------------------------------------
using System;
+
using SharpCompress.Algorithms;
namespace SharpCompress.Compressors.Deflate;
@@ -342,9 +343,9 @@ internal sealed partial class DeflateManager
private readonly short[] dyn_dtree; // distance tree
private readonly short[] bl_tree; // Huffman tree for bit lengths
- private readonly Tree treeLiterals = new(); // desc for literal tree
- private readonly Tree treeDistances = new(); // desc for distance tree
- private readonly Tree treeBitLengths = new(); // desc for bit length tree
+ private readonly Tree treeLiterals = new Tree(); // desc for literal tree
+ private readonly Tree treeDistances = new Tree(); // desc for distance tree
+ private readonly Tree treeBitLengths = new Tree(); // desc for bit length tree
// number of codes at each bit length for an optimal tree
private readonly short[] bl_count = new short[InternalConstants.MAX_BITS + 1];
@@ -1787,14 +1788,21 @@ internal sealed partial class DeflateManager
return status == BUSY_STATE ? ZlibConstants.Z_DATA_ERROR : ZlibConstants.Z_OK;
}
- private void SetDeflater() =>
- DeflateFunction = config.Flavor switch
+ private void SetDeflater()
+ {
+ switch (config.Flavor)
{
- DeflateFlavor.Store => DeflateNone,
- DeflateFlavor.Fast => DeflateFast,
- DeflateFlavor.Slow => DeflateSlow,
- _ => DeflateFunction
- };
+ case DeflateFlavor.Store:
+ DeflateFunction = DeflateNone;
+ break;
+ case DeflateFlavor.Fast:
+ DeflateFunction = DeflateFast;
+ break;
+ case DeflateFlavor.Slow:
+ DeflateFunction = DeflateSlow;
+ break;
+ }
+ }
internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
{
@@ -1951,9 +1959,7 @@ internal sealed partial class DeflateManager
// returning Z_STREAM_END instead of Z_BUFF_ERROR.
}
else if (
- _codec.AvailableBytesIn == 0
- && (int)flush <= old_flush
- && flush != FlushType.Finish
+ _codec.AvailableBytesIn == 0 && (int)flush <= old_flush && flush != FlushType.Finish
)
{
// workitem 8557
diff --git a/src/SharpCompress/Compressors/Deflate/DeflateStream.cs b/src/SharpCompress/Compressors/Deflate/DeflateStream.cs
index 5566e817..05003d7f 100644
--- a/src/SharpCompress/Compressors/Deflate/DeflateStream.cs
+++ b/src/SharpCompress/Compressors/Deflate/DeflateStream.cs
@@ -366,5 +366,9 @@ public class DeflateStream : Stream
#endregion
public MemoryStream InputBuffer =>
- new(_baseStream._z.InputBuffer, _baseStream._z.NextIn, _baseStream._z.AvailableBytesIn);
+ new MemoryStream(
+ _baseStream._z.InputBuffer,
+ _baseStream._z.NextIn,
+ _baseStream._z.AvailableBytesIn
+ );
}
diff --git a/src/SharpCompress/Compressors/Deflate/GZipStream.cs b/src/SharpCompress/Compressors/Deflate/GZipStream.cs
index 0f7beca8..c547df14 100644
--- a/src/SharpCompress/Compressors/Deflate/GZipStream.cs
+++ b/src/SharpCompress/Compressors/Deflate/GZipStream.cs
@@ -35,7 +35,15 @@ namespace SharpCompress.Compressors.Deflate;
public class GZipStream : Stream
{
- internal static readonly DateTime UNIX_EPOCH = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ internal static readonly DateTime UNIX_EPOCH = new DateTime(
+ 1970,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ DateTimeKind.Utc
+ );
private string? _comment;
private string? _fileName;
diff --git a/src/SharpCompress/Compressors/Deflate/Inflate.cs b/src/SharpCompress/Compressors/Deflate/Inflate.cs
index d768548b..ebea2805 100644
--- a/src/SharpCompress/Compressors/Deflate/Inflate.cs
+++ b/src/SharpCompress/Compressors/Deflate/Inflate.cs
@@ -64,6 +64,7 @@
// -----------------------------------------------------------------------
using System;
+
using SharpCompress.Algorithms;
namespace SharpCompress.Compressors.Deflate;
@@ -105,11 +106,11 @@ internal sealed class InflateBlocks
internal int[] blens; // bit lengths of codes
internal uint check; // check on output
internal object checkfn; // check function
- internal InflateCodes codes = new(); // if CODES, current state
+ internal InflateCodes codes = new InflateCodes(); // if CODES, current state
internal int end; // one byte after sliding window
internal int[] hufts; // single malloc for tree space
internal int index; // index into blens (or border)
- internal InfTree inftree = new();
+ internal InfTree inftree = new InfTree();
internal int last; // true if this block is the last block
internal int left; // if STORED, bytes left to copy
private InflateBlockMode mode; // current inflate_block mode
diff --git a/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs b/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs
index 94b1491d..19a3c60a 100644
--- a/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs
+++ b/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs
@@ -30,8 +30,8 @@ using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
-using System.Text;
using SharpCompress.Common.Tar.Headers;
+using System.Text;
namespace SharpCompress.Compressors.Deflate;
@@ -102,7 +102,7 @@ internal class ZlibBaseStream : Stream
{
if (_z is null)
{
- var wantRfc1950Header = (_flavor == ZlibStreamFlavor.ZLIB);
+ bool wantRfc1950Header = (_flavor == ZlibStreamFlavor.ZLIB);
_z = new ZlibCodec();
if (_compressionMode == CompressionMode.Decompress)
{
@@ -147,13 +147,13 @@ internal class ZlibBaseStream : Stream
z.InputBuffer = buffer;
_z.NextIn = offset;
_z.AvailableBytesIn = count;
- var done = false;
+ bool done = false;
do
{
_z.OutputBuffer = workingBuffer;
_z.NextOut = 0;
_z.AvailableBytesOut = _workingBuffer.Length;
- var rc = (_wantCompress) ? _z.Deflate(_flushMode) : _z.Inflate(_flushMode);
+ int rc = (_wantCompress) ? _z.Deflate(_flushMode) : _z.Inflate(_flushMode);
if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
{
throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message);
@@ -181,18 +181,18 @@ internal class ZlibBaseStream : Stream
if (_streamMode == StreamMode.Writer)
{
- var done = false;
+ bool done = false;
do
{
_z.OutputBuffer = workingBuffer;
_z.NextOut = 0;
_z.AvailableBytesOut = _workingBuffer.Length;
- var rc =
+ int rc =
(_wantCompress) ? _z.Deflate(FlushType.Finish) : _z.Inflate(FlushType.Finish);
if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
{
- var verb = (_wantCompress ? "de" : "in") + "flating";
+ string verb = (_wantCompress ? "de" : "in") + "flating";
if (_z.Message is null)
{
throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc));
@@ -225,7 +225,7 @@ internal class ZlibBaseStream : Stream
Span intBuf = stackalloc byte[4];
BinaryPrimitives.WriteInt32LittleEndian(intBuf, crc.Crc32Result);
_stream.Write(intBuf);
- var c2 = (int)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
+ int c2 = (int)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
BinaryPrimitives.WriteInt32LittleEndian(intBuf, c2);
_stream.Write(intBuf);
}
@@ -256,8 +256,8 @@ internal class ZlibBaseStream : Stream
{
// Make sure we have read to the end of the stream
_z.InputBuffer.AsSpan(_z.NextIn, _z.AvailableBytesIn).CopyTo(trailer);
- var bytesNeeded = 8 - _z.AvailableBytesIn;
- var bytesRead = _stream.Read(
+ int bytesNeeded = 8 - _z.AvailableBytesIn;
+ int bytesRead = _stream.Read(
trailer.Slice(_z.AvailableBytesIn, bytesNeeded)
);
if (bytesNeeded != bytesRead)
@@ -275,10 +275,10 @@ internal class ZlibBaseStream : Stream
_z.InputBuffer.AsSpan(_z.NextIn, trailer.Length).CopyTo(trailer);
}
- var crc32_expected = BinaryPrimitives.ReadInt32LittleEndian(trailer);
- var crc32_actual = crc.Crc32Result;
- var isize_expected = BinaryPrimitives.ReadInt32LittleEndian(trailer.Slice(4));
- var isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF);
+ Int32 crc32_expected = BinaryPrimitives.ReadInt32LittleEndian(trailer);
+ Int32 crc32_actual = crc.Crc32Result;
+ Int32 isize_expected = BinaryPrimitives.ReadInt32LittleEndian(trailer.Slice(4));
+ Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF);
if (crc32_actual != crc32_expected)
{
@@ -380,11 +380,11 @@ internal class ZlibBaseStream : Stream
private string ReadZeroTerminatedString()
{
var list = new List();
- var done = false;
+ bool done = false;
do
{
// workitem 7740
- var n = _stream.Read(_buf1, 0, 1);
+ int n = _stream.Read(_buf1, 0, 1);
if (n != 1)
{
throw new ZlibException("Unexpected EOF reading GZIP header.");
@@ -398,17 +398,17 @@ internal class ZlibBaseStream : Stream
list.Add(_buf1[0]);
}
} while (!done);
- var buffer = list.ToArray();
+ byte[] buffer = list.ToArray();
return _encoding.GetString(buffer, 0, buffer.Length);
}
private int _ReadAndValidateGzipHeader()
{
- var totalBytesRead = 0;
+ int totalBytesRead = 0;
// read the header on the first read
Span header = stackalloc byte[10];
- var n = _stream.Read(header);
+ int n = _stream.Read(header);
// workitem 8501: handle edge case (decompress empty stream)
if (n == 0)
@@ -426,7 +426,7 @@ internal class ZlibBaseStream : Stream
throw new ZlibException("Bad GZIP header.");
}
- var timet = BinaryPrimitives.ReadInt32LittleEndian(header.Slice(4));
+ int timet = BinaryPrimitives.ReadInt32LittleEndian(header.Slice(4));
_GzipMtime = TarHeader.EPOCH.AddSeconds(timet);
totalBytesRead += n;
if ((header[3] & 0x04) == 0x04)
@@ -435,8 +435,8 @@ internal class ZlibBaseStream : Stream
n = _stream.Read(header.Slice(0, 2)); // 2-byte length field
totalBytesRead += n;
- var extraLength = (short)(header[0] + header[1] * 256);
- var extra = new byte[extraLength];
+ short extraLength = (short)(header[0] + header[1] * 256);
+ byte[] extra = new byte[extraLength];
n = _stream.Read(extra, 0, extra.Length);
if (n != extraLength)
{
@@ -498,7 +498,7 @@ internal class ZlibBaseStream : Stream
throw new ZlibException("Cannot Read after Writing.");
}
- var rc = 0;
+ int rc = 0;
// set up the output of the deflate/inflate codec:
_z.OutputBuffer = buffer;
diff --git a/src/SharpCompress/Compressors/Deflate64/Deflate64Stream.cs b/src/SharpCompress/Compressors/Deflate64/Deflate64Stream.cs
index da4117b9..149f7c92 100644
--- a/src/SharpCompress/Compressors/Deflate64/Deflate64Stream.cs
+++ b/src/SharpCompress/Compressors/Deflate64/Deflate64Stream.cs
@@ -4,11 +4,11 @@
#nullable disable
+using SharpCompress.Common.Zip;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
-using SharpCompress.Common.Zip;
namespace SharpCompress.Compressors.Deflate64;
@@ -118,8 +118,8 @@ public sealed class Deflate64Stream : Stream
EnsureNotDisposed();
int bytesRead;
- var currentOffset = offset;
- var remainingCount = count;
+ int currentOffset = offset;
+ int remainingCount = count;
while (true)
{
@@ -142,7 +142,7 @@ public sealed class Deflate64Stream : Stream
break;
}
- var bytes = _stream.Read(_buffer, 0, _buffer.Length);
+ int bytes = _stream.Read(_buffer, 0, _buffer.Length);
if (bytes <= 0)
{
break;
diff --git a/src/SharpCompress/Compressors/Deflate64/DeflateInput.cs b/src/SharpCompress/Compressors/Deflate64/DeflateInput.cs
index 304a2a78..6a12df3b 100644
--- a/src/SharpCompress/Compressors/Deflate64/DeflateInput.cs
+++ b/src/SharpCompress/Compressors/Deflate64/DeflateInput.cs
@@ -22,7 +22,7 @@ internal sealed class DeflateInput
Debug.Assert(StartIndex + Count <= Buffer.Length, "Input buffer is in invalid state!");
}
- internal InputState DumpState() => new(Count, StartIndex);
+ internal InputState DumpState() => new InputState(Count, StartIndex);
internal void RestoreState(InputState state)
{
diff --git a/src/SharpCompress/Compressors/Deflate64/HuffmanTree.cs b/src/SharpCompress/Compressors/Deflate64/HuffmanTree.cs
index e37802bb..051b613e 100644
--- a/src/SharpCompress/Compressors/Deflate64/HuffmanTree.cs
+++ b/src/SharpCompress/Compressors/Deflate64/HuffmanTree.cs
@@ -42,9 +42,11 @@ internal sealed class HuffmanTree
private readonly int _tableMask;
// huffman tree for static block
- public static HuffmanTree StaticLiteralLengthTree { get; } = new(GetStaticLiteralTreeLength());
+ public static HuffmanTree StaticLiteralLengthTree { get; } =
+ new HuffmanTree(GetStaticLiteralTreeLength());
- public static HuffmanTree StaticDistanceTree { get; } = new(GetStaticDistanceTreeLength());
+ public static HuffmanTree StaticDistanceTree { get; } =
+ new HuffmanTree(GetStaticDistanceTreeLength());
public HuffmanTree(byte[] codeLengths)
{
diff --git a/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs b/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs
index 4e11854f..6a3c226b 100644
--- a/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs
+++ b/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs
@@ -243,8 +243,8 @@ internal sealed class InflaterManaged
private void Reset() =>
_state = //_hasFormatReader ?
- //InflaterState.ReadingHeader : // start by reading Header info
- InflaterState.ReadingBFinal; // start by reading BFinal bit
+ //InflaterState.ReadingHeader : // start by reading Header info
+ InflaterState.ReadingBFinal; // start by reading BFinal bit
public void SetInput(byte[] inputBytes, int offset, int length) =>
_input.SetInput(inputBytes, offset, length); // append the bytes
diff --git a/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs b/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs
index 1ed531cc..f658b385 100644
--- a/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJ2Filter.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
namespace SharpCompress.Compressors.Filters;
@@ -79,7 +79,7 @@ internal class BCJ2Filter : Stream
public override bool CanWrite => false;
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override long Length => _baseStream.Length + _data1.Length + _data2.Length;
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterARM.cs b/src/SharpCompress/Compressors/Filters/BCJFilterARM.cs
index 5d861621..86e90b10 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilterARM.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilterARM.cs
@@ -18,7 +18,7 @@ internal class BCJFilterARM : Filter
{
if ((buffer[i + 3] & 0xFF) == 0xEB)
{
- var src =
+ int src =
((buffer[i + 2] & 0xFF) << 16)
| ((buffer[i + 1] & 0xFF) << 8)
| (buffer[i] & 0xFF);
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterARM64.cs b/src/SharpCompress/Compressors/Filters/BCJFilterARM64.cs
deleted file mode 100644
index 24f5ab17..00000000
--- a/src/SharpCompress/Compressors/Filters/BCJFilterARM64.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-using System.Buffers.Binary;
-using System.IO;
-
-namespace SharpCompress.Compressors.Filters;
-
-internal class BCJFilterARM64 : Filter
-{
- private int _pos;
-
- public BCJFilterARM64(bool isEncoder, Stream baseStream)
- : base(isEncoder, baseStream, 8) => _pos = 0;
-
- protected override int Transform(byte[] buffer, int offset, int count)
- {
- var end = offset + count - 4;
- int i;
-
- for (i = offset; i <= end; i += 4)
- {
- uint pc = (uint)(_pos + i - offset);
- uint instr = BinaryPrimitives.ReadUInt32LittleEndian(
- new ReadOnlySpan(buffer, i, 4)
- );
-
- if ((instr >> 26) == 0x25)
- {
- uint src = instr;
- instr = 0x94000000;
-
- pc >>= 2;
- if (!_isEncoder)
- pc = 0U - pc;
-
- instr |= (src + pc) & 0x03FFFFFF;
- BinaryPrimitives.WriteUInt32LittleEndian(new Span(buffer, i, 4), instr);
- }
- else if ((instr & 0x9F000000) == 0x90000000)
- {
- uint src = ((instr >> 29) & 3) | ((instr >> 3) & 0x001FFFFC);
-
- if (((src + 0x00020000) & 0x001C0000) != 0)
- continue;
-
- instr &= 0x9000001F;
-
- pc >>= 12;
- if (!_isEncoder)
- pc = 0U - pc;
-
- uint dest = src + pc;
- instr |= (dest & 3) << 29;
- instr |= (dest & 0x0003FFFC) << 3;
- instr |= (0U - (dest & 0x00020000)) & 0x00E00000;
- BinaryPrimitives.WriteUInt32LittleEndian(new Span(buffer, i, 4), instr);
- }
- }
-
- i -= offset;
- _pos += i;
- return i;
- }
-}
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterARMT.cs b/src/SharpCompress/Compressors/Filters/BCJFilterARMT.cs
index db5b36f2..d2ad1bbf 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilterARMT.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilterARMT.cs
@@ -18,7 +18,7 @@ internal class BCJFilterARMT : Filter
{
if ((buffer[i + 1] & 0xF8) == 0xF0 && (buffer[i + 3] & 0xF8) == 0xF8)
{
- var src =
+ int src =
((buffer[i + 1] & 0x07) << 19)
| ((buffer[i] & 0xFF) << 11)
| ((buffer[i + 3] & 0x07) << 8)
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs b/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs
index 07eaf319..4d89ba39 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs
@@ -52,29 +52,29 @@ internal class BCJFilterIA64 : Filter
for (i = offset; i <= end; i += 16)
{
- var instrTemplate = buffer[i] & 0x1F;
- var mask = BRANCH_TABLE[instrTemplate];
+ int instrTemplate = buffer[i] & 0x1F;
+ int mask = BRANCH_TABLE[instrTemplate];
for (int slot = 0, bitPos = 5; slot < 3; ++slot, bitPos += 41)
{
if (((mask >>> slot) & 1) == 0)
continue;
- var bytePos = bitPos >>> 3;
- var bitRes = bitPos & 7;
+ int bytePos = bitPos >>> 3;
+ int bitRes = bitPos & 7;
long instr = 0;
- for (var j = 0; j < 6; ++j)
+ for (int j = 0; j < 6; ++j)
{
instr |= (buffer[i + bytePos + j] & 0xFFL) << (8 * j);
}
- var instrNorm = instr >>> bitRes;
+ long instrNorm = instr >>> bitRes;
if (((instrNorm >>> 37) & 0x0F) != 0x05 || ((instrNorm >>> 9) & 0x07) != 0x00)
continue;
- var src = (int)((instrNorm >>> 13) & 0x0FFFFF);
+ int src = (int)((instrNorm >>> 13) & 0x0FFFFF);
src |= ((int)(instrNorm >>> 36) & 1) << 20;
src <<= 4;
@@ -93,7 +93,7 @@ internal class BCJFilterIA64 : Filter
instr &= (1 << bitRes) - 1;
instr |= instrNorm << bitRes;
- for (var j = 0; j < 6; ++j)
+ for (int j = 0; j < 6; ++j)
{
buffer[i + bytePos + j] = (byte)(instr >>> (8 * j));
}
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterPPC.cs b/src/SharpCompress/Compressors/Filters/BCJFilterPPC.cs
index ccfa7480..11ed61a1 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilterPPC.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilterPPC.cs
@@ -18,7 +18,7 @@ internal class BCJFilterPPC : Filter
{
if ((buffer[i] & 0xFC) == 0x48 && (buffer[i + 3] & 0x03) == 0x01)
{
- var src =
+ int src =
((buffer[i] & 0x03) << 24)
| ((buffer[i + 1] & 0xFF) << 16)
| ((buffer[i + 2] & 0xFF) << 8)
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterRISCV.cs b/src/SharpCompress/Compressors/Filters/BCJFilterRISCV.cs
deleted file mode 100644
index 67d9cb52..00000000
--- a/src/SharpCompress/Compressors/Filters/BCJFilterRISCV.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-using System;
-using System.Buffers.Binary;
-using System.IO;
-
-namespace SharpCompress.Compressors.Filters;
-
-internal class BCJFilterRISCV : Filter
-{
- private int _pos;
-
- public BCJFilterRISCV(bool isEncoder, Stream baseStream)
- : base(isEncoder, baseStream, 8) => _pos = 0;
-
- private int Decode(byte[] buffer, int offset, int count)
- {
- if (count < 8)
- {
- return 0;
- }
-
- var end = offset + count - 8;
- int i;
- for (i = offset; i <= end; i += 2)
- {
- uint inst = buffer[i];
- if (inst == 0xEF)
- {
- uint b1 = buffer[i + 1];
- if ((b1 & 0x0D) != 0)
- continue;
-
- uint b2 = buffer[i + 2];
- uint b3 = buffer[i + 3];
- uint pc = (uint)(_pos + i);
-
- uint addr = ((b1 & 0xF0) << 13) | (b2 << 9) | (b3 << 1);
-
- addr -= pc;
-
- buffer[i + 1] = (byte)((b1 & 0x0F) | ((addr >> 8) & 0xF0));
-
- buffer[i + 2] = (byte)(
- ((addr >> 16) & 0x0F) | ((addr >> 7) & 0x10) | ((addr << 4) & 0xE0)
- );
-
- buffer[i + 3] = (byte)(((addr >> 4) & 0x7F) | ((addr >> 13) & 0x80));
-
- i += 4 - 2;
- }
- else if ((inst & 0x7F) == 0x17)
- {
- uint inst2 = 0;
- inst |= (uint)buffer[i + 1] << 8;
- inst |= (uint)buffer[i + 2] << 16;
- inst |= (uint)buffer[i + 3] << 24;
-
- if ((inst & 0xE80) != 0)
- {
- inst2 = BinaryPrimitives.ReadUInt32LittleEndian(
- new ReadOnlySpan(buffer, i + 4, 4)
- );
- if (((((inst) << 8) ^ (inst2)) & 0xF8003) != 3)
- {
- i += 6 - 2;
- continue;
- }
- uint addr = inst & 0xFFFFF000;
- addr += inst2 >> 20;
-
- inst = 0x17 | (2 << 7) | (inst2 << 12);
- inst2 = addr;
- }
- else
- {
- uint inst2_rs1 = inst >> 27;
- if ((uint)(((inst) - 0x3117) << 18) >= ((inst2_rs1) & 0x1D))
- {
- i += 4 - 2;
- continue;
- }
-
- uint addr = BinaryPrimitives.ReadUInt32BigEndian(
- new ReadOnlySpan(buffer, i + 4, 4)
- );
-
- addr -= (uint)(_pos + i);
-
- inst2 = (inst >> 12) | (addr << 20);
-
- inst = 0x17 | (inst2_rs1 << 7) | ((addr + 0x800) & 0xFFFFF000);
- }
- BinaryPrimitives.WriteUInt32LittleEndian(new Span(buffer, i, 4), inst);
- BinaryPrimitives.WriteUInt32LittleEndian(new Span(buffer, i + 4, 4), inst2);
-
- i += 8 - 2;
- }
- }
- i -= offset;
- _pos += i;
- return i;
- }
-
- private int Encode(byte[] buffer, int offset, int count)
- {
- if (count < 8)
- {
- return 0;
- }
-
- var end = offset + count - 8;
- int i;
- for (i = offset; i <= end; i += 2)
- {
- uint inst = buffer[i];
- if (inst == 0xEF)
- {
- uint b1 = buffer[i + 1];
- if ((b1 & 0x0D) != 0)
- continue;
-
- uint b2 = buffer[i + 2];
- uint b3 = buffer[i + 3];
- uint pc = (uint)(_pos + i);
-
- uint addr =
- ((b1 & 0xF0) << 8)
- | ((b2 & 0x0F) << 16)
- | ((b2 & 0x10) << 7)
- | ((b2 & 0xE0) >> 4)
- | ((b3 & 0x7F) << 4)
- | ((b3 & 0x80) << 13);
-
- addr += pc;
-
- buffer[i + 1] = (byte)((b1 & 0x0F) | ((addr >> 13) & 0xF0));
-
- buffer[i + 2] = (byte)(addr >> 9);
-
- buffer[i + 3] = (byte)(addr >> 1);
-
- i += 4 - 2;
- }
- else if ((inst & 0x7F) == 0x17)
- {
- inst |= (uint)buffer[i + 1] << 8;
- inst |= (uint)buffer[i + 2] << 16;
- inst |= (uint)buffer[i + 3] << 24;
-
- if ((inst & 0xE80) != 0)
- {
- uint inst2 = BinaryPrimitives.ReadUInt32LittleEndian(
- new ReadOnlySpan(buffer, i + 4, 4)
- );
- if (((((inst) << 8) ^ (inst2)) & 0xF8003) != 3)
- {
- i += 6 - 2;
- continue;
- }
- uint addr = inst & 0xFFFFF000;
- addr += (inst2 >> 20) - ((inst2 >> 19) & 0x1000);
-
- addr += (uint)(_pos + i);
- inst = 0x17 | (2 << 7) | (inst2 << 12);
-
- BinaryPrimitives.WriteUInt32LittleEndian(new Span(buffer, i, 4), inst);
- BinaryPrimitives.WriteUInt32BigEndian(new Span(buffer, i + 4, 4), addr);
- }
- else
- {
- uint fake_rs1 = inst >> 27;
- if ((uint)(((inst) - 0x3117) << 18) >= ((fake_rs1) & 0x1D))
- {
- i += 4 - 2;
- continue;
- }
-
- uint fake_addr = BinaryPrimitives.ReadUInt32LittleEndian(
- new ReadOnlySpan(buffer, i + 4, 4)
- );
-
- uint fake_inst2 = (inst >> 12) | (fake_addr << 20);
-
- inst = 0x17 | (fake_rs1 << 7) | (fake_addr & 0xFFFFF000);
-
- BinaryPrimitives.WriteUInt32LittleEndian(new Span(buffer, i, 4), inst);
- BinaryPrimitives.WriteUInt32LittleEndian(
- new Span(buffer, i + 4, 4),
- fake_inst2
- );
- }
- i += 8 - 2;
- }
- }
- i -= offset;
- _pos += i;
- return i;
- }
-
- protected override int Transform(byte[] buffer, int offset, int count)
- {
- if (_isEncoder)
- {
- return Encode(buffer, offset, count);
- }
- else
- {
- return Decode(buffer, offset, count);
- }
- }
-}
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterSPARC.cs b/src/SharpCompress/Compressors/Filters/BCJFilterSPARC.cs
index db7c75be..67756d34 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilterSPARC.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilterSPARC.cs
@@ -21,7 +21,7 @@ internal class BCJFilterSPARC : Filter
|| (buffer[i] == 0x7F && (buffer[i + 1] & 0xC0) == 0xC0)
)
{
- var src =
+ int src =
((buffer[i] & 0xFF) << 24)
| ((buffer[i + 1] & 0xFF) << 16)
| ((buffer[i + 2] & 0xFF) << 8)
diff --git a/src/SharpCompress/Compressors/Filters/BranchExecFilter.cs b/src/SharpCompress/Compressors/Filters/BranchExecFilter.cs
index d198cf8f..9fc439d4 100644
--- a/src/SharpCompress/Compressors/Filters/BranchExecFilter.cs
+++ b/src/SharpCompress/Compressors/Filters/BranchExecFilter.cs
@@ -24,27 +24,40 @@ public sealed class BranchExecFilter
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static bool X86TestByte(byte b) => b == 0x00 || b == 0xFF;
+ private static bool X86TestByte(byte b)
+ {
+ return b == 0x00 || b == 0xFF;
+ }
//Replaced X86Converter with bcj_x86() - https://github.com/torvalds/linux/blob/master/lib/xz/xz_dec_bcj.c
//This was to fix an issue decoding a Test zip made with WinZip (that 7zip was also able to read).
//The previous version of the code would corrupt 2 bytes in the Test.exe at 0x6CF9 (3D6D - should be 4000) - Test zip: WinZip27.Xz.zipx
public static void X86Converter(byte[] buf, uint ip, ref uint state)
{
- var mask_to_allowed_status = new[] { true, true, true, false, true, false, false, false };
+ bool[] mask_to_allowed_status = new[]
+ {
+ true,
+ true,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false
+ };
- var mask_to_bit_num = new byte[] { 0, 1, 2, 2, 3, 3, 3, 3 };
+ byte[] mask_to_bit_num = new byte[] { 0, 1, 2, 2, 3, 3, 3, 3 };
int i;
- var prev_pos = -1;
- var prev_mask = state & 7;
+ int prev_pos = -1;
+ uint prev_mask = state & 7;
uint src;
uint dest;
uint j;
byte b;
- var pos = ip;
+ uint pos = ip;
- var size = (uint)buf.Length;
+ uint size = (uint)buf.Length;
if (size <= 4)
return;
diff --git a/src/SharpCompress/Compressors/Filters/DeltaFilter.cs b/src/SharpCompress/Compressors/Filters/DeltaFilter.cs
index 85ec9b15..c5fbeb41 100644
--- a/src/SharpCompress/Compressors/Filters/DeltaFilter.cs
+++ b/src/SharpCompress/Compressors/Filters/DeltaFilter.cs
@@ -23,9 +23,9 @@ namespace SharpCompress.Compressors.Filters
protected override int Transform(byte[] buffer, int offset, int count)
{
- var end = offset + count;
+ int end = offset + count;
- for (var i = offset; i < end; i++)
+ for (int i = offset; i < end; i++)
{
buffer[i] += _history[(_distance + _position--) & DISTANCE_MASK];
_history[_position & DISTANCE_MASK] = buffer[i];
diff --git a/src/SharpCompress/Compressors/Filters/Filter.cs b/src/SharpCompress/Compressors/Filters/Filter.cs
index aa5e620d..93d95195 100644
--- a/src/SharpCompress/Compressors/Filters/Filter.cs
+++ b/src/SharpCompress/Compressors/Filters/Filter.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
namespace SharpCompress.Compressors.Filters;
@@ -40,7 +40,7 @@ internal abstract class Filter : Stream
public override bool CanWrite => _isEncoder;
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override long Length => _baseStream.Length;
diff --git a/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs b/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs
index e89d705a..24823c73 100644
--- a/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs
+++ b/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs
@@ -20,8 +20,7 @@ internal sealed class AesDecoderStream : DecoderStream2
public AesDecoderStream(Stream input, byte[] info, IPasswordProvider pass, long limit)
{
- var password = pass.CryptoGetTextPassword();
- if (password == null)
+ if (pass.CryptoGetTextPassword() == null)
{
throw new SharpCompress.Common.CryptographicException(
"Encrypted 7Zip archive has no password specified."
@@ -36,10 +35,10 @@ internal sealed class AesDecoderStream : DecoderStream2
throw new NotSupportedException("AES decoder does not support padding.");
}
- Init(info, out var numCyclesPower, out var salt, out var seed);
+ Init(info, out int numCyclesPower, out byte[] salt, out byte[] seed);
- var passwordBytes = Encoding.Unicode.GetBytes(password);
- var key = InitKey(numCyclesPower, salt, passwordBytes);
+ byte[] password = Encoding.Unicode.GetBytes(pass.CryptoGetTextPassword());
+ byte[]? key = InitKey(numCyclesPower, salt, password);
if (key == null)
{
throw new InvalidOperationException("Initialized with null key");
@@ -101,7 +100,7 @@ internal sealed class AesDecoderStream : DecoderStream2
do
{
- var read = mStream.Read(mBuffer, mEnding, mBuffer.Length - mEnding);
+ int read = mStream.Read(mBuffer, mEnding, mBuffer.Length - mEnding);
if (read == 0)
{
// We are not done decoding and have less than 16 bytes.
@@ -134,7 +133,7 @@ internal sealed class AesDecoderStream : DecoderStream2
}
// Otherwise we transform directly into the target buffer.
- var processed = mDecoder.TransformBlock(mBuffer, mOffset, count & ~15, buffer, offset);
+ int processed = mDecoder.TransformBlock(mBuffer, mOffset, count & ~15, buffer, offset);
mOffset += processed;
mWritten += processed;
return processed;
@@ -144,7 +143,7 @@ internal sealed class AesDecoderStream : DecoderStream2
private void Init(byte[] info, out int numCyclesPower, out byte[] salt, out byte[] iv)
{
- var bt = info[0];
+ byte bt = info[0];
numCyclesPower = bt & 0x3F;
if ((bt & 0xC0) == 0)
@@ -154,14 +153,14 @@ internal sealed class AesDecoderStream : DecoderStream2
return;
}
- var saltSize = (bt >> 7) & 1;
- var ivSize = (bt >> 6) & 1;
+ int saltSize = (bt >> 7) & 1;
+ int ivSize = (bt >> 6) & 1;
if (info.Length == 1)
{
throw new InvalidOperationException();
}
- var bt2 = info[1];
+ byte bt2 = info[1];
saltSize += (bt2 >> 4);
ivSize += (bt2 & 15);
if (info.Length < 2 + saltSize + ivSize)
@@ -170,13 +169,13 @@ internal sealed class AesDecoderStream : DecoderStream2
}
salt = new byte[saltSize];
- for (var i = 0; i < saltSize; i++)
+ for (int i = 0; i < saltSize; i++)
{
salt[i] = info[i + 2];
}
iv = new byte[16];
- for (var i = 0; i < ivSize; i++)
+ for (int i = 0; i < ivSize; i++)
{
iv[i] = info[i + saltSize + 2];
}
@@ -199,7 +198,7 @@ internal sealed class AesDecoderStream : DecoderStream2
key[pos] = salt[pos];
}
- for (var i = 0; i < pass.Length && pos < 32; i++)
+ for (int i = 0; i < pass.Length && pos < 32; i++)
{
key[pos++] = pass[i];
}
@@ -208,9 +207,31 @@ internal sealed class AesDecoderStream : DecoderStream2
}
else
{
+#if NETSTANDARD2_0
+ using IncrementalHash sha = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);
+ byte[] counter = new byte[8];
+ long numRounds = 1L << mNumCyclesPower;
+ for (long round = 0; round < numRounds; round++)
+ {
+ sha.AppendData(salt, 0, salt.Length);
+ sha.AppendData(pass, 0, pass.Length);
+ sha.AppendData(counter, 0, 8);
+
+ // 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();
+#else
using var sha = SHA256.Create();
- var counter = new byte[8];
- var numRounds = 1L << mNumCyclesPower;
+ byte[] counter = new byte[8];
+ long numRounds = 1L << mNumCyclesPower;
for (long round = 0; round < numRounds; round++)
{
sha.TransformBlock(salt, 0, salt.Length, null, 0);
@@ -219,7 +240,7 @@ internal sealed class AesDecoderStream : DecoderStream2
// 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 (var i = 0; i < 8; i++)
+ for (int i = 0; i < 8; i++)
{
if (++counter[i] != 0)
{
@@ -230,6 +251,7 @@ internal sealed class AesDecoderStream : DecoderStream2
sha.TransformFinalBlock(counter, 0, 0);
return sha.Hash;
+#endif
}
}
@@ -239,7 +261,7 @@ internal sealed class AesDecoderStream : DecoderStream2
// Just transform as much as possible so we can feed from it as long as possible.
if (mUnderflow == 0)
{
- var blockSize = (mEnding - mOffset) & ~15;
+ int blockSize = (mEnding - mOffset) & ~15;
mUnderflow = mDecoder.TransformBlock(mBuffer, mOffset, blockSize, mBuffer, mOffset);
}
diff --git a/src/SharpCompress/Compressors/LZMA/DecoderStream.cs b/src/SharpCompress/Compressors/LZMA/DecoderStream.cs
index a3dbf37f..16865351 100644
--- a/src/SharpCompress/Compressors/LZMA/DecoderStream.cs
+++ b/src/SharpCompress/Compressors/LZMA/DecoderStream.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using SharpCompress.Common.SevenZip;
using SharpCompress.Compressors.LZMA.Utilites;
@@ -14,7 +14,7 @@ internal abstract class DecoderStream2 : Stream
public override bool CanWrite => false;
- public override void Flush() { }
+ public override void Flush() => throw new NotSupportedException();
public override long Length => throw new NotSupportedException();
diff --git a/src/SharpCompress/Compressors/LZMA/LZipStream.cs b/src/SharpCompress/Compressors/LZMA/LZipStream.cs
index 5e987214..4b63a621 100644
--- a/src/SharpCompress/Compressors/LZMA/LZipStream.cs
+++ b/src/SharpCompress/Compressors/LZMA/LZipStream.cs
@@ -63,18 +63,18 @@ public sealed class LZipStream : Stream
var crc32Stream = (Crc32Stream)_stream;
crc32Stream.WrappedStream.Dispose();
crc32Stream.Dispose();
- var compressedCount = _countingWritableSubStream.NotNull().Count;
+ var compressedCount = _countingWritableSubStream!.Count;
Span intBuf = stackalloc byte[8];
BinaryPrimitives.WriteUInt32LittleEndian(intBuf, crc32Stream.Crc);
- _countingWritableSubStream?.Write(intBuf.Slice(0, 4));
+ _countingWritableSubStream.Write(intBuf.Slice(0, 4));
BinaryPrimitives.WriteInt64LittleEndian(intBuf, _writeCount);
- _countingWritableSubStream?.Write(intBuf);
+ _countingWritableSubStream.Write(intBuf);
//total with headers
BinaryPrimitives.WriteUInt64LittleEndian(intBuf, compressedCount + 6 + 20);
- _countingWritableSubStream?.Write(intBuf);
+ _countingWritableSubStream.Write(intBuf);
}
_finished = true;
}
diff --git a/src/SharpCompress/Compressors/LZMA/Log.cs b/src/SharpCompress/Compressors/LZMA/Log.cs
index 1431966c..e954e259 100644
--- a/src/SharpCompress/Compressors/LZMA/Log.cs
+++ b/src/SharpCompress/Compressors/LZMA/Log.cs
@@ -6,7 +6,7 @@ namespace SharpCompress.Compressors.LZMA;
internal static class Log
{
- private static readonly Stack INDENT = new();
+ private static readonly Stack INDENT = new Stack();
private static bool NEEDS_INDENT = true;
static Log() => INDENT.Push("");
diff --git a/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs b/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs
index 1b2fdc81..31039761 100644
--- a/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs
+++ b/src/SharpCompress/Compressors/LZMA/LzmaDecoder.cs
@@ -11,11 +11,11 @@ public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
{
private class LenDecoder
{
- private BitDecoder _choice = new();
- private BitDecoder _choice2 = new();
+ private BitDecoder _choice = new BitDecoder();
+ private BitDecoder _choice2 = new BitDecoder();
private readonly BitTreeDecoder[] _lowCoder = new BitTreeDecoder[Base.K_NUM_POS_STATES_MAX];
private readonly BitTreeDecoder[] _midCoder = new BitTreeDecoder[Base.K_NUM_POS_STATES_MAX];
- private BitTreeDecoder _highCoder = new(Base.K_NUM_HIGH_LEN_BITS);
+ private BitTreeDecoder _highCoder = new BitTreeDecoder(Base.K_NUM_HIGH_LEN_BITS);
private uint _numPosStates;
public void Create(uint numPosStates)
@@ -173,18 +173,18 @@ public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
Base.K_NUM_FULL_DISTANCES - Base.K_END_POS_MODEL_INDEX
];
- private BitTreeDecoder _posAlignDecoder = new(Base.K_NUM_ALIGN_BITS);
+ private BitTreeDecoder _posAlignDecoder = new BitTreeDecoder(Base.K_NUM_ALIGN_BITS);
- private readonly LenDecoder _lenDecoder = new();
- private readonly LenDecoder _repLenDecoder = new();
+ private readonly LenDecoder _lenDecoder = new LenDecoder();
+ private readonly LenDecoder _repLenDecoder = new LenDecoder();
- private readonly LiteralDecoder _literalDecoder = new();
+ private readonly LiteralDecoder _literalDecoder = new LiteralDecoder();
private int _dictionarySize;
private uint _posStateMask;
- private Base.State _state = new();
+ private Base.State _state = new Base.State();
private uint _rep0,
_rep1,
_rep2,
@@ -318,8 +318,9 @@ public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
{
var posState = (uint)outWindow._total & _posStateMask;
if (
- _isMatchDecoders[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState]
- .Decode(rangeDecoder) == 0
+ _isMatchDecoders[
+ (_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState
+ ].Decode(rangeDecoder) == 0
)
{
byte b;
@@ -354,8 +355,7 @@ public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
if (
_isRep0LongDecoders[
(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState
- ]
- .Decode(rangeDecoder) == 0
+ ].Decode(rangeDecoder) == 0
)
{
_state.UpdateShortRep();
diff --git a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
index 509e54c8..558fe37b 100644
--- a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
+++ b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
@@ -61,7 +61,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
return (uint)(G_FAST_POS[pos >> 26] + 52);
}
- private Base.State _state = new();
+ private Base.State _state = new Base.State();
private byte _previousByte;
private readonly uint[] _repDistances = new uint[Base.K_NUM_REP_DISTANCES];
@@ -191,15 +191,15 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
private class LenEncoder
{
- private BitEncoder _choice = new();
- private BitEncoder _choice2 = new();
+ private BitEncoder _choice = new BitEncoder();
+ private BitEncoder _choice2 = new BitEncoder();
private readonly BitTreeEncoder[] _lowCoder = new BitTreeEncoder[
Base.K_NUM_POS_STATES_ENCODING_MAX
];
private readonly BitTreeEncoder[] _midCoder = new BitTreeEncoder[
Base.K_NUM_POS_STATES_ENCODING_MAX
];
- private BitTreeEncoder _highCoder = new(Base.K_NUM_HIGH_LEN_BITS);
+ private BitTreeEncoder _highCoder = new BitTreeEncoder(Base.K_NUM_HIGH_LEN_BITS);
public LenEncoder()
{
@@ -359,7 +359,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
private readonly Optimal[] _optimum = new Optimal[K_NUM_OPTS];
private BinTree _matchFinder;
- private readonly RangeCoder.Encoder _rangeEncoder = new();
+ private readonly RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder();
private readonly BitEncoder[] _isMatch = new BitEncoder[
Base.K_NUM_STATES << Base.K_NUM_POS_STATES_BITS_MAX
@@ -382,12 +382,12 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
Base.K_NUM_FULL_DISTANCES - Base.K_END_POS_MODEL_INDEX
];
- private BitTreeEncoder _posAlignEncoder = new(Base.K_NUM_ALIGN_BITS);
+ private BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.K_NUM_ALIGN_BITS);
- private readonly LenPriceTableEncoder _lenEncoder = new();
- private readonly LenPriceTableEncoder _repMatchLenEncoder = new();
+ private readonly LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
+ private readonly LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
- private readonly LiteralEncoder _literalEncoder = new();
+ private readonly LiteralEncoder _literalEncoder = new LiteralEncoder();
private readonly uint[] _matchDistances = new uint[(Base.K_MATCH_MAX_LEN * 2) + 2];
@@ -553,8 +553,9 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
if (repIndex == 0)
{
price = _isRepG0[state._index].GetPrice0();
- price += _isRep0Long[(state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState]
- .GetPrice1();
+ price += _isRep0Long[
+ (state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState
+ ].GetPrice1();
}
else
{
@@ -712,8 +713,9 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
.GetPrice(!_state.IsCharState(), matchByte, currentByte);
_optimum[1].MakeAsChar();
- var matchPrice = _isMatch[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState]
- .GetPrice1();
+ var matchPrice = _isMatch[
+ (_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState
+ ].GetPrice1();
var repMatchPrice = matchPrice + _isRep[_state._index].GetPrice1();
if (matchByte == currentByte)
@@ -993,8 +995,9 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
var posStateNext = (position + 1) & _posStateMask;
var nextRepMatchPrice =
curAnd1Price
- + _isMatch[(state2._index << Base.K_NUM_POS_STATES_BITS_MAX) + posStateNext]
- .GetPrice1()
+ + _isMatch[
+ (state2._index << Base.K_NUM_POS_STATES_BITS_MAX) + posStateNext
+ ].GetPrice1()
+ _isRep[state2._index].GetPrice1();
{
var offset = cur + 1 + lenTest2;
@@ -1066,8 +1069,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
+ GetRepPrice(repIndex, lenTest, state, posState)
+ _isMatch[
(state2._index << Base.K_NUM_POS_STATES_BITS_MAX) + posStateNext
- ]
- .GetPrice0()
+ ].GetPrice0()
+ _literalEncoder
.GetSubCoder(
position + lenTest,
@@ -1086,8 +1088,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
curAndLenCharPrice
+ _isMatch[
(state2._index << Base.K_NUM_POS_STATES_BITS_MAX) + posStateNext
- ]
- .GetPrice1();
+ ].GetPrice1();
var nextRepMatchPrice = nextMatchPrice + _isRep[state2._index].GetPrice1();
// for(; lenTest2 >= 2; lenTest2--)
@@ -1173,8 +1174,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
+ _isMatch[
(state2._index << Base.K_NUM_POS_STATES_BITS_MAX)
+ posStateNext
- ]
- .GetPrice0()
+ ].GetPrice0()
+ _literalEncoder
.GetSubCoder(
position + lenTest,
@@ -1194,8 +1194,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
+ _isMatch[
(state2._index << Base.K_NUM_POS_STATES_BITS_MAX)
+ posStateNext
- ]
- .GetPrice1();
+ ].GetPrice1();
var nextRepMatchPrice =
nextMatchPrice + _isRep[state2._index].GetPrice1();
@@ -1244,8 +1243,10 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
return;
}
- _isMatch[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState]
- .Encode(_rangeEncoder, 1);
+ _isMatch[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState].Encode(
+ _rangeEncoder,
+ 1
+ );
_isRep[_state._index].Encode(_rangeEncoder, 0);
_state.UpdateMatch();
var len = Base.K_MATCH_MIN_LEN;
@@ -1320,8 +1321,10 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
// it's not used
ReadMatchDistances(out var len, out var numDistancePairs);
var posState = (uint)(_nowPos64) & _posStateMask;
- _isMatch[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState]
- .Encode(_rangeEncoder, 0);
+ _isMatch[(_state._index << Base.K_NUM_POS_STATES_BITS_MAX) + posState].Encode(
+ _rangeEncoder,
+ 0
+ );
_state.UpdateChar();
var curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset));
_literalEncoder
@@ -1727,7 +1730,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
ReadOnlySpan