mirror of
https://github.com/SabreTools/SabreTools.Models.git
synced 2026-02-10 05:54:30 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2749c2f5bd | ||
|
|
41ce962700 | ||
|
|
85b7103bd3 | ||
|
|
4c61a191e8 | ||
|
|
0f70598969 | ||
|
|
d6b057d808 | ||
|
|
3d8036e7b5 | ||
|
|
bb35946866 | ||
|
|
78f9f1b36f | ||
|
|
9d1b1ca36d | ||
|
|
6e1f8bf55e | ||
|
|
a19afc240c | ||
|
|
148e97ef64 | ||
|
|
676b446025 | ||
|
|
aeff75d8d3 | ||
|
|
e20e515f56 |
@@ -1,4 +1,4 @@
|
||||
name: Nuget Pack
|
||||
name: Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -17,24 +17,21 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Pack
|
||||
run: dotnet pack
|
||||
|
||||
- name: Run publish script
|
||||
run: ./publish-nix.sh
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'Nuget Package'
|
||||
path: 'SabreTools.Models/bin/Release/*.nupkg'
|
||||
path: '*.nupkg'
|
||||
|
||||
- name: Upload to rolling
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
with:
|
||||
allowUpdates: True
|
||||
artifacts: 'SabreTools.Models/bin/Release/*.nupkg'
|
||||
artifacts: '*.nupkg'
|
||||
body: 'Last built commit: ${{ github.sha }}'
|
||||
name: 'Rolling Release'
|
||||
prerelease: True
|
||||
@@ -1,9 +1,17 @@
|
||||
# SabreTools.Models
|
||||
|
||||
[](https://github.com/SabreTools/SabreTools.Models/actions/workflows/build_and_test.yml)
|
||||
|
||||
This library comprises of models that represent either directly serializable or representative structures for all SabreTools projects. All of the main models representing metadata files should have parsers created outside of the current code.
|
||||
|
||||
Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTools.Models).
|
||||
|
||||
## Releases
|
||||
|
||||
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/SabreTools.Models/releases)
|
||||
|
||||
For the latest WIP build here: [Rolling Release](https://github.com/SabreTools/SabreTools.Models/releases/rolling)
|
||||
|
||||
## Missing Metadata Models
|
||||
|
||||
The following metadata file formats do not have models included in this library yet and, as such, do not have serializers:
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public class BlockHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Set if and only if this is the last block of the data set.
|
||||
/// </summary>
|
||||
/// <remarks>Bit 0</remarks>
|
||||
public bool BFINAL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how the data are compressed
|
||||
/// </summary>
|
||||
/// <remarks>Bits 1-2</remarks>
|
||||
public CompressionType BTYPE { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <summary>
|
||||
/// Compression with Huffman codes (BTYPE=01 or BTYPE=02)
|
||||
/// </summary>
|
||||
/// <see href="https://interoperability.blob.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public abstract class CompressedDataHeader : DataHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Huffman code lengths for the literal / length alphabet
|
||||
/// </summary>
|
||||
public virtual uint[]? LiteralLengths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Huffman distance codes for the literal / length alphabet
|
||||
/// </summary>
|
||||
public virtual uint[]? DistanceCodes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Bits in base literal/length lookup table
|
||||
/// </summary>
|
||||
public const int ZIPLBITS = 9;
|
||||
|
||||
/// <summary>
|
||||
/// Bits in base distance lookup table
|
||||
/// </summary>
|
||||
public const int ZIPDBITS = 6;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum bit length of any code
|
||||
/// </summary>
|
||||
public const int ZIPBMAX = 16;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of codes in any set
|
||||
/// </summary>
|
||||
public const int ZIPN_MAX = 288;
|
||||
|
||||
#region Fixed Huffman Codes
|
||||
|
||||
/// <summary>
|
||||
/// Fixed Huffman code lengths for the literal / length alphabet
|
||||
/// </summary>
|
||||
public static readonly uint[] FixedLiteralLengths =
|
||||
[
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Fixed Huffman distance codes for the literal / length alphabet
|
||||
/// </summary>
|
||||
public static readonly uint[] FixedDistanceCodes =
|
||||
[
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5,
|
||||
];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Literal and Length Alphabets
|
||||
|
||||
/// <summary>
|
||||
/// Extra bits for distance codes
|
||||
/// </summary>
|
||||
public static readonly ushort[] DistanceExtraBits =
|
||||
[
|
||||
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
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Copy offsets for distance codes 0..29
|
||||
/// </summary>
|
||||
public static readonly ushort[] DistanceOffsets =
|
||||
[
|
||||
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
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Extra bits for literal codes 257..285
|
||||
/// </summary>
|
||||
public static readonly ushort[] LiteralExtraBits =
|
||||
[
|
||||
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,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Copy lengths for literal codes 257..285
|
||||
/// </summary>
|
||||
public static readonly ushort[] LiteralLengths =
|
||||
[
|
||||
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,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Order of the bit length code lengths
|
||||
/// </summary>
|
||||
public static readonly byte[] BitLengthOrder =
|
||||
[
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
||||
];
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all data headers (BTYPE=00, BTYPE=01, or BTYPE=02)
|
||||
/// </summary>
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public abstract class DataHeader
|
||||
{
|
||||
// No common fields between all data headers
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <summary>
|
||||
/// Compression with dynamic Huffman codes (BTYPE=10)
|
||||
/// </summary>
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public class DynamicCompressedDataHeader : CompressedDataHeader
|
||||
{
|
||||
// Codes are provided externally
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public enum CompressionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// no compression
|
||||
/// </summary>
|
||||
NoCompression = 0b00,
|
||||
|
||||
/// <summary>
|
||||
/// Compressed with fixed Huffman codes
|
||||
/// </summary>
|
||||
FixedHuffman = 0b01,
|
||||
|
||||
/// <summary>
|
||||
/// Compressed with dynamic Huffman codes
|
||||
/// </summary>
|
||||
DynamicHuffman = 0b10,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved (error)
|
||||
/// </summary>
|
||||
Reserved = 0b11,
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <summary>
|
||||
/// Compression with fixed Huffman codes (BTYPE=01)
|
||||
/// </summary>
|
||||
/// <see href="https://interoperability.blob.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public class FixedCompressedDataHeader : CompressedDataHeader
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Huffman code lengths for the literal / length alphabet
|
||||
/// </summary>
|
||||
public override uint[]? LiteralLengths => Constants.FixedLiteralLengths;
|
||||
|
||||
/// <summary>
|
||||
/// Huffman distance codes for the literal / length alphabet
|
||||
/// </summary>
|
||||
public override uint[]? DistanceCodes => Constants.FixedDistanceCodes;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.Deflate
|
||||
{
|
||||
/// <summary>
|
||||
/// Non-compressed blocks (BTYPE=00)
|
||||
/// </summary>
|
||||
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
|
||||
public class NonCompressedBlockHeader : DataHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of data bytes in the block
|
||||
/// </summary>
|
||||
/// <remarks>Bytes 0-1</remarks>
|
||||
public ushort LEN { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The one's complement of LEN
|
||||
/// </summary>
|
||||
/// <remarks>Bytes 2-3</remarks>
|
||||
public ushort NLEN { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.LZ
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const int GETLEN = 2048;
|
||||
|
||||
public const int LZ_MAGIC_LEN = 8;
|
||||
|
||||
public const int LZ_HEADER_LEN = 14;
|
||||
|
||||
public static readonly byte[] MagicBytes = [0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33];
|
||||
|
||||
public static readonly string MagicString = System.Text.Encoding.ASCII.GetString(MagicBytes);
|
||||
|
||||
public const ulong MagicUInt64 = 0x3327f08844445a53;
|
||||
|
||||
public const int LZ_TABLE_SIZE = 0x1000;
|
||||
|
||||
public const int MAX_LZSTATES = 16;
|
||||
|
||||
public const int LZ_MIN_HANDLE = 0x400;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.LZ
|
||||
{
|
||||
/// <see href="https://github.com/wine-mirror/wine/blob/master/include/lzexpand.h"/>
|
||||
public enum LZERROR
|
||||
{
|
||||
LZERROR_OK = 1,
|
||||
LZERROR_NOT_LZ = 0,
|
||||
LZERROR_BADINHANDLE = -1,
|
||||
LZERROR_BADOUTHANDLE = -2,
|
||||
LZERROR_READ = -3,
|
||||
LZERROR_WRITE = -4,
|
||||
LZERROR_GLOBALLOC = -5,
|
||||
LZERROR_GLOBLOCK = -6,
|
||||
LZERROR_BADVALUE = -7,
|
||||
LZERROR_UNKNOWNALG = -8,
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.Compression.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// Format of first 14 byte of LZ compressed file
|
||||
/// </summary>
|
||||
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/kernel32/lzexpand.c"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class FileHeaader
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
|
||||
public string? Magic;
|
||||
|
||||
public byte CompressionType;
|
||||
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public char LastChar;
|
||||
|
||||
public uint RealLength;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SabreTools.Models.Compression.LZ
|
||||
{
|
||||
public sealed class State
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal backing stream
|
||||
/// </summary>
|
||||
public Stream? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The last char of the filename for replacement
|
||||
/// </summary>
|
||||
public char LastChar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Decompressed length of the file
|
||||
/// </summary>
|
||||
public uint RealLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position the decompressor currently is
|
||||
/// </summary>
|
||||
public uint RealCurrent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position the user wants to read from
|
||||
/// </summary>
|
||||
public uint RealWanted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The rotating LZ table
|
||||
/// </summary>
|
||||
public byte[]? Table { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CURrent TABle ENTry
|
||||
/// </summary>
|
||||
public uint CurrentTableEntry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Length and position of current string
|
||||
/// </summary>
|
||||
public byte StringLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// From stringtable
|
||||
/// </summary>
|
||||
public uint StringPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bitmask within blocks
|
||||
/// </summary>
|
||||
public ushort ByteType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// GETLEN bytes
|
||||
/// </summary>
|
||||
public byte[]? Window { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current read
|
||||
/// </summary>
|
||||
public uint WindowCurrent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Length last got
|
||||
/// </summary>
|
||||
public uint WindowLength { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.MSZIP
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// MSZIP block is determined by the compressor, as defined in [RFC1951]. The last RFC 1951 block in
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <see href="https://interoperability.blob.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
|
||||
public class Block
|
||||
{
|
||||
/// <summary>
|
||||
/// Block header
|
||||
/// </summary>
|
||||
public BlockHeader? BlockHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compressed blocks
|
||||
/// </summary>
|
||||
public DeflateBlock[]? CompressedBlocks { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,18 @@ namespace SabreTools.Models.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
|
||||
/// MSZIP block is determined by the compressor, as defined in [RFC1951]. The last RFC 1951 block in
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <see href="https://interoperability.blob.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
|
||||
public class BlockHeader
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.MSZIP
|
||||
{
|
||||
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Window size
|
||||
/// </summary>
|
||||
public const ushort ZIPWSIZE = 0x8000;
|
||||
|
||||
/// <summary>
|
||||
/// And'ing with Zipmask[n] masks the lower n bits
|
||||
/// </summary>
|
||||
public static readonly ushort[] BitMasks =
|
||||
[
|
||||
0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
namespace SabreTools.Models.Compression.MSZIP
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// MSZIP block is determined by the compressor, as defined in [RFC1951]. The last RFC 1951 block in
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <see href="https://interoperability.blob.core.windows.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
|
||||
public class DeflateBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// Deflate block (RFC-1951) header
|
||||
/// </summary>
|
||||
public Deflate.BlockHeader? Header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compression-specific data header
|
||||
/// </summary>
|
||||
public Deflate.DataHeader? DataHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MSZIP data
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Depending on the implementation of these models, this property could either be
|
||||
/// compressed or uncompressed data. Keep this in mind when using the built
|
||||
/// versions of this model.
|
||||
/// </remarks>
|
||||
public byte[]? Data { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@ namespace SabreTools.Models.DosCenter
|
||||
[Required]
|
||||
public string? CRC { get; set; }
|
||||
|
||||
/// <remarks>sha1, attribute</remarks>
|
||||
public string? SHA1 { get; set; }
|
||||
|
||||
/// <remarks>date, attribute</remarks>
|
||||
public string? Date { get; set; }
|
||||
}
|
||||
|
||||
17
SabreTools.Models/LZ/Constants.cs
Normal file
17
SabreTools.Models/LZ/Constants.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const string KWAJPrefix = "KWAJ";
|
||||
|
||||
public static readonly byte[] KWAJSignatureBytes = [0x4B, 0x57, 0x41, 0x4A, 0x88, 0xF0, 0x27, 0xD1];
|
||||
|
||||
public const string QBasicPrefix = "SZ ";
|
||||
|
||||
public static readonly byte[] QBasicSignatureBytes = [0x53, 0x5A, 0x20, 0x88, 0xF0, 0x27, 0x33, 0xD1];
|
||||
|
||||
public const string SZDDPrefix = "SZDD";
|
||||
|
||||
public static readonly byte[] SZDDSignatureBytes = [0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33];
|
||||
}
|
||||
}
|
||||
82
SabreTools.Models/LZ/Enums.cs
Normal file
82
SabreTools.Models/LZ/Enums.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
public enum KWAJCompressionType : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// No compression
|
||||
/// </summary>
|
||||
NoCompression = 0,
|
||||
|
||||
/// <summary>
|
||||
/// No compression, data is XORed with byte 0xFF
|
||||
/// </summary>
|
||||
NoCompressionXor = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The same compression method as the QBasic variant of SZDD
|
||||
/// </summary>
|
||||
QBasic = 2,
|
||||
|
||||
/// <summary>
|
||||
/// LZ + Huffman "Jeff Johnson" compression
|
||||
/// </summary>
|
||||
LZH = 3,
|
||||
|
||||
/// <summary>
|
||||
/// MS-ZIP
|
||||
/// </summary>
|
||||
MSZIP = 4,
|
||||
}
|
||||
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
[Flags]
|
||||
public enum KWAJHeaderFlags : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// Header extensions contains 4-byte decompressed length
|
||||
/// </summary>
|
||||
HasDecompressedLength = 0x0001,
|
||||
|
||||
/// <summary>
|
||||
/// Header extensions contains 2-byte unknown value
|
||||
/// </summary>
|
||||
HasUnknownFlag = 0x0002,
|
||||
|
||||
/// <summary>
|
||||
/// Header extensions contains 2-byte prefix followed by
|
||||
/// that many bytes of (unknown purpose) data
|
||||
/// </summary>
|
||||
HasPrefixedData = 0x0004,
|
||||
|
||||
/// <summary>
|
||||
/// Header extensions contains null-terminated string of
|
||||
/// max length 8 representing the file name
|
||||
/// </summary>
|
||||
HasFileName = 0x0008,
|
||||
|
||||
/// <summary>
|
||||
/// Header extensions contains null-terminated string of
|
||||
/// max length 3 representing the file name
|
||||
/// </summary>
|
||||
HasFileExtension = 0x0010,
|
||||
|
||||
/// <summary>
|
||||
/// Header extensions contains 2-byte prefix followed by
|
||||
/// that many bytes of (arbitrary text) data
|
||||
/// </summary>
|
||||
HasAdditionalText = 0x0020,
|
||||
}
|
||||
|
||||
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/kernel32/lzexpand.c"/>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
public enum ExpandCompressionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Only valid compression type: 'A'
|
||||
/// </summary>
|
||||
A = 0x41,
|
||||
}
|
||||
}
|
||||
21
SabreTools.Models/LZ/KWAJFile.cs
Normal file
21
SabreTools.Models/LZ/KWAJFile.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// LZ variant with variable compression
|
||||
/// </summary>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
public sealed class KWAJFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Header
|
||||
/// </summary>
|
||||
public KWAJHeader? Header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional extensions defined by <see cref="KWAJHeader.HeaderFlags"/>
|
||||
/// </summary>
|
||||
public KWAJHeaderExtensions? HeaderExtensions { get; set; }
|
||||
|
||||
// Followed immediately by compressed data
|
||||
}
|
||||
}
|
||||
35
SabreTools.Models/LZ/KWAJHeader.cs
Normal file
35
SabreTools.Models/LZ/KWAJHeader.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// LZ variant with variable compression
|
||||
/// </summary>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class KWAJHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// "KWAJ" signature
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
|
||||
public byte[]? Magic;
|
||||
|
||||
/// <summary>
|
||||
/// Compression method
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.U2)]
|
||||
public KWAJCompressionType CompressionType;
|
||||
|
||||
/// <summary>
|
||||
/// File offset of compressed data
|
||||
/// </summary>
|
||||
public ushort DataOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Header flags to mark header extensions
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.U2)]
|
||||
public KWAJHeaderFlags HeaderFlags;
|
||||
}
|
||||
}
|
||||
51
SabreTools.Models/LZ/KWAJHeaderExtensions.cs
Normal file
51
SabreTools.Models/LZ/KWAJHeaderExtensions.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// Additional information stored after the KWAJ header
|
||||
/// </summary>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
public sealed class KWAJHeaderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Decompressed length of file
|
||||
/// </summary>
|
||||
public uint? DecompressedLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unknown purpose
|
||||
/// </summary>
|
||||
public ushort? UnknownPurpose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Length of <see cref="UnknownData"/>
|
||||
/// </summary>
|
||||
public ushort? UnknownDataLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unknown purpose data whose length is defined
|
||||
/// by <see cref="UnknownDataLength"/>
|
||||
/// </summary>
|
||||
public byte[]? UnknownData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Null-terminated string with max length 8: file name
|
||||
/// </summary>
|
||||
public string? FileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Null-terminated string with max length 3: file extension
|
||||
/// </summary>
|
||||
public string? FileExtension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Length of <see cref="ArbitraryText"/>
|
||||
/// </summary>
|
||||
public ushort? ArbitraryTextLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Arbitrary text data whose length is defined
|
||||
/// by <see cref="ArbitraryTextLength"/>
|
||||
/// </summary>
|
||||
public byte[]? ArbitraryText { get; set; }
|
||||
}
|
||||
}
|
||||
16
SabreTools.Models/LZ/QBasicFile.cs
Normal file
16
SabreTools.Models/LZ/QBasicFile.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// LZ variant used in QBasic 4.5 installer
|
||||
/// </summary>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
public sealed class QBasicFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Header
|
||||
/// </summary>
|
||||
public QBasicHeader? Header { get; set; }
|
||||
|
||||
// Followed immediately by compressed data
|
||||
}
|
||||
}
|
||||
23
SabreTools.Models/LZ/QBasicHeader.cs
Normal file
23
SabreTools.Models/LZ/QBasicHeader.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// LZ variant used in QBasic 4.5 installer
|
||||
/// </summary>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class QBasicHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// "SZ" signature
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
|
||||
public byte[]? Magic;
|
||||
|
||||
/// <summary>
|
||||
/// The integer length of the file when unpacked
|
||||
/// </summary>
|
||||
public uint RealLength;
|
||||
}
|
||||
}
|
||||
17
SabreTools.Models/LZ/SZDDFile.cs
Normal file
17
SabreTools.Models/LZ/SZDDFile.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard LZ variant
|
||||
/// </summary>
|
||||
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/kernel32/lzexpand.c"/>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
public sealed class SZDDFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Header
|
||||
/// </summary>
|
||||
public SZDDHeader? Header { get; set; }
|
||||
|
||||
// Followed immediately by compressed data
|
||||
}
|
||||
}
|
||||
38
SabreTools.Models/LZ/SZDDHeader.cs
Normal file
38
SabreTools.Models/LZ/SZDDHeader.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SabreTools.Models.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard LZ variant
|
||||
/// </summary>
|
||||
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/kernel32/lzexpand.c"/>
|
||||
/// <see href="https://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html"/>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public sealed class SZDDHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// "SZDD" signature
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
|
||||
public byte[]? Magic;
|
||||
|
||||
/// <summary>
|
||||
/// Compression mode
|
||||
/// </summary>
|
||||
/// <remarks>Only <see cref="ExpandCompressionType.A"/> is supported</remarks>
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ExpandCompressionType CompressionType;
|
||||
|
||||
/// <summary>
|
||||
/// The character missing from the end of the filename
|
||||
/// </summary>
|
||||
/// <remarks>0 means unknown</remarks>
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public char LastChar;
|
||||
|
||||
/// <summary>
|
||||
/// The integer length of the file when unpacked
|
||||
/// </summary>
|
||||
public uint RealLength;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<NoWarn>CS0618</NoWarn>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.5.5</Version>
|
||||
<Version>1.5.7</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
|
||||
Reference in New Issue
Block a user