13 Commits
1.8.0 ... main

Author SHA1 Message Date
Matt Nadareski
e7f7bd4d0d Clean up test classes 2026-01-27 08:51:29 -05:00
Matt Nadareski
b3e410180a Add editorconfig, fix issues 2026-01-25 17:04:11 -05:00
Matt Nadareski
6bd77c7377 Fix MS-ZIP test 2025-12-04 09:34:44 -05:00
Matt Nadareski
4dc1378d36 Make MS-ZIP more consistent 2025-12-04 09:30:53 -05:00
Matt Nadareski
ae87869bb9 Add GrindCore package 2025-11-30 19:39:15 -05:00
Matt Nadareski
46ad576668 Format GHA definitions 2025-11-17 08:40:06 -05:00
Matt Nadareski
37b09b07a6 Bump version 2025-11-13 20:02:30 -05:00
Matt Nadareski
448e43dd05 Add MergeWith dictionary extension 2025-11-13 10:35:02 -05:00
Matt Nadareski
e29b8ab4db Add support for .NET 10 2025-11-13 08:56:30 -05:00
Matt Nadareski
6075aa25a2 Name some type parameters 2025-11-11 09:54:18 -05:00
Matt Nadareski
c53fb33278 Add remaining encryption constants 2025-11-04 10:10:20 -05:00
Matt Nadareski
fb1fc5d85d Add IsNumericArray extension 2025-11-04 10:08:56 -05:00
Matt Nadareski
2763d3915b Add MPQ hashing methods 2025-11-02 22:54:10 -05:00
144 changed files with 11434 additions and 10820 deletions

167
.editorconfig Normal file
View File

@@ -0,0 +1,167 @@
# top-most EditorConfig file
root = true
# C# files
[*.cs]
# Indentation and spacing
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
trim_trailing_whitespace = true
# New line preferences
end_of_line = lf
insert_final_newline = true
max_line_length = unset
# using directive preferences
csharp_using_directive_placement = outside_namespace
dotnet_diagnostic.IDE0005.severity = error
# Code-block preferences
csharp_style_namespace_declarations = block_scoped
csharp_style_prefer_method_group_conversion = true
csharp_style_prefer_top_level_statements = false
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_inlined_variable_declaration = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
dotnet_diagnostic.IDE0001.severity = warning
dotnet_diagnostic.IDE0002.severity = warning
dotnet_diagnostic.IDE0004.severity = warning
dotnet_diagnostic.IDE0010.severity = error
dotnet_diagnostic.IDE0051.severity = warning
dotnet_diagnostic.IDE0052.severity = warning
dotnet_diagnostic.IDE0072.severity = warning
dotnet_diagnostic.IDE0080.severity = warning
dotnet_diagnostic.IDE0100.severity = error
dotnet_diagnostic.IDE0110.severity = error
dotnet_diagnostic.IDE0120.severity = warning
dotnet_diagnostic.IDE0121.severity = warning
dotnet_diagnostic.IDE0240.severity = error
dotnet_diagnostic.IDE0241.severity = error
dotnet_style_coalesce_expression = true
dotnet_style_namespace_match_folder = false
dotnet_style_null_propagation = true
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_collection_expression = when_types_loosely_match
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_compound_assignment = true
csharp_style_prefer_simple_property_accessors = true
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_prefer_simplified_boolean_expressions = true
csharp_style_prefer_unbound_generic_type_in_nameof = true
# Field preferences
dotnet_diagnostic.IDE0044.severity = warning
dotnet_style_readonly_field = true
# Language keyword vs. framework types preferences
dotnet_diagnostic.IDE0049.severity = error
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# Modifier preferences
csharp_prefer_static_local_function = true
csharp_style_prefer_readonly_struct = true
dotnet_diagnostic.IDE0036.severity = warning
dotnet_diagnostic.IDE0040.severity = error
dotnet_diagnostic.IDE0380.severity = error
dotnet_style_require_accessibility_modifiers = always
# New-line preferences
dotnet_diagnostic.IDE2000.severity = warning
dotnet_diagnostic.IDE2002.severity = warning
dotnet_diagnostic.IDE2003.severity = warning
dotnet_diagnostic.IDE2004.severity = warning
dotnet_diagnostic.IDE2005.severity = warning
dotnet_diagnostic.IDE2006.severity = warning
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
dotnet_style_allow_multiple_blank_lines_experimental = false
dotnet_style_allow_statement_immediately_after_block_experimental = false
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all
dotnet_diagnostic.IDE0280.severity = error
# Parentheses preferences
dotnet_diagnostic.IDE0047.severity = warning
dotnet_diagnostic.IDE0048.severity = warning
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = always_for_clarity
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
# Pattern-matching preferences
dotnet_diagnostic.IDE0019.severity = warning
dotnet_diagnostic.IDE0020.severity = warning
dotnet_diagnostic.IDE0038.severity = warning
dotnet_diagnostic.IDE0066.severity = none
dotnet_diagnostic.IDE0083.severity = warning
dotnet_diagnostic.IDE0260.severity = warning
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# var preferences
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = true
# .NET formatting options
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
# C# formatting options
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false

View File

@@ -1,48 +1,48 @@
name: Build and Test
on:
push:
branches: [ "main" ]
push:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Update rolling tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f rolling
git push origin :refs/tags/rolling || true
git push origin rolling --force
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg"
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh
- name: Update rolling tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f rolling
git push origin :refs/tags/rolling || true
git push origin rolling --force
- name: Upload to rolling
uses: ncipollo/release-action@v1.20.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg"
body: "Last built commit: ${{ github.sha }}"
name: "Rolling Release"
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

View File

@@ -3,21 +3,21 @@ name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Build
run: dotnet build
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Run tests
run: dotnet test
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Build
run: dotnet build
- name: Run tests
run: dotnet test

View File

@@ -29,7 +29,7 @@ namespace SabreTools.IO.Test.Compression
{
string path = Path.Combine(Environment.CurrentDirectory, "TestData", "file-to-compress.bin");
byte[] input = File.ReadAllBytes(path);
MemoryStream output = new MemoryStream();
var output = new MemoryStream();
var bzip = new BZip2OutputStream(output, leaveOpen: true);
bzip.Write(input, 0, input.Length);
@@ -38,4 +38,4 @@ namespace SabreTools.IO.Test.Compression
Assert.Equal(122, output.Length);
}
}
}
}

View File

@@ -24,4 +24,4 @@ namespace SabreTools.IO.Test.Compression
Assert.Equal("AIAIAIAIAIAIA", str);
}
}
}
}

View File

@@ -16,8 +16,8 @@ namespace SabreTools.IO.Test.Compression
// CFDATA blocks.
string path = Path.Combine(Environment.CurrentDirectory, "TestData", "test-archive.msz");
byte[] inputBytes = File.ReadAllBytes(path);
MemoryStream input = new MemoryStream(inputBytes);
MemoryStream output = new MemoryStream();
var input = new MemoryStream(inputBytes);
var output = new MemoryStream();
var decompressor = Decompressor.Create();
input.SeekIfPossible(0x0000);
@@ -25,7 +25,7 @@ namespace SabreTools.IO.Test.Compression
input.SeekIfPossible(0x3969);
decompressor.CopyTo(input, output);
Assert.Equal(38470, output.Length);
Assert.Equal(65536, output.Length);
}
}
}
}

View File

@@ -3,6 +3,7 @@ using System.IO;
using SabreTools.IO.Compression.Quantum;
using Xunit;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.IO.Test.Compression
{
public class QuantumTests
@@ -26,4 +27,4 @@ namespace SabreTools.IO.Test.Compression
Assert.Equal(38470, output.Length);
}
}
}
}

View File

@@ -636,7 +636,7 @@ namespace SabreTools.IO.Test.Extensions
[Fact]
public void ReadDecimalBigEndianTest()
{
var stream = new MemoryStream(_decimalBytes.Reverse().ToArray());
var stream = new MemoryStream([.. Enumerable.Reverse(_decimalBytes)]);
var br = new BinaryReader(stream);
decimal expected = 0.0123456789M;
decimal read = br.ReadDecimalBigEndian();
@@ -658,7 +658,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(_bytes);
var br = new BinaryReader(stream);
var expected = new Guid(_bytes.Reverse().ToArray());
var expected = new Guid([.. Enumerable.Reverse(_bytes)]);
Guid read = br.ReadGuidBigEndian();
Assert.Equal(expected, read);
}
@@ -678,7 +678,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(_bytes);
var br = new BinaryReader(stream);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (Int128)new BigInteger(reversed);
Int128 read = br.ReadInt128BigEndian();
Assert.Equal(expected, read);
@@ -699,7 +699,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(_bytes);
var br = new BinaryReader(stream);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (UInt128)new BigInteger(reversed);
UInt128 read = br.ReadUInt128BigEndian();
Assert.Equal(expected, read);
@@ -780,14 +780,14 @@ namespace SabreTools.IO.Test.Extensions
br = new BinaryReader(stream);
Int128 expectedInt128 = (Int128)new BigInteger(_bytes);
Int128 actualInt128 = br.ReadType<Int128>();
Assert.Equal(expectedHalf, actualHalf);
Assert.Equal(expectedInt128, actualInt128);
// UInt128
stream = new MemoryStream(_bytes);
br = new BinaryReader(stream);
UInt128 expectedUInt128 = (UInt128)new BigInteger(_bytes);
UInt128 actualUInt128 = br.ReadType<UInt128>();
Assert.Equal(expectedHalf, actualHalf);
Assert.Equal(expectedUInt128, actualUInt128);
// Enum
stream = new MemoryStream(_bytes);
@@ -1627,7 +1627,7 @@ namespace SabreTools.IO.Test.Extensions
[Fact]
public void PeekDecimalBigEndianTest()
{
var stream = new MemoryStream(_decimalBytes.Reverse().ToArray());
var stream = new MemoryStream([.. Enumerable.Reverse(_decimalBytes)]);
var br = new BinaryReader(stream);
decimal expected = 0.0123456789M;
decimal read = br.PeekDecimalBigEndian();
@@ -1651,7 +1651,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(_bytes);
var br = new BinaryReader(stream);
var expected = new Guid(_bytes.Reverse().ToArray());
var expected = new Guid([.. Enumerable.Reverse(_bytes)]);
Guid read = br.PeekGuidBigEndian();
Assert.Equal(expected, read);
Assert.Equal(0, br.BaseStream.Position);
@@ -1673,7 +1673,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(_bytes);
var br = new BinaryReader(stream);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (Int128)new BigInteger(reversed);
Int128 read = br.PeekInt128BigEndian();
Assert.Equal(expected, read);
@@ -1696,7 +1696,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(_bytes);
var br = new BinaryReader(stream);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (UInt128)new BigInteger(reversed);
UInt128 read = br.PeekUInt128BigEndian();
Assert.Equal(expected, read);
@@ -1908,7 +1908,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
Half expected = BitConverter.Int16BitsToHalf(0x0100);
bool actual = br.TryReadHalf(out Half read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1919,7 +1918,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
Half expected = BitConverter.Int16BitsToHalf(0x0001);
bool actual = br.TryReadHalfBigEndian(out Half read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2113,7 +2111,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
float expected = BitConverter.Int32BitsToSingle(0x03020100);
bool actual = br.TryReadSingle(out float read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2124,7 +2121,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
float expected = BitConverter.Int32BitsToSingle(0x00010203);
bool actual = br.TryReadSingleBigEndian(out float read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2318,7 +2314,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
double expected = BitConverter.Int64BitsToDouble(0x0706050403020100);
bool actual = br.TryReadDouble(out double read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2329,7 +2324,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
double expected = BitConverter.Int64BitsToDouble(0x0001020304050607);
bool actual = br.TryReadDoubleBigEndian(out double read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2360,7 +2354,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
var expected = new Guid(_bytes);
bool actual = br.TryReadGuid(out Guid read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2371,7 +2364,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
var expected = new Guid(_bytes.Reverse().ToArray());
bool actual = br.TryReadGuidBigEndian(out Guid read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2382,7 +2374,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
var expected = (Int128)new BigInteger(_bytes);
bool actual = br.TryReadInt128(out Int128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2393,8 +2384,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
var reversed = _bytes.Reverse().ToArray();
var expected = (Int128)new BigInteger(reversed);
bool actual = br.TryReadInt128BigEndian(out Int128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2405,7 +2394,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
var expected = (UInt128)new BigInteger(_bytes);
bool actual = br.TryReadUInt128(out UInt128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2416,8 +2404,6 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream([]);
var br = new BinaryReader(stream);
var reversed = _bytes.Reverse().ToArray();
var expected = (UInt128)new BigInteger(reversed);
bool actual = br.TryReadUInt128BigEndian(out UInt128 read);
Assert.False(actual);
Assert.Equal(default, read);

View File

@@ -33,7 +33,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bw.Write((byte)0x00);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -43,7 +43,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadByteBothEndian(ref offset));
@@ -55,7 +55,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bw.Write([0x00, 0x01, 0x02, 0x03]);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -65,7 +65,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bw.WriteBigEndian([0x03, 0x02, 0x01, 0x00]);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -75,7 +75,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bw.Write((sbyte)0x00);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -85,7 +85,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadSByteBothEndian(ref offset));
@@ -97,7 +97,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bw.Write('\0');
ValidateBytes(expected, stream.GetBuffer());
}
@@ -117,7 +117,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bw.Write((short)0x0100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -127,7 +127,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = bw.WriteBigEndian((short)0x0001);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -138,7 +138,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadInt16BothEndian(ref offset));
@@ -150,7 +150,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bw.Write((ushort)0x0100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -160,7 +160,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = bw.WriteBigEndian((ushort)0x0001);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -171,7 +171,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadUInt16BothEndian(ref offset));
@@ -183,7 +183,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bw.Write(BitConverter.Int16BitsToHalf(0x0100));
ValidateBytes(expected, stream.GetBuffer());
}
@@ -193,7 +193,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = bw.WriteBigEndian(BitConverter.Int16BitsToHalf(0x0001));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -204,7 +204,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bw.WriteAsInt24(0x020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -214,7 +214,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = bw.WriteAsInt24BigEndian(0x000102);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -225,7 +225,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bw.WriteAsUInt24(0x020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -235,7 +235,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = bw.WriteAsUInt24BigEndian(0x000102);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -246,7 +246,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bw.Write(0x03020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -256,7 +256,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = bw.WriteBigEndian(0x00010203);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -267,7 +267,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadInt32BothEndian(ref offset));
@@ -279,7 +279,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bw.Write((uint)0x03020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -289,7 +289,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = bw.WriteBigEndian((uint)0x00010203);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -300,7 +300,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadUInt32BothEndian(ref offset));
@@ -312,7 +312,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bw.Write(BitConverter.Int32BitsToSingle(0x03020100));
ValidateBytes(expected, stream.GetBuffer());
}
@@ -322,7 +322,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = bw.WriteBigEndian(BitConverter.Int32BitsToSingle(0x00010203));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -333,7 +333,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bw.WriteAsInt48(0x050403020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -343,7 +343,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = bw.WriteAsInt48BigEndian(0x000102030405);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -354,7 +354,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bw.WriteAsUInt48(0x050403020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -364,7 +364,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = bw.WriteAsUInt48BigEndian(0x000102030405);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -375,7 +375,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bw.Write(0x0706050403020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -385,7 +385,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = bw.WriteBigEndian(0x0001020304050607);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -396,7 +396,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadInt64BothEndian(ref offset));
@@ -408,7 +408,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bw.Write((ulong)0x0706050403020100);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -418,7 +418,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = bw.WriteBigEndian((ulong)0x0001020304050607);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -429,7 +429,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
int offset = 0;
bw.WriteBothEndian(_bytes.ReadUInt64BothEndian(ref offset));
@@ -441,7 +441,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bw.Write(BitConverter.Int64BitsToDouble(0x0706050403020100));
ValidateBytes(expected, stream.GetBuffer());
}
@@ -451,7 +451,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = bw.WriteBigEndian(BitConverter.Int64BitsToDouble(0x0001020304050607));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -462,7 +462,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _decimalBytes.Take(16).ToArray();
byte[] expected = [.. _decimalBytes.Take(16)];
bw.Write(0.0123456789M);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -472,7 +472,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _decimalBytes.Take(16).Reverse().ToArray();
byte[] expected = [.. _decimalBytes.Take(16).Reverse()];
bool write = bw.WriteBigEndian(0.0123456789M);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -483,7 +483,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = bw.Write(new Guid(_bytes));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -494,8 +494,8 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
bool write = bw.WriteBigEndian(new Guid(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = bw.WriteBigEndian(new Guid([.. Enumerable.Reverse(_bytes)]));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -505,7 +505,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = bw.Write((Int128)new BigInteger(_bytes));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -516,8 +516,8 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
bool write = bw.WriteBigEndian((Int128)new BigInteger(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = bw.WriteBigEndian((Int128)new BigInteger(Enumerable.Reverse(_bytes).ToArray()));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -527,7 +527,7 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = bw.Write((UInt128)new BigInteger(_bytes));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -538,8 +538,8 @@ namespace SabreTools.IO.Test.Extensions
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(16).ToArray();
bool write = bw.WriteBigEndian((UInt128)new BigInteger(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = bw.WriteBigEndian((UInt128)new BigInteger(Enumerable.Reverse(_bytes).ToArray()));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -622,35 +622,35 @@ namespace SabreTools.IO.Test.Extensions
// Guid
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
bool actual = bw.WriteType<Guid>(new Guid(_bytes));
bool actual = bw.WriteType(new Guid(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// Half
stream = new MemoryStream(new byte[2], 0, 2, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<Half>(BitConverter.Int16BitsToHalf(0x0100));
actual = bw.WriteType(BitConverter.Int16BitsToHalf(0x0100));
Assert.True(actual);
ValidateBytes([.. _bytes.Take(2)], stream.GetBuffer());
// Int128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<Int128>((Int128)new BigInteger(_bytes));
actual = bw.WriteType((Int128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// UInt128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<UInt128>((UInt128)new BigInteger(_bytes));
actual = bw.WriteType((UInt128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// Enum
stream = new MemoryStream(new byte[4], 0, 4, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<TestEnum>((TestEnum)0x03020100);
actual = bw.WriteType((TestEnum)0x03020100);
Assert.True(actual);
ValidateBytes([.. _bytes.Take(4)], stream.GetBuffer());
}
@@ -672,7 +672,7 @@ namespace SabreTools.IO.Test.Extensions
SecondValue = 0x07060504,
FifthValue = "ABC",
};
byte[] expected = bytesWithString.Take(12).ToArray();
byte[] expected = [.. bytesWithString.Take(12)];
bool write = bw.WriteType(obj);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -697,7 +697,7 @@ namespace SabreTools.IO.Test.Extensions
FourthValue = 0x0B0A,
FifthValue = "ABC",
};
byte[] expected = bytesWithString.Take(16).ToArray();
byte[] expected = [.. bytesWithString.Take(16)];
bool write = bw.WriteType(obj);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());

View File

@@ -36,6 +36,42 @@ namespace SabreTools.IO.Test.Extensions
#endregion
#region IsNumericArray
[Fact]
public void IsNumericArray_Empty_False()
{
byte[] arr = [];
bool actual = arr.IsNumericArray();
Assert.False(actual);
}
[Fact]
public void IsNumericArray_NonNumeric_False()
{
byte[] arr = Encoding.ASCII.GetBytes("ABCDEF");
bool actual = arr.IsNumericArray();
Assert.False(actual);
}
[Fact]
public void IsNumericArray_MixedNumeric_False()
{
byte[] arr = Encoding.ASCII.GetBytes("ABC123");
bool actual = arr.IsNumericArray();
Assert.False(actual);
}
[Fact]
public void IsNumericArray_Numeric_True()
{
byte[] arr = Encoding.ASCII.GetBytes("0123456789");
bool actual = arr.IsNumericArray();
Assert.True(actual);
}
#endregion
#region FindAllPositions
[Fact]

View File

@@ -550,7 +550,7 @@ namespace SabreTools.IO.Test.Extensions
{
int offset = 0;
decimal expected = 0.0123456789M;
decimal read = _decimalBytes.Reverse().ToArray().ReadDecimalBigEndian(ref offset);
decimal read = Enumerable.Reverse(_decimalBytes).ToArray().ReadDecimalBigEndian(ref offset);
Assert.Equal(expected, read);
}
@@ -567,7 +567,7 @@ namespace SabreTools.IO.Test.Extensions
public void ReadGuidBigEndianTest()
{
int offset = 0;
var expected = new Guid(_bytes.Reverse().ToArray());
var expected = new Guid([.. Enumerable.Reverse(_bytes)]);
Guid read = _bytes.ReadGuidBigEndian(ref offset);
Assert.Equal(expected, read);
}
@@ -585,7 +585,7 @@ namespace SabreTools.IO.Test.Extensions
public void ReadInt128BigEndianTest()
{
int offset = 0;
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (Int128)new BigInteger(reversed);
Int128 read = _bytes.ReadInt128BigEndian(ref offset);
Assert.Equal(expected, read);
@@ -604,7 +604,7 @@ namespace SabreTools.IO.Test.Extensions
public void ReadUInt128BigEndianTest()
{
int offset = 0;
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (UInt128)new BigInteger(reversed);
UInt128 read = _bytes.ReadUInt128BigEndian(ref offset);
Assert.Equal(expected, read);
@@ -675,13 +675,13 @@ namespace SabreTools.IO.Test.Extensions
offset = 0;
Int128 expectedInt128 = (Int128)new BigInteger(_bytes);
Int128 actualInt128 = _bytes.ReadType<Int128>(ref offset);
Assert.Equal(expectedHalf, actualHalf);
Assert.Equal(expectedInt128, actualInt128);
// UInt128
offset = 0;
UInt128 expectedUInt128 = (UInt128)new BigInteger(_bytes);
UInt128 actualUInt128 = _bytes.ReadType<UInt128>(ref offset);
Assert.Equal(expectedHalf, actualHalf);
Assert.Equal(expectedUInt128, actualUInt128);
// Enum
offset = 0;
@@ -1473,7 +1473,7 @@ namespace SabreTools.IO.Test.Extensions
{
int offset = 0;
decimal expected = 0.0123456789M;
decimal read = _decimalBytes.Reverse().ToArray().PeekDecimalBigEndian(ref offset);
decimal read = Enumerable.Reverse(_decimalBytes).ToArray().PeekDecimalBigEndian(ref offset);
Assert.Equal(expected, read);
Assert.Equal(0, offset);
}
@@ -1492,7 +1492,7 @@ namespace SabreTools.IO.Test.Extensions
public void PeekGuidBigEndianTest()
{
int offset = 0;
var expected = new Guid(_bytes.Reverse().ToArray());
var expected = new Guid([.. Enumerable.Reverse(_bytes)]);
Guid read = _bytes.PeekGuidBigEndian(ref offset);
Assert.Equal(expected, read);
Assert.Equal(0, offset);
@@ -1512,7 +1512,7 @@ namespace SabreTools.IO.Test.Extensions
public void PeekInt128BigEndianTest()
{
int offset = 0;
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (Int128)new BigInteger(reversed);
Int128 read = _bytes.PeekInt128BigEndian(ref offset);
Assert.Equal(expected, read);
@@ -1533,7 +1533,7 @@ namespace SabreTools.IO.Test.Extensions
public void PeekUInt128BigEndianTest()
{
int offset = 0;
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (UInt128)new BigInteger(reversed);
UInt128 read = _bytes.PeekUInt128BigEndian(ref offset);
Assert.Equal(expected, read);
@@ -1724,7 +1724,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadHalfTest()
{
int offset = 0;
Half expected = BitConverter.Int16BitsToHalf(0x0100);
bool actual = Array.Empty<byte>().TryReadHalf(ref offset, out Half read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1734,7 +1733,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadHalfBigEndianTest()
{
int offset = 0;
Half expected = BitConverter.Int16BitsToHalf(0x0001);
bool actual = Array.Empty<byte>().TryReadHalfBigEndian(ref offset, out Half read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1909,7 +1907,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadSingleTest()
{
int offset = 0;
float expected = BitConverter.Int32BitsToSingle(0x03020100);
bool actual = Array.Empty<byte>().TryReadSingle(ref offset, out float read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1919,7 +1916,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadSingleBigEndianTest()
{
int offset = 0;
float expected = BitConverter.Int32BitsToSingle(0x00010203);
bool actual = Array.Empty<byte>().TryReadSingleBigEndian(ref offset, out float read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2094,7 +2090,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadDoubleTest()
{
int offset = 0;
double expected = BitConverter.Int64BitsToDouble(0x0706050403020100);
bool actual = Array.Empty<byte>().TryReadDouble(ref offset, out double read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2104,7 +2099,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadDoubleBigEndianTest()
{
int offset = 0;
double expected = BitConverter.Int64BitsToDouble(0x0001020304050607);
bool actual = Array.Empty<byte>().TryReadDoubleBigEndian(ref offset, out double read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2132,7 +2126,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadGuidTest()
{
int offset = 0;
var expected = new Guid(_bytes);
bool actual = Array.Empty<byte>().TryReadGuid(ref offset, out Guid read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2142,7 +2135,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadGuidBigEndianTest()
{
int offset = 0;
var expected = new Guid(_bytes.Reverse().ToArray());
bool actual = Array.Empty<byte>().TryReadGuidBigEndian(ref offset, out Guid read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2152,7 +2144,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadInt128Test()
{
int offset = 0;
var expected = (Int128)new BigInteger(_bytes);
bool actual = Array.Empty<byte>().TryReadInt128(ref offset, out Int128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2162,8 +2153,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadInt128BigEndianTest()
{
int offset = 0;
var reversed = _bytes.Reverse().ToArray();
var expected = (Int128)new BigInteger(reversed);
bool actual = Array.Empty<byte>().TryReadInt128BigEndian(ref offset, out Int128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2173,7 +2162,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadUInt128Test()
{
int offset = 0;
var expected = (UInt128)new BigInteger(_bytes);
bool actual = Array.Empty<byte>().TryReadUInt128(ref offset, out UInt128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2183,8 +2171,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadUInt128BigEndianTest()
{
int offset = 0;
var reversed = _bytes.Reverse().ToArray();
var expected = (UInt128)new BigInteger(reversed);
bool actual = Array.Empty<byte>().TryReadUInt128BigEndian(ref offset, out UInt128 read);
Assert.False(actual);
Assert.Equal(default, read);

View File

@@ -32,7 +32,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bool write = buffer.Write(ref offset, (byte)0x00);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -43,7 +43,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadByteBothEndian(ref readOffset));
@@ -55,7 +55,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.Write(ref offset, [0x00, 0x01, 0x02, 0x03]);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -66,7 +66,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.WriteBigEndian(ref offset, [0x03, 0x02, 0x01, 0x00]);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -77,7 +77,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bool write = buffer.Write(ref offset, (sbyte)0x00);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -88,7 +88,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadSByteBothEndian(ref readOffset));
@@ -100,7 +100,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bool write = buffer.Write(ref offset, '\0');
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -122,7 +122,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = buffer.Write(ref offset, (short)0x0100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -133,7 +133,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = buffer.WriteBigEndian(ref offset, (short)0x0001);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -144,7 +144,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadInt16BothEndian(ref readOffset));
@@ -156,7 +156,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = buffer.Write(ref offset, (ushort)0x0100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -167,7 +167,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = buffer.WriteBigEndian(ref offset, (ushort)0x0001);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -178,7 +178,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadUInt16BothEndian(ref readOffset));
@@ -190,7 +190,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = buffer.Write(ref offset, BitConverter.Int16BitsToHalf(0x0100));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -201,7 +201,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = buffer.WriteBigEndian(ref offset, BitConverter.Int16BitsToHalf(0x0001));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -212,7 +212,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = buffer.WriteAsInt24(ref offset, 0x020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -223,7 +223,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = buffer.WriteAsInt24BigEndian(ref offset, 0x000102);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -234,7 +234,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = buffer.WriteAsUInt24(ref offset, 0x020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -245,7 +245,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = buffer.WriteAsUInt24BigEndian(ref offset, 0x000102);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -256,7 +256,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.Write(ref offset, 0x03020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -267,7 +267,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.WriteBigEndian(ref offset, 0x00010203);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -278,7 +278,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadInt32BothEndian(ref readOffset));
@@ -290,7 +290,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.Write(ref offset, (uint)0x03020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -301,7 +301,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.WriteBigEndian(ref offset, (uint)0x00010203);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -312,7 +312,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadUInt32BothEndian(ref readOffset));
@@ -324,7 +324,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.Write(ref offset, BitConverter.Int32BitsToSingle(0x03020100));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -335,7 +335,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = buffer.WriteBigEndian(ref offset, BitConverter.Int32BitsToSingle(0x00010203));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -346,7 +346,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = buffer.WriteAsInt48(ref offset, 0x050403020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -357,7 +357,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = buffer.WriteAsInt48BigEndian(ref offset, 0x000102030405);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -368,7 +368,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = buffer.WriteAsUInt48(ref offset, 0x050403020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -379,7 +379,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = buffer.WriteAsUInt48BigEndian(ref offset, 0x000102030405);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -390,7 +390,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = buffer.Write(ref offset, 0x0706050403020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -401,7 +401,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = buffer.WriteBigEndian(ref offset, 0x0001020304050607);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -412,7 +412,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadInt64BothEndian(ref readOffset));
@@ -424,7 +424,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = buffer.Write(ref offset, (ulong)0x0706050403020100);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -435,7 +435,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = buffer.WriteBigEndian(ref offset, (ulong)0x0001020304050607);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -446,7 +446,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
int readOffset = 0;
buffer.WriteBothEndian(ref offset, _bytes.ReadUInt64BothEndian(ref readOffset));
@@ -458,7 +458,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = buffer.Write(ref offset, BitConverter.Int64BitsToDouble(0x0706050403020100));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -469,7 +469,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = buffer.WriteBigEndian(ref offset, BitConverter.Int64BitsToDouble(0x0001020304050607));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -480,7 +480,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _decimalBytes.Take(16).ToArray();
byte[] expected = [.. _decimalBytes.Take(16)];
bool write = buffer.Write(ref offset, 0.0123456789M);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -491,7 +491,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _decimalBytes.Take(16).Reverse().ToArray();
byte[] expected = [.. _decimalBytes.Take(16).Reverse()];
bool write = buffer.WriteBigEndian(ref offset, 0.0123456789M);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -502,7 +502,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = buffer.Write(ref offset, new Guid(_bytes));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -513,8 +513,8 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
bool write = buffer.WriteBigEndian(ref offset, new Guid(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = buffer.WriteBigEndian(ref offset, new Guid([.. Enumerable.Reverse(_bytes)]));
Assert.True(write);
ValidateBytes(expected, buffer);
}
@@ -524,7 +524,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = buffer.Write(ref offset, (Int128)new BigInteger(_bytes));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -535,8 +535,8 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
bool write = buffer.WriteBigEndian(ref offset, (Int128)new BigInteger(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = buffer.WriteBigEndian(ref offset, (Int128)new BigInteger(Enumerable.Reverse(_bytes).ToArray()));
Assert.True(write);
ValidateBytes(expected, buffer);
}
@@ -546,7 +546,7 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = buffer.Write(ref offset, (UInt128)new BigInteger(_bytes));
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -557,8 +557,8 @@ namespace SabreTools.IO.Test.Extensions
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(16).ToArray();
bool write = buffer.WriteBigEndian(ref offset, (UInt128)new BigInteger(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = buffer.WriteBigEndian(ref offset, (UInt128)new BigInteger(Enumerable.Reverse(_bytes).ToArray()));
Assert.True(write);
ValidateBytes(expected, buffer);
}
@@ -641,35 +641,35 @@ namespace SabreTools.IO.Test.Extensions
// Guid
int offset = 0;
byte[] buffer = new byte[16];
bool actual = buffer.WriteType<Guid>(ref offset, new Guid(_bytes));
bool actual = buffer.WriteType(ref offset, new Guid(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, buffer);
// Half
offset = 0;
buffer = new byte[2];
actual = buffer.WriteType<Half>(ref offset, BitConverter.Int16BitsToHalf(0x0100));
actual = buffer.WriteType(ref offset, BitConverter.Int16BitsToHalf(0x0100));
Assert.True(actual);
ValidateBytes([.. _bytes.Take(2)], buffer);
// Int128
offset = 0;
buffer = new byte[16];
actual = buffer.WriteType<Int128>(ref offset, (Int128)new BigInteger(_bytes));
actual = buffer.WriteType(ref offset, (Int128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, buffer);
// UInt128
offset = 0;
buffer = new byte[16];
actual = buffer.WriteType<UInt128>(ref offset, (UInt128)new BigInteger(_bytes));
actual = buffer.WriteType(ref offset, (UInt128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, buffer);
// Enum
offset = 0;
buffer = new byte[4];
actual = buffer.WriteType<TestEnum>(ref offset, (TestEnum)0x03020100);
actual = buffer.WriteType(ref offset, (TestEnum)0x03020100);
Assert.True(actual);
ValidateBytes([.. _bytes.Take(4)], buffer);
}
@@ -691,7 +691,7 @@ namespace SabreTools.IO.Test.Extensions
SecondValue = 0x07060504,
FifthValue = "ABC",
};
byte[] expected = bytesWithString.Take(12).ToArray();
byte[] expected = [.. bytesWithString.Take(12)];
bool write = buffer.WriteType(ref offset, obj);
Assert.True(write);
ValidateBytes(expected, buffer);
@@ -716,7 +716,7 @@ namespace SabreTools.IO.Test.Extensions
FourthValue = 0x0B0A,
FifthValue = "ABC",
};
byte[] expected = bytesWithString.Take(16).ToArray();
byte[] expected = [.. bytesWithString.Take(16)];
bool write = buffer.WriteType(ref offset, obj);
Assert.True(write);
ValidateBytes(expected, buffer);

View File

@@ -0,0 +1,86 @@
using System.Collections.Generic;
using SabreTools.IO.Extensions;
using Xunit;
namespace SabreTools.IO.Test.Extensions
{
public class DictionaryExtensionsTests
{
#region MergeWith
[Fact]
public void MergeWith_EmptySource_EmptyOther_Empty()
{
Dictionary<string, List<string>> source = [];
Dictionary<string, List<string>> other = [];
source.MergeWith(other);
Assert.Empty(source);
}
[Fact]
public void MergeWith_EmptySource_EmptyKeyOther_Empty()
{
Dictionary<string, List<string>> source = [];
Dictionary<string, List<string>> other = [];
other.Add("key", []);
source.MergeWith(other);
Assert.Empty(source);
}
[Fact]
public void MergeWith_EmptySource_FilledOther_Filled()
{
Dictionary<string, List<string>> source = [];
Dictionary<string, List<string>> other = [];
other.Add("key", ["value"]);
source.MergeWith(other);
string key = Assert.Single(source.Keys);
Assert.Equal("key", key);
List<string> actual = source[key];
string value = Assert.Single(actual);
Assert.Equal("value", value);
}
[Fact]
public void MergeWith_FilledSource_EmptyOther_Filled()
{
Dictionary<string, List<string>> source = [];
source.Add("key", ["value"]);
Dictionary<string, List<string>> other = [];
source.MergeWith(other);
string key = Assert.Single(source.Keys);
Assert.Equal("key", key);
List<string> actual = source[key];
string value = Assert.Single(actual);
Assert.Equal("value", value);
}
[Fact]
public void MergeWith_FilledSource_FilledOther_Filled()
{
Dictionary<string, List<string>> source = [];
source.Add("key1", ["value1"]);
Dictionary<string, List<string>> other = [];
other.Add("key2", ["value2"]);
source.MergeWith(other);
Assert.Equal(2, source.Keys.Count);
Assert.Contains("key1", source.Keys);
List<string> actualKey1 = source["key1"];
string value1 = Assert.Single(actualKey1);
Assert.Equal("value1", value1);
Assert.Contains("key2", source.Keys);
List<string> actualKey2 = source["key2"];
string value2 = Assert.Single(actualKey2);
Assert.Equal("value2", value2);
}
#endregion
}
}

View File

@@ -6,6 +6,8 @@ using System.Threading;
using SabreTools.IO.Extensions;
using Xunit;
#pragma warning disable IDE0060 // Remove unused parameter
#pragma warning disable IDE0290 // Use primary constructor
namespace SabreTools.IO.Test.Extensions
{
public class EnumerableExtensionsTests
@@ -80,7 +82,7 @@ namespace SabreTools.IO.Test.Extensions
#endregion
/// <summary>
/// Fake enumerable that uses <see cref="ErrorEnumerator"/>
/// Fake enumerable that uses <see cref="ErrorEnumerator"/>
/// </summary>
private class ErrorEnumerable : IEnumerable<string>
{

View File

@@ -20,7 +20,7 @@ namespace SabreTools.IO.Test.Extensions
{
// Handle test setup
expected ??= PathTool.GetRuntimeDirectory();
if (expected != null)
if (expected is not null)
expected = Path.GetFullPath(expected);
string actual = dir.Ensure(create: false);

View File

@@ -4,6 +4,7 @@ using System.Text;
using SabreTools.IO.Extensions;
using Xunit;
#pragma warning disable IDE0017 // Object initialization can be simplified
namespace SabreTools.IO.Test.Extensions
{
public class StreamExtensionsTests
@@ -323,7 +324,7 @@ namespace SabreTools.IO.Test.Extensions
long actual = stream.SeekIfPossible(0, origin);
Assert.Equal(8, actual);
}
[Theory]
[InlineData(SeekOrigin.Begin)]
[InlineData(SeekOrigin.Current)]
@@ -334,7 +335,7 @@ namespace SabreTools.IO.Test.Extensions
long actual = stream.SeekIfPossible(0, origin);
Assert.Equal(-1, actual);
}
[Theory]
[InlineData(SeekOrigin.Begin)]
[InlineData(SeekOrigin.Current)]
@@ -345,7 +346,7 @@ namespace SabreTools.IO.Test.Extensions
long actual = stream.SeekIfPossible(0, origin);
Assert.Equal(-1, actual);
}
[Theory]
[InlineData(SeekOrigin.Begin, 5, 5)]
[InlineData(SeekOrigin.Current, 5, 7)]

View File

@@ -552,7 +552,7 @@ namespace SabreTools.IO.Test.Extensions
[Fact]
public void ReadDecimalBigEndianTest()
{
var stream = new MemoryStream(_decimalBytes.Reverse().ToArray());
var stream = new MemoryStream([.. Enumerable.Reverse(_decimalBytes)]);
decimal expected = 0.0123456789M;
decimal read = stream.ReadDecimalBigEndian();
Assert.Equal(expected, read);
@@ -571,7 +571,7 @@ namespace SabreTools.IO.Test.Extensions
public void ReadGuidBigEndianTest()
{
var stream = new MemoryStream(_bytes);
var expected = new Guid(_bytes.Reverse().ToArray());
var expected = new Guid([.. Enumerable.Reverse(_bytes)]);
Guid read = stream.ReadGuidBigEndian();
Assert.Equal(expected, read);
}
@@ -589,7 +589,7 @@ namespace SabreTools.IO.Test.Extensions
public void ReadInt128BigEndianTest()
{
var stream = new MemoryStream(_bytes);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (Int128)new BigInteger(reversed);
Int128 read = stream.ReadInt128BigEndian();
Assert.Equal(expected, read);
@@ -608,7 +608,7 @@ namespace SabreTools.IO.Test.Extensions
public void ReadUInt128BigEndianTest()
{
var stream = new MemoryStream(_bytes);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (UInt128)new BigInteger(reversed);
UInt128 read = stream.ReadUInt128BigEndian();
Assert.Equal(expected, read);
@@ -679,13 +679,13 @@ namespace SabreTools.IO.Test.Extensions
stream = new MemoryStream(_bytes);
Int128 expectedInt128 = (Int128)new BigInteger(_bytes);
Int128 actualInt128 = stream.ReadType<Int128>();
Assert.Equal(expectedHalf, actualHalf);
Assert.Equal(expectedInt128, actualInt128);
// UInt128
stream = new MemoryStream(_bytes);
UInt128 expectedUInt128 = (UInt128)new BigInteger(_bytes);
UInt128 actualUInt128 = stream.ReadType<UInt128>();
Assert.Equal(expectedHalf, actualHalf);
Assert.Equal(expectedUInt128, actualUInt128);
// Enum
stream = new MemoryStream(_bytes);
@@ -1467,7 +1467,7 @@ namespace SabreTools.IO.Test.Extensions
[Fact]
public void PeekDecimalBigEndianTest()
{
var stream = new MemoryStream(_decimalBytes.Reverse().ToArray());
var stream = new MemoryStream([.. Enumerable.Reverse(_decimalBytes)]);
decimal expected = 0.0123456789M;
decimal read = stream.PeekDecimalBigEndian();
Assert.Equal(expected, read);
@@ -1488,7 +1488,7 @@ namespace SabreTools.IO.Test.Extensions
public void PeekGuidBigEndianTest()
{
var stream = new MemoryStream(_bytes);
var expected = new Guid(_bytes.Reverse().ToArray());
var expected = new Guid([.. Enumerable.Reverse(_bytes)]);
Guid read = stream.PeekGuidBigEndian();
Assert.Equal(expected, read);
Assert.Equal(0, stream.Position);
@@ -1508,7 +1508,7 @@ namespace SabreTools.IO.Test.Extensions
public void PeekInt128BigEndianTest()
{
var stream = new MemoryStream(_bytes);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (Int128)new BigInteger(reversed);
Int128 read = stream.PeekInt128BigEndian();
Assert.Equal(expected, read);
@@ -1529,7 +1529,7 @@ namespace SabreTools.IO.Test.Extensions
public void PeekUInt128BigEndianTest()
{
var stream = new MemoryStream(_bytes);
var reversed = _bytes.Reverse().ToArray();
var reversed = Enumerable.Reverse(_bytes).ToArray();
var expected = (UInt128)new BigInteger(reversed);
UInt128 read = stream.PeekUInt128BigEndian();
Assert.Equal(expected, read);
@@ -1712,7 +1712,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadHalfTest()
{
var stream = new MemoryStream([]);
Half expected = BitConverter.Int16BitsToHalf(0x0100);
bool actual = stream.TryReadHalf(out Half read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1722,7 +1721,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadHalfBigEndianTest()
{
var stream = new MemoryStream([]);
Half expected = BitConverter.Int16BitsToHalf(0x0001);
bool actual = stream.TryReadHalfBigEndian(out Half read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1897,7 +1895,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadSingleTest()
{
var stream = new MemoryStream([]);
float expected = BitConverter.Int32BitsToSingle(0x03020100);
bool actual = stream.TryReadSingle(out float read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -1907,7 +1904,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadSingleBigEndianTest()
{
var stream = new MemoryStream([]);
float expected = BitConverter.Int32BitsToSingle(0x00010203);
bool actual = stream.TryReadSingleBigEndian(out float read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2082,7 +2078,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadDoubleTest()
{
var stream = new MemoryStream([]);
double expected = BitConverter.Int64BitsToDouble(0x0706050403020100);
bool actual = stream.TryReadDouble(out double read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2092,7 +2087,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadDoubleBigEndianTest()
{
var stream = new MemoryStream([]);
double expected = BitConverter.Int64BitsToDouble(0x0001020304050607);
bool actual = stream.TryReadDoubleBigEndian(out double read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2120,7 +2114,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadGuidTest()
{
var stream = new MemoryStream([]);
var expected = new Guid(_bytes);
bool actual = stream.TryReadGuid(out Guid read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2130,7 +2123,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadGuidBigEndianTest()
{
var stream = new MemoryStream([]);
var expected = new Guid(_bytes.Reverse().ToArray());
bool actual = stream.TryReadGuidBigEndian(out Guid read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2140,7 +2132,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadInt128Test()
{
var stream = new MemoryStream([]);
var expected = (Int128)new BigInteger(_bytes);
bool actual = stream.TryReadInt128(out Int128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2150,8 +2141,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadInt128BigEndianTest()
{
var stream = new MemoryStream([]);
var reversed = _bytes.Reverse().ToArray();
var expected = (Int128)new BigInteger(reversed);
bool actual = stream.TryReadInt128BigEndian(out Int128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2161,7 +2150,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadUInt128Test()
{
var stream = new MemoryStream([]);
var expected = (UInt128)new BigInteger(_bytes);
bool actual = stream.TryReadUInt128(out UInt128 read);
Assert.False(actual);
Assert.Equal(default, read);
@@ -2171,8 +2159,6 @@ namespace SabreTools.IO.Test.Extensions
public void TryReadUInt128BigEndianTest()
{
var stream = new MemoryStream([]);
var reversed = _bytes.Reverse().ToArray();
var expected = (UInt128)new BigInteger(reversed);
bool actual = stream.TryReadUInt128BigEndian(out UInt128 read);
Assert.False(actual);
Assert.Equal(default, read);

View File

@@ -32,7 +32,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteByteValueTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bool write = stream.Write((byte)0x00);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -42,7 +42,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteByteBothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadByteBothEndian(ref offset));
@@ -53,7 +53,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteBytesTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = StreamWriterExtensions.Write(stream, [0x00, 0x01, 0x02, 0x03]);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -63,7 +63,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteBytesBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
stream.WriteBigEndian([0x03, 0x02, 0x01, 0x00]);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -72,7 +72,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteSByteTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bool write = stream.Write((sbyte)0x00);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -82,7 +82,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteSByteBothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadSByteBothEndian(ref offset));
@@ -93,7 +93,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteCharTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(1).ToArray();
byte[] expected = [.. _bytes.Take(1)];
bool write = stream.Write('\0');
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -112,7 +112,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt16Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = stream.Write((short)0x0100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -122,7 +122,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt16BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = stream.WriteBigEndian((short)0x0001);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -132,7 +132,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt16BothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadInt16BothEndian(ref offset));
@@ -143,7 +143,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt16Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = stream.Write((ushort)0x0100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -153,7 +153,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt16BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = stream.WriteBigEndian((ushort)0x0001);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -163,7 +163,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt16BothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadUInt16BothEndian(ref offset));
@@ -174,7 +174,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteHalfTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = stream.Write(BitConverter.Int16BitsToHalf(0x0100));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -184,7 +184,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteHalfBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(2).ToArray();
byte[] expected = [.. _bytes.Take(2)];
bool write = stream.WriteBigEndian(BitConverter.Int16BitsToHalf(0x0001));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -194,7 +194,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt24Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = stream.WriteAsInt24(0x020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -204,7 +204,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt24BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = stream.WriteAsInt24BigEndian(0x000102);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -214,7 +214,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt24Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = stream.WriteAsUInt24(0x020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -224,7 +224,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt24BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(3).ToArray();
byte[] expected = [.. _bytes.Take(3)];
bool write = stream.WriteAsUInt24BigEndian(0x000102);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -234,7 +234,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt32Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = stream.Write(0x03020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -244,7 +244,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt32BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = stream.WriteBigEndian(0x00010203);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -254,7 +254,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt32BothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadInt32BothEndian(ref offset));
@@ -265,7 +265,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt32Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = stream.Write((uint)0x03020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -275,7 +275,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt32BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = stream.WriteBigEndian((uint)0x00010203);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -285,7 +285,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt32BothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadUInt32BothEndian(ref offset));
@@ -296,7 +296,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteSingleTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = stream.Write(BitConverter.Int32BitsToSingle(0x03020100));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -306,7 +306,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteSingleBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
byte[] expected = [.. _bytes.Take(4)];
bool write = stream.WriteBigEndian(BitConverter.Int32BitsToSingle(0x00010203));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -316,7 +316,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt48Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = stream.WriteAsInt48(0x050403020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -326,7 +326,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt48BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = stream.WriteAsInt48BigEndian(0x000102030405);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -336,7 +336,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt48Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = stream.WriteAsUInt48(0x050403020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -346,7 +346,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt48BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(6).ToArray();
byte[] expected = [.. _bytes.Take(6)];
bool write = stream.WriteAsUInt48BigEndian(0x000102030405);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -356,7 +356,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt64Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = stream.Write(0x0706050403020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -366,7 +366,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt64BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = stream.WriteBigEndian(0x0001020304050607);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -376,7 +376,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt64BothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadInt64BothEndian(ref offset));
@@ -387,7 +387,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt64Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = stream.Write((ulong)0x0706050403020100);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -397,7 +397,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt64BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = stream.WriteBigEndian((ulong)0x0001020304050607);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -407,7 +407,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt64BothEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
int offset = 0;
stream.WriteBothEndian(_bytes.ReadUInt64BothEndian(ref offset));
@@ -418,7 +418,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteDoubleTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = stream.Write(BitConverter.Int64BitsToDouble(0x0706050403020100));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -428,7 +428,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteDoubleBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
byte[] expected = [.. _bytes.Take(8)];
bool write = stream.WriteBigEndian(BitConverter.Int64BitsToDouble(0x0001020304050607));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -438,7 +438,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteDecimalTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _decimalBytes.Take(16).ToArray();
byte[] expected = [.. _decimalBytes.Take(16)];
bool write = stream.Write(0.0123456789M);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -448,7 +448,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteDecimalBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _decimalBytes.Take(16).Reverse().ToArray();
byte[] expected = [.. _decimalBytes.Take(16).Reverse()];
bool write = stream.WriteBigEndian(0.0123456789M);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -458,7 +458,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteGuidTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = stream.Write(new Guid(_bytes));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -468,8 +468,8 @@ namespace SabreTools.IO.Test.Extensions
public void WriteGuidBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
bool write = stream.WriteBigEndian(new Guid(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = stream.WriteBigEndian(new Guid([.. Enumerable.Reverse(_bytes)]));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -478,7 +478,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt128Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = stream.Write((Int128)new BigInteger(_bytes));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -488,8 +488,8 @@ namespace SabreTools.IO.Test.Extensions
public void WriteInt128BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
bool write = stream.WriteBigEndian((Int128)new BigInteger(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = stream.WriteBigEndian((Int128)new BigInteger(Enumerable.Reverse(_bytes).ToArray()));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -498,7 +498,7 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt128Test()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
byte[] expected = [.. _bytes.Take(16)];
bool write = stream.Write((UInt128)new BigInteger(_bytes));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -508,8 +508,8 @@ namespace SabreTools.IO.Test.Extensions
public void WriteUInt128BigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(16).ToArray();
bool write = stream.WriteBigEndian((UInt128)new BigInteger(_bytes.Reverse().ToArray()));
byte[] expected = [.. _bytes.Take(16)];
bool write = stream.WriteBigEndian((UInt128)new BigInteger(Enumerable.Reverse(_bytes).ToArray()));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
@@ -585,31 +585,31 @@ namespace SabreTools.IO.Test.Extensions
{
// Guid
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
bool actual = stream.WriteType<Guid>(new Guid(_bytes));
bool actual = stream.WriteType(new Guid(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// Half
stream = new MemoryStream(new byte[2], 0, 2, true, true);
actual = stream.WriteType<Half>(BitConverter.Int16BitsToHalf(0x0100));
actual = stream.WriteType(BitConverter.Int16BitsToHalf(0x0100));
Assert.True(actual);
ValidateBytes([.. _bytes.Take(2)], stream.GetBuffer());
// Int128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
actual = stream.WriteType<Int128>((Int128)new BigInteger(_bytes));
actual = stream.WriteType((Int128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// UInt128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
actual = stream.WriteType<UInt128>((UInt128)new BigInteger(_bytes));
actual = stream.WriteType((UInt128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// Enum
stream = new MemoryStream(new byte[4], 0, 4, true, true);
actual = stream.WriteType<TestEnum>((TestEnum)0x03020100);
actual = stream.WriteType((TestEnum)0x03020100);
Assert.True(actual);
ValidateBytes([.. _bytes.Take(4)], stream.GetBuffer());
}
@@ -630,7 +630,7 @@ namespace SabreTools.IO.Test.Extensions
SecondValue = 0x07060504,
FifthValue = "ABC",
};
byte[] expected = bytesWithString.Take(12).ToArray();
byte[] expected = [.. bytesWithString.Take(12)];
bool write = stream.WriteType(obj);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
@@ -654,7 +654,7 @@ namespace SabreTools.IO.Test.Extensions
FourthValue = 0x0B0A,
FifthValue = "ABC",
};
byte[] expected = bytesWithString.Take(16).ToArray();
byte[] expected = [.. bytesWithString.Take(16)];
bool write = stream.WriteType(obj);
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());

View File

@@ -73,4 +73,4 @@ namespace SabreTools.IO.Test.Extensions
#endregion
}
}
}

View File

@@ -30,7 +30,7 @@ namespace SabreTools.IO.Test.Extensions
public TestStructPoint[]? StructArray;
/// <summary>
/// Length of <see cref="LPByteArray"/>
/// Length of <see cref="LPByteArray"/>
/// </summary>
public ushort LPByteArrayLength;
@@ -39,7 +39,7 @@ namespace SabreTools.IO.Test.Extensions
/// </summary>
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]
public byte[]? LPByteArray;
// /// <summary>
// /// 4 entry nested byte array
// /// </summary>

View File

@@ -18,7 +18,7 @@ namespace SabreTools.IO.Test.Extensions
public uint FieldB;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class TestStructInheritanceChild2 : TestStructInheritanceParent
{

View File

@@ -10,7 +10,7 @@ namespace SabreTools.IO.Test.Extensions
public int SecondValue;
public ushort ThirdValue;
public short FourthValue;
[MarshalAs(UnmanagedType.LPStr)]

View File

@@ -5,7 +5,7 @@ using Xunit;
namespace SabreTools.IO.Test.Matching
{
/// <remarks>
/// All other test cases are covered by <see cref="PathMatchTests"/>
/// All other test cases are covered by <see cref="PathMatchTests"/>
/// </remarks>
public class FilePathMatchTests
{

View File

@@ -4,6 +4,7 @@ using System.IO;
using SabreTools.IO.Matching;
using Xunit;
#pragma warning disable CA1861 // Prefer 'static readonly' fields
namespace SabreTools.IO.Test.Matching
{
public class PathMatchSetTests

View File

@@ -48,7 +48,7 @@ namespace SabreTools.IO.Test.Numerics
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((int)1).GetTypeCode();
TypeCode expected = 1.GetTypeCode();
var val = new BothInt32(1, 1);
Assert.Equal(expected, val.GetTypeCode());
@@ -59,51 +59,51 @@ namespace SabreTools.IO.Test.Numerics
{
var val = new BothInt32(1, 1);
bool expectedBool = Convert.ToBoolean((int)1);
bool expectedBool = Convert.ToBoolean(1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((int)1);
char expectedChar = Convert.ToChar(1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((int)1);
sbyte expectedSByte = Convert.ToSByte(1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((int)1);
byte expectedByte = Convert.ToByte(1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((int)1);
short expectedInt16 = Convert.ToInt16(1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((int)1);
ushort expectedUInt16 = Convert.ToUInt16(1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((int)1);
int expectedInt32 = Convert.ToInt32(1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((int)1);
uint expectedUInt32 = Convert.ToUInt32(1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((int)1);
long expectedInt64 = Convert.ToInt64(1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((int)1);
ulong expectedUInt64 = Convert.ToUInt64(1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((int)1);
float expectedSingle = Convert.ToSingle(1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((int)1);
double expectedDouble = Convert.ToDouble(1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((int)1);
decimal expectedDecimal = Convert.ToDecimal(1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((int)1);
string expectedString = Convert.ToString(1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((int)1);
ulong expectedObject = Convert.ToUInt64(1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}

View File

@@ -185,7 +185,7 @@ namespace SabreTools.IO.Test.Numerics
public void BitwiseUnaryOperatorsTest()
{
var valA = new BothUInt32(2, 2);
uint expected = ~((uint)2);
uint expected = ~(uint)2;
BothUInt32 actual = ~valA;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);

View File

@@ -185,7 +185,7 @@ namespace SabreTools.IO.Test.Numerics
public void BitwiseUnaryOperatorsTest()
{
var valA = new BothUInt64(2, 2);
ulong expected = ~((ulong)2);
ulong expected = ~(ulong)2;
BothUInt64 actual = ~valA;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
@@ -24,7 +24,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -37,4 +37,4 @@ namespace SabreTools.IO.Test.Streams
#endregion
}
}
}

View File

@@ -3,6 +3,7 @@ using System.IO;
using SabreTools.IO.Streams;
using Xunit;
#pragma warning disable IDE0017 // Object initialization can be simplified
namespace SabreTools.IO.Test.Streams
{
public class ViewStreamTests
@@ -415,4 +416,4 @@ namespace SabreTools.IO.Test.Streams
#endregion
}
}
}

View File

@@ -4,6 +4,7 @@ using SabreTools.IO.Extensions;
using SabreTools.IO.Transform;
using Xunit;
#pragma warning disable IDE0230 // Use UTF-8 string literal
namespace SabreTools.IO.Test.Transform
{
public class SwapTests

View File

@@ -1,12 +1,12 @@
/*
*
*
* Links for info and original source code:
*
*
* https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
* http://www.codeproject.com/Articles/22517/Natural-Sort-Comparer
*
* Exact code implementation used with permission, originally by motoschifo
*
*
*/
using System;
@@ -31,11 +31,11 @@ namespace SabreTools.Text.Compare
public override int Compare(string? x, string? y)
{
if (x == null || y == null)
if (x is null || y is null)
{
if (x == null && y != null)
if (x is null && y is not null)
return -1;
else if (x != null && y == null)
else if (x is not null && y is null)
return 1;
else
return 0;

View File

@@ -8,13 +8,13 @@
public static int ComparePaths(string? left, string? right)
{
// If both strings are null, return
if (left == null && right == null)
if (left is null && right is null)
return 0;
// If one is null, then say that's less than
if (left == null)
if (left is null)
return -1;
if (right == null)
if (right is null)
return 1;
// Normalize the path seperators

View File

@@ -1,12 +1,12 @@
/*
*
*
* Links for info and original source code:
*
*
* https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
* http://www.codeproject.com/Articles/22517/Natural-Sort-Comparer
*
* Exact code implementation used with permission, originally by motoschifo
*
*
*/
using System;
@@ -31,11 +31,11 @@ namespace SabreTools.Text.Compare
public override int Compare(string? x, string? y)
{
if (x == null || y == null)
if (x is null || y is null)
{
if (x == null && y != null)
if (x is null && y is not null)
return -1;
else if (x != null && y == null)
else if (x is not null && y is null)
return 1;
else
return 0;

View File

@@ -54,6 +54,10 @@
namespace SabreTools.IO.Compression.BZip2
{
#pragma warning disable IDE0047
#pragma warning disable IDE2000
#pragma warning disable IDE2002
#pragma warning disable IDE2003
// /**
// * Checks if the signature matches what is expected for a bzip2 file.
// *
@@ -111,4 +115,4 @@ namespace SabreTools.IO.Compression.BZip2
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -58,13 +58,24 @@ using System.IO;
#nullable disable
namespace SabreTools.IO.Compression.BZip2
{
#pragma warning disable IDE0001
#pragma warning disable IDE0002
#pragma warning disable IDE0004
#pragma warning disable IDE0036
#pragma warning disable IDE0040
#pragma warning disable IDE0047
#pragma warning disable IDE0048
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2002
#pragma warning disable IDE2003
/// <summary>
/// A read-only decorator stream that performs BZip2 decompression on Read.
/// </summary>
public class BZip2InputStream : System.IO.Stream
{
bool _disposed;
bool _leaveOpen;
readonly bool _leaveOpen;
Int64 totalBytesRead;
private int last;
@@ -79,7 +90,7 @@ namespace SabreTools.IO.Compression.BZip2
private bool blockRandomised;
private int bsBuff;
private int bsLive;
private readonly CRC32 crc = new CRC32(true);
private readonly CRC32 crc = new(true);
private int nInUse;
private Stream input;
private int currentChar = -1;
@@ -208,7 +219,7 @@ namespace SabreTools.IO.Compression.BZip2
throw new IndexOutOfRangeException(String.Format("offset({0}) count({1}) bLength({2})",
offset, count, buffer.Length));
if (this.input == null)
if (this.input is null)
throw new IOException("the stream is not open");
@@ -408,7 +419,7 @@ namespace SabreTools.IO.Compression.BZip2
{
if (!_disposed)
{
if (disposing && (this.input != null))
if (disposing && (this.input is not null))
this.input.Close();
_disposed = true;
}
@@ -491,8 +502,7 @@ namespace SabreTools.IO.Compression.BZip2
this.blockRandomised = (GetBits(1) == 1);
// Lazily allocate data
if (this.data == null)
this.data = new DecompressionState(this.blockSize100k);
this.data ??= new DecompressionState(this.blockSize100k);
// currBlockNo++;
getAndMoveToFrontDecode();
@@ -552,7 +562,7 @@ namespace SabreTools.IO.Compression.BZip2
public override void Close()
{
Stream inShadow = this.input;
if (inShadow != null)
if (inShadow is not null)
{
try
{
@@ -1094,7 +1104,7 @@ namespace SabreTools.IO.Compression.BZip2
private void SetupBlock()
{
if (this.data == null)
if (this.data is null)
return;
int i;
@@ -1372,7 +1382,7 @@ namespace SabreTools.IO.Compression.BZip2
// it can happen, if the compressor mixed small and large
// blocks. Normally only the last block will be smaller
// than others.
if ((ttShadow == null) || (ttShadow.Length < length))
if ((ttShadow is null) || (ttShadow.Length < length))
{
this.tt = ttShadow = new int[length];
}
@@ -1383,4 +1393,4 @@ namespace SabreTools.IO.Compression.BZip2
}
}
}

View File

@@ -47,7 +47,6 @@
* under the License.
*/
// Design Notes:
//
// This class follows the classic Decorator pattern: it is a Stream that
@@ -85,6 +84,14 @@ using System.IO;
#nullable disable
namespace SabreTools.IO.Compression.BZip2
{
#pragma warning disable IDE0001
#pragma warning disable IDE0004
#pragma warning disable IDE0040
#pragma warning disable IDE0048
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2002
#pragma warning disable IDE2003
/// <summary>
/// A write-only decorator stream that compresses data as it is
/// written using the BZip2 algorithm.
@@ -92,14 +99,14 @@ namespace SabreTools.IO.Compression.BZip2
public class BZip2OutputStream : System.IO.Stream
{
int totalBytesWrittenIn;
bool leaveOpen;
readonly bool leaveOpen;
BZip2Compressor compressor;
uint combinedCRC;
Stream output;
BitWriter bw;
int blockSize100k; // 0...9
readonly int blockSize100k; // 0...9
private TraceBits desiredTrace = TraceBits.Crc | TraceBits.Write;
private readonly TraceBits desiredTrace = TraceBits.Crc | TraceBits.Write;
/// <summary>
/// Constructs a new <c>BZip2OutputStream</c>, that sends its
@@ -218,7 +225,7 @@ namespace SabreTools.IO.Compression.BZip2
/// </remarks>
public override void Close()
{
if (output != null)
if (output is not null)
{
Stream o = this.output;
Finish();
@@ -233,7 +240,7 @@ namespace SabreTools.IO.Compression.BZip2
/// </summary>
public override void Flush()
{
if (this.output != null)
if (this.output is not null)
{
this.bw.Flush();
this.output.Flush();
@@ -348,7 +355,7 @@ namespace SabreTools.IO.Compression.BZip2
if (offset + count > buffer.Length)
throw new IndexOutOfRangeException(String.Format("offset({0}) count({1}) bLength({2})",
offset, count, buffer.Length));
if (this.output == null)
if (this.output is null)
throw new IOException("the stream is not open");
if (count == 0) return; // nothing to do
@@ -429,7 +436,7 @@ namespace SabreTools.IO.Compression.BZip2
{
get
{
if (this.output == null) throw new ObjectDisposedException("BZip2Stream");
if (this.output is null) throw new ObjectDisposedException("BZip2Stream");
return this.output.CanWrite;
}
}

View File

@@ -1,246 +1,249 @@
// BitWriter.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2011 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-July-25 18:57:31>
//
// ------------------------------------------------------------------
//
// This module defines the BitWriter class, which writes bits at a time
// to an output stream. It's used by the BZip2Compressor class, and by
// the BZip2OutputStream class and its parallel variant,
// ParallelBZip2OutputStream.
//
// ------------------------------------------------------------------
//
// Design notes:
//
// BZip2 employs byte-shredding in its data format - rather than
// aligning all data items in a compressed .bz2 file on byte barriers,
// the BZip2 format uses portions of bytes to represent independent
// pieces of information. This "shredding" starts with the first
// "randomised" bit - just 12 bytes or so into a bz2 file or stream. But
// the approach is used extensively in bzip2 files - sometimes 5 bits
// are used, sometimes 24 or 3 bits, sometimes just 1 bit, and so on.
// It's not possible to send this information directly to a stream in
// this form; Streams in .NET accept byte-oriented input. Therefore,
// when actually writing a bz2 file, the output data must be organized
// into a byte-aligned format before being written to the output stream.
//
// This BitWriter class provides the byte-shredding necessary for BZip2
// output. Think of this class as an Adapter that enables Bit-oriented
// output to a standard byte-oriented .NET stream. This class writes
// data out to the captive output stream only after the data bits have
// been accumulated and aligned. For example, suppose that during
// operation, the BZip2 compressor emits 5 bits, then 24 bits, then 32
// bits. When the first 5 bits are sent to the BitWriter, nothing is
// written to the output stream; instead these 5 bits are simply stored
// in the internal accumulator. When the next 24 bits are written, the
// first 3 bits are gathered with the accumulated bits. The resulting
// 5+3 constitutes an entire byte; the BitWriter then actually writes
// that byte to the output stream. This leaves 21 bits. BitWriter writes
// 2 more whole bytes (16 more bits), in 8-bit chunks, leaving 5 in the
// accumulator. BitWriter then follows the same procedure with the 32
// new bits. And so on.
//
// A quick tour of the implementation:
//
// The accumulator is a uint - so it can accumulate at most 4 bytes of
// information. In practice because of the design of this class, it
// never accumulates more than 3 bytes.
//
// The Flush() method emits all whole bytes available. After calling
// Flush(), there may be between 0-7 bits yet to be emitted into the
// output stream.
//
// FinishAndPad() emits all data, including the last partial byte and
// any necessary padding. In effect, it establishes a byte-alignment
// barrier. To support bzip2, FinishAndPad() should be called only once
// for a bz2 file, after the last bit of data has been written through
// this adapter. Other binary file formats may use byte-alignment at
// various points within the file, and FinishAndPad() would support that
// scenario.
//
// The internal fn Reset() is used to reset the state of the adapter;
// this class is used by BZip2Compressor, instances of which get re-used
// by multiple distinct threads, for different blocks of data.
//
using System;
using System.IO;
namespace SabreTools.IO.Compression.BZip2
{
internal class BitWriter
{
uint accumulator;
int nAccumulatedBits;
Stream output;
int totalBytesWrittenOut;
public BitWriter(Stream s)
{
this.output = s;
}
/// <summary>
/// Delivers the remaining bits, left-aligned, in a byte.
/// </summary>
/// <remarks>
/// <para>
/// This is valid only if NumRemainingBits is less than 8;
/// in other words it is valid only after a call to Flush().
/// </para>
/// </remarks>
public byte RemainingBits
{
get
{
return (byte)(this.accumulator >> (32 - this.nAccumulatedBits) & 0xff);
}
}
public int NumRemainingBits
{
get
{
return this.nAccumulatedBits;
}
}
public int TotalBytesWrittenOut
{
get
{
return this.totalBytesWrittenOut;
}
}
/// <summary>
/// Reset the BitWriter.
/// </summary>
/// <remarks>
/// <para>
/// This is useful when the BitWriter writes into a MemoryStream, and
/// is used by a BZip2Compressor, which itself is re-used for multiple
/// distinct data blocks.
/// </para>
/// </remarks>
public void Reset()
{
this.accumulator = 0;
this.nAccumulatedBits = 0;
this.totalBytesWrittenOut = 0;
this.output.Seek(0, SeekOrigin.Begin);
this.output.SetLength(0);
}
/// <summary>
/// Write some number of bits from the given value, into the output.
/// </summary>
/// <remarks>
/// <para>
/// The nbits value should be a max of 25, for safety. For performance
/// reasons, this method does not check!
/// </para>
/// </remarks>
public void WriteBits(int nbits, uint value)
{
int nAccumulated = this.nAccumulatedBits;
uint u = this.accumulator;
while (nAccumulated >= 8)
{
this.output.WriteByte((byte)(u >> 24 & 0xff));
this.totalBytesWrittenOut++;
u <<= 8;
nAccumulated -= 8;
}
this.accumulator = u | (value << (32 - nAccumulated - nbits));
this.nAccumulatedBits = nAccumulated + nbits;
// Console.WriteLine("WriteBits({0}, 0x{1:X2}) => {2:X8} n({3})",
// nbits, value, accumulator, nAccumulatedBits);
// Console.ReadLine();
// At this point the accumulator may contain up to 31 bits waiting for
// output.
}
/// <summary>
/// Write a full 8-bit byte into the output.
/// </summary>
public void WriteByte(byte b)
{
WriteBits(8, b);
}
/// <summary>
/// Write four 8-bit bytes into the output.
/// </summary>
public void WriteInt(uint u)
{
WriteBits(8, (u >> 24) & 0xff);
WriteBits(8, (u >> 16) & 0xff);
WriteBits(8, (u >> 8) & 0xff);
WriteBits(8, u & 0xff);
}
/// <summary>
/// Write all available byte-aligned bytes.
/// </summary>
/// <remarks>
/// <para>
/// This method writes no new output, but flushes any accumulated
/// bits. At completion, the accumulator may contain up to 7
/// bits.
/// </para>
/// <para>
/// This is necessary when re-assembling output from N independent
/// compressors, one for each of N blocks. The output of any
/// particular compressor will in general have some fragment of a byte
/// remaining. This fragment needs to be accumulated into the
/// parent BZip2OutputStream.
/// </para>
/// </remarks>
public void Flush()
{
WriteBits(0, 0);
}
/// <summary>
/// Writes all available bytes, and emits padding for the final byte as
/// necessary. This must be the last method invoked on an instance of
/// BitWriter.
/// </summary>
public void FinishAndPad()
{
Flush();
if (this.NumRemainingBits > 0)
{
byte b = (byte)((this.accumulator >> 24) & 0xff);
this.output.WriteByte(b);
this.totalBytesWrittenOut++;
}
}
}
}
// BitWriter.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2011 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-July-25 18:57:31>
//
// ------------------------------------------------------------------
//
// This module defines the BitWriter class, which writes bits at a time
// to an output stream. It's used by the BZip2Compressor class, and by
// the BZip2OutputStream class and its parallel variant,
// ParallelBZip2OutputStream.
//
// ------------------------------------------------------------------
//
// Design notes:
//
// BZip2 employs byte-shredding in its data format - rather than
// aligning all data items in a compressed .bz2 file on byte barriers,
// the BZip2 format uses portions of bytes to represent independent
// pieces of information. This "shredding" starts with the first
// "randomised" bit - just 12 bytes or so into a bz2 file or stream. But
// the approach is used extensively in bzip2 files - sometimes 5 bits
// are used, sometimes 24 or 3 bits, sometimes just 1 bit, and so on.
// It's not possible to send this information directly to a stream in
// this form; Streams in .NET accept byte-oriented input. Therefore,
// when actually writing a bz2 file, the output data must be organized
// into a byte-aligned format before being written to the output stream.
//
// This BitWriter class provides the byte-shredding necessary for BZip2
// output. Think of this class as an Adapter that enables Bit-oriented
// output to a standard byte-oriented .NET stream. This class writes
// data out to the captive output stream only after the data bits have
// been accumulated and aligned. For example, suppose that during
// operation, the BZip2 compressor emits 5 bits, then 24 bits, then 32
// bits. When the first 5 bits are sent to the BitWriter, nothing is
// written to the output stream; instead these 5 bits are simply stored
// in the internal accumulator. When the next 24 bits are written, the
// first 3 bits are gathered with the accumulated bits. The resulting
// 5+3 constitutes an entire byte; the BitWriter then actually writes
// that byte to the output stream. This leaves 21 bits. BitWriter writes
// 2 more whole bytes (16 more bits), in 8-bit chunks, leaving 5 in the
// accumulator. BitWriter then follows the same procedure with the 32
// new bits. And so on.
//
// A quick tour of the implementation:
//
// The accumulator is a uint - so it can accumulate at most 4 bytes of
// information. In practice because of the design of this class, it
// never accumulates more than 3 bytes.
//
// The Flush() method emits all whole bytes available. After calling
// Flush(), there may be between 0-7 bits yet to be emitted into the
// output stream.
//
// FinishAndPad() emits all data, including the last partial byte and
// any necessary padding. In effect, it establishes a byte-alignment
// barrier. To support bzip2, FinishAndPad() should be called only once
// for a bz2 file, after the last bit of data has been written through
// this adapter. Other binary file formats may use byte-alignment at
// various points within the file, and FinishAndPad() would support that
// scenario.
//
// The internal fn Reset() is used to reset the state of the adapter;
// this class is used by BZip2Compressor, instances of which get re-used
// by multiple distinct threads, for different blocks of data.
//
using System.IO;
#pragma warning disable IDE0040
#pragma warning disable IDE0048
#pragma warning disable IDE2000
#pragma warning disable IDE2002
namespace SabreTools.IO.Compression.BZip2
{
internal class BitWriter
{
uint accumulator;
int nAccumulatedBits;
readonly Stream output;
int totalBytesWrittenOut;
public BitWriter(Stream s)
{
this.output = s;
}
/// <summary>
/// Delivers the remaining bits, left-aligned, in a byte.
/// </summary>
/// <remarks>
/// <para>
/// This is valid only if NumRemainingBits is less than 8;
/// in other words it is valid only after a call to Flush().
/// </para>
/// </remarks>
public byte RemainingBits
{
get
{
return (byte)(this.accumulator >> (32 - this.nAccumulatedBits) & 0xff);
}
}
public int NumRemainingBits
{
get
{
return this.nAccumulatedBits;
}
}
public int TotalBytesWrittenOut
{
get
{
return this.totalBytesWrittenOut;
}
}
/// <summary>
/// Reset the BitWriter.
/// </summary>
/// <remarks>
/// <para>
/// This is useful when the BitWriter writes into a MemoryStream, and
/// is used by a BZip2Compressor, which itself is re-used for multiple
/// distinct data blocks.
/// </para>
/// </remarks>
public void Reset()
{
this.accumulator = 0;
this.nAccumulatedBits = 0;
this.totalBytesWrittenOut = 0;
this.output.Seek(0, SeekOrigin.Begin);
this.output.SetLength(0);
}
/// <summary>
/// Write some number of bits from the given value, into the output.
/// </summary>
/// <remarks>
/// <para>
/// The nbits value should be a max of 25, for safety. For performance
/// reasons, this method does not check!
/// </para>
/// </remarks>
public void WriteBits(int nbits, uint value)
{
int nAccumulated = this.nAccumulatedBits;
uint u = this.accumulator;
while (nAccumulated >= 8)
{
this.output.WriteByte((byte)(u >> 24 & 0xff));
this.totalBytesWrittenOut++;
u <<= 8;
nAccumulated -= 8;
}
this.accumulator = u | (value << (32 - nAccumulated - nbits));
this.nAccumulatedBits = nAccumulated + nbits;
// Console.WriteLine("WriteBits({0}, 0x{1:X2}) => {2:X8} n({3})",
// nbits, value, accumulator, nAccumulatedBits);
// Console.ReadLine();
// At this point the accumulator may contain up to 31 bits waiting for
// output.
}
/// <summary>
/// Write a full 8-bit byte into the output.
/// </summary>
public void WriteByte(byte b)
{
WriteBits(8, b);
}
/// <summary>
/// Write four 8-bit bytes into the output.
/// </summary>
public void WriteInt(uint u)
{
WriteBits(8, (u >> 24) & 0xff);
WriteBits(8, (u >> 16) & 0xff);
WriteBits(8, (u >> 8) & 0xff);
WriteBits(8, u & 0xff);
}
/// <summary>
/// Write all available byte-aligned bytes.
/// </summary>
/// <remarks>
/// <para>
/// This method writes no new output, but flushes any accumulated
/// bits. At completion, the accumulator may contain up to 7
/// bits.
/// </para>
/// <para>
/// This is necessary when re-assembling output from N independent
/// compressors, one for each of N blocks. The output of any
/// particular compressor will in general have some fragment of a byte
/// remaining. This fragment needs to be accumulated into the
/// parent BZip2OutputStream.
/// </para>
/// </remarks>
public void Flush()
{
WriteBits(0, 0);
}
/// <summary>
/// Writes all available bytes, and emits padding for the final byte as
/// necessary. This must be the last method invoked on an instance of
/// BitWriter.
/// </summary>
public void FinishAndPad()
{
Flush();
if (this.NumRemainingBits > 0)
{
byte b = (byte)((this.accumulator >> 24) & 0xff);
this.output.WriteByte(b);
this.totalBytesWrittenOut++;
}
}
}
}

View File

@@ -29,9 +29,17 @@ using System;
using Interop = System.Runtime.InteropServices;
#nullable disable
#pragma warning disable CS0618
namespace SabreTools.IO.Compression.BZip2
{
#pragma warning disable IDE0001
#pragma warning disable IDE0002
#pragma warning disable IDE0047
#pragma warning disable IDE0048
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2002
#pragma warning disable IDE2003
#pragma warning disable IDE2004
/// <summary>
/// Computes a CRC-32. The CRC-32 algorithm is parameterized - you
/// can set the polynomial and enable or disable bit
@@ -91,7 +99,7 @@ namespace SabreTools.IO.Compression.BZip2
/// <returns>the CRC32 calculation</returns>
public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output)
{
if (input == null)
if (input is null)
throw new Exception("The input stream must not be null.");
unchecked
@@ -101,13 +109,13 @@ namespace SabreTools.IO.Compression.BZip2
_TotalBytesRead = 0;
int count = input.Read(buffer, 0, readSize);
if (output != null) output.Write(buffer, 0, count);
output?.Write(buffer, 0, count);
_TotalBytesRead += count;
while (count > 0)
{
SlurpBlock(buffer, 0, count);
count = input.Read(buffer, 0, readSize);
if (output != null) output.Write(buffer, 0, count);
output?.Write(buffer, 0, count);
_TotalBytesRead += count;
}
@@ -143,7 +151,7 @@ namespace SabreTools.IO.Compression.BZip2
/// <param name="count">how many bytes within the block to slurp</param>
public void SlurpBlock(byte[] block, int offset, int count)
{
if (block == null)
if (block is null)
throw new Exception("The data buffer must not be null.");
// bzip algorithm
@@ -279,7 +287,7 @@ namespace SabreTools.IO.Compression.BZip2
crc32Table[i] = dwCrc;
}
i++;
} while (i!=0);
} while (i != 0);
}
#if VERBOSE
@@ -303,10 +311,10 @@ namespace SabreTools.IO.Compression.BZip2
private uint gf2_matrix_times(uint[] matrix, uint vec)
{
uint sum = 0;
int i=0;
int i = 0;
while (vec != 0)
{
if ((vec & 0x01)== 0x01)
if ((vec & 0x01) == 0x01)
sum ^= matrix[i];
vec >>= 1;
i++;
@@ -341,8 +349,8 @@ namespace SabreTools.IO.Compression.BZip2
if (length == 0)
return;
uint crc1= ~_register;
uint crc2= (uint) crc;
uint crc1 = ~_register;
uint crc2 = (uint)crc;
// put operator for one zero bit in odd
odd[0] = this.dwPolynomial; // the CRC-32 polynomial
@@ -359,15 +367,16 @@ namespace SabreTools.IO.Compression.BZip2
// put operator for four zero bits in odd
gf2_matrix_square(odd, even);
uint len2 = (uint) length;
uint len2 = (uint)length;
// apply len2 zeros to crc1 (first square will put the operator for one
// zero byte, eight zero bits, in even)
do {
do
{
// apply zeros operator for this bit of len2
gf2_matrix_square(even, odd);
if ((len2 & 1)== 1)
if ((len2 & 1) == 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
@@ -376,7 +385,7 @@ namespace SabreTools.IO.Compression.BZip2
// another iteration of the loop with odd and even swapped
gf2_matrix_square(odd, even);
if ((len2 & 1)==1)
if ((len2 & 1) == 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
@@ -385,7 +394,7 @@ namespace SabreTools.IO.Compression.BZip2
crc1 ^= crc2;
_register= ~crc1;
_register = ~crc1;
//return (int) crc1;
return;
@@ -417,7 +426,7 @@ namespace SabreTools.IO.Compression.BZip2
/// </para>
/// </remarks>
public CRC32(bool reverseBits) :
this( unchecked((int)0xEDB88320), reverseBits)
this(unchecked((int)0xEDB88320), reverseBits)
{
}
@@ -450,7 +459,7 @@ namespace SabreTools.IO.Compression.BZip2
public CRC32(int polynomial, bool reverseBits)
{
this.reverseBits = reverseBits;
this.dwPolynomial = (uint) polynomial;
this.dwPolynomial = (uint)polynomial;
this.GenerateLookupTable();
}
@@ -469,9 +478,9 @@ namespace SabreTools.IO.Compression.BZip2
}
// private member vars
private UInt32 dwPolynomial;
private readonly UInt32 dwPolynomial;
private Int64 _TotalBytesRead;
private bool reverseBits;
private readonly bool reverseBits;
private UInt32[] crc32Table;
private const int BUFFER_SIZE = 8192;
private UInt32 _register = 0xFFFFFFFFU;
@@ -502,8 +511,8 @@ namespace SabreTools.IO.Compression.BZip2
private static readonly Int64 UnsetLengthLimit = -99;
internal System.IO.Stream _innerStream;
private CRC32 _Crc32;
private Int64 _lengthLimit = -99;
private readonly CRC32 _Crc32;
private readonly Int64 _lengthLimit = -99;
private bool _leaveOpen;
/// <summary>
@@ -812,4 +821,4 @@ namespace SabreTools.IO.Compression.BZip2
}
}
}

View File

@@ -1,99 +1,96 @@
// Rand.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2011 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-July-31 15:09:16>
//
// ------------------------------------------------------------------
//
// This module defines a helper class for the BZip2 classes. This code
// is derived from the original BZip2 source code.
//
// ------------------------------------------------------------------
namespace SabreTools.IO.Compression.BZip2
{
internal static class Rand
{
private static int[] RNUMS =
{
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
};
/// <summary>
/// Returns the "random" number at a specific index.
/// </summary>
/// <param name='i'>the index</param>
/// <returns>the random number</returns>
internal static int Rnums(int i)
{
return RNUMS[i];
}
}
}
// Rand.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2011 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-July-31 15:09:16>
//
// ------------------------------------------------------------------
//
// This module defines a helper class for the BZip2 classes. This code
// is derived from the original BZip2 source code.
//
// ------------------------------------------------------------------
namespace SabreTools.IO.Compression.BZip2
{
internal static class Rand
{
private static readonly int[] RNUMS =
[
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
];
/// <summary>
/// Returns the "random" number at a specific index.
/// </summary>
/// <param name='i'>the index</param>
/// <returns>the random number</returns>
internal static int Rnums(int i)
{
return RNUMS[i];
}
}
}

View File

@@ -41,12 +41,12 @@ namespace SabreTools.IO.Compression.Blast
/// that library. (Note: PKWare overused the "implode" verb, and the format
/// used by their library implode() function is completely different and
/// incompatible with the implode compression method supported by PKZIP.)
///
///
/// The binary mode for stdio functions should be used to assure that the
/// compressed data is not corrupted when read or written. For example:
/// fopen(..., "rb") and fopen(..., "wb").
/// </summary>
public unsafe class Decompressor
public class Decompressor
{
#region Huffman Encoding
@@ -168,29 +168,29 @@ namespace SabreTools.IO.Compression.Blast
/// First byte is 0 if literals are uncoded or 1 if they are coded. Second
/// byte is 4, 5, or 6 for the number of extra bits in the distance code.
/// This is the base-2 logarithm of the dictionary size minus six.
///
///
/// Compressed data is a combination of literals and length/distance pairs
/// terminated by an end code. Literals are either Huffman coded or
/// uncoded bytes. A length/distance pair is a coded length followed by a
/// coded distance to represent a string that occurs earlier in the
/// uncompressed data that occurs again at the current location.
///
///
/// A bit preceding a literal or length/distance pair indicates which comes
/// next, 0 for literals, 1 for length/distance.
///
///
/// If literals are uncoded, then the next eight bits are the literal, in the
/// normal bit order in the stream, i.e. no bit-reversal is needed. Similarly,
/// no bit reversal is needed for either the length extra bits or the distance
/// extra bits.
///
///
/// Literal bytes are simply written to the output. A length/distance pair is
/// an instruction to copy previously uncompressed bytes to the output. The
/// copy is from distance bytes back in the output stream, copying for length
/// bytes.
///
///
/// Distances pointing before the beginning of the output data are not
/// permitted.
///
///
/// Overlapped copies, where the length is greater than the distance, are
/// allowed and common. For example, a distance of one and a length of 518
/// simply copies the last byte 518 times. A distance of four and a length of

View File

@@ -90,7 +90,7 @@ namespace SabreTools.IO.Compression.Blast
// Assumes lengths are within bounds
for (symbol = 0; symbol < n; symbol++)
{
(Count[length[symbol]])++;
Count[length[symbol]]++;
}
// No codes! Complete, but decode() will fail
@@ -138,7 +138,7 @@ namespace SabreTools.IO.Compression.Blast
/// bits are pulled from the compressed data one at a time and used to
/// build the code value reversed from what is in the stream in order to
/// permit simple integer comparisons for decoding.
///
///
/// The first code for the shortest length is all ones. Subsequent codes of
/// the same length are simply integer decrements of the previous code. When
/// moving up a length, a one bit is appended to the code. For a complete
@@ -182,7 +182,7 @@ namespace SabreTools.IO.Compression.Blast
len++;
}
left = (MAXBITS + 1) - len;
left = MAXBITS + 1 - len;
if (left == 0)
break;

View File

@@ -1,180 +1,177 @@
// Zlib.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-August-03 19:52:28>
//
// ------------------------------------------------------------------
//
// This module defines classes for ZLIB compression and
// decompression. This code is derived from the jzlib implementation of
// zlib, but significantly modified. The object model is not the same,
// and many of the behaviors are new or different. Nonetheless, in
// keeping with the license for jzlib, the copyright to that code is
// included below.
//
// ------------------------------------------------------------------
//
// The following notice applies to jzlib:
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// jzlib is based on zlib-1.1.3.
//
// The following notice applies to zlib:
//
// -----------------------------------------------------------------------
//
// Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
//
// The ZLIB software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// Jean-loup Gailly jloup@gzip.org
// Mark Adler madler@alumni.caltech.edu
//
// -----------------------------------------------------------------------
namespace SabreTools.IO.Compression.Deflate
{
/// <summary>
/// Computes an Adler-32 checksum.
/// </summary>
/// <remarks>
/// The Adler checksum is similar to a CRC checksum, but faster to compute, though less
/// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum
/// is a required part of the "ZLIB" standard. Applications will almost never need to
/// use this class directly.
/// </remarks>
///
/// <exclude/>
public sealed class Adler
{
// largest prime smaller than 65536
private static readonly uint BASE = 65521;
// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
private static readonly int NMAX = 5552;
#pragma warning disable 3001
#pragma warning disable 3002
/// <summary>
/// Calculates the Adler32 checksum.
/// </summary>
/// <remarks>
/// <para>
/// This is used within ZLIB. You probably don't need to use this directly.
/// </para>
/// </remarks>
/// <example>
/// To compute an Adler32 checksum on a byte array:
/// <code>
/// var adler = Adler.Adler32(0, null, 0, 0);
/// adler = Adler.Adler32(adler, buffer, index, length);
/// </code>
/// </example>
public static uint Adler32(uint adler, byte[] buf, int index, int len)
{
if (buf == null)
return 1;
uint s1 = (uint)(adler & 0xffff);
uint s2 = (uint)((adler >> 16) & 0xffff);
while (len > 0)
{
int k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16)
{
//s1 += (buf[index++] & 0xff); s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
k -= 16;
}
if (k != 0)
{
do
{
s1 += buf[index++];
s2 += s1;
}
while (--k != 0);
}
s1 %= BASE;
s2 %= BASE;
}
return (uint)((s2 << 16) | s1);
}
#pragma warning restore 3001
#pragma warning restore 3002
}
}
// Zlib.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-August-03 19:52:28>
//
// ------------------------------------------------------------------
//
// This module defines classes for ZLIB compression and
// decompression. This code is derived from the jzlib implementation of
// zlib, but significantly modified. The object model is not the same,
// and many of the behaviors are new or different. Nonetheless, in
// keeping with the license for jzlib, the copyright to that code is
// included below.
//
// ------------------------------------------------------------------
//
// The following notice applies to jzlib:
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// jzlib is based on zlib-1.1.3.
//
// The following notice applies to zlib:
//
// -----------------------------------------------------------------------
//
// Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
//
// The ZLIB software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// Jean-loup Gailly jloup@gzip.org
// Mark Adler madler@alumni.caltech.edu
//
// -----------------------------------------------------------------------
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0004
#pragma warning disable IDE2002
#pragma warning disable IDE2003
/// <summary>
/// Computes an Adler-32 checksum.
/// </summary>
/// <remarks>
/// The Adler checksum is similar to a CRC checksum, but faster to compute, though less
/// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum
/// is a required part of the "ZLIB" standard. Applications will almost never need to
/// use this class directly.
/// </remarks>
///
/// <exclude/>
public sealed class Adler
{
// largest prime smaller than 65536
private static readonly uint BASE = 65521;
// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
private static readonly int NMAX = 5552;
/// <summary>
/// Calculates the Adler32 checksum.
/// </summary>
/// <remarks>
/// <para>
/// This is used within ZLIB. You probably don't need to use this directly.
/// </para>
/// </remarks>
/// <example>
/// To compute an Adler32 checksum on a byte array:
/// <code>
/// var adler = Adler.Adler32(0, null, 0, 0);
/// adler = Adler.Adler32(adler, buffer, index, length);
/// </code>
/// </example>
public static uint Adler32(uint adler, byte[] buf, int index, int len)
{
if (buf is null)
return 1;
uint s1 = (uint)(adler & 0xffff);
uint s2 = (uint)((adler >> 16) & 0xffff);
while (len > 0)
{
int k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16)
{
//s1 += (buf[index++] & 0xff); s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
k -= 16;
}
if (k != 0)
{
do
{
s1 += buf[index++];
s2 += s1;
}
while (--k != 0);
}
s1 %= BASE;
s2 %= BASE;
}
return (uint)((s2 << 16) | s1);
}
}
}

View File

@@ -75,4 +75,4 @@ namespace SabreTools.IO.Compression.Deflate
FinishStarted, // finish started, need only more output at next deflate
FinishDone // finish done, accept no more input or output
}
}
}

View File

@@ -29,9 +29,17 @@ using System;
using Interop = System.Runtime.InteropServices;
#nullable disable
#pragma warning disable CS0618
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0001
#pragma warning disable IDE0002
#pragma warning disable IDE0047
#pragma warning disable IDE0048
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2002
#pragma warning disable IDE2003
#pragma warning disable IDE2004
/// <summary>
/// Computes a CRC-32. The CRC-32 algorithm is parameterized - you
/// can set the polynomial and enable or disable bit
@@ -91,7 +99,7 @@ namespace SabreTools.IO.Compression.Deflate
/// <returns>the CRC32 calculation</returns>
public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output)
{
if (input == null)
if (input is null)
throw new Exception("The input stream must not be null.");
unchecked
@@ -101,13 +109,13 @@ namespace SabreTools.IO.Compression.Deflate
_TotalBytesRead = 0;
int count = input.Read(buffer, 0, readSize);
if (output != null) output.Write(buffer, 0, count);
output?.Write(buffer, 0, count);
_TotalBytesRead += count;
while (count > 0)
{
SlurpBlock(buffer, 0, count);
count = input.Read(buffer, 0, readSize);
if (output != null) output.Write(buffer, 0, count);
output?.Write(buffer, 0, count);
_TotalBytesRead += count;
}
@@ -143,7 +151,7 @@ namespace SabreTools.IO.Compression.Deflate
/// <param name="count">how many bytes within the block to slurp</param>
public void SlurpBlock(byte[] block, int offset, int count)
{
if (block == null)
if (block is null)
throw new Exception("The data buffer must not be null.");
// bzip algorithm
@@ -279,7 +287,7 @@ namespace SabreTools.IO.Compression.Deflate
crc32Table[i] = dwCrc;
}
i++;
} while (i!=0);
} while (i != 0);
}
#if VERBOSE
@@ -303,10 +311,10 @@ namespace SabreTools.IO.Compression.Deflate
private uint gf2_matrix_times(uint[] matrix, uint vec)
{
uint sum = 0;
int i=0;
int i = 0;
while (vec != 0)
{
if ((vec & 0x01)== 0x01)
if ((vec & 0x01) == 0x01)
sum ^= matrix[i];
vec >>= 1;
i++;
@@ -341,8 +349,8 @@ namespace SabreTools.IO.Compression.Deflate
if (length == 0)
return;
uint crc1= ~_register;
uint crc2= (uint) crc;
uint crc1 = ~_register;
uint crc2 = (uint)crc;
// put operator for one zero bit in odd
odd[0] = this.dwPolynomial; // the CRC-32 polynomial
@@ -359,15 +367,16 @@ namespace SabreTools.IO.Compression.Deflate
// put operator for four zero bits in odd
gf2_matrix_square(odd, even);
uint len2 = (uint) length;
uint len2 = (uint)length;
// apply len2 zeros to crc1 (first square will put the operator for one
// zero byte, eight zero bits, in even)
do {
do
{
// apply zeros operator for this bit of len2
gf2_matrix_square(even, odd);
if ((len2 & 1)== 1)
if ((len2 & 1) == 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
@@ -376,7 +385,7 @@ namespace SabreTools.IO.Compression.Deflate
// another iteration of the loop with odd and even swapped
gf2_matrix_square(odd, even);
if ((len2 & 1)==1)
if ((len2 & 1) == 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
@@ -385,7 +394,7 @@ namespace SabreTools.IO.Compression.Deflate
crc1 ^= crc2;
_register= ~crc1;
_register = ~crc1;
//return (int) crc1;
return;
@@ -417,7 +426,7 @@ namespace SabreTools.IO.Compression.Deflate
/// </para>
/// </remarks>
public CRC32(bool reverseBits) :
this( unchecked((int)0xEDB88320), reverseBits)
this(unchecked((int)0xEDB88320), reverseBits)
{
}
@@ -450,7 +459,7 @@ namespace SabreTools.IO.Compression.Deflate
public CRC32(int polynomial, bool reverseBits)
{
this.reverseBits = reverseBits;
this.dwPolynomial = (uint) polynomial;
this.dwPolynomial = (uint)polynomial;
this.GenerateLookupTable();
}
@@ -469,9 +478,9 @@ namespace SabreTools.IO.Compression.Deflate
}
// private member vars
private UInt32 dwPolynomial;
private readonly UInt32 dwPolynomial;
private Int64 _TotalBytesRead;
private bool reverseBits;
private readonly bool reverseBits;
private UInt32[] crc32Table;
private const int BUFFER_SIZE = 8192;
private UInt32 _register = 0xFFFFFFFFU;
@@ -502,8 +511,8 @@ namespace SabreTools.IO.Compression.Deflate
private static readonly Int64 UnsetLengthLimit = -99;
internal System.IO.Stream _innerStream;
private CRC32 _Crc32;
private Int64 _lengthLimit = -99;
private readonly CRC32 _Crc32;
private readonly Int64 _lengthLimit = -99;
private bool _leaveOpen;
/// <summary>
@@ -812,4 +821,4 @@ namespace SabreTools.IO.Compression.Deflate
}
}
}

View File

@@ -164,5 +164,4 @@ namespace SabreTools.IO.Compression.Deflate
/// </summary>
Level9 = 9,
}
}
}

View File

@@ -102,5 +102,4 @@ namespace SabreTools.IO.Compression.Deflate
/// </summary>
Decompress = 1,
}
}
}

View File

@@ -115,5 +115,4 @@ namespace SabreTools.IO.Compression.Deflate
/// </summary>
HuffmanOnly = 2,
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,4 +31,4 @@ namespace SabreTools.IO.Compression.Deflate
/// </summary>
FAIL,
}
}
}

View File

@@ -129,5 +129,4 @@ namespace SabreTools.IO.Compression.Deflate
/// <summary>Signals the end of the compression/decompression stream.</summary>
Finish,
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,435 +1,440 @@
// Inftree.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-October-28 12:43:54>
//
// ------------------------------------------------------------------
//
// This module defines classes used in decompression. This code is derived
// from the jzlib implementation of zlib. In keeping with the license for jzlib,
// the copyright to that code is below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
sealed class InfTree
{
private const int MANY = 1440;
private const int Z_OK = 0;
private const int Z_STREAM_END = 1;
private const int Z_NEED_DICT = 2;
private const int Z_ERRNO = -1;
private const int Z_STREAM_ERROR = -2;
private const int Z_DATA_ERROR = -3;
private const int Z_MEM_ERROR = -4;
private const int Z_BUF_ERROR = -5;
private const int Z_VERSION_ERROR = -6;
internal const int fixed_bl = 9;
internal const int fixed_bd = 5;
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186,
0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8,
14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255};
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] fixed_td = new int[] { 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 };
// Tables for deflate from PKZIP's appnote.txt.
//UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cplens = new int[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
// see note #13 above about 258
//UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cplext = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 };
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cpdist = new int[] { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 };
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cpdext = new int[] { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
// If BMAX needs to be larger than 16, then h and x[] should be uLong.
internal const int BMAX = 15; // maximum bit length of any code
internal int[] hn = null; // hufts used in space
internal int[] v = null; // work area for huft_build
internal int[] c = null; // bit length count table
internal int[] r = null; // table entry for structure assignment
internal int[] u = null; // table stack
internal int[] x = null; // bit offsets, then code stack
private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v)
{
// Given a list of code lengths and a maximum table size, make a set of
// tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
// if the given code set is incomplete (the tables are still built in this
// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
// lengths), or Z_MEM_ERROR if not enough memory.
int a; // counter for codes of length k
int f; // i repeats in table every f entries
int g; // maximum code length
int h; // table level
int i; // counter, current code
int j; // counter
int k; // number of bits in current code
int l; // bits per table (returned in m)
int mask; // (1 << w) - 1, to avoid cc -O bug on HP
int p; // pointer into c[], b[], or v[]
int q; // points to current table
int w; // bits before this table == (l * h)
int xp; // pointer into x
int y; // number of dummy codes added
int z; // number of entries in current table
// Generate counts for each bit length
p = 0; i = n;
do
{
c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX
}
while (i != 0);
if (c[0] == n)
{
// null input--all zero length codes
t[0] = -1;
m[0] = 0;
return Z_OK;
}
// Find minimum and maximum length, bound *m by those
l = m[0];
for (j = 1; j <= BMAX; j++)
if (c[j] != 0)
break;
k = j; // minimum code length
if (l < j)
{
l = j;
}
for (i = BMAX; i != 0; i--)
{
if (c[i] != 0)
break;
}
g = i; // maximum code length
if (l > i)
{
l = i;
}
m[0] = l;
// Adjust last length count to fill out codes, if needed
for (y = 1 << j; j < i; j++, y <<= 1)
{
if ((y -= c[j]) < 0)
{
return Z_DATA_ERROR;
}
}
if ((y -= c[i]) < 0)
{
return Z_DATA_ERROR;
}
c[i] += y;
// Generate starting offsets into the value table for each length
x[1] = j = 0;
p = 1; xp = 2;
while (--i != 0)
{
// note that i == g from above
x[xp] = (j += c[p]);
xp++;
p++;
}
// Make a table of values in order of bit lengths
i = 0; p = 0;
do
{
if ((j = b[bindex + p]) != 0)
{
v[x[j]++] = i;
}
p++;
}
while (++i < n);
n = x[g]; // set n to length of v
// Generate the Huffman codes and for each, make the table entries
x[0] = i = 0; // first Huffman code is zero
p = 0; // grab values in bit order
h = -1; // no tables yet--level -1
w = -l; // bits decoded == (l * h)
u[0] = 0; // just to keep compilers happy
q = 0; // ditto
z = 0; // ditto
// go through the bit lengths (k already is bits in shortest code)
for (; k <= g; k++)
{
a = c[k];
while (a-- != 0)
{
// here i is the Huffman code of length k bits for value *p
// make tables up to required level
while (k > w + l)
{
h++;
w += l; // previous table always l bits
// compute minimum size table less than or equal to l bits
z = g - w;
z = (z > l) ? l : z; // table size upper limit
if ((f = 1 << (j = k - w)) > a + 1)
{
// try a k-w bit table
// too few codes for k-w bit table
f -= (a + 1); // deduct codes from patterns left
xp = k;
if (j < z)
{
while (++j < z)
{
// try smaller tables up to z bits
if ((f <<= 1) <= c[++xp])
break; // enough codes to use up j bits
f -= c[xp]; // else deduct codes from patterns
}
}
}
z = 1 << j; // table entries for j-bit table
// allocate new table
if (hn[0] + z > MANY)
{
// (note: doesn't matter for fixed)
return Z_DATA_ERROR; // overflow of MANY
}
u[h] = q = hn[0]; // DEBUG
hn[0] += z;
// connect to last table, if there is one
if (h != 0)
{
x[h] = i; // save pattern for backing up
r[0] = (sbyte)j; // bits in this table
r[1] = (sbyte)l; // bits to dump before this table
j = SharedUtils.URShift(i, (w - l));
r[2] = (int)(q - u[h - 1] - j); // offset to this table
Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table
}
else
{
t[0] = q; // first table is returned result
}
}
// set up table entry in r
r[1] = (sbyte)(k - w);
if (p >= n)
{
r[0] = 128 + 64; // out of values--invalid code
}
else if (v[p] < s)
{
r[0] = (sbyte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block
r[2] = v[p++]; // simple code is just the value
}
else
{
r[0] = (sbyte)(e[v[p] - s] + 16 + 64); // non-simple--look up in lists
r[2] = d[v[p++] - s];
}
// fill code-like entries with r
f = 1 << (k - w);
for (j = SharedUtils.URShift(i, w); j < z; j += f)
{
Array.Copy(r, 0, hp, (q + j) * 3, 3);
}
// backwards increment the k-bit code i
for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1))
{
i ^= j;
}
i ^= j;
// backup over finished tables
mask = (1 << w) - 1; // needed on HP, cc -O bug
while ((i & mask) != x[h])
{
h--; // don't need to update q
w -= l;
mask = (1 << w) - 1;
}
}
}
// Return Z_BUF_ERROR if we were given an incomplete table
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
}
internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z)
{
int result;
initWorkArea(19);
hn[0] = 0;
result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed dynamic bit lengths tree";
}
else if (result == Z_BUF_ERROR || bb[0] == 0)
{
z.Message = "incomplete dynamic bit lengths tree";
result = Z_DATA_ERROR;
}
return result;
}
internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
{
int result;
// build literal/length tree
initWorkArea(288);
hn[0] = 0;
result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
if (result != Z_OK || bl[0] == 0)
{
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed literal/length tree";
}
else if (result != Z_MEM_ERROR)
{
z.Message = "incomplete literal/length tree";
result = Z_DATA_ERROR;
}
return result;
}
// build distance tree
initWorkArea(288);
result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
if (result != Z_OK || (bd[0] == 0 && nl > 257))
{
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed distance tree";
}
else if (result == Z_BUF_ERROR)
{
z.Message = "incomplete distance tree";
result = Z_DATA_ERROR;
}
else if (result != Z_MEM_ERROR)
{
z.Message = "empty distance tree with lengths";
result = Z_DATA_ERROR;
}
return result;
}
return Z_OK;
}
internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
{
bl[0] = fixed_bl;
bd[0] = fixed_bd;
tl[0] = fixed_tl;
td[0] = fixed_td;
return Z_OK;
}
private void initWorkArea(int vsize)
{
if (hn == null)
{
hn = new int[1];
v = new int[vsize];
c = new int[BMAX + 1];
r = new int[3];
u = new int[BMAX];
x = new int[BMAX + 1];
}
else
{
if (v.Length < vsize)
{
v = new int[vsize];
}
Array.Clear(v, 0, vsize);
Array.Clear(c, 0, BMAX + 1);
r[0] = 0; r[1] = 0; r[2] = 0;
// for(int i=0; i<BMAX; i++){u[i]=0;}
//Array.Copy(c, 0, u, 0, BMAX);
Array.Clear(u, 0, BMAX);
// for(int i=0; i<BMAX+1; i++){x[i]=0;}
//Array.Copy(c, 0, x, 0, BMAX + 1);
Array.Clear(x, 0, BMAX + 1);
}
}
}
}
// Inftree.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-October-28 12:43:54>
//
// ------------------------------------------------------------------
//
// This module defines classes used in decompression. This code is derived
// from the jzlib implementation of zlib. In keeping with the license for jzlib,
// the copyright to that code is below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0004
#pragma warning disable IDE0040
#pragma warning disable IDE0047
#pragma warning disable IDE0051
#pragma warning disable IDE2003
sealed class InfTree
{
private const int MANY = 1440;
private const int Z_OK = 0;
private const int Z_STREAM_END = 1;
private const int Z_NEED_DICT = 2;
private const int Z_ERRNO = -1;
private const int Z_STREAM_ERROR = -2;
private const int Z_DATA_ERROR = -3;
private const int Z_MEM_ERROR = -4;
private const int Z_BUF_ERROR = -5;
private const int Z_VERSION_ERROR = -6;
internal const int fixed_bl = 9;
internal const int fixed_bd = 5;
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] fixed_tl = [96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186,
0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8,
14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255];
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] fixed_td = [80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577];
// Tables for deflate from PKZIP's appnote.txt.
//UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cplens = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0];
// see note #13 above about 258
//UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cplext = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112];
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cpdist = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cpdext = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13];
// If BMAX needs to be larger than 16, then h and x[] should be uLong.
internal const int BMAX = 15; // maximum bit length of any code
internal int[] hn = null; // hufts used in space
internal int[] v = null; // work area for huft_build
internal int[] c = null; // bit length count table
internal int[] r = null; // table entry for structure assignment
internal int[] u = null; // table stack
internal int[] x = null; // bit offsets, then code stack
private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v)
{
// Given a list of code lengths and a maximum table size, make a set of
// tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
// if the given code set is incomplete (the tables are still built in this
// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
// lengths), or Z_MEM_ERROR if not enough memory.
int a; // counter for codes of length k
int f; // i repeats in table every f entries
int g; // maximum code length
int h; // table level
int i; // counter, current code
int j; // counter
int k; // number of bits in current code
int l; // bits per table (returned in m)
int mask; // (1 << w) - 1, to avoid cc -O bug on HP
int p; // pointer into c[], b[], or v[]
int q; // points to current table
int w; // bits before this table == (l * h)
int xp; // pointer into x
int y; // number of dummy codes added
int z; // number of entries in current table
// Generate counts for each bit length
p = 0; i = n;
do
{
c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX
}
while (i != 0);
if (c[0] == n)
{
// null input--all zero length codes
t[0] = -1;
m[0] = 0;
return Z_OK;
}
// Find minimum and maximum length, bound *m by those
l = m[0];
for (j = 1; j <= BMAX; j++)
if (c[j] != 0)
break;
k = j; // minimum code length
if (l < j)
{
l = j;
}
for (i = BMAX; i != 0; i--)
{
if (c[i] != 0)
break;
}
g = i; // maximum code length
if (l > i)
{
l = i;
}
m[0] = l;
// Adjust last length count to fill out codes, if needed
for (y = 1 << j; j < i; j++, y <<= 1)
{
if ((y -= c[j]) < 0)
{
return Z_DATA_ERROR;
}
}
if ((y -= c[i]) < 0)
{
return Z_DATA_ERROR;
}
c[i] += y;
// Generate starting offsets into the value table for each length
x[1] = j = 0;
p = 1; xp = 2;
while (--i != 0)
{
// note that i == g from above
x[xp] = (j += c[p]);
xp++;
p++;
}
// Make a table of values in order of bit lengths
i = 0; p = 0;
do
{
if ((j = b[bindex + p]) != 0)
{
v[x[j]++] = i;
}
p++;
}
while (++i < n);
n = x[g]; // set n to length of v
// Generate the Huffman codes and for each, make the table entries
x[0] = i = 0; // first Huffman code is zero
p = 0; // grab values in bit order
h = -1; // no tables yet--level -1
w = -l; // bits decoded == (l * h)
u[0] = 0; // just to keep compilers happy
q = 0; // ditto
z = 0; // ditto
// go through the bit lengths (k already is bits in shortest code)
for (; k <= g; k++)
{
a = c[k];
while (a-- != 0)
{
// here i is the Huffman code of length k bits for value *p
// make tables up to required level
while (k > w + l)
{
h++;
w += l; // previous table always l bits
// compute minimum size table less than or equal to l bits
z = g - w;
z = (z > l) ? l : z; // table size upper limit
if ((f = 1 << (j = k - w)) > a + 1)
{
// try a k-w bit table
// too few codes for k-w bit table
f -= (a + 1); // deduct codes from patterns left
xp = k;
if (j < z)
{
while (++j < z)
{
// try smaller tables up to z bits
if ((f <<= 1) <= c[++xp])
break; // enough codes to use up j bits
f -= c[xp]; // else deduct codes from patterns
}
}
}
z = 1 << j; // table entries for j-bit table
// allocate new table
if (hn[0] + z > MANY)
{
// (note: doesn't matter for fixed)
return Z_DATA_ERROR; // overflow of MANY
}
u[h] = q = hn[0]; // DEBUG
hn[0] += z;
// connect to last table, if there is one
if (h != 0)
{
x[h] = i; // save pattern for backing up
r[0] = (sbyte)j; // bits in this table
r[1] = (sbyte)l; // bits to dump before this table
j = SharedUtils.URShift(i, (w - l));
r[2] = (int)(q - u[h - 1] - j); // offset to this table
Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table
}
else
{
t[0] = q; // first table is returned result
}
}
// set up table entry in r
r[1] = (sbyte)(k - w);
if (p >= n)
{
r[0] = 128 + 64; // out of values--invalid code
}
else if (v[p] < s)
{
r[0] = (sbyte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block
r[2] = v[p++]; // simple code is just the value
}
else
{
r[0] = (sbyte)(e[v[p] - s] + 16 + 64); // non-simple--look up in lists
r[2] = d[v[p++] - s];
}
// fill code-like entries with r
f = 1 << (k - w);
for (j = SharedUtils.URShift(i, w); j < z; j += f)
{
Array.Copy(r, 0, hp, (q + j) * 3, 3);
}
// backwards increment the k-bit code i
for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1))
{
i ^= j;
}
i ^= j;
// backup over finished tables
mask = (1 << w) - 1; // needed on HP, cc -O bug
while ((i & mask) != x[h])
{
h--; // don't need to update q
w -= l;
mask = (1 << w) - 1;
}
}
}
// Return Z_BUF_ERROR if we were given an incomplete table
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
}
internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z)
{
int result;
initWorkArea(19);
hn[0] = 0;
result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed dynamic bit lengths tree";
}
else if (result == Z_BUF_ERROR || bb[0] == 0)
{
z.Message = "incomplete dynamic bit lengths tree";
result = Z_DATA_ERROR;
}
return result;
}
internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
{
int result;
// build literal/length tree
initWorkArea(288);
hn[0] = 0;
result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
if (result != Z_OK || bl[0] == 0)
{
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed literal/length tree";
}
else if (result != Z_MEM_ERROR)
{
z.Message = "incomplete literal/length tree";
result = Z_DATA_ERROR;
}
return result;
}
// build distance tree
initWorkArea(288);
result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
if (result != Z_OK || (bd[0] == 0 && nl > 257))
{
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed distance tree";
}
else if (result == Z_BUF_ERROR)
{
z.Message = "incomplete distance tree";
result = Z_DATA_ERROR;
}
else if (result != Z_MEM_ERROR)
{
z.Message = "empty distance tree with lengths";
result = Z_DATA_ERROR;
}
return result;
}
return Z_OK;
}
internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
{
bl[0] = fixed_bl;
bd[0] = fixed_bd;
tl[0] = fixed_tl;
td[0] = fixed_td;
return Z_OK;
}
private void initWorkArea(int vsize)
{
if (hn is null)
{
hn = new int[1];
v = new int[vsize];
c = new int[BMAX + 1];
r = new int[3];
u = new int[BMAX];
x = new int[BMAX + 1];
}
else
{
if (v.Length < vsize)
{
v = new int[vsize];
}
Array.Clear(v, 0, vsize);
Array.Clear(c, 0, BMAX + 1);
r[0] = 0; r[1] = 0; r[2] = 0;
// for(int i=0; i<BMAX; i++){u[i]=0;}
//Array.Copy(c, 0, u, 0, BMAX);
Array.Clear(u, 0, BMAX);
// for(int i=0; i<BMAX+1; i++){x[i]=0;}
//Array.Copy(c, 0, x, 0, BMAX + 1);
Array.Clear(x, 0, BMAX + 1);
}
}
}
}

View File

@@ -66,13 +66,20 @@ using System;
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0004
#pragma warning disable IDE0010
#pragma warning disable IDE0040
#pragma warning disable IDE0047
#pragma warning disable IDE0048
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2003
sealed class InflateBlocks
{
private const int MANY = 1440;
// Table for deflate from PKZIP's appnote.txt.
internal static readonly int[] border = new int[]
{ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
internal static readonly int[] border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
private enum InflateBlockMode
{
@@ -98,7 +105,7 @@ namespace SabreTools.IO.Compression.Deflate
internal int[] bb = new int[1]; // bit length tree depth
internal int[] tb = new int[1]; // bit length decoding tree
internal InflateCodes codes = new InflateCodes(); // if CODES, current state
internal InflateCodes codes = new(); // if CODES, current state
internal int last; // true if this block is the last block
@@ -115,7 +122,7 @@ namespace SabreTools.IO.Compression.Deflate
internal System.Object checkfn; // check function
internal uint check; // check on output
internal InfTree inftree = new InfTree();
internal InfTree inftree = new();
internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w)
{
@@ -136,7 +143,7 @@ namespace SabreTools.IO.Compression.Deflate
bitb = 0;
readAt = writeAt = 0;
if (checkfn != null)
if (checkfn is not null)
_codec._Adler32 = check = Adler.Adler32(0, null, 0, 0);
return oldCheck;
}
@@ -363,7 +370,7 @@ namespace SabreTools.IO.Compression.Deflate
return Flush(r);
}
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
if (blens == null || blens.Length < t)
if (blens is null || blens.Length < t)
{
blens = new int[t];
}
@@ -545,8 +552,8 @@ namespace SabreTools.IO.Compression.Deflate
tb[0] = -1;
{
int[] bl = new int[] { 9 }; // must be <= 9 for lookahead assumptions
int[] bd = new int[] { 6 }; // must be <= 9 for lookahead assumptions
int[] bl = [9]; // must be <= 9 for lookahead assumptions
int[] bd = [6]; // must be <= 9 for lookahead assumptions
int[] tl = new int[1];
int[] td = new int[1];
@@ -711,7 +718,7 @@ namespace SabreTools.IO.Compression.Deflate
_codec.TotalBytesOut += nBytes;
// update check information
if (checkfn != null)
if (checkfn is not null)
_codec._Adler32 = check = Adler.Adler32(check, window, readAt, nBytes);
// copy as far as end of window
@@ -734,4 +741,4 @@ namespace SabreTools.IO.Compression.Deflate
return r;
}
}
}
}

View File

@@ -66,6 +66,12 @@ using System;
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0004
#pragma warning disable IDE0040
#pragma warning disable IDE0047
#pragma warning disable IDE0048
#pragma warning disable IDE2000
#pragma warning disable IDE2003
sealed class InflateCodes
{
// waiting for "i:"=input,
@@ -720,4 +726,4 @@ namespace SabreTools.IO.Compression.Deflate
return ZlibConstants.Z_OK;
}
}
}
}

View File

@@ -1,465 +1,467 @@
// Inflate.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2010-January-08 18:32:12>
//
// ------------------------------------------------------------------
//
// This module defines classes for decompression. This code is derived
// from the jzlib implementation of zlib, but significantly modified.
// The object model is not the same, and many of the behaviors are
// different. Nonetheless, in keeping with the license for jzlib, I am
// reproducing the copyright to that code here.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
internal sealed class InflateManager
{
// preset dictionary flag in zlib header
private const int PRESET_DICT = 0x20;
private const int Z_DEFLATED = 8;
private enum InflateManagerMode
{
METHOD = 0, // waiting for method byte
FLAG = 1, // waiting for flag byte
DICT4 = 2, // four dictionary check bytes to go
DICT3 = 3, // three dictionary check bytes to go
DICT2 = 4, // two dictionary check bytes to go
DICT1 = 5, // one dictionary check byte to go
DICT0 = 6, // waiting for inflateSetDictionary
BLOCKS = 7, // decompressing blocks
CHECK4 = 8, // four check bytes to go
CHECK3 = 9, // three check bytes to go
CHECK2 = 10, // two check bytes to go
CHECK1 = 11, // one check byte to go
DONE = 12, // finished check, done
BAD = 13, // got an error--stay here
}
private InflateManagerMode mode; // current inflate mode
internal ZlibCodec _codec; // pointer back to this zlib stream
// mode dependent information
internal int method; // if FLAGS, method byte
// if CHECK, check values to compare
internal uint computedCheck; // computed check value
internal uint expectedCheck; // stream check value
// if BAD, inflateSync's marker bytes count
internal int marker;
// mode independent information
//internal int nowrap; // flag for no wrapper
private bool _handleRfc1950HeaderBytes = true;
internal bool HandleRfc1950HeaderBytes
{
get { return _handleRfc1950HeaderBytes; }
set { _handleRfc1950HeaderBytes = value; }
}
internal int wbits; // log2(window size) (8..15, defaults to 15)
internal InflateBlocks blocks; // current inflate_blocks state
public InflateManager() { }
public InflateManager(bool expectRfc1950HeaderBytes)
{
_handleRfc1950HeaderBytes = expectRfc1950HeaderBytes;
}
internal int Reset()
{
_codec.TotalBytesIn = _codec.TotalBytesOut = 0;
_codec.Message = null;
mode = HandleRfc1950HeaderBytes ? InflateManagerMode.METHOD : InflateManagerMode.BLOCKS;
blocks.Reset();
return ZlibConstants.Z_OK;
}
internal int End()
{
if (blocks != null)
blocks.Free();
blocks = null;
return ZlibConstants.Z_OK;
}
internal int Initialize(ZlibCodec codec, int w)
{
_codec = codec;
_codec.Message = null;
blocks = null;
// handle undocumented nowrap option (no zlib header or check)
//nowrap = 0;
//if (w < 0)
//{
// w = - w;
// nowrap = 1;
//}
// set window size
if (w < 8 || w > 15)
{
End();
throw new ZlibException("Bad window size.");
//return ZlibConstants.Z_STREAM_ERROR;
}
wbits = w;
blocks = new InflateBlocks(codec,
HandleRfc1950HeaderBytes ? this : null,
1 << w);
// reset state
Reset();
return ZlibConstants.Z_OK;
}
internal int Inflate(FlushType flush)
{
int b;
if (_codec.InputBuffer == null)
throw new ZlibException("InputBuffer is null. ");
// int f = (flush == FlushType.Finish)
// ? ZlibConstants.Z_BUF_ERROR
// : ZlibConstants.Z_OK;
// workitem 8870
int f = ZlibConstants.Z_OK;
int r = ZlibConstants.Z_BUF_ERROR;
while (true)
{
switch (mode)
{
case InflateManagerMode.METHOD:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED)
{
mode = InflateManagerMode.BAD;
_codec.Message = String.Format("unknown compression method (0x{0:X2})", method);
marker = 5; // can't try inflateSync
break;
}
if ((method >> 4) + 8 > wbits)
{
mode = InflateManagerMode.BAD;
_codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8);
marker = 5; // can't try inflateSync
break;
}
mode = InflateManagerMode.FLAG;
break;
case InflateManagerMode.FLAG:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff;
if ((((method << 8) + b) % 31) != 0)
{
mode = InflateManagerMode.BAD;
_codec.Message = "incorrect header check";
marker = 5; // can't try inflateSync
break;
}
mode = ((b & PRESET_DICT) == 0)
? InflateManagerMode.BLOCKS
: InflateManagerMode.DICT4;
break;
case InflateManagerMode.DICT4:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
mode = InflateManagerMode.DICT3;
break;
case InflateManagerMode.DICT3:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
mode = InflateManagerMode.DICT2;
break;
case InflateManagerMode.DICT2:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
mode = InflateManagerMode.DICT1;
break;
case InflateManagerMode.DICT1:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--; _codec.TotalBytesIn++;
expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
_codec._Adler32 = expectedCheck;
mode = InflateManagerMode.DICT0;
return ZlibConstants.Z_NEED_DICT;
case InflateManagerMode.DICT0:
mode = InflateManagerMode.BAD;
_codec.Message = "need dictionary";
marker = 0; // can try inflateSync
return ZlibConstants.Z_STREAM_ERROR;
case InflateManagerMode.BLOCKS:
r = blocks.Process(r);
if (r == ZlibConstants.Z_DATA_ERROR)
{
mode = InflateManagerMode.BAD;
marker = 0; // can try inflateSync
break;
}
if (r == ZlibConstants.Z_OK) r = f;
if (r != ZlibConstants.Z_STREAM_END)
return r;
r = f;
computedCheck = blocks.Reset();
if (!HandleRfc1950HeaderBytes)
{
mode = InflateManagerMode.DONE;
return ZlibConstants.Z_STREAM_END;
}
mode = InflateManagerMode.CHECK4;
break;
case InflateManagerMode.CHECK4:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
mode = InflateManagerMode.CHECK3;
break;
case InflateManagerMode.CHECK3:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--; _codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
mode = InflateManagerMode.CHECK2;
break;
case InflateManagerMode.CHECK2:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
mode = InflateManagerMode.CHECK1;
break;
case InflateManagerMode.CHECK1:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--; _codec.TotalBytesIn++;
expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
if (computedCheck != expectedCheck)
{
mode = InflateManagerMode.BAD;
_codec.Message = "incorrect data check";
marker = 5; // can't try inflateSync
break;
}
mode = InflateManagerMode.DONE;
return ZlibConstants.Z_STREAM_END;
case InflateManagerMode.DONE:
return ZlibConstants.Z_STREAM_END;
case InflateManagerMode.BAD:
throw new ZlibException(String.Format("Bad state ({0})", _codec.Message));
default:
throw new ZlibException("Stream error.");
}
}
}
internal int SetDictionary(byte[] dictionary, bool check = true)
{
int index = 0;
int length = dictionary.Length;
if (check)
{
if (mode != InflateManagerMode.DICT0)
throw new ZlibException("Stream error.");
if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
{
return ZlibConstants.Z_DATA_ERROR;
}
}
_codec._Adler32 = Adler.Adler32(0, null, 0, 0);
if (length >= (1 << wbits))
{
length = (1 << wbits) - 1;
index = dictionary.Length - length;
}
blocks.SetDictionary(dictionary, index, length);
mode = InflateManagerMode.BLOCKS;
return ZlibConstants.Z_OK;
}
private static readonly byte[] mark = new byte[] { 0, 0, 0xff, 0xff };
internal int Sync()
{
int n; // number of bytes to look at
int p; // pointer to bytes
int m; // number of marker bytes found in a row
long r, w; // temporaries to save total_in and total_out
// set up
if (mode != InflateManagerMode.BAD)
{
mode = InflateManagerMode.BAD;
marker = 0;
}
if ((n = _codec.AvailableBytesIn) == 0)
return ZlibConstants.Z_BUF_ERROR;
p = _codec.NextIn;
m = marker;
// search
while (n != 0 && m < 4)
{
if (_codec.InputBuffer[p] == mark[m])
{
m++;
}
else if (_codec.InputBuffer[p] != 0)
{
m = 0;
}
else
{
m = 4 - m;
}
p++; n--;
}
// restore
_codec.TotalBytesIn += p - _codec.NextIn;
_codec.NextIn = p;
_codec.AvailableBytesIn = n;
marker = m;
// return no joy or set up to restart on a new block
if (m != 4)
{
return ZlibConstants.Z_DATA_ERROR;
}
r = _codec.TotalBytesIn;
w = _codec.TotalBytesOut;
Reset();
_codec.TotalBytesIn = r;
_codec.TotalBytesOut = w;
mode = InflateManagerMode.BLOCKS;
return ZlibConstants.Z_OK;
}
// Returns true if inflate is currently at the end of a block generated
// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
// implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
// but removes the length bytes of the resulting empty stored block. When
// decompressing, PPP checks that at the end of input packet, inflate is
// waiting for these length bytes.
internal int SyncPoint(ZlibCodec z)
{
return blocks.SyncPoint();
}
}
}
// Inflate.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2010-January-08 18:32:12>
//
// ------------------------------------------------------------------
//
// This module defines classes for decompression. This code is derived
// from the jzlib implementation of zlib, but significantly modified.
// The object model is not the same, and many of the behaviors are
// different. Nonetheless, in keeping with the license for jzlib, I am
// reproducing the copyright to that code here.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0047
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2003
internal sealed class InflateManager
{
// preset dictionary flag in zlib header
private const int PRESET_DICT = 0x20;
private const int Z_DEFLATED = 8;
private enum InflateManagerMode
{
METHOD = 0, // waiting for method byte
FLAG = 1, // waiting for flag byte
DICT4 = 2, // four dictionary check bytes to go
DICT3 = 3, // three dictionary check bytes to go
DICT2 = 4, // two dictionary check bytes to go
DICT1 = 5, // one dictionary check byte to go
DICT0 = 6, // waiting for inflateSetDictionary
BLOCKS = 7, // decompressing blocks
CHECK4 = 8, // four check bytes to go
CHECK3 = 9, // three check bytes to go
CHECK2 = 10, // two check bytes to go
CHECK1 = 11, // one check byte to go
DONE = 12, // finished check, done
BAD = 13, // got an error--stay here
}
private InflateManagerMode mode; // current inflate mode
internal ZlibCodec _codec; // pointer back to this zlib stream
// mode dependent information
internal int method; // if FLAGS, method byte
// if CHECK, check values to compare
internal uint computedCheck; // computed check value
internal uint expectedCheck; // stream check value
// if BAD, inflateSync's marker bytes count
internal int marker;
// mode independent information
//internal int nowrap; // flag for no wrapper
private bool _handleRfc1950HeaderBytes = true;
internal bool HandleRfc1950HeaderBytes
{
get { return _handleRfc1950HeaderBytes; }
set { _handleRfc1950HeaderBytes = value; }
}
internal int wbits; // log2(window size) (8..15, defaults to 15)
internal InflateBlocks blocks; // current inflate_blocks state
public InflateManager() { }
public InflateManager(bool expectRfc1950HeaderBytes)
{
_handleRfc1950HeaderBytes = expectRfc1950HeaderBytes;
}
internal int Reset()
{
_codec.TotalBytesIn = _codec.TotalBytesOut = 0;
_codec.Message = null;
mode = HandleRfc1950HeaderBytes ? InflateManagerMode.METHOD : InflateManagerMode.BLOCKS;
blocks.Reset();
return ZlibConstants.Z_OK;
}
internal int End()
{
blocks?.Free();
blocks = null;
return ZlibConstants.Z_OK;
}
internal int Initialize(ZlibCodec codec, int w)
{
_codec = codec;
_codec.Message = null;
blocks = null;
// handle undocumented nowrap option (no zlib header or check)
//nowrap = 0;
//if (w < 0)
//{
// w = - w;
// nowrap = 1;
//}
// set window size
if (w < 8 || w > 15)
{
End();
throw new ZlibException("Bad window size.");
//return ZlibConstants.Z_STREAM_ERROR;
}
wbits = w;
blocks = new InflateBlocks(codec,
HandleRfc1950HeaderBytes ? this : null,
1 << w);
// reset state
Reset();
return ZlibConstants.Z_OK;
}
internal int Inflate(FlushType flush)
{
int b;
if (_codec.InputBuffer is null)
throw new ZlibException("InputBuffer is null. ");
// int f = (flush == FlushType.Finish)
// ? ZlibConstants.Z_BUF_ERROR
// : ZlibConstants.Z_OK;
// workitem 8870
int f = ZlibConstants.Z_OK;
int r = ZlibConstants.Z_BUF_ERROR;
while (true)
{
switch (mode)
{
case InflateManagerMode.METHOD:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED)
{
mode = InflateManagerMode.BAD;
_codec.Message = String.Format("unknown compression method (0x{0:X2})", method);
marker = 5; // can't try inflateSync
break;
}
if ((method >> 4) + 8 > wbits)
{
mode = InflateManagerMode.BAD;
_codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8);
marker = 5; // can't try inflateSync
break;
}
mode = InflateManagerMode.FLAG;
break;
case InflateManagerMode.FLAG:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff;
if ((((method << 8) + b) % 31) != 0)
{
mode = InflateManagerMode.BAD;
_codec.Message = "incorrect header check";
marker = 5; // can't try inflateSync
break;
}
mode = ((b & PRESET_DICT) == 0)
? InflateManagerMode.BLOCKS
: InflateManagerMode.DICT4;
break;
case InflateManagerMode.DICT4:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
mode = InflateManagerMode.DICT3;
break;
case InflateManagerMode.DICT3:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
mode = InflateManagerMode.DICT2;
break;
case InflateManagerMode.DICT2:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
mode = InflateManagerMode.DICT1;
break;
case InflateManagerMode.DICT1:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--; _codec.TotalBytesIn++;
expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
_codec._Adler32 = expectedCheck;
mode = InflateManagerMode.DICT0;
return ZlibConstants.Z_NEED_DICT;
case InflateManagerMode.DICT0:
mode = InflateManagerMode.BAD;
_codec.Message = "need dictionary";
marker = 0; // can try inflateSync
return ZlibConstants.Z_STREAM_ERROR;
case InflateManagerMode.BLOCKS:
r = blocks.Process(r);
if (r == ZlibConstants.Z_DATA_ERROR)
{
mode = InflateManagerMode.BAD;
marker = 0; // can try inflateSync
break;
}
if (r == ZlibConstants.Z_OK) r = f;
if (r != ZlibConstants.Z_STREAM_END)
return r;
r = f;
computedCheck = blocks.Reset();
if (!HandleRfc1950HeaderBytes)
{
mode = InflateManagerMode.DONE;
return ZlibConstants.Z_STREAM_END;
}
mode = InflateManagerMode.CHECK4;
break;
case InflateManagerMode.CHECK4:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
mode = InflateManagerMode.CHECK3;
break;
case InflateManagerMode.CHECK3:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--; _codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
mode = InflateManagerMode.CHECK2;
break;
case InflateManagerMode.CHECK2:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--;
_codec.TotalBytesIn++;
expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
mode = InflateManagerMode.CHECK1;
break;
case InflateManagerMode.CHECK1:
if (_codec.AvailableBytesIn == 0) return r;
r = f;
_codec.AvailableBytesIn--; _codec.TotalBytesIn++;
expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
if (computedCheck != expectedCheck)
{
mode = InflateManagerMode.BAD;
_codec.Message = "incorrect data check";
marker = 5; // can't try inflateSync
break;
}
mode = InflateManagerMode.DONE;
return ZlibConstants.Z_STREAM_END;
case InflateManagerMode.DONE:
return ZlibConstants.Z_STREAM_END;
case InflateManagerMode.BAD:
throw new ZlibException(String.Format("Bad state ({0})", _codec.Message));
default:
throw new ZlibException("Stream error.");
}
}
}
internal int SetDictionary(byte[] dictionary, bool check = true)
{
int index = 0;
int length = dictionary.Length;
if (check)
{
if (mode != InflateManagerMode.DICT0)
throw new ZlibException("Stream error.");
if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
{
return ZlibConstants.Z_DATA_ERROR;
}
}
_codec._Adler32 = Adler.Adler32(0, null, 0, 0);
if (length >= (1 << wbits))
{
length = (1 << wbits) - 1;
index = dictionary.Length - length;
}
blocks.SetDictionary(dictionary, index, length);
mode = InflateManagerMode.BLOCKS;
return ZlibConstants.Z_OK;
}
private static readonly byte[] mark = [0, 0, 0xff, 0xff];
internal int Sync()
{
int n; // number of bytes to look at
int p; // pointer to bytes
int m; // number of marker bytes found in a row
long r, w; // temporaries to save total_in and total_out
// set up
if (mode != InflateManagerMode.BAD)
{
mode = InflateManagerMode.BAD;
marker = 0;
}
if ((n = _codec.AvailableBytesIn) == 0)
return ZlibConstants.Z_BUF_ERROR;
p = _codec.NextIn;
m = marker;
// search
while (n != 0 && m < 4)
{
if (_codec.InputBuffer[p] == mark[m])
{
m++;
}
else if (_codec.InputBuffer[p] != 0)
{
m = 0;
}
else
{
m = 4 - m;
}
p++; n--;
}
// restore
_codec.TotalBytesIn += p - _codec.NextIn;
_codec.NextIn = p;
_codec.AvailableBytesIn = n;
marker = m;
// return no joy or set up to restart on a new block
if (m != 4)
{
return ZlibConstants.Z_DATA_ERROR;
}
r = _codec.TotalBytesIn;
w = _codec.TotalBytesOut;
Reset();
_codec.TotalBytesIn = r;
_codec.TotalBytesOut = w;
mode = InflateManagerMode.BLOCKS;
return ZlibConstants.Z_OK;
}
// Returns true if inflate is currently at the end of a block generated
// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
// implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
// but removes the length bytes of the resulting empty stored block. When
// decompressing, PPP checks that at the end of input packet, inflate is
// waiting for these length bytes.
internal int SyncPoint(ZlibCodec z)
{
return blocks.SyncPoint();
}
}
}

View File

@@ -93,7 +93,7 @@ namespace SabreTools.IO.Compression.Deflate
out var foundFilename);
// If the extracted data is invalid
if (status != ExtractionStatus.GOOD || destination == null)
if (status != ExtractionStatus.GOOD || destination is null)
return status;
// Ensure directory separators are consistent
@@ -106,7 +106,7 @@ namespace SabreTools.IO.Compression.Deflate
// Ensure the full output directory exists
filename = Path.Combine(outputDirectory, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
if (directoryName is not null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
// Write the output file
@@ -182,11 +182,11 @@ namespace SabreTools.IO.Compression.Deflate
long zipHeaderBytes = source.Position - current;
// Always trust the PKZIP CRC-32 value over what is supplied
if (zipHeader != null)
if (zipHeader is not null)
expected.Crc32 = zipHeader.CRC32;
// If the filename is [NULL], replace with the zip filename
if (zipHeader?.FileName != null)
if (zipHeader?.FileName is not null)
{
filename = zipHeader.FileName;
if (includeDebug) Console.WriteLine($"Filename from PKZIP header: {filename}");
@@ -197,7 +197,7 @@ namespace SabreTools.IO.Compression.Deflate
// Extract the file
var actual = Inflate(source, destination);
if (actual == null)
if (actual is null)
{
if (includeDebug) Console.Error.WriteLine($"Could not extract {filename}");
return ExtractionStatus.FAIL;
@@ -244,7 +244,7 @@ namespace SabreTools.IO.Compression.Deflate
// Extract the file
var actual = Inflate(source, destination);
if (actual == null)
if (actual is null)
{
if (includeDebug) Console.Error.WriteLine($"Could not extract");
return ExtractionStatus.FAIL;
@@ -467,4 +467,4 @@ namespace SabreTools.IO.Compression.Deflate
#endregion
}
}
}

View File

@@ -88,27 +88,29 @@
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0047
#pragma warning disable IDE2002
internal static class InternalConstants
{
internal static readonly int MAX_BITS = 15;
internal static readonly int BL_CODES = 19;
internal static readonly int D_CODES = 30;
internal static readonly int LITERALS = 256;
internal static readonly int MAX_BITS = 15;
internal static readonly int BL_CODES = 19;
internal static readonly int D_CODES = 30;
internal static readonly int LITERALS = 256;
internal static readonly int LENGTH_CODES = 29;
internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES);
internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES);
// Bit length codes must not exceed MAX_BL_BITS bits
internal static readonly int MAX_BL_BITS = 7;
internal static readonly int MAX_BL_BITS = 7;
// repeat previous bit length 3-6 times (2 bits of repeat count)
internal static readonly int REP_3_6 = 16;
internal static readonly int REP_3_6 = 16;
// repeat a zero length 3-10 times (3 bits of repeat count)
internal static readonly int REPZ_3_10 = 17;
internal static readonly int REPZ_3_10 = 17;
// repeat a zero length 11-138 times (7 bits of repeat count)
internal static readonly int REPZ_11_138 = 18;
internal static readonly int REPZ_11_138 = 18;
}
}
}

View File

@@ -66,10 +66,10 @@ namespace SabreTools.IO.Compression.Deflate
internal static class InternalInflateConstants
{
// And'ing with mask[n] masks the lower n bits
internal static readonly int[] InflateMask = new int[] {
internal static readonly int[] InflateMask = [
0x00000000, 0x00000001, 0x00000003, 0x00000007,
0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff };
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ];
}
}
}

View File

@@ -88,6 +88,10 @@
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0002
#pragma warning disable IDE0049
#pragma warning disable IDE2000
#pragma warning disable IDE2002
internal class SharedUtils
{
/// <summary>
@@ -159,4 +163,4 @@ namespace SabreTools.IO.Compression.Deflate
}
}
}
}

View File

@@ -90,7 +90,7 @@ namespace SabreTools.IO.Compression.Deflate
{
internal sealed class StaticTree
{
internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] {
internal static readonly short[] lengthAndLiteralsTreeCodes = [
12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8,
28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8,
2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8,
@@ -127,13 +127,13 @@ namespace SabreTools.IO.Compression.Deflate
8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7,
4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7,
3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8
};
];
internal static readonly short[] distTreeCodes = new short[] {
internal static readonly short[] distTreeCodes = [
0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5,
2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5,
1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5,
3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 };
3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];
internal static readonly StaticTree Literals;
internal static readonly StaticTree Distances;
@@ -160,5 +160,4 @@ namespace SabreTools.IO.Compression.Deflate
BitLengths = new StaticTree(null, Tree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS);
}
}
}
}

View File

@@ -1,421 +1,428 @@
// Tree.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-October-28 13:29:50>
//
// ------------------------------------------------------------------
//
// This module defines classes for zlib compression and
// decompression. This code is derived from the jzlib implementation of
// zlib. In keeping with the license for jzlib, the copyright to that
// code is below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
sealed class Tree
{
private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
// extra bits for each length code
internal static readonly int[] ExtraLengthBits = new int[]
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
};
// extra bits for each distance code
internal static readonly int[] ExtraDistanceBits = new int[]
{
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
};
// extra bits for each bit length code
internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
// The lengths of the bit length codes are sent in order of decreasing
// probability, to avoid transmitting the lengths for unused bit
// length codes.
internal const int Buf_size = 8 * 2;
// see definition of array dist_code below
//internal const int DIST_CODE_LEN = 512;
private static readonly sbyte[] _dist_code = new sbyte[]
{
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
internal static readonly sbyte[] LengthCode = new sbyte[]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
};
internal static readonly int[] LengthBase = new int[]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28,
32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0
};
internal static readonly int[] DistanceBase = new int[]
{
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
};
/// <summary>
/// Map from a distance to a distance code.
/// </summary>
/// <remarks>
/// No side effects. _dist_code[256] and _dist_code[257] are never used.
/// </remarks>
internal static int DistanceCode(int dist)
{
return (dist < 256)
? _dist_code[dist]
: _dist_code[256 + SharedUtils.URShift(dist, 7)];
}
internal short[] dyn_tree; // the dynamic tree
internal int max_code; // largest code with non zero frequency
internal StaticTree staticTree; // the corresponding static tree
// Compute the optimal bit lengths for a tree and update the total bit length
// for the current block.
// IN assertion: the fields freq and dad are set, heap[heap_max] and
// above are the tree nodes sorted by increasing frequency.
// OUT assertions: the field len is set to the optimal bit length, the
// array bl_count contains the frequencies for each bit length.
// The length opt_len is updated; static_len is also updated if stree is
// not null.
internal void gen_bitlen(DeflateManager s)
{
short[] tree = dyn_tree;
short[] stree = staticTree.treeCodes;
int[] extra = staticTree.extraBits;
int base_Renamed = staticTree.extraBase;
int max_length = staticTree.maxLength;
int h; // heap index
int n, m; // iterate over the tree elements
int bits; // bit length
int xbits; // extra bits
short f; // frequency
int overflow = 0; // number of elements with bit length too large
for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++)
s.bl_count[bits] = 0;
// In a first pass, compute the optimal bit lengths (which may
// overflow in the case of the bit length tree).
tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
for (h = s.heap_max + 1; h < HEAP_SIZE; h++)
{
n = s.heap[h];
bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
if (bits > max_length)
{
bits = max_length; overflow++;
}
tree[n * 2 + 1] = (short) bits;
// We overwrite tree[n*2+1] which is no longer needed
if (n > max_code)
continue; // not a leaf node
s.bl_count[bits]++;
xbits = 0;
if (n >= base_Renamed)
xbits = extra[n - base_Renamed];
f = tree[n * 2];
s.opt_len += f * (bits + xbits);
if (stree != null)
s.static_len += f * (stree[n * 2 + 1] + xbits);
}
if (overflow == 0)
return ;
// This happens for example on obj2 and pic of the Calgary corpus
// Find the first bit length which could increase:
do
{
bits = max_length - 1;
while (s.bl_count[bits] == 0)
bits--;
s.bl_count[bits]--; // move one leaf down the tree
s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother
s.bl_count[max_length]--;
// The brother of the overflow item also moves one step up,
// but this does not affect bl_count[max_length]
overflow -= 2;
}
while (overflow > 0);
for (bits = max_length; bits != 0; bits--)
{
n = s.bl_count[bits];
while (n != 0)
{
m = s.heap[--h];
if (m > max_code)
continue;
if (tree[m * 2 + 1] != bits)
{
s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]);
tree[m * 2 + 1] = (short) bits;
}
n--;
}
}
}
// Construct one Huffman tree and assigns the code bit strings and lengths.
// Update the total bit length for the current block.
// IN assertion: the field freq is set for all tree elements.
// OUT assertions: the fields len and code are set to the optimal bit length
// and corresponding code. The length opt_len is updated; static_len is
// also updated if stree is not null. The field max_code is set.
internal void build_tree(DeflateManager s)
{
short[] tree = dyn_tree;
short[] stree = staticTree.treeCodes;
int elems = staticTree.elems;
int n, m; // iterate over heap elements
int max_code = -1; // largest code with non zero frequency
int node; // new node being created
// Construct the initial heap, with least frequent element in
// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
// heap[0] is not used.
s.heap_len = 0;
s.heap_max = HEAP_SIZE;
for (n = 0; n < elems; n++)
{
if (tree[n * 2] != 0)
{
s.heap[++s.heap_len] = max_code = n;
s.depth[n] = 0;
}
else
{
tree[n * 2 + 1] = 0;
}
}
// The pkzip format requires that at least one distance code exists,
// and that at least one bit should be sent even if there is only one
// possible code. So to avoid special checks later on we force at least
// two codes of non zero frequency.
while (s.heap_len < 2)
{
node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0);
tree[node * 2] = 1;
s.depth[node] = 0;
s.opt_len--;
if (stree != null)
s.static_len -= stree[node * 2 + 1];
// node is 0 or 1 so it does not have extra bits
}
this.max_code = max_code;
// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
// establish sub-heaps of increasing lengths:
for (n = s.heap_len / 2; n >= 1; n--)
s.pqdownheap(tree, n);
// Construct the Huffman tree by repeatedly combining the least two
// frequent nodes.
node = elems; // next internal node of the tree
do
{
// n = node of least frequency
n = s.heap[1];
s.heap[1] = s.heap[s.heap_len--];
s.pqdownheap(tree, 1);
m = s.heap[1]; // m = node of next least frequency
s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
s.heap[--s.heap_max] = m;
// Create a new node father of n and m
tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2]));
s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1);
tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node;
// and insert the new node in the heap
s.heap[1] = node++;
s.pqdownheap(tree, 1);
}
while (s.heap_len >= 2);
s.heap[--s.heap_max] = s.heap[1];
// At this point, the fields freq and dad are set. We can now
// generate the bit lengths.
gen_bitlen(s);
// The field len is now set, we can generate the bit codes
gen_codes(tree, max_code, s.bl_count);
}
// Generate the codes for a given tree and bit counts (which need not be
// optimal).
// IN assertion: the array bl_count contains the bit length statistics for
// the given tree and the field len is set for all tree elements.
// OUT assertion: the field code is set for all tree elements of non
// zero code length.
internal static void gen_codes(short[] tree, int max_code, short[] bl_count)
{
short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length
short code = 0; // running code value
int bits; // bit index
int n; // code index
// The distribution counts are first used to generate the code values
// without bit reversal.
for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++)
unchecked {
next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1);
}
// Check that the bit counts in bl_count are consistent. The last code
// must be all ones.
//Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
// "inconsistent bit counts");
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
for (n = 0; n <= max_code; n++)
{
int len = tree[n * 2 + 1];
if (len == 0)
continue;
// Now reverse the bits
tree[n * 2] = unchecked((short) (bi_reverse(next_code[len]++, len)));
}
}
// Reverse the first len bits of a code, using straightforward code (a faster
// method would use a table)
// IN assertion: 1 <= len <= 15
internal static int bi_reverse(int code, int len)
{
int res = 0;
do
{
res |= code & 1;
code >>= 1; //SharedUtils.URShift(code, 1);
res <<= 1;
}
while (--len > 0);
return res >> 1;
}
}
}
// Tree.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-October-28 13:29:50>
//
// ------------------------------------------------------------------
//
// This module defines classes for zlib compression and
// decompression. This code is derived from the jzlib implementation of
// zlib. In keeping with the license for jzlib, the copyright to that
// code is below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
#nullable disable
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0004
#pragma warning disable IDE0040
#pragma warning disable IDE0047
#pragma warning disable IDE0048
#pragma warning disable IDE2000
#pragma warning disable IDE2003
sealed class Tree
{
private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
// extra bits for each length code
internal static readonly int[] ExtraLengthBits =
[
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
];
// extra bits for each distance code
internal static readonly int[] ExtraDistanceBits =
[
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
];
// extra bits for each bit length code
internal static readonly int[] extra_blbits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7];
internal static readonly sbyte[] bl_order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
// The lengths of the bit length codes are sent in order of decreasing
// probability, to avoid transmitting the lengths for unused bit
// length codes.
internal const int Buf_size = 8 * 2;
// see definition of array dist_code below
//internal const int DIST_CODE_LEN = 512;
private static readonly sbyte[] _dist_code =
[
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
];
internal static readonly sbyte[] LengthCode =
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
];
internal static readonly int[] LengthBase =
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28,
32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0
];
internal static readonly int[] DistanceBase =
[
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
];
/// <summary>
/// Map from a distance to a distance code.
/// </summary>
/// <remarks>
/// No side effects. _dist_code[256] and _dist_code[257] are never used.
/// </remarks>
internal static int DistanceCode(int dist)
{
return (dist < 256)
? _dist_code[dist]
: _dist_code[256 + SharedUtils.URShift(dist, 7)];
}
internal short[] dyn_tree; // the dynamic tree
internal int max_code; // largest code with non zero frequency
internal StaticTree staticTree; // the corresponding static tree
// Compute the optimal bit lengths for a tree and update the total bit length
// for the current block.
// IN assertion: the fields freq and dad are set, heap[heap_max] and
// above are the tree nodes sorted by increasing frequency.
// OUT assertions: the field len is set to the optimal bit length, the
// array bl_count contains the frequencies for each bit length.
// The length opt_len is updated; static_len is also updated if stree is
// not null.
internal void gen_bitlen(DeflateManager s)
{
short[] tree = dyn_tree;
short[] stree = staticTree.treeCodes;
int[] extra = staticTree.extraBits;
int base_Renamed = staticTree.extraBase;
int max_length = staticTree.maxLength;
int h; // heap index
int n, m; // iterate over the tree elements
int bits; // bit length
int xbits; // extra bits
short f; // frequency
int overflow = 0; // number of elements with bit length too large
for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++)
s.bl_count[bits] = 0;
// In a first pass, compute the optimal bit lengths (which may
// overflow in the case of the bit length tree).
tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
for (h = s.heap_max + 1; h < HEAP_SIZE; h++)
{
n = s.heap[h];
bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
if (bits > max_length)
{
bits = max_length; overflow++;
}
tree[n * 2 + 1] = (short)bits;
// We overwrite tree[n*2+1] which is no longer needed
if (n > max_code)
continue; // not a leaf node
s.bl_count[bits]++;
xbits = 0;
if (n >= base_Renamed)
xbits = extra[n - base_Renamed];
f = tree[n * 2];
s.opt_len += f * (bits + xbits);
if (stree is not null)
s.static_len += f * (stree[n * 2 + 1] + xbits);
}
if (overflow == 0)
return;
// This happens for example on obj2 and pic of the Calgary corpus
// Find the first bit length which could increase:
do
{
bits = max_length - 1;
while (s.bl_count[bits] == 0)
bits--;
s.bl_count[bits]--; // move one leaf down the tree
s.bl_count[bits + 1] = (short)(s.bl_count[bits + 1] + 2); // move one overflow item as its brother
s.bl_count[max_length]--;
// The brother of the overflow item also moves one step up,
// but this does not affect bl_count[max_length]
overflow -= 2;
}
while (overflow > 0);
for (bits = max_length; bits != 0; bits--)
{
n = s.bl_count[bits];
while (n != 0)
{
m = s.heap[--h];
if (m > max_code)
continue;
if (tree[m * 2 + 1] != bits)
{
s.opt_len = (int)(s.opt_len + ((long)bits - (long)tree[m * 2 + 1]) * (long)tree[m * 2]);
tree[m * 2 + 1] = (short)bits;
}
n--;
}
}
}
// Construct one Huffman tree and assigns the code bit strings and lengths.
// Update the total bit length for the current block.
// IN assertion: the field freq is set for all tree elements.
// OUT assertions: the fields len and code are set to the optimal bit length
// and corresponding code. The length opt_len is updated; static_len is
// also updated if stree is not null. The field max_code is set.
internal void build_tree(DeflateManager s)
{
short[] tree = dyn_tree;
short[] stree = staticTree.treeCodes;
int elems = staticTree.elems;
int n, m; // iterate over heap elements
int max_code = -1; // largest code with non zero frequency
int node; // new node being created
// Construct the initial heap, with least frequent element in
// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
// heap[0] is not used.
s.heap_len = 0;
s.heap_max = HEAP_SIZE;
for (n = 0; n < elems; n++)
{
if (tree[n * 2] != 0)
{
s.heap[++s.heap_len] = max_code = n;
s.depth[n] = 0;
}
else
{
tree[n * 2 + 1] = 0;
}
}
// The pkzip format requires that at least one distance code exists,
// and that at least one bit should be sent even if there is only one
// possible code. So to avoid special checks later on we force at least
// two codes of non zero frequency.
while (s.heap_len < 2)
{
node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
tree[node * 2] = 1;
s.depth[node] = 0;
s.opt_len--;
if (stree is not null)
s.static_len -= stree[node * 2 + 1];
// node is 0 or 1 so it does not have extra bits
}
this.max_code = max_code;
// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
// establish sub-heaps of increasing lengths:
for (n = s.heap_len / 2; n >= 1; n--)
s.pqdownheap(tree, n);
// Construct the Huffman tree by repeatedly combining the least two
// frequent nodes.
node = elems; // next internal node of the tree
do
{
// n = node of least frequency
n = s.heap[1];
s.heap[1] = s.heap[s.heap_len--];
s.pqdownheap(tree, 1);
m = s.heap[1]; // m = node of next least frequency
s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
s.heap[--s.heap_max] = m;
// Create a new node father of n and m
tree[node * 2] = unchecked((short)(tree[n * 2] + tree[m * 2]));
s.depth[node] = (sbyte)(System.Math.Max((byte)s.depth[n], (byte)s.depth[m]) + 1);
tree[n * 2 + 1] = tree[m * 2 + 1] = (short)node;
// and insert the new node in the heap
s.heap[1] = node++;
s.pqdownheap(tree, 1);
}
while (s.heap_len >= 2);
s.heap[--s.heap_max] = s.heap[1];
// At this point, the fields freq and dad are set. We can now
// generate the bit lengths.
gen_bitlen(s);
// The field len is now set, we can generate the bit codes
gen_codes(tree, max_code, s.bl_count);
}
// Generate the codes for a given tree and bit counts (which need not be
// optimal).
// IN assertion: the array bl_count contains the bit length statistics for
// the given tree and the field len is set for all tree elements.
// OUT assertion: the field code is set for all tree elements of non
// zero code length.
internal static void gen_codes(short[] tree, int max_code, short[] bl_count)
{
short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length
short code = 0; // running code value
int bits; // bit index
int n; // code index
// The distribution counts are first used to generate the code values
// without bit reversal.
for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++)
unchecked
{
next_code[bits] = code = (short)((code + bl_count[bits - 1]) << 1);
}
// Check that the bit counts in bl_count are consistent. The last code
// must be all ones.
//Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
// "inconsistent bit counts");
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
for (n = 0; n <= max_code; n++)
{
int len = tree[n * 2 + 1];
if (len == 0)
continue;
// Now reverse the bits
tree[n * 2] = unchecked((short)(bi_reverse(next_code[len]++, len)));
}
}
// Reverse the first len bits of a code, using straightforward code (a faster
// method would use a table)
// IN assertion: 1 <= len <= 15
internal static int bi_reverse(int code, int len)
{
int res = 0;
do
{
res |= code & 1;
code >>= 1; //SharedUtils.URShift(code, 1);
res <<= 1;
}
while (--len > 0);
return res >> 1;
}
}
}

View File

@@ -28,6 +28,10 @@
#pragma warning disable CS0649
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0001
#pragma warning disable IDE0048
#pragma warning disable IDE2000
#pragma warning disable IDE2002
internal class WorkItem
{
public byte[] buffer;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +1,126 @@
// ZlibConstants.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-November-03 18:50:19>
//
// ------------------------------------------------------------------
//
// This module defines constants used by the zlib class library. This
// code is derived from the jzlib implementation of zlib, but
// significantly modified. In keeping with the license for jzlib, the
// copyright to that code is included here.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
namespace SabreTools.IO.Compression.Deflate
{
/// <summary>
/// A bunch of constants used in the Zlib interface.
/// </summary>
public static class ZlibConstants
{
/// <summary>
/// The maximum number of window bits for the Deflate algorithm.
/// </summary>
public const int WindowBitsMax = 15; // 32K LZ77 window
/// <summary>
/// The default number of window bits for the Deflate algorithm.
/// </summary>
public const int WindowBitsDefault = WindowBitsMax;
/// <summary>
/// indicates everything is A-OK
/// </summary>
public const int Z_OK = 0;
/// <summary>
/// Indicates that the last operation reached the end of the stream.
/// </summary>
public const int Z_STREAM_END = 1;
/// <summary>
/// The operation ended in need of a dictionary.
/// </summary>
public const int Z_NEED_DICT = 2;
/// <summary>
/// There was an error with the stream - not enough data, not open and readable, etc.
/// </summary>
public const int Z_STREAM_ERROR = -2;
/// <summary>
/// There was an error with the data - not enough data, bad data, etc.
/// </summary>
public const int Z_DATA_ERROR = -3;
/// <summary>
/// There was an error with the working buffer.
/// </summary>
public const int Z_BUF_ERROR = -5;
/// <summary>
/// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
/// </summary>
#if NETCF
public const int WorkingBufferSizeDefault = 8192;
#else
public const int WorkingBufferSizeDefault = 16384;
#endif
/// <summary>
/// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes.
/// </summary>
public const int WorkingBufferSizeMin = 1024;
}
}
// ZlibConstants.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-November-03 18:50:19>
//
// ------------------------------------------------------------------
//
// This module defines constants used by the zlib class library. This
// code is derived from the jzlib implementation of zlib, but
// significantly modified. In keeping with the license for jzlib, the
// copyright to that code is included here.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE2002
/// <summary>
/// A bunch of constants used in the Zlib interface.
/// </summary>
public static class ZlibConstants
{
/// <summary>
/// The maximum number of window bits for the Deflate algorithm.
/// </summary>
public const int WindowBitsMax = 15; // 32K LZ77 window
/// <summary>
/// The default number of window bits for the Deflate algorithm.
/// </summary>
public const int WindowBitsDefault = WindowBitsMax;
/// <summary>
/// indicates everything is A-OK
/// </summary>
public const int Z_OK = 0;
/// <summary>
/// Indicates that the last operation reached the end of the stream.
/// </summary>
public const int Z_STREAM_END = 1;
/// <summary>
/// The operation ended in need of a dictionary.
/// </summary>
public const int Z_NEED_DICT = 2;
/// <summary>
/// There was an error with the stream - not enough data, not open and readable, etc.
/// </summary>
public const int Z_STREAM_ERROR = -2;
/// <summary>
/// There was an error with the data - not enough data, bad data, etc.
/// </summary>
public const int Z_DATA_ERROR = -3;
/// <summary>
/// There was an error with the working buffer.
/// </summary>
public const int Z_BUF_ERROR = -5;
/// <summary>
/// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
/// </summary>
#if NETCF
public const int WorkingBufferSizeDefault = 8192;
#else
public const int WorkingBufferSizeDefault = 16384;
#endif
/// <summary>
/// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes.
/// </summary>
public const int WorkingBufferSizeMin = 1024;
}
}

View File

@@ -86,12 +86,13 @@
//
// -----------------------------------------------------------------------
using Interop = System.Runtime.InteropServices;
namespace SabreTools.IO.Compression.Deflate
{
#pragma warning disable IDE0001
#pragma warning disable IDE0049
#pragma warning disable IDE2002
/// <summary>
/// A general purpose exception class for exceptions in the Zlib library.
/// </summary>
@@ -117,4 +118,4 @@ namespace SabreTools.IO.Compression.Deflate
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -55,4 +55,4 @@ namespace SabreTools.IO.Compression.LZX
/// <remarks>Variable</remarks>
public byte[]? TokenSequence { get; set; }
}
}
}

View File

@@ -21,4 +21,4 @@ namespace SabreTools.IO.Compression.LZX
/// </summary>
public BlockData? BlockData { get; set; }
}
}
}

View File

@@ -5,4 +5,4 @@ namespace SabreTools.IO.Compression.LZX
{
// No common fields between all block data
}
}
}

View File

@@ -30,4 +30,4 @@ namespace SabreTools.IO.Compression.LZX
/// <remarks>8 bits</remarks>
public byte BlocksizeLSB { get; set; }
}
}
}

View File

@@ -22,4 +22,4 @@ namespace SabreTools.IO.Compression.LZX
/// </summary>
public Block[]? Blocks { get; set; }
}
}
}

View File

@@ -43,4 +43,4 @@ namespace SabreTools.IO.Compression.LZX
/// </summary>
public ushort? TranslationSizeLowWord { get; set; }
}
}
}

View File

@@ -26,7 +26,7 @@ namespace SabreTools.IO.Compression.LZX
/* LZX huffman defines: tweak tablebits as desired */
public const int LZX_PRETREE_MAXSYMBOLS = LZX_PRETREE_NUM_ELEMENTS;
public const int LZX_PRETREE_TABLEBITS = 6;
public const int LZX_MAINTREE_MAXSYMBOLS = LZX_NUM_CHARS + 50 * 8;
public const int LZX_MAINTREE_MAXSYMBOLS = (LZX_NUM_CHARS + 50) * 8;
public const int LZX_MAINTREE_TABLEBITS = 12;
public const int LZX_LENGTH_MAXSYMBOLS = LZX_NUM_SECONDARY_LENGTHS + 1;
public const int LZX_LENGTH_TABLEBITS = 12;
@@ -35,4 +35,4 @@ namespace SabreTools.IO.Compression.LZX
public const int LZX_LENTABLE_SAFETY = 64; /* we allow length table decoding overruns */
}
}
}

View File

@@ -6,10 +6,10 @@ namespace SabreTools.IO.Compression.LZX
/// begins. Following the zero padding, new 32-bit values for R0, R1, and R2 are output in little-endian
/// form, followed by the uncompressed data bytes themselves. Finally, if the uncompressed data length
/// is odd, one extra byte of zero padding is encoded to realign the following bitstream.
///
///
/// Then the bitstream of byte-swapped 16-bit integers resumes for the next Block Type field (if there
/// are subsequent blocks).
///
///
/// The decoded R0, R1, and R2 values are used as initial repeated offset values to decode the
/// subsequent compressed block if present.
/// </summary>
@@ -51,4 +51,4 @@ namespace SabreTools.IO.Compression.LZX
/// </summary>
public byte AlignmentByte { get; set; }
}
}
}

View File

@@ -48,4 +48,4 @@ namespace SabreTools.IO.Compression.LZX
/// <remarks>Variable</remarks>
public byte[]? TokenSequence { get; set; }
}
}
}

View File

@@ -4,7 +4,7 @@ namespace SabreTools.IO.Compression.MSZIP
/// Each MSZIP block MUST consist of a 2-byte MSZIP signature and one or more RFC 1951 blocks. The
/// 2-byte MSZIP signature MUST consist of the bytes 0x43 and 0x4B. The MSZIP signature MUST be
/// the first 2 bytes in the MSZIP block. The MSZIP signature is shown in the following packet diagram.
///
///
/// Each MSZIP block is the result of a single deflate compression operation, as defined in [RFC1951].
/// The compressor that performs the compression operation MUST generate one or more RFC 1951
/// blocks, as defined in [RFC1951]. The number, deflation mode, and type of RFC 1951 blocks in each
@@ -12,7 +12,7 @@ namespace SabreTools.IO.Compression.MSZIP
/// each MSZIP block MUST be marked as the "end" of the stream(1), as defined by [RFC1951]
/// section 3.2.3. Decoding trees MUST be discarded after each RFC 1951 block, but the history buffer
/// MUST be maintained.Each MSZIP block MUST represent no more than 32 KB of uncompressed data.
///
///
/// The maximum compressed size of each MSZIP block is 32 KB + 12 bytes. This enables the MSZIP
/// block to contain 32 KB of data split between two noncompressed RFC 1951 blocks, each of which
/// has a value of BTYPE = 00.
@@ -25,4 +25,4 @@ namespace SabreTools.IO.Compression.MSZIP
/// </summary>
public ushort Signature { get; set; }
}
}
}

View File

@@ -4,7 +4,7 @@ using SabreTools.IO.Extensions;
namespace SabreTools.IO.Compression.MSZIP
{
/// <see href="https://msopenspecs.azureedge.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
/// <see href="https://officeprotocoldoc.z19.web.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
public class Decompressor
{
/// <summary>
@@ -12,6 +12,11 @@ namespace SabreTools.IO.Compression.MSZIP
/// </summary>
private byte[]? _history = null;
/// <summary>
/// Required output buffer size (32KiB)
/// </summary>
private const int _bufferSize = 0x8000;
#region Constructors
/// <summary>
@@ -51,20 +56,20 @@ namespace SabreTools.IO.Compression.MSZIP
if (header.Signature != 0x4B43)
throw new InvalidDataException(nameof(source));
byte[] buffer = new byte[32 * 1024];
byte[] buffer = new byte[_bufferSize];
var blockStream = new Deflate.DeflateStream(source, Deflate.CompressionMode.Decompress, leaveOpen: true);
if (_history != null)
if (_history is not null)
blockStream.SetDictionary(_history, check: false);
int read = blockStream.Read(buffer, 0, buffer.Length);
int read = blockStream.Read(buffer, 0, _bufferSize);
if (read > 0)
{
// Write to output
dest.Write(buffer, 0, read);
dest.Write(buffer, 0, _bufferSize);
// Save the history for rollover
_history = new byte[read];
Array.Copy(buffer, _history, read);
_history = new byte[_bufferSize];
Array.Copy(buffer, _history, _bufferSize);
}
// Flush and return

View File

@@ -47,4 +47,4 @@ namespace SabreTools.IO.Compression.Quantum
20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42
];
}
}
}

View File

@@ -6,7 +6,7 @@ using static SabreTools.IO.Compression.Quantum.Constants;
namespace SabreTools.IO.Compression.Quantum
{
/// <see href="www.russotto.net/quantumcomp.html"/>
/// <see href="www.russotto.net/quantumcomp.html"/>
public class Decompressor
{
/// <summary>
@@ -283,9 +283,9 @@ namespace SabreTools.IO.Compression.Quantum
/// </summary>
private void GetCode(int prevFrequency, int currentFrequency, int totalFrequency)
{
uint range = (ushort)((CS_H - CS_L) + 1);
CS_H = (ushort)(CS_L + (prevFrequency * range) / totalFrequency - 1);
CS_L = (ushort)(CS_L + (currentFrequency * range) / totalFrequency);
uint range = (ushort)(CS_H - CS_L + 1);
CS_H = (ushort)(CS_L + (prevFrequency * range / totalFrequency) - 1);
CS_L = (ushort)(CS_L + (currentFrequency * range / totalFrequency));
while (true)
{
@@ -306,7 +306,7 @@ namespace SabreTools.IO.Compression.Quantum
CS_L <<= 1;
CS_H = (ushort)((CS_H << 1) | 1);
CS_C = (ushort)((CS_C << 1) | _bitStream.ReadBit() ?? 0);
CS_C = (ushort)((CS_C << 1) | (_bitStream.ReadBit() ?? 0));
}
}
@@ -362,9 +362,13 @@ namespace SabreTools.IO.Compression.Quantum
{
if (model.Symbols![i]!.CumulativeFrequency < model.Symbols![j]!.CumulativeFrequency)
{
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
(model.Symbols[j], model.Symbols[i]) = (model.Symbols[i], model.Symbols[j]);
#else
var temp = model.Symbols[i];
model.Symbols[i] = model.Symbols[j];
model.Symbols[j] = temp;
#endif
}
}
}

View File

@@ -42,4 +42,4 @@ namespace SabreTools.IO.Compression.Quantum
/// </summary>
SELECTOR_6_LENGTH = 7,
}
}
}

View File

@@ -21,4 +21,4 @@ namespace SabreTools.IO.Compression.Quantum
/// <remarks>The initial time_to_reorder value is 4</remarks>
public int TimeToReorder { get; set; }
}
}
}

View File

@@ -12,4 +12,4 @@ namespace SabreTools.IO.Compression.Quantum
/// </summary>
public ushort CumulativeFrequency { get; set; }
}
}
}

View File

@@ -96,7 +96,7 @@ namespace SabreTools.IO.Compression.SZDD
/// </summary>
public static Decompressor CreateSZDD(Stream source)
{
// Create the decompressor
// Create the decompressors
var decompressor = new Decompressor(source);
// Set the format and return
@@ -143,7 +143,7 @@ namespace SabreTools.IO.Compression.SZDD
{
// Get the control byte
byte? control = _source.ReadNextByte();
if (control == null)
if (control is null)
break;
for (int cbit = 0x01; (cbit & 0xFF) != 0; cbit <<= 1)
@@ -153,7 +153,7 @@ namespace SabreTools.IO.Compression.SZDD
{
// Read the literal byte
byte? literal = _source.ReadNextByte();
if (literal == null)
if (literal is null)
break;
// Store the data in the window and write
@@ -168,12 +168,12 @@ namespace SabreTools.IO.Compression.SZDD
// Read the match position
int? matchpos = _source.ReadNextByte();
if (matchpos == null)
if (matchpos is null)
break;
// Read the match length
int? matchlen = _source.ReadNextByte();
if (matchlen == null)
if (matchlen is null)
break;
// Adjust the position and length
@@ -213,7 +213,7 @@ namespace SabreTools.IO.Compression.SZDD
{
// Read the next byte
byte? next = _source.ReadNextByte();
if (next == null)
if (next is null)
break;
// XOR with 0xFF if required

View File

@@ -23,7 +23,7 @@ namespace SabreTools.IO.Compression.zlib
public static void free(void* a)
{
if (a == null)
if (a is null)
return;
var ptr = new IntPtr(a);
@@ -57,7 +57,7 @@ namespace SabreTools.IO.Compression.zlib
finally
{
if (temp != null)
if (temp is not null)
free(temp);
}
}
@@ -117,7 +117,7 @@ namespace SabreTools.IO.Compression.zlib
public static void* realloc(void* a, long newSize)
{
if (a == null)
if (a is null)
return malloc(newSize);
var ptr = new IntPtr(a);
@@ -207,7 +207,7 @@ namespace SabreTools.IO.Compression.zlib
--length;
}
if (end != null)
if (end is not null)
{
*end = ptr;
}
@@ -215,4 +215,4 @@ namespace SabreTools.IO.Compression.zlib
return result;
}
}
}
}

View File

@@ -1,28 +1,29 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading;
namespace SabreTools.IO.Compression.zlib
{
public unsafe static class MemoryStats
{
private static int _allocations;
public static int Allocations
{
get
{
return _allocations;
}
}
#pragma warning disable IDE0036
#pragma warning disable IDE0380
public unsafe static class MemoryStats
{
private static int _allocations;
internal static void Allocated()
{
Interlocked.Increment(ref _allocations);
}
public static int Allocations
{
get
{
return _allocations;
}
}
internal static void Freed()
{
Interlocked.Decrement(ref _allocations);
}
}
}
internal static void Allocated()
{
Interlocked.Increment(ref _allocations);
}
internal static void Freed()
{
Interlocked.Decrement(ref _allocations);
}
}
}

View File

@@ -3,86 +3,86 @@ using System.Runtime.InteropServices;
namespace SabreTools.IO.Compression.zlib
{
public unsafe class UnsafeArray1D<T> where T : struct
{
private readonly T[] _data;
private readonly GCHandle _pinHandle;
public bool IsFreed { get; private set; }
public unsafe class UnsafeArray1D<T> where T : struct
{
private readonly T[] _data;
private readonly GCHandle _pinHandle;
public bool IsFreed { get; private set; }
internal GCHandle PinHandle => _pinHandle;
internal GCHandle PinHandle => _pinHandle;
public T this[int index]
{
get => _data[index];
set
{
_data[index] = value;
}
}
public T this[int index]
{
get => _data[index];
set
{
_data[index] = value;
}
}
public T this[uint index]
{
get => _data[index];
set
{
_data[index] = value;
}
}
public T this[uint index]
{
get => _data[index];
set
{
_data[index] = value;
}
}
public T[] Data => _data;
public T[] Data => _data;
public UnsafeArray1D(int size)
{
if (size < 0)
{
throw new ArgumentOutOfRangeException(nameof(size));
}
public UnsafeArray1D(int size)
{
if (size < 0)
{
throw new ArgumentOutOfRangeException(nameof(size));
}
_data = new T[size];
_pinHandle = GCHandle.Alloc(_data, GCHandleType.Pinned);
IsFreed = false;
}
_data = new T[size];
_pinHandle = GCHandle.Alloc(_data, GCHandleType.Pinned);
IsFreed = false;
}
public UnsafeArray1D(T[] data, int sizeOf)
{
if (sizeOf <= 0)
{
throw new ArgumentOutOfRangeException(nameof(sizeOf));
}
public UnsafeArray1D(T[] data, int sizeOf)
{
if (sizeOf <= 0)
{
throw new ArgumentOutOfRangeException(nameof(sizeOf));
}
_data = data ?? throw new ArgumentNullException(nameof(data));
_pinHandle = GCHandle.Alloc(_data, GCHandleType.Pinned);
IsFreed = false;
}
_data = data ?? throw new ArgumentNullException(nameof(data));
_pinHandle = GCHandle.Alloc(_data, GCHandleType.Pinned);
IsFreed = false;
}
public void Free()
{
if (!IsFreed)
{
_pinHandle.Free();
IsFreed = true;
}
}
public void Free()
{
if (!IsFreed)
{
_pinHandle.Free();
IsFreed = true;
}
}
~UnsafeArray1D()
{
if (!IsFreed)
_pinHandle.Free();
}
~UnsafeArray1D()
{
if (!IsFreed)
_pinHandle.Free();
}
public void* ToPointer()
{
return _pinHandle.AddrOfPinnedObject().ToPointer();
}
public void* ToPointer()
{
return _pinHandle.AddrOfPinnedObject().ToPointer();
}
public static implicit operator void*(UnsafeArray1D<T> array)
{
return array.ToPointer();
}
public static implicit operator void*(UnsafeArray1D<T> array)
{
return array.ToPointer();
}
public static void* operator +(UnsafeArray1D<T> array, int delta)
{
return array.ToPointer();
}
}
}
public static void* operator +(UnsafeArray1D<T> array, int delta)
{
return array.ToPointer();
}
}
}

View File

@@ -2,44 +2,45 @@
namespace SabreTools.IO.Compression.zlib
{
public unsafe class UnsafeArray2D<T> where T : struct
{
private readonly UnsafeArray1D<T>[] _data;
private long[] _pinAddresses;
private readonly GCHandle _pinAddressesHandle;
#pragma warning disable IDE0044
public unsafe class UnsafeArray2D<T> where T : struct
{
private readonly UnsafeArray1D<T>[] _data;
private long[] _pinAddresses;
private readonly GCHandle _pinAddressesHandle;
public UnsafeArray1D<T> this[int index]
{
get => _data[index];
set
{
_data[index] = value;
}
}
public UnsafeArray1D<T> this[int index]
{
get => _data[index];
set
{
_data[index] = value;
}
}
public UnsafeArray2D(int size1, int size2)
{
_data = new UnsafeArray1D<T>[size1];
_pinAddresses = new long[size1];
for (var i = 0; i < size1; ++i)
{
_data[i] = new UnsafeArray1D<T>(size2);
_pinAddresses[i] = _data[i].PinHandle.AddrOfPinnedObject().ToInt64();
}
public UnsafeArray2D(int size1, int size2)
{
_data = new UnsafeArray1D<T>[size1];
_pinAddresses = new long[size1];
for (var i = 0; i < size1; ++i)
{
_data[i] = new UnsafeArray1D<T>(size2);
_pinAddresses[i] = _data[i].PinHandle.AddrOfPinnedObject().ToInt64();
}
_pinAddressesHandle = GCHandle.Alloc(_pinAddresses, GCHandleType.Pinned);
}
_pinAddressesHandle = GCHandle.Alloc(_pinAddresses, GCHandleType.Pinned);
}
~UnsafeArray2D()
{
_pinAddressesHandle.Free();
}
~UnsafeArray2D()
{
_pinAddressesHandle.Free();
}
public void* ToPointer() => _pinAddressesHandle.AddrOfPinnedObject().ToPointer();
public void* ToPointer() => _pinAddressesHandle.AddrOfPinnedObject().ToPointer();
public static implicit operator void*(UnsafeArray2D<T> array)
{
return array.ToPointer();
}
}
}
public static implicit operator void*(UnsafeArray2D<T> array)
{
return array.ToPointer();
}
}
}

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace SabreTools.IO.Compression.zlib
{
#pragma warning disable IDE0036
#pragma warning disable IDE0380
#pragma warning disable IDE2002
#pragma warning disable IDE2003
public class ZlibDeflateStream : Stream
{
private readonly bool _leaveOpen;
@@ -73,14 +74,14 @@ namespace SabreTools.IO.Compression.zlib
unsafe public override void Write(byte[] buffer, int offset, int count)
{
if (buffer == null) throw new ArgumentNullException();
if (buffer is null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset + count) > buffer.Length) throw new ArgumentException();
int err = 0;
int hdr = 0;
if (_s == null)
if (_s is null)
{
_s = new ZLib.z_stream_s();
ZLib.deflateInit_(_s, this.Level, this.Version, 0); //0 = sizeof(z_stream_s) not used
@@ -134,7 +135,7 @@ namespace SabreTools.IO.Compression.zlib
unsafe public long BlockFlush()
{
//finish previous stream
if (_s != null)
if (_s is not null)
{
int err = 0;
fixed (byte* o = _b)

View File

@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace SabreTools.IO.Compression.zlib
{
#pragma warning disable IDE0004
#pragma warning disable IDE0036
#pragma warning disable IDE0047
#pragma warning disable IDE2003
public class ZlibInflateStream : Stream
{
private readonly bool _leaveOpen;
@@ -80,7 +80,7 @@ namespace SabreTools.IO.Compression.zlib
unsafe public override int Read(byte[] buffer, int offset, int count)
{
if (buffer == null) throw new ArgumentNullException();
if (buffer is null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset + count) > buffer.Length) throw new ArgumentException();
if (_complete)
@@ -88,7 +88,7 @@ namespace SabreTools.IO.Compression.zlib
int err = 0;
int hdr = 0;
if (_s == null)
if (_s is null)
{
_s = new ZLib.z_stream_s();
ZLib.inflateInit_(_s, this.Version, 0); //0 = sizeof(z_stream_s) not used
@@ -147,7 +147,7 @@ namespace SabreTools.IO.Compression.zlib
public long BlockFlush(int maxRead)
{
this.MaxRead = maxRead;
if (_s != null)
if (_s is not null)
{
ZLib.deflateEnd(_s);
_s = null;

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,6 @@
namespace SabreTools.IO.Compression.zlib
{
#pragma warning disable IDE0047
public static class zlibConst
{
public const int Z_NO_FLUSH = 0;
@@ -44,4 +45,4 @@ namespace SabreTools.IO.Compression.zlib
};
}
}
}
}

View File

@@ -122,4 +122,4 @@ namespace SabreTools.IO.Encryption
progress?.Invoke($"{blockCount + 1} / {blockCount + 1} MB... Done!\r\n");
}
}
}
}

View File

@@ -1,8 +1,10 @@
using System;
using System.IO;
using System.Text;
using SabreTools.Hashing;
using SabreTools.IO.Extensions;
#pragma warning disable IDE0051
namespace SabreTools.IO.Encryption
{
/// <summary>
@@ -12,6 +14,86 @@ namespace SabreTools.IO.Encryption
{
#region Constants
/// <summary>
/// Converts ASCII characters to lowercase
/// </summary>
/// <remarks>Converts slash (0x2F) to backslash (0x5C)</remarks>
private static readonly byte[] AsciiToLowerTable =
[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
];
/// <summary>
/// Converts ASCII characters to uppercase
/// </summary>
/// <remarks>Converts slash (0x2F) to backslash (0x5C)</remarks>
private static readonly byte[] AsciiToUpperTable =
[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
];
/// <summary>
/// Converts ASCII characters to uppercase
/// </summary>
/// <remarks>Does NOT convert slash (0x2F) to backslash (0x5C)</remarks>
private static readonly byte[] AsciiToUpperTable_Slash =
[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
];
private const uint MPQ_HASH_TABLE_INDEX = 0x000;
private const uint MPQ_HASH_NAME_A = 0x100;
private const uint MPQ_HASH_NAME_B = 0x200;
private const uint MPQ_HASH_FILE_KEY = 0x300;
private const uint MPQ_HASH_KEY2_MIX = 0x400;
private const uint STORM_BUFFER_SIZE = 0x500;
@@ -42,13 +124,13 @@ namespace SabreTools.IO.Encryption
{
for (uint index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
{
seed = (seed * 125 + 3) % 0x2AAAAB;
seed = ((seed * 125) + 3) % 0x2AAAAB;
uint temp1 = (seed & 0xFFFF) << 0x10;
seed = (seed * 125 + 3) % 0x2AAAAB;
uint temp2 = (seed & 0xFFFF);
seed = ((seed * 125) + 3) % 0x2AAAAB;
uint temp2 = seed & 0xFFFF;
_stormBuffer[index2] = (temp1 | temp2);
_stormBuffer[index2] = temp1 | temp2;
}
}
}
@@ -118,7 +200,7 @@ namespace SabreTools.IO.Encryption
// Verify the MD5 of the table, if present
byte[]? actualHash = HashTool.GetByteArrayHashArray(readBytes, HashType.MD5);
if (expectedHash != null && actualHash != null && !actualHash.EqualsExactly(expectedHash))
if (expectedHash is not null && actualHash is not null && !actualHash.EqualsExactly(expectedHash))
{
Console.WriteLine("Table is corrupt!");
return null;
@@ -151,7 +233,7 @@ namespace SabreTools.IO.Encryption
/// <summary>
/// Decrypt a single block of data
/// </summary>
public unsafe byte[] DecryptBlock(byte[] block, long length, uint key)
public byte[] DecryptBlock(byte[] block, long length, uint key)
{
uint seed = 0xEEEEEEEE;
@@ -175,5 +257,108 @@ namespace SabreTools.IO.Encryption
Buffer.BlockCopy(castBlock, 0, block, 0, block.Length >> 2);
return block;
}
#region Hashing
//
// Note: Implementation of this function in WorldEdit.exe and storm.dll
// incorrectly treats the character as signed, which leads to the
// a buffer underflow if the character in the file name >= 0x80:
// The following steps happen when *pbKey == 0xBF and hashType == 0x0000
// (calculating hash index)
//
// 1) Result of AsciiToUpperTable_Slash[*pbKey++] is sign-extended to 0xffffffbf
// 2) The "ch" is added to hashType (0xffffffbf + 0x0000 => 0xffffffbf)
// 3) The result is used as index to the StormBuffer table,
// thus dereferences a random value BEFORE the begin of StormBuffer.
//
// As result, MPQs containing files with non-ANSI characters will not work between
// various game versions and localizations. Even WorldEdit, after importing a file
// with Korean characters in the name, cannot open the file back.
//
/// <summary>
/// Hash a string representing a filename based on the hash type
/// using upper-case normalization
/// </summary>
/// <param name="filename">Filename to hash</param>
/// <param name="hashType">Hash type to perform</param>
/// <returns>Value representing the hashed filename</returns>
public uint HashString(string filename, uint hashType)
{
uint seed1 = 0x7FED7FED;
uint seed2 = 0xEEEEEEEE;
byte[] key = Encoding.ASCII.GetBytes(filename);
int keyPtr = 0;
while (key[keyPtr] != 0)
{
// Convert the input character to uppercase
// Convert slash (0x2F) to backslash (0x5C)
byte ch = AsciiToUpperTable[key[keyPtr++]];
seed1 = _stormBuffer[hashType + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
}
return seed1;
}
/// <summary>
/// Hash a string representing a filename based on the hash type
/// using upper-case normalization
/// </summary>
/// <param name="filename">Filename to hash</param>
/// <param name="hashType">Hash type to perform</param>
/// <returns>Value representing the hashed filename</returns>
/// <remarks>This preserves slashes when hashing</remarks>
public uint HashStringSlash(string filename, uint hashType)
{
uint seed1 = 0x7FED7FED;
uint seed2 = 0xEEEEEEEE;
byte[] key = Encoding.ASCII.GetBytes(filename);
int keyPtr = 0;
while (key[keyPtr] != 0)
{
// Convert the input character to uppercase
// DON'T convert slash (0x2F) to backslash (0x5C)
byte ch = AsciiToUpperTable_Slash[key[keyPtr++]];
seed1 = _stormBuffer[hashType + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
}
return seed1;
}
/// <summary>
/// Hash a string representing a filename based on the hash type
/// using lower-case normalization
/// </summary>
/// <param name="filename">Filename to hash</param>
/// <param name="hashType">Hash type to perform</param>
/// <returns>Value representing the hashed filename</returns>
public uint HashStringLower(string filename, uint hashType)
{
uint seed1 = 0x7FED7FED;
uint seed2 = 0xEEEEEEEE;
byte[] key = Encoding.ASCII.GetBytes(filename);
int keyPtr = 0;
while (key[keyPtr] != 0)
{
// Convert the input character to lower
// DON'T convert slash (0x2F) to backslash (0x5C)
byte ch = AsciiToLowerTable[key[keyPtr++]];
seed1 = _stormBuffer[hashType + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
}
return seed1;
}
#endregion
}
}

View File

@@ -3,7 +3,7 @@
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
internal sealed class ExtensionAttribute : Attribute {}
internal sealed class ExtensionAttribute : Attribute { }
}
#endif

View File

@@ -148,9 +148,9 @@ namespace SabreTools.IO.Extensions
public static int ReadInt24BigEndian(this BinaryReader reader)
{
byte[] buffer = reader.ReadBytes(3);
return (int)(buffer[2]
| (buffer[1] << 8)
| (buffer[0] << 16));
return buffer[2]
| (buffer[1] << 8)
| (buffer[0] << 16);
}
/// <summary>
@@ -160,9 +160,9 @@ namespace SabreTools.IO.Extensions
public static int ReadInt24LittleEndian(this BinaryReader reader)
{
byte[] buffer = reader.ReadBytes(3);
return (int)(buffer[0]
| (buffer[1] << 8)
| (buffer[2] << 16));
return buffer[0]
| (buffer[1] << 8)
| (buffer[2] << 16);
}
/// <summary>
@@ -206,10 +206,10 @@ namespace SabreTools.IO.Extensions
public static int ReadInt32BigEndian(this BinaryReader reader)
{
byte[] buffer = reader.ReadBytes(4);
return (int)(buffer[3]
| (buffer[2] << 8)
| (buffer[1] << 16)
| (buffer[0] << 24));
return buffer[3]
| (buffer[2] << 8)
| (buffer[1] << 16)
| (buffer[0] << 24);
}
/// <inheritdoc cref="BinaryReader.ReadInt32"/>
@@ -217,10 +217,10 @@ namespace SabreTools.IO.Extensions
public static int ReadInt32LittleEndian(this BinaryReader reader)
{
byte[] buffer = reader.ReadBytes(4);
return (int)(buffer[0]
| (buffer[1] << 8)
| (buffer[2] << 16)
| (buffer[3] << 24));
return buffer[0]
| (buffer[1] << 8)
| (buffer[2] << 16)
| (buffer[3] << 24);
}
/// <inheritdoc cref="BinaryReader.ReadInt32"/>
@@ -815,7 +815,7 @@ namespace SabreTools.IO.Extensions
{
// Try to create an instance of the type
var instance = Activator.CreateInstance(type);
if (instance == null)
if (instance is null)
return null;
// Get the layout information
@@ -836,7 +836,7 @@ namespace SabreTools.IO.Extensions
if (layoutKind == LayoutKind.Explicit)
{
var fieldOffset = MarshalHelpers.GetAttribute<FieldOffsetAttribute>(fi);
reader.BaseStream.Seek(currentOffset + fieldOffset?.Value ?? 0, SeekOrigin.Begin);
reader.BaseStream.Seek(currentOffset + (fieldOffset?.Value ?? 0), SeekOrigin.Begin);
}
SetField(reader, encoding, fields, instance, fi);
@@ -881,7 +881,7 @@ namespace SabreTools.IO.Extensions
private static Array ReadArrayType(BinaryReader reader, FieldInfo[] fields, object instance, FieldInfo fi)
{
var marshalAsAttr = MarshalHelpers.GetAttribute<MarshalAsAttribute>(fi);
if (marshalAsAttr == null)
if (marshalAsAttr is null)
return new object[0];
// Get the number of elements expected
@@ -897,7 +897,7 @@ namespace SabreTools.IO.Extensions
for (int i = 0; i < elementCount; i++)
{
var value = ReadType(reader, elementType);
if (value != null && elementType.IsEnum)
if (value is not null && elementType.IsEnum)
arr.SetValue(Enum.ToObject(elementType, value), i);
else
arr.SetValue(value, i);
@@ -913,7 +913,7 @@ namespace SabreTools.IO.Extensions
private static string? ReadStringType(BinaryReader reader, Encoding encoding, FieldInfo? fi)
{
// If the FieldInfo is null
if (fi == null)
if (fi is null)
return null;
// Get all MarshalAs attributes for the field, if possible
@@ -923,6 +923,7 @@ namespace SabreTools.IO.Extensions
// Use the first found attribute
var marshalAsAttr = attributes[0] as MarshalAsAttribute;
#pragma warning disable IDE0010
switch (marshalAsAttr?.Value)
{
case UnmanagedType.AnsiBStr:
@@ -954,6 +955,7 @@ namespace SabreTools.IO.Extensions
default:
return null;
}
#pragma warning restore IDE0010
}
/// <summary>

View File

@@ -400,7 +400,7 @@ namespace SabreTools.IO.Extensions
public static bool WriteNullTerminatedString(this BinaryWriter writer, string? value, Encoding encoding)
{
// If the value is null
if (value == null)
if (value is null)
return false;
// Add the null terminator and write
@@ -453,7 +453,7 @@ namespace SabreTools.IO.Extensions
public static bool WritePrefixedAnsiString(this BinaryWriter writer, string? value)
{
// If the value is null
if (value == null)
if (value is null)
return false;
// Get the buffer
@@ -473,7 +473,7 @@ namespace SabreTools.IO.Extensions
public static bool WritePrefixedLatin1String(this BinaryWriter writer, string? value)
{
// If the value is null
if (value == null)
if (value is null)
return false;
// Get the buffer
@@ -493,7 +493,7 @@ namespace SabreTools.IO.Extensions
public static bool WritePrefixedUnicodeString(this BinaryWriter writer, string? value)
{
// If the value is null
if (value == null)
if (value is null)
return false;
// Get the buffer
@@ -512,7 +512,7 @@ namespace SabreTools.IO.Extensions
public static bool WritePrefixedBigEndianUnicodeString(this BinaryWriter writer, string? value)
{
// If the value is null
if (value == null)
if (value is null)
return false;
// Get the buffer
@@ -553,7 +553,7 @@ namespace SabreTools.IO.Extensions
public static bool WriteType(this BinaryWriter writer, object? value, Type type)
{
// Null values cannot be written
if (value == null)
if (value is null)
return true;
// Handle special struct cases
@@ -589,7 +589,7 @@ namespace SabreTools.IO.Extensions
try
{
// Null values cannot be written
if (value == null)
if (value is null)
return true;
int typeSize = Marshal.SizeOf(type);
@@ -617,7 +617,7 @@ namespace SabreTools.IO.Extensions
try
{
// Null values cannot be written
if (value == null)
if (value is null)
return true;
// Get the layout information
@@ -638,7 +638,7 @@ namespace SabreTools.IO.Extensions
if (layoutKind == LayoutKind.Explicit)
{
var fieldOffset = MarshalHelpers.GetAttribute<FieldOffsetAttribute>(fi);
writer.BaseStream.Seek(currentOffset + fieldOffset?.Value ?? 0, SeekOrigin.Begin);
writer.BaseStream.Seek(currentOffset + (fieldOffset?.Value ?? 0), SeekOrigin.Begin);
}
if (!GetField(writer, encoding, fields, value, fi))
@@ -679,12 +679,11 @@ namespace SabreTools.IO.Extensions
private static bool WriteArrayType(BinaryWriter writer, FieldInfo[] fields, object instance, FieldInfo fi)
{
var marshalAsAttr = MarshalHelpers.GetAttribute<MarshalAsAttribute>(fi);
if (marshalAsAttr == null)
if (marshalAsAttr is null)
return false;
// Get the array
Array? arr = fi.GetValue(instance) as Array;
if (arr == null)
if (fi.GetValue(instance) is not Array arr)
return false;
// Get the number of elements expected
@@ -712,10 +711,10 @@ namespace SabreTools.IO.Extensions
private static bool WriteStringType(BinaryWriter writer, Encoding encoding, object instance, FieldInfo fi)
{
var marshalAsAttr = MarshalHelpers.GetAttribute<MarshalAsAttribute>(fi);
string? fieldValue = fi.GetValue(instance) as string;
if (fieldValue == null)
if (fi.GetValue(instance) is not string fieldValue)
return true;
#pragma warning disable IDE0010
switch (marshalAsAttr?.Value)
{
case UnmanagedType.AnsiBStr:
@@ -750,6 +749,7 @@ namespace SabreTools.IO.Extensions
default:
return false;
}
#pragma warning restore IDE0010
}
/// <summary>

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