45 Commits

Author SHA1 Message Date
Matt Nadareski
b3f3f12b3e Use "main" instead of "master" 2024-02-27 19:06:26 -05:00
Matt Nadareski
b41700ff92 Update copyright date 2024-02-27 17:18:02 -05:00
Matt Nadareski
e8a357546b Add nuget package and PR workflows 2024-02-27 17:17:50 -05:00
Matt Nadareski
68f0201c11 Add SafeDisc encrypted file entry model 2023-11-30 19:11:52 -05:00
Matt Nadareski
25b6493249 Bump version 2023-11-21 11:15:24 -05:00
Matt Nadareski
a551363c0b Support .NET Framework 2.0 2023-11-20 23:44:05 -05:00
Matt Nadareski
2fd92aea8f Support .NET Framework 3.5 2023-11-20 21:10:43 -05:00
Matt Nadareski
a61b3d0ed9 Add IS Archive V3 models 2023-11-15 14:30:25 -05:00
Matt Nadareski
a40a6871df Bump version 2023-11-14 12:30:15 -05:00
Matt Nadareski
5792ec64c0 Cut off at .NET Framework 4.0 2023-11-08 10:45:12 -05:00
Matt Nadareski
3b13c7cc96 Cut off at .NET Framework 4.0 2023-11-08 10:44:47 -05:00
Matt Nadareski
894d7b62e2 Enable warnings as errors 2023-11-07 21:52:01 -05:00
Matt Nadareski
38e37b1a63 Support ancient .NET 2023-11-07 21:18:17 -05:00
Matt Nadareski
1f340bd244 Remove framework gating 2023-11-07 20:57:05 -05:00
Matt Nadareski
e582ce8726 Enable latest language version 2023-11-07 20:48:49 -05:00
Matt Nadareski
dad71add36 Expand supported RIDs 2023-11-07 20:47:31 -05:00
Matt Nadareski
cb2a28016e Enable broader support 2023-11-07 20:46:11 -05:00
Matt Nadareski
46a814ac73 Add PS3 SFB and SFO models 2023-11-03 15:18:26 -04:00
Matt Nadareski
8fabe9c02d Rename IRD to File internally 2023-10-29 21:53:12 -04:00
Matt Nadareski
21e22a1476 Bump version 2023-10-25 12:36:33 -04:00
Matt Nadareski
016057a837 Add mapping dictionaries for Xbox 2023-10-24 22:48:41 -04:00
Matt Nadareski
69ca889ac7 Add version guards around LZX.Chunk 2023-10-24 21:45:32 -04:00
Matt Nadareski
cd67a7282b Add version guards to IRD model 2023-10-23 11:33:50 -04:00
Matt Nadareski
948edbad58 Merge pull request #4 from Deterous/Deterous-patch-1
Improve IRD Model
2023-10-23 10:54:21 -04:00
Deterous
d445f02ba6 Specify the reserved attributes 2023-10-23 12:23:55 +13:00
Deterous
835fce7876 Comment on UID 2023-10-23 12:00:05 +13:00
Deterous
97513840e0 ID and UID are the same Property 2023-10-23 11:53:34 +13:00
Matt Nadareski
6112dcb391 Add IRD model 2023-10-22 01:03:34 -04:00
Matt Nadareski
c000e581c8 Bump version 2023-09-28 23:24:58 -04:00
Matt Nadareski
465cef4224 Add XGD4 identifier for PIC 2023-09-28 23:21:44 -04:00
Matt Nadareski
87cadbfd2b Add documentation around Quantum 2023-09-22 21:24:05 -04:00
Matt Nadareski
648ee2eaa5 Add back two properties 2023-09-22 21:15:52 -04:00
Matt Nadareski
daa814728d Simplify the Quantum models for now 2023-09-22 21:13:31 -04:00
Matt Nadareski
68aac36623 Fully create Chunk and ChunkHeader 2023-09-22 21:00:41 -04:00
Matt Nadareski
0c95cfcde4 More LZX cleanup 2023-09-22 20:47:29 -04:00
Matt Nadareski
6d6361c153 Start making LZX models better 2023-09-22 20:40:22 -04:00
Matt Nadareski
e4be402052 Bump version 2023-09-22 16:02:57 -04:00
Matt Nadareski
182c9bc756 Add remark on DeflateBlock 2023-09-22 15:37:49 -04:00
Matt Nadareski
cc62b3ffae This is an array 2023-09-22 15:34:55 -04:00
Matt Nadareski
7d34f486cd Make the MSZIP models better 2023-09-22 15:32:19 -04:00
Matt Nadareski
9c68cfc0c1 Fix issues found during MSZIP research 2023-09-22 11:54:48 -04:00
Matt Nadareski
9a5d681ad2 Bump version 2023-09-13 13:55:46 -04:00
Matt Nadareski
afb20e00be Add PIC models from MPF 2023-09-13 12:20:01 -04:00
Matt Nadareski
5a055a98c7 Add XMID and XeMID models from MPF 2023-09-13 12:11:56 -04:00
Matt Nadareski
793a4e2fdd Add cuesheet models from MPF 2023-09-13 11:34:58 -04:00
398 changed files with 1808 additions and 7360 deletions

43
.github/workflows/build_nupkg.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Nuget Pack
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Pack
run: dotnet pack
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: 'Nuget Package'
path: 'bin/Release/*.nupkg'
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: 'bin/Release/*.nupkg'
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

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

@@ -0,0 +1,17 @@
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: 8.0.x
- name: Build
run: dotnet build

View File

@@ -8,10 +8,6 @@ namespace SabreTools.Models.AACS
/// <summary>
/// Null-terminated ASCII string representing the copyright
/// </summary>
#if NET48
public string Copyright { get; set; }
#else
public string? Copyright { get; set; }
#endif
}
}

View File

@@ -16,10 +16,6 @@ namespace SabreTools.Models.AACS
/// (or the first in a range of Licensed Drives being revoked, in the
/// case of a non-zero Range value).
/// </summary>
#if NET48
public byte[] DriveID { get; set; }
#else
public byte[]? DriveID { get; set; }
#endif
}
}

View File

@@ -21,10 +21,6 @@ namespace SabreTools.Models.AACS
/// <summary>
/// Revocation list entries
/// </summary>
#if NET48
public DriveRevocationSignatureBlock[] SignatureBlocks { get; set; }
#else
public DriveRevocationSignatureBlock?[]? SignatureBlocks { get; set; }
#endif
}
}

View File

@@ -12,10 +12,6 @@ namespace SabreTools.Models.AACS
/// A list of 8-byte Host Drive List Entry fields, the length of this
/// list being equal to the number in the signature block.
/// </summary>
#if NET48
public DriveRevocationListEntry[] EntryFields { get; set; }
#else
public DriveRevocationListEntry?[]? EntryFields { get; set; }
#endif
}
}

View File

@@ -18,10 +18,6 @@ namespace SabreTools.Models.AACS
/// determines that the signature does not verify or is omitted, it
/// must refuse to use the Media Key.
/// </summary>
#if NET48
public byte[] SignatureData { get; set; }
#else
public byte[]? SignatureData { get; set; }
#endif
}
}

View File

@@ -6,10 +6,6 @@ namespace SabreTools.Models.AACS
/// <summary>
/// In this record, each subset-difference is encoded with 5 bytes.
/// </summary>
#if NET48
public SubsetDifference[] SubsetDifferences { get; set; }
#else
public SubsetDifference?[]? SubsetDifferences { get; set; }
#endif
}
}

View File

@@ -16,10 +16,6 @@ namespace SabreTools.Models.AACS
/// first in a range of hosts being revoked, in the case of a non-zero
/// Range value).
/// </summary>
#if NET48
public byte[] HostID { get; set; }
#else
public byte[]? HostID { get; set; }
#endif
}
}

View File

@@ -24,10 +24,6 @@ namespace SabreTools.Models.AACS
/// <summary>
/// Revocation list entries
/// </summary>
#if NET48
public HostRevocationSignatureBlock[] SignatureBlocks { get; set; }
#else
public HostRevocationSignatureBlock?[]? SignatureBlocks { get; set; }
#endif
}
}

View File

@@ -12,10 +12,6 @@ namespace SabreTools.Models.AACS
/// A list of 8-byte Host Revocation List Entry fields, the length of this
/// list being equal to the number in the signature block.
/// </summary>
#if NET48
public HostRevocationListEntry[] EntryFields { get; set; }
#else
public HostRevocationListEntry?[]? EntryFields { get; set; }
#endif
}
}

View File

@@ -9,10 +9,6 @@ namespace SabreTools.Models.AACS
/// <summary>
/// Records
/// </summary>
#if NET48
public Record[] Records { get; set; }
#else
public Record?[]? Records { get; set; }
#endif
}
}

View File

@@ -13,10 +13,6 @@ namespace SabreTools.Models.AACS
/// record. This 16 bytes is the ciphertext value C in the media
/// key calculation.
/// </summary>
#if NET48
public byte[][] MediaKeyData { get; set; }
#else
public byte[][]? MediaKeyData { get; set; }
#endif
}
}

View File

@@ -21,10 +21,6 @@ namespace SabreTools.Models.AACS
/// Subset-Difference record, with 0 being the start of the record.
/// </summary>
// <remarks>UInt24 not UInt32</remarks>
#if NET48
public uint[] Offsets { get; set; }
#else
public uint[]? Offsets { get; set; }
#endif
}
}

View File

@@ -19,10 +19,6 @@ namespace SabreTools.Models.AACS
/// where 0xXXXXXXXXXXXXXXXX is an arbitrary 8-byte value, and Km is
/// the correct final Media Key value.
/// </summary>
#if NET48
public byte[] CiphertextValue { get; set; }
#else
public byte[]? CiphertextValue { get; set; }
#endif
}
}

View File

@@ -7,438 +7,198 @@ namespace SabreTools.Models.ArchiveDotOrg
public class File
{
[XmlAttribute("name")]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>Is this a set of defined values?</remarks>
[XmlAttribute("source")]
#if NET48
public string Source { get; set; }
#else
public string? Source { get; set; }
#endif
[XmlElement("btih")]
#if NET48
public string BitTorrentMagnetHash { get; set; }
#else
public string? BitTorrentMagnetHash { get; set; }
#endif
[XmlElement("mtime")]
#if NET48
public string LastModifiedTime { get; set; }
#else
public string? LastModifiedTime { get; set; }
#endif
[XmlElement("size")]
#if NET48
public string Size { get; set; }
#else
public string? Size { get; set; }
#endif
[XmlElement("md5")]
#if NET48
public string MD5 { get; set; }
#else
public string? MD5 { get; set; }
#endif
[XmlElement("crc32")]
#if NET48
public string CRC32 { get; set; }
#else
public string? CRC32 { get; set; }
#endif
[XmlElement("sha1")]
#if NET48
public string SHA1 { get; set; }
#else
public string? SHA1 { get; set; }
#endif
[XmlElement("filecount")]
#if NET48
public string FileCount { get; set; }
#else
public string? FileCount { get; set; }
#endif
/// <remarks>Is this a set of defined values?</remarks>
[XmlElement("format")]
#if NET48
public string Format { get; set; }
#else
public string? Format { get; set; }
#endif
[XmlElement("original")]
#if NET48
public string Original { get; set; }
#else
public string? Original { get; set; }
#endif
/// <remarks>Is this a set of defined values?</remarks>
[XmlElement("summation")]
#if NET48
public string Summation { get; set; }
#else
public string? Summation { get; set; }
#endif
[XmlElement("matrix_number")]
#if NET48
public string MatrixNumber { get; set; }
#else
public string? MatrixNumber { get; set; }
#endif
[XmlElement("collection-catalog-number")]
#if NET48
public string CollectionCatalogNumber { get; set; }
#else
public string? CollectionCatalogNumber { get; set; }
#endif
[XmlElement("publisher")]
#if NET48
public string Publisher { get; set; }
#else
public string? Publisher { get; set; }
#endif
[XmlElement("comment")]
#if NET48
public string Comment { get; set; }
#else
public string? Comment { get; set; }
#endif
#region ASR-Related
[XmlElement("asr_detected_lang")]
#if NET48
public string ASRDetectedLang { get; set; }
#else
public string? ASRDetectedLang { get; set; }
#endif
[XmlElement("asr_detected_lang_conf")]
#if NET48
public string ASRDetectedLangConf { get; set; }
#else
public string? ASRDetectedLangConf { get; set; }
#endif
[XmlElement("asr_transcribed_lang")]
#if NET48
public string ASRTranscribedLang { get; set; }
#else
public string? ASRTranscribedLang { get; set; }
#endif
[XmlElement("whisper_asr_module_version")]
#if NET48
public string WhisperASRModuleVersion { get; set; }
#else
public string? WhisperASRModuleVersion { get; set; }
#endif
[XmlElement("whisper_model_hash")]
#if NET48
public string WhisperModelHash { get; set; }
#else
public string? WhisperModelHash { get; set; }
#endif
[XmlElement("whisper_model_name")]
#if NET48
public string WhisperModelName { get; set; }
#else
public string? WhisperModelName { get; set; }
#endif
[XmlElement("whisper_version")]
#if NET48
public string WhisperVersion { get; set; }
#else
public string? WhisperVersion { get; set; }
#endif
#endregion
#region OCR-Related
[XmlElement("cloth_cover_detection_module_version")]
#if NET48
public string ClothCoverDetectionModuleVersion { get; set; }
#else
public string? ClothCoverDetectionModuleVersion { get; set; }
#endif
[XmlElement("hocr_char_to_word_hocr_version")]
#if NET48
public string hOCRCharToWordhOCRVersion { get; set; }
#else
public string? hOCRCharToWordhOCRVersion { get; set; }
#endif
[XmlElement("hocr_char_to_word_module_version")]
#if NET48
public string hOCRCharToWordModuleVersion { get; set; }
#else
public string? hOCRCharToWordModuleVersion { get; set; }
#endif
[XmlElement("hocr_fts_text_hocr_version")]
#if NET48
public string hOCRFtsTexthOCRVersion { get; set; }
#else
public string? hOCRFtsTexthOCRVersion { get; set; }
#endif
[XmlElement("hocr_fts_text_module_version")]
#if NET48
public string hOCRFtsTextModuleVersion { get; set; }
#else
public string? hOCRFtsTextModuleVersion { get; set; }
#endif
[XmlElement("hocr_pageindex_hocr_version")]
#if NET48
public string hOCRPageIndexhOCRVersion { get; set; }
#else
public string? hOCRPageIndexhOCRVersion { get; set; }
#endif
[XmlElement("hocr_pageindex_module_version")]
#if NET48
public string hOCRPageIndexModuleVersion { get; set; }
#else
public string? hOCRPageIndexModuleVersion { get; set; }
#endif
[XmlElement("ocr")]
#if NET48
public string TesseractOCR { get; set; }
#else
public string? TesseractOCR { get; set; }
#endif
[XmlElement("ocr_converted")]
#if NET48
public string TesseractOCRConverted { get; set; }
#else
public string? TesseractOCRConverted { get; set; }
#endif
[XmlElement("ocr_detected_lang")]
#if NET48
public string TesseractOCRDetectedLang { get; set; }
#else
public string? TesseractOCRDetectedLang { get; set; }
#endif
[XmlElement("ocr_detected_lang_conf")]
#if NET48
public string TesseractOCRDetectedLangConf { get; set; }
#else
public string? TesseractOCRDetectedLangConf { get; set; }
#endif
[XmlElement("ocr_detected_script")]
#if NET48
public string TesseractOCRDetectedScript { get; set; }
#else
public string? TesseractOCRDetectedScript { get; set; }
#endif
[XmlElement("ocr_detected_script_conf")]
#if NET48
public string TesseractOCRDetectedScriptConf { get; set; }
#else
public string? TesseractOCRDetectedScriptConf { get; set; }
#endif
[XmlElement("ocr_module_version")]
#if NET48
public string TesseractOCRModuleVersion { get; set; }
#else
public string? TesseractOCRModuleVersion { get; set; }
#endif
[XmlElement("ocr_parameters")]
#if NET48
public string TesseractOCRParameters { get; set; }
#else
public string? TesseractOCRParameters { get; set; }
#endif
[XmlElement("pdf_module_version")]
#if NET48
public string PDFModuleVersion { get; set; }
#else
public string? PDFModuleVersion { get; set; }
#endif
[XmlElement("word_conf_0_10")]
#if NET48
public string WordConfidenceInterval0To10 { get; set; }
#else
public string? WordConfidenceInterval0To10 { get; set; }
#endif
[XmlElement("word_conf_11_20")]
#if NET48
public string WordConfidenceInterval11To20 { get; set; }
#else
public string? WordConfidenceInterval11To20 { get; set; }
#endif
[XmlElement("word_conf_21_30")]
#if NET48
public string WordConfidenceInterval21To30 { get; set; }
#else
public string? WordConfidenceInterval21To30 { get; set; }
#endif
[XmlElement("word_conf_31_40")]
#if NET48
public string WordConfidenceInterval31To40 { get; set; }
#else
public string? WordConfidenceInterval31To40 { get; set; }
#endif
[XmlElement("word_conf_41_50")]
#if NET48
public string WordConfidenceInterval41To50 { get; set; }
#else
public string? WordConfidenceInterval41To50 { get; set; }
#endif
[XmlElement("word_conf_51_60")]
#if NET48
public string WordConfidenceInterval51To60 { get; set; }
#else
public string? WordConfidenceInterval51To60 { get; set; }
#endif
[XmlElement("word_conf_61_70")]
#if NET48
public string WordConfidenceInterval61To70 { get; set; }
#else
public string? WordConfidenceInterval61To70 { get; set; }
#endif
[XmlElement("word_conf_71_80")]
#if NET48
public string WordConfidenceInterval71To80 { get; set; }
#else
public string? WordConfidenceInterval71To80 { get; set; }
#endif
[XmlElement("word_conf_81_90")]
#if NET48
public string WordConfidenceInterval81To90 { get; set; }
#else
public string? WordConfidenceInterval81To90 { get; set; }
#endif
[XmlElement("word_conf_91_100")]
#if NET48
public string WordConfidenceInterval91To100 { get; set; }
#else
public string? WordConfidenceInterval91To100 { get; set; }
#endif
#endregion
#region Media-Related
[XmlElement("album")]
#if NET48
public string Album { get; set; }
#else
public string? Album { get; set; }
#endif
[XmlElement("artist")]
#if NET48
public string Artist { get; set; }
#else
public string? Artist { get; set; }
#endif
[XmlElement("bitrate")]
#if NET48
public string Bitrate { get; set; }
#else
public string? Bitrate { get; set; }
#endif
[XmlElement("creator")]
#if NET48
public string Creator { get; set; }
#else
public string? Creator { get; set; }
#endif
[XmlElement("height")]
#if NET48
public string Height { get; set; }
#else
public string? Height { get; set; }
#endif
[XmlElement("length")]
#if NET48
public string Length { get; set; }
#else
public string? Length { get; set; }
#endif
[XmlElement("preview-image")]
#if NET48
public string PreviewImage { get; set; }
#else
public string? PreviewImage { get; set; }
#endif
/// <remarks>Is this a set of defined values?</remarks>
[XmlElement("rotation")]
#if NET48
public string Rotation { get; set; }
#else
public string? Rotation { get; set; }
#endif
[XmlElement("title")]
#if NET48
public string Title { get; set; }
#else
public string? Title { get; set; }
#endif
[XmlElement("track")]
#if NET48
public string Track { get; set; }
#else
public string? Track { get; set; }
#endif
[XmlElement("width")]
#if NET48
public string Width { get; set; }
#else
public string? Width { get; set; }
#endif
#endregion
@@ -446,19 +206,11 @@ namespace SabreTools.Models.ArchiveDotOrg
/// <remarks>Should be empty</remarks>
[XmlAnyAttribute]
#if NET48
public XmlAttribute[] ADDITIONAL_ATTRIBUTES { get; set; }
#else
public XmlAttribute[]? ADDITIONAL_ATTRIBUTES { get; set; }
#endif
/// <remarks>Should be empty</remarks>
[XmlAnyElement]
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -7,29 +7,17 @@ namespace SabreTools.Models.ArchiveDotOrg
public class Files
{
[XmlElement("file")]
#if NET48
public File[] File { get; set; }
#else
public File?[]? File { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
[XmlAnyAttribute]
#if NET48
public XmlAttribute[] ADDITIONAL_ATTRIBUTES { get; set; }
#else
public XmlAttribute[]? ADDITIONAL_ATTRIBUTES { get; set; }
#endif
/// <remarks>Should be empty</remarks>
[XmlAnyElement]
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -6,16 +6,8 @@ namespace SabreTools.Models.AttractMode
public class MetadataFile
{
[Required]
#if NET48
public string[] Header { get; set; }
#else
public string[]? Header { get; set; }
#endif
#if NET48
public Row[] Row { get; set; }
#else
public Row?[]? Row { get; set; }
#endif
}
}

View File

@@ -4,146 +4,54 @@ namespace SabreTools.Models.AttractMode
{
/// <remarks>Also called Romname</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
#if NET48
public string Title { get; set; }
#else
public string? Title { get; set; }
#endif
#if NET48
public string Emulator { get; set; }
#else
public string? Emulator { get; set; }
#endif
#if NET48
public string CloneOf { get; set; }
#else
public string? CloneOf { get; set; }
#endif
#if NET48
public string Year { get; set; }
#else
public string? Year { get; set; }
#endif
#if NET48
public string Manufacturer { get; set; }
#else
public string? Manufacturer { get; set; }
#endif
#if NET48
public string Category { get; set; }
#else
public string? Category { get; set; }
#endif
#if NET48
public string Players { get; set; }
#else
public string? Players { get; set; }
#endif
#if NET48
public string Rotation { get; set; }
#else
public string? Rotation { get; set; }
#endif
#if NET48
public string Control { get; set; }
#else
public string? Control { get; set; }
#endif
#if NET48
public string Status { get; set; }
#else
public string? Status { get; set; }
#endif
#if NET48
public string DisplayCount { get; set; }
#else
public string? DisplayCount { get; set; }
#endif
#if NET48
public string DisplayType { get; set; }
#else
public string? DisplayType { get; set; }
#endif
#if NET48
public string AltRomname { get; set; }
#else
public string? AltRomname { get; set; }
#endif
#if NET48
public string AltTitle { get; set; }
#else
public string? AltTitle { get; set; }
#endif
#if NET48
public string Extra { get; set; }
#else
public string? Extra { get; set; }
#endif
#if NET48
public string Buttons { get; set; }
#else
public string? Buttons { get; set; }
#endif
#if NET48
public string Favorite { get; set; }
#else
public string? Favorite { get; set; }
#endif
#if NET48
public string Tags { get; set; }
#else
public string? Tags { get; set; }
#endif
#if NET48
public string PlayedCount { get; set; }
#else
public string? PlayedCount { get; set; }
#endif
#if NET48
public string PlayedTime { get; set; }
#else
public string? PlayedTime { get; set; }
#endif
#if NET48
public string FileIsAvailable { get; set; }
#else
public string? FileIsAvailable { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -6,20 +6,12 @@ namespace SabreTools.Models.BDPlus
/// <summary>
/// "BDSVM_CC"
/// </summary>
#if NET48
public string Signature { get; set; }
#else
public string? Signature { get; set; }
#endif
/// <summary>
/// 5 bytes of unknown data
/// </summary>
#if NET48
public byte[] Unknown1 { get; set; }
#else
public byte[]? Unknown1 { get; set; }
#endif
/// <summary>
/// Version year
@@ -39,11 +31,7 @@ namespace SabreTools.Models.BDPlus
/// <summary>
/// 4 bytes of unknown data
/// </summary>
#if NET48
public byte[] Unknown2 { get; set; }
#else
public byte[]? Unknown2 { get; set; }
#endif
/// <summary>
/// Length
@@ -53,10 +41,6 @@ namespace SabreTools.Models.BDPlus
/// <summary>
/// Length bytes of data
/// </summary>
#if NET48
public byte[] Data { get; set; }
#else
public byte[]? Data { get; set; }
#endif
}
}

View File

@@ -9,19 +9,11 @@
/// <summary>
/// Header
/// </summary>
#if NET48
public Header Header { get; set; }
#else
public Header? Header { get; set; }
#endif
/// <summary>
/// Files
/// </summary>
#if NET48
public FileEntry[] Files { get; set; }
#else
public FileEntry?[]? Files { get; set; }
#endif
}
}

View File

@@ -14,11 +14,7 @@
/// <summary>
/// Name
/// </summary>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <summary>
/// Uncompressed size

View File

@@ -9,11 +9,7 @@
/// <summary>
/// "BFPK"
/// </summary>
#if NET48
public string Magic { get; set; }
#else
public string? Magic { get; set; }
#endif
/// <summary>
/// Version

View File

@@ -9,37 +9,21 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Header data
/// </summary>
#if NET48
public Header Header { get; set; }
#else
public Header? Header { get; set; }
#endif
/// <summary>
/// Lumps
/// </summary>
#if NET48
public Lump[] Lumps { get; set; }
#else
public Lump?[]? Lumps { get; set; }
#endif
/// <summary>
/// Texture header data
/// </summary>
#if NET48
public TextureHeader TextureHeader { get; set; }
#else
public TextureHeader? TextureHeader { get; set; }
#endif
/// <summary>
/// Textures
/// </summary>
#if NET48
public Texture[] Textures { get; set; }
#else
public Texture?[]? Textures { get; set; }
#endif
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Name
/// </summary>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <summary>
/// Width
@@ -25,20 +21,12 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Offsets
/// </summary>
#if NET48
public uint[] Offsets { get; set; }
#else
public uint[]? Offsets { get; set; }
#endif
/// <summary>
/// Texture data
/// </summary>
#if NET48
public byte[] TextureData { get; set; }
#else
public byte[]? TextureData { get; set; }
#endif
/// <summary>
/// Palette size
@@ -48,10 +36,6 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Palette data
/// </summary>
#if NET48
public byte[] PaletteData { get; set; }
#else
public byte[]? PaletteData { get; set; }
#endif
}
}

View File

@@ -11,10 +11,6 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Offsets
/// </summary>
#if NET48
public uint[] Offsets { get; set; }
#else
public uint[]? Offsets { get; set; }
#endif
}
}

View File

@@ -12,11 +12,7 @@ namespace SabreTools.Models.CFB
/// <summary>
/// Compound file header
/// </summary>
#if NET48
public FileHeader Header { get; set; }
#else
public FileHeader? Header { get; set; }
#endif
/// <summary>
/// The FAT is the main allocator for space within a compound file.
@@ -29,11 +25,7 @@ namespace SabreTools.Models.CFB
///
/// If Header Major Version is 4, there MUST be 1,024 fields specified to fill a 4,096-byte sector
/// </remarks>
#if NET48
public SectorNumber[] FATSectorNumbers { get; set; }
#else
public SectorNumber?[]? FATSectorNumbers { get; set; }
#endif
/// <summary>
/// The mini FAT is used to allocate space in the mini stream.
@@ -46,11 +38,7 @@ namespace SabreTools.Models.CFB
///
/// If Header Major Version is 4, there MUST be 1,024 fields specified to fill a 4,096-byte sector
/// </remarks>
#if NET48
public SectorNumber[] MiniFATSectorNumbers { get; set; }
#else
public SectorNumber?[]? MiniFATSectorNumbers { get; set; }
#endif
/// <summary>
/// The DIFAT array is used to represent storage of the FAT sectors.
@@ -67,11 +55,7 @@ namespace SabreTools.Models.CFB
/// If Header Major Version is 4, there MUST be 1,023 fields specified
/// to fill a 4,096-byte sector minus the "Next DIFAT Sector Location" field.
/// </remarks>
#if NET48
public SectorNumber[] DIFATSectorNumbers { get; set; }
#else
public SectorNumber?[]? DIFATSectorNumbers { get; set; }
#endif
/// <summary>
/// The directory entry array is an array of directory entries that
@@ -103,10 +87,6 @@ namespace SabreTools.Models.CFB
/// all zeroes. The Modified Time field in the root storage directory
/// entry MAY be all zeroes.
/// <remarks>
#if NET48
public DirectoryEntry[] DirectoryEntries { get; set; }
#else
public DirectoryEntry?[]? DirectoryEntries { get; set; }
#endif
}
}

View File

@@ -16,11 +16,7 @@ namespace SabreTools.Models.CFB
/// The following characters are illegal and MUST NOT be part of the
/// name: '/', '\', ':', '!'.
/// </summary>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <summary>
/// This field MUST be 0x00, 0x01, 0x02, or 0x05, depending on the

View File

@@ -57,11 +57,7 @@ namespace SabreTools.Models.CFB
/// <summary>
/// This field MUST be set to all zeroes.
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// This integer field contains the count of the number of directory sectors
@@ -126,10 +122,6 @@ namespace SabreTools.Models.CFB
/// This array of 32-bit integer fields contains the first 109 FAT sector
/// locations of the compound file
/// </summary>
#if NET48
public SectorNumber[] DIFAT { get; set; }
#else
public SectorNumber?[]? DIFAT { get; set; }
#endif
}
}

View File

@@ -36,11 +36,7 @@ namespace SabreTools.Models.CFB
/// <summary>
/// 4 bytes of reserved data
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
#endregion
@@ -54,11 +50,7 @@ namespace SabreTools.Models.CFB
/// <summary>
/// 16 bytes of unknown data
/// </summary>
#if NET48
public byte[] Unknown { get; set; }
#else
public byte[]? Unknown { get; set; }
#endif
#endregion
@@ -83,11 +75,7 @@ namespace SabreTools.Models.CFB
/// Properties
/// </summary>
/// <remarks>Each Variant might be followed by an index and offset value</remarks>
#if NET48
public Variant[] Properties { get; set; }
#else
public Variant?[]? Properties { get; set; }
#endif
#endregion
}

View File

@@ -40,10 +40,6 @@ namespace SabreTools.Models.CFB
/// MUST contain an instance of the type, according to the value
/// in the <see cref="VariantType"/> field.
/// </summary>
#if NET48
public object Union { get; set; }
#else
public object? Union { get; set; }
#endif
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Models.CHD
/// <summary>
/// 'MComprHD'
/// </summary>
#if NET48
public string Tag { get; set; }
#else
public string? Tag { get; set; }
#endif
/// <summary>
/// Length of header (including tag and length fields)

View File

@@ -41,19 +41,11 @@
/// <summary>
/// MD5 checksum of raw data
/// </summary>
#if NET48
public byte[] MD5 { get; set; } = new byte[16];
#else
public byte[]? MD5 { get; set; } = new byte[16];
#endif
/// <summary>
/// MD5 checksum of parent file
/// </summary>
#if NET48
public byte[] ParentMD5 { get; set; } = new byte[16];
#else
public byte[]? ParentMD5 { get; set; } = new byte[16];
#endif
}
}

View File

@@ -41,20 +41,12 @@
/// <summary>
/// MD5 checksum of raw data
/// </summary>
#if NET48
public byte[] MD5 { get; set; } = new byte[16];
#else
public byte[]? MD5 { get; set; } = new byte[16];
#endif
/// <summary>
/// MD5 checksum of parent file
/// </summary>
#if NET48
public byte[] ParentMD5 { get; set; } = new byte[16];
#else
public byte[]? ParentMD5 { get; set; } = new byte[16];
#endif
/// <summary>
/// Number of bytes per sector

View File

@@ -31,20 +31,12 @@
/// <summary>
/// MD5 checksum of raw data
/// </summary>
#if NET48
public byte[] MD5 { get; set; } = new byte[16];
#else
public byte[]? MD5 { get; set; } = new byte[16];
#endif
/// <summary>
/// MD5 checksum of parent file
/// </summary>
#if NET48
public byte[] ParentMD5 { get; set; } = new byte[16];
#else
public byte[]? ParentMD5 { get; set; } = new byte[16];
#endif
/// <summary>
/// Number of bytes per hunk
@@ -54,19 +46,11 @@
/// <summary>
/// SHA1 checksum of raw data
/// </summary>
#if NET48
public byte[] SHA1 { get; set; } = new byte[20];
#else
public byte[]? SHA1 { get; set; } = new byte[20];
#endif
/// <summary>
/// SHA1 checksum of parent file
/// </summary>
#if NET48
public byte[] ParentSHA1 { get; set; } = new byte[20];
#else
public byte[]? ParentSHA1 { get; set; } = new byte[20];
#endif
}
}

View File

@@ -36,28 +36,16 @@
/// <summary>
/// Combined raw+meta SHA1
/// </summary>
#if NET48
public byte[] SHA1 { get; set; } = new byte[20];
#else
public byte[]? SHA1 { get; set; } = new byte[20];
#endif
/// <summary>
/// Combined raw+meta SHA1 of parent
/// </summary>
#if NET48
public byte[] ParentSHA1 { get; set; } = new byte[20];
#else
public byte[]? ParentSHA1 { get; set; } = new byte[20];
#endif
/// <summary>
/// Raw data SHA1
/// </summary>
#if NET48
public byte[] RawSHA1 { get; set; } = new byte[20];
#else
public byte[]? RawSHA1 { get; set; } = new byte[20];
#endif
}
}

View File

@@ -36,28 +36,16 @@
/// <summary>
/// Raw data SHA1
/// </summary>
#if NET48
public byte[] RawSHA1 { get; set; }
#else
public byte[]? RawSHA1 { get; set; }
#endif
/// <summary>
/// Combined raw+meta SHA1
/// </summary>
#if NET48
public byte[] SHA1 { get; set; }
#else
public byte[]? SHA1 { get; set; }
#endif
/// <summary>
/// Combined raw+meta SHA1 of parent
/// </summary>
#if NET48
public byte[] ParentSHA1 { get; set; }
#else
public byte[]? ParentSHA1 { get; set; }
#endif
}
}

View File

@@ -12,71 +12,43 @@ namespace SabreTools.Models.Charts
/// Title of the song.
/// </summary>
/// <remarks>name</remarks>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <summary>
/// Artist(s) or band(s) behind the song.
/// </summary>
/// <remarks>artist</remarks>
#if NET48
public string Artist { get; set; }
#else
public string? Artist { get; set; }
#endif
/// <summary>
/// Title of the album the song is featured in.
/// </summary>
/// <remarks>album</remarks>
#if NET48
public string Album { get; set; }
#else
public string? Album { get; set; }
#endif
/// <summary>
/// Genre of the song.
/// </summary>
/// <remarks>genre</remarks>
#if NET48
public string Genre { get; set; }
#else
public string? Genre { get; set; }
#endif
/// <summary>
/// Sub-genre for the song.
/// </summary>
/// <remarks>sub_genre</remarks>
#if NET48
public string SubGenre { get; set; }
#else
public string? SubGenre { get; set; }
#endif
/// <summary>
/// Year of the songs release.
/// </summary>
/// <remarks>year</remarks>
#if NET48
public string Year { get; set; }
#else
public string? Year { get; set; }
#endif
/// <summary>
/// Community member responsible for charting the song.
/// </summary>
/// <remarks>charter, frets</remarks>
#if NET48
public string Charter { get; set; }
#else
public string? Charter { get; set; }
#endif
/// <summary>
/// Version number for the song.
@@ -118,11 +90,7 @@ namespace SabreTools.Models.Charts
/// Flavor text for this song, usually shown after picking the song or during loading.
/// </summary>
/// <remarks>loading_phrase</remarks>
#if NET48
public string LoadingPhrase { get; set; }
#else
public string? LoadingPhrase { get; set; }
#endif
#endregion
@@ -132,53 +100,33 @@ namespace SabreTools.Models.Charts
/// (FoFiX) Hex color to use in the song screen for the cassette.
/// </summary>
/// <remarks>cassettecolor</remarks>
#if NET48
public string CassetteColor { get; set; }
#else
public string? CassetteColor { get; set; }
#endif
/// <summary>
/// (FoFiX) Miscellaneous tags for the chart.
/// Only known valid value is `cover`.
/// </summary>
/// <remarks>tags</remarks>
#if NET48
public string Tags { get; set; }
#else
public string? Tags { get; set; }
#endif
/// <summary>
/// (PS) Two timestamps in milliseconds for preview start and end time.
/// Example: `55000 85000`
/// </summary>
/// <remarks>preview</remarks>
#if NET48
public long[] Preview { get; set; }
#else
public long[]? Preview { get; set; }
#endif
/// <summary>
/// (CH) Playlist that the song should show up in.
/// </summary>
/// <remarks>playlist</remarks>
#if NET48
public string Playlist { get; set; }
#else
public string? Playlist { get; set; }
#endif
/// <summary>
/// (CH) Sub-playlist that the song should show up in.
/// </summary>
/// <remarks>sub_playlist</remarks>
#if NET48
public string SubPlaylist { get; set; }
#else
public string? SubPlaylist { get; set; }
#endif
/// <summary>
/// (CH) Indicates if this song is a modchart.
@@ -350,51 +298,31 @@ namespace SabreTools.Models.Charts
/// Specifies a voice type for the singer (either "male" or "female").
/// </summary>
/// <remarks>vocal_gender</remarks>
#if NET48
public string VocalGender { get; set; }
#else
public string? VocalGender { get; set; }
#endif
/// <summary>
/// Specifies a tuning for 17-fret Pro Guitar.
/// </summary>
/// <remarks>real_guitar_tuning</remarks>
#if NET48
public string RealGuitarTuning { get; set; }
#else
public string? RealGuitarTuning { get; set; }
#endif
/// <summary>
/// Specifies a tuning for 22-fret Pro Guitar.
/// </summary>
/// <remarks>real_guitar_22_tuning</remarks>
#if NET48
public string RealGuitar22Tuning { get; set; }
#else
public string? RealGuitar22Tuning { get; set; }
#endif
/// <summary>
/// Specifies a tuning for 17-fret Pro Bass.
/// </summary>
/// <remarks>real_bass_tuning</remarks>
#if NET48
public string RealBassTuning { get; set; }
#else
public string? RealBassTuning { get; set; }
#endif
/// <summary>
/// Specifies a tuning for 22-fret Pro Bass.
/// </summary>
/// <remarks>real_bass_22_tuning</remarks>
#if NET48
public string RealBass22Tuning { get; set; }
#else
public string? RealBass22Tuning { get; set; }
#endif
/// <summary>
/// Specifies the number of lanes for the right hand in Real Keys.
@@ -479,11 +407,7 @@ namespace SabreTools.Models.Charts
/// Valid values are "none", "half", or "full".
/// </summary>
/// <remarks>early_hit_window_size</remarks>
#if NET48
public string EarlyHitWindowSize { get; set; }
#else
public string? EarlyHitWindowSize { get; set; }
#endif
/// <summary>
/// (CH) Sets whether or not end events in the chart will be respected.
@@ -560,31 +484,19 @@ namespace SabreTools.Models.Charts
/// Included in either the chart folder or the game the chart was made for, or sourced from this repository of icons.
/// </summary>
/// <remarks>icon</remarks>
#if NET48
public string Icon { get; set; }
#else
public string? Icon { get; set; }
#endif
/// <summary>
/// Name for a background image file.
/// </summary>
/// <remarks>background</remarks>
#if NET48
public string Background { get; set; }
#else
public string? Background { get; set; }
#endif
/// <summary>
/// Name for a background video file.
/// </summary>
/// <remarks>video</remarks>
#if NET48
public string Video { get; set; }
#else
public string? Video { get; set; }
#endif
/// <summary>
/// Name for a background video file.
@@ -610,11 +522,7 @@ namespace SabreTools.Models.Charts
/// Name for a cover image file.
/// </summary>
/// <remarks>cover</remarks>
#if NET48
public string Cover { get; set; }
#else
public string? Cover { get; set; }
#endif
#endregion
@@ -624,41 +532,25 @@ namespace SabreTools.Models.Charts
/// (PS) Name for banner A.
/// </summary>
/// <remarks>link_name_a</remarks>
#if NET48
public string LinkNameA { get; set; }
#else
public string? LinkNameA { get; set; }
#endif
/// <summary>
/// (PS) Name for banner B.
/// </summary>
/// <remarks>link_name_b</remarks>
#if NET48
public string LinkNameB { get; set; }
#else
public string? LinkNameB { get; set; }
#endif
/// <summary>
/// (PS) Link that clicking banner A will open.
/// </summary>
/// <remarks>banner_link_a</remarks>
#if NET48
public string BannerLinkA { get; set; }
#else
public string? BannerLinkA { get; set; }
#endif
/// <summary>
/// (PS) Link that clicking banner B will open.
/// </summary>
/// <remarks>banner_link_b</remarks>
#if NET48
public string BannerLinkB { get; set; }
#else
public string? BannerLinkB { get; set; }
#endif
#endregion
@@ -668,21 +560,13 @@ namespace SabreTools.Models.Charts
/// (FoFiX) High score data.
/// </summary>
/// <remarks>scores</remarks>
#if NET48
public string Scores { get; set; }
#else
public string? Scores { get; set; }
#endif
/// <summary>
/// (FoFiX) Additional score data.
/// </summary>
/// <remarks>scores_ext</remarks>
#if NET48
public string ScoresExt { get; set; }
#else
public string? ScoresExt { get; set; }
#endif
/// <summary>
/// (FoFiX) Play count.
@@ -700,31 +584,19 @@ namespace SabreTools.Models.Charts
/// (FoFiX) Career ID for this song.
/// </summary>
/// <remarks>unlock_id</remarks>
#if NET48
public string UnlockId { get; set; }
#else
public string? UnlockId { get; set; }
#endif
/// <summary>
/// (FoFiX) The career ID that must be completed to unlock this song.
/// </summary>
/// <remarks>unlock_require</remarks>
#if NET48
public string UnlockRequire { get; set; }
#else
public string? UnlockRequire { get; set; }
#endif
/// <summary>
/// (FoFiX) Text to display if the song is locked.
/// </summary>
/// <remarks>unlock_text</remarks>
#if NET48
public string UnlockText { get; set; }
#else
public string? UnlockText { get; set; }
#endif
/// <summary>
/// (FoFiX) Indicates if the song is unlocked.

View File

@@ -10,20 +10,12 @@ namespace SabreTools.Models.Charts
/// A space-separated list of .ini sections to include in the career.
/// </summary>
/// <remarks>sections</remarks>
#if NET48
public string[] SectionList { get; set; }
#else
public string[]? SectionList { get; set; }
#endif
/// <summary>
/// `name` - Display name of the tier.
/// `unlock_id` - Name used for associating a song with this tier, and for checking unlock requirements.
/// </summary>
#if NET48
public Dictionary<string, (string Name, string UnlockId)> Sections { get; set; }
#else
public Dictionary<string, (string? Name, string? UnlockId)>? Sections { get; set; }
#endif
}
}

View File

@@ -5,20 +5,12 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,35 +5,19 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>description</remarks>
[Required]
#if NET48
public string Description { get; set; }
#else
public string? Description { get; set; }
#endif
/// <remarks>default</remarks>
#if NET48
public string Default { get; set; }
#else
public string? Default { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,42 +5,22 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>type, (cpu|audio)</remarks>
[Required]
#if NET48
public string Type { get; set; }
#else
public string? Type { get; set; }
#endif
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>flags</remarks>
#if NET48
public string Flags { get; set; }
#else
public string? Flags { get; set; }
#endif
/// <remarks>clock, Numeric?</remarks>
#if NET48
public string Clock { get; set; }
#else
public string? Clock { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -4,118 +4,54 @@ namespace SabreTools.Models.ClrMamePro
public class ClrMamePro
{
/// <remarks>name</remarks>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>description</remarks>
#if NET48
public string Description { get; set; }
#else
public string? Description { get; set; }
#endif
/// <remarks>rootdir</remarks>
#if NET48
public string RootDir { get; set; }
#else
public string? RootDir { get; set; }
#endif
/// <remarks>category</remarks>
#if NET48
public string Category { get; set; }
#else
public string? Category { get; set; }
#endif
/// <remarks>version</remarks>
#if NET48
public string Version { get; set; }
#else
public string? Version { get; set; }
#endif
/// <remarks>date</remarks>
#if NET48
public string Date { get; set; }
#else
public string? Date { get; set; }
#endif
/// <remarks>author</remarks>
#if NET48
public string Author { get; set; }
#else
public string? Author { get; set; }
#endif
/// <remarks>homepage</remarks>
#if NET48
public string Homepage { get; set; }
#else
public string? Homepage { get; set; }
#endif
/// <remarks>url</remarks>
#if NET48
public string Url { get; set; }
#else
public string? Url { get; set; }
#endif
/// <remarks>comment</remarks>
#if NET48
public string Comment { get; set; }
#else
public string? Comment { get; set; }
#endif
/// <remarks>header</remarks>
#if NET48
public string Header { get; set; }
#else
public string? Header { get; set; }
#endif
/// <remarks>type</remarks>
#if NET48
public string Type { get; set; }
#else
public string? Type { get; set; }
#endif
/// <remarks>forcemerging</remarks>
#if NET48
public string ForceMerging { get; set; }
#else
public string? ForceMerging { get; set; }
#endif
/// <remarks>forcezipping</remarks>
#if NET48
public string ForceZipping { get; set; }
#else
public string? ForceZipping { get; set; }
#endif
/// <remarks>forcepacking</remarks>
#if NET48
public string ForcePacking { get; set; }
#else
public string? ForcePacking { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,34 +5,18 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>entry</remarks>
#if NET48
public string[] Entry { get; set; }
#else
public string[]? Entry { get; set; }
#endif
/// <remarks>default, (yes|no) "no"</remarks>
#if NET48
public string Default { get; set; }
#else
public string? Default { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,55 +5,27 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>md5</remarks>
#if NET48
public string MD5 { get; set; }
#else
public string? MD5 { get; set; }
#endif
/// <remarks>sha1</remarks>
#if NET48
public string SHA1 { get; set; }
#else
public string? SHA1 { get; set; }
#endif
/// <remarks>merge</remarks>
#if NET48
public string Merge { get; set; }
#else
public string? Merge { get; set; }
#endif
/// <remarks>status</remarks>
#if NET48
public string Status { get; set; }
#else
public string? Status { get; set; }
#endif
/// <remarks>flags</remarks>
#if NET48
public string Flags { get; set; }
#else
public string? Flags { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,48 +5,24 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>status, (good|imperfect|preliminary)</remarks>
[Required]
#if NET48
public string Status { get; set; }
#else
public string? Status { get; set; }
#endif
/// <remarks>color, (good|imperfect|preliminary)</remarks>
#if NET48
public string Color { get; set; }
#else
public string? Color { get; set; }
#endif
/// <remarks>sound, (good|imperfect|preliminary)</remarks>
#if NET48
public string Sound { get; set; }
#else
public string? Sound { get; set; }
#endif
/// <remarks>palettesize, Numeric?</remarks>
#if NET48
public string PaletteSize { get; set; }
#else
public string? PaletteSize { get; set; }
#endif
/// <remarks>blit, (plain|dirty)</remarks>
#if NET48
public string Blit { get; set; }
#else
public string? Blit { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -7,168 +7,80 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>description</remarks>
#if NET48
public string Description { get; set; }
#else
public string? Description { get; set; }
#endif
/// <remarks>year</remarks>
#if NET48
public string Year { get; set; }
#else
public string? Year { get; set; }
#endif
/// <remarks>manufacturer</remarks>
#if NET48
public string Manufacturer { get; set; }
#else
public string? Manufacturer { get; set; }
#endif
/// <remarks>category</remarks>
#if NET48
public string Category { get; set; }
#else
public string? Category { get; set; }
#endif
/// <remarks>cloneof</remarks>
#if NET48
public string CloneOf { get; set; }
#else
public string? CloneOf { get; set; }
#endif
/// <remarks>romof</remarks>
#if NET48
public string RomOf { get; set; }
#else
public string? RomOf { get; set; }
#endif
/// <remarks>sampleof</remarks>
#if NET48
public string SampleOf { get; set; }
#else
public string? SampleOf { get; set; }
#endif
/// <remarks>release</remarks>
#if NET48
public Release[] Release { get; set; }
#else
public Release[]? Release { get; set; }
#endif
/// <remarks>biosset</remarks>
#if NET48
public BiosSet[] BiosSet { get; set; }
#else
public BiosSet[]? BiosSet { get; set; }
#endif
/// <remarks>rom</remarks>
#if NET48
public Rom[] Rom { get; set; }
#else
public Rom[]? Rom { get; set; }
#endif
/// <remarks>disk</remarks>
#if NET48
public Disk[] Disk { get; set; }
#else
public Disk[]? Disk { get; set; }
#endif
/// <remarks>sample</remarks>
#if NET48
public Sample[] Sample { get; set; }
#else
public Sample[]? Sample { get; set; }
#endif
/// <remarks>archive</remarks>
#if NET48
public Archive[] Archive { get; set; }
#else
public Archive[]? Archive { get; set; }
#endif
#region Aaru Extensions
/// <remarks>media, Appears after Disk</remarks>
#if NET48
public Media[] Media { get; set; }
#else
public Media[]? Media { get; set; }
#endif
#endregion
#region MAME Extensions
/// <remarks>chip, Appears after Archive</remarks>
#if NET48
public Chip[] Chip { get; set; }
#else
public Chip[]? Chip { get; set; }
#endif
/// <remarks>video, Appears after Chip</remarks>
#if NET48
public Video[] Video { get; set; }
#else
public Video[]? Video { get; set; }
#endif
/// <remarks>sound, Appears after Video</remarks>
#if NET48
public Sound Sound { get; set; }
#else
public Sound? Sound { get; set; }
#endif
/// <remarks>input, Appears after Sound</remarks>
#if NET48
public Input Input { get; set; }
#else
public Input? Input { get; set; }
#endif
/// <remarks>dipswitch, Appears after Input</remarks>
#if NET48
public DipSwitch[] DipSwitch { get; set; }
#else
public DipSwitch[]? DipSwitch { get; set; }
#endif
/// <remarks>driver, Appears after DipSwitch</remarks>
#if NET48
public Driver Driver { get; set; }
#else
public Driver? Driver { get; set; }
#endif
#endregion
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,56 +5,28 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>players, Numeric/remarks>
[Required]
#if NET48
public string Players { get; set; }
#else
public string? Players { get; set; }
#endif
/// <remarks>control</remarks>
#if NET48
public string Control { get; set; }
#else
public string? Control { get; set; }
#endif
/// <remarks>buttons, Numeric</remarks>
[Required]
#if NET48
public string Buttons { get; set; }
#else
public string? Buttons { get; set; }
#endif
/// <remarks>coins, Numeric</remarks>
#if NET48
public string Coins { get; set; }
#else
public string? Coins { get; set; }
#endif
/// <remarks>tilt, (yes|no) "no"</remarks>
#if NET48
public string Tilt { get; set; }
#else
public string? Tilt { get; set; }
#endif
/// <remarks>service, (yes|no) "no"</remarks>
#if NET48
public string Service { get; set; }
#else
public string? Service { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,48 +5,24 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>md5</remarks>
#if NET48
public string MD5 { get; set; }
#else
public string? MD5 { get; set; }
#endif
/// <remarks>sha1</remarks>
#if NET48
public string SHA1 { get; set; }
#else
public string? SHA1 { get; set; }
#endif
/// <remarks>sha256</remarks>
#if NET48
public string SHA256 { get; set; }
#else
public string? SHA256 { get; set; }
#endif
/// <remarks>spamsum</remarks>
#if NET48
public string SpamSum { get; set; }
#else
public string? SpamSum { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -3,27 +3,15 @@ namespace SabreTools.Models.ClrMamePro
public class MetadataFile
{
/// <remarks>clrmamepro</remarks>
#if NET48
public ClrMamePro ClrMamePro { get; set; }
#else
public ClrMamePro? ClrMamePro { get; set; }
#endif
/// <remarks>game, machine, resource, set</remarks>
#if NET48
public GameBase[] Game { get; set; }
#else
public GameBase?[]? Game { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,49 +5,25 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>region</remarks>
[Required]
#if NET48
public string Region { get; set; }
#else
public string? Region { get; set; }
#endif
/// <remarks>language</remarks>
#if NET48
public string Language { get; set; }
#else
public string? Language { get; set; }
#endif
/// <remarks>date</remarks>
#if NET48
public string Date { get; set; }
#else
public string? Date { get; set; }
#endif
/// <remarks>default</remarks>
#if NET48
public string Default { get; set; }
#else
public string? Default { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,181 +5,93 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>size, Numeric</remarks>
[Required]
#if NET48
public string Size { get; set; }
#else
public string? Size { get; set; }
#endif
/// <remarks>crc</remarks>
#if NET48
public string CRC { get; set; }
#else
public string? CRC { get; set; }
#endif
/// <remarks>md5</remarks>
#if NET48
public string MD5 { get; set; }
#else
public string? MD5 { get; set; }
#endif
/// <remarks>sha1</remarks>
#if NET48
public string SHA1 { get; set; }
#else
public string? SHA1 { get; set; }
#endif
/// <remarks>merge</remarks>
#if NET48
public string Merge { get; set; }
#else
public string? Merge { get; set; }
#endif
/// <remarks>status</remarks>
#if NET48
public string Status { get; set; }
#else
public string? Status { get; set; }
#endif
/// <remarks>flags</remarks>
#if NET48
public string Flags { get; set; }
#else
public string? Flags { get; set; }
#endif
/// <remarks>date</remarks>
#if NET48
public string Date { get; set; }
#else
public string? Date { get; set; }
#endif
#region Hash Extensions
/// <remarks>sha256; Also in No-Intro spec; Appears after SHA1</remarks>
#if NET48
public string SHA256 { get; set; }
#else
public string? SHA256 { get; set; }
#endif
/// <remarks>sha384; Appears after SHA256</remarks>
#if NET48
public string SHA384 { get; set; }
#else
public string? SHA384 { get; set; }
#endif
/// <remarks>sha512; Appears after SHA384</remarks>
#if NET48
public string SHA512 { get; set; }
#else
public string? SHA512 { get; set; }
#endif
/// <remarks>spamsum; Appears after SHA512</remarks>
#if NET48
public string SpamSum { get; set; }
#else
public string? SpamSum { get; set; }
#endif
#endregion
#region DiscImgeCreator Extensions
/// <remarks>xxh3_64; Appears after SpamSum</remarks>
#if NET48
public string xxHash364 { get; set; }
#else
public string? xxHash364 { get; set; }
#endif
/// <remarks>xxh3_128; Appears after xxHash364</remarks>
#if NET48
public string xxHash3128 { get; set; }
#else
public string? xxHash3128 { get; set; }
#endif
#endregion
#region MAME Extensions
/// <remarks>region; Appears after Status</remarks>
#if NET48
public string Region { get; set; }
#else
public string? Region { get; set; }
#endif
/// <remarks>offs; Appears after Flags</remarks>
#if NET48
public string Offs { get; set; }
#else
public string? Offs { get; set; }
#endif
#endregion
#region No-Intro Extensions
/// <remarks>serial; Appears after Offs</remarks>
#if NET48
public string Serial { get; set; }
#else
public string? Serial { get; set; }
#endif
/// <remarks>header; Appears after Serial</remarks>
#if NET48
public string Header { get; set; }
#else
public string? Header { get; set; }
#endif
#endregion
#region RomVault Extensions
/// <remarks>inverted; Boolean; Appears after Date</remarks>
#if NET48
public string Inverted { get; set; }
#else
public string? Inverted { get; set; }
#endif
/// <remarks>mia; Boolean; Appears after Inverted</remarks>
#if NET48
public string MIA { get; set; }
#else
public string? MIA { get; set; }
#endif
#endregion
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -4,108 +4,48 @@ namespace SabreTools.Models.ClrMamePro
public class RomVault
{
/// <remarks>name</remarks>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>description</remarks>
#if NET48
public string Description { get; set; }
#else
public string? Description { get; set; }
#endif
/// <remarks>rootdir</remarks>
#if NET48
public string RootDir { get; set; }
#else
public string? RootDir { get; set; }
#endif
/// <remarks>category</remarks>
#if NET48
public string Category { get; set; }
#else
public string? Category { get; set; }
#endif
/// <remarks>version</remarks>
#if NET48
public string Version { get; set; }
#else
public string? Version { get; set; }
#endif
/// <remarks>date</remarks>
#if NET48
public string Date { get; set; }
#else
public string? Date { get; set; }
#endif
/// <remarks>author</remarks>
#if NET48
public string Author { get; set; }
#else
public string? Author { get; set; }
#endif
/// <remarks>homepage</remarks>
#if NET48
public string Homepage { get; set; }
#else
public string? Homepage { get; set; }
#endif
/// <remarks>url</remarks>
#if NET48
public string Url { get; set; }
#else
public string? Url { get; set; }
#endif
/// <remarks>comment</remarks>
#if NET48
public string Comment { get; set; }
#else
public string? Comment { get; set; }
#endif
/// <remarks>header</remarks>
#if NET48
public string Header { get; set; }
#else
public string? Header { get; set; }
#endif
/// <remarks>type</remarks>
#if NET48
public string Type { get; set; }
#else
public string? Type { get; set; }
#endif
/// <remarks>forcemerging</remarks>
#if NET48
public string ForceMerging { get; set; }
#else
public string? ForceMerging { get; set; }
#endif
/// <remarks>forcezipping</remarks>
#if NET48
public string ForceZipping { get; set; }
#else
public string? ForceZipping { get; set; }
#endif
/// <remarks>forcepacking</remarks>
#if NET48
public string ForcePacking { get; set; }
#else
public string? ForcePacking { get; set; }
#endif
}
}

View File

@@ -5,20 +5,12 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,20 +5,12 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>channels, Numeric?</remarks>
[Required]
#if NET48
public string Channels { get; set; }
#else
public string? Channels { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,63 +5,31 @@ namespace SabreTools.Models.ClrMamePro
{
/// <remarks>screen, (raster|vector)</remarks>
[Required]
#if NET48
public string Screen { get; set; }
#else
public string? Screen { get; set; }
#endif
/// <remarks>orientation, (vertical|horizontal)</remarks>
[Required]
#if NET48
public string Orientation { get; set; }
#else
public string? Orientation { get; set; }
#endif
/// <remarks>x, Numeric?</remarks>
#if NET48
public string X { get; set; }
#else
public string? X { get; set; }
#endif
/// <remarks>y, Numeric?</remarks>
#if NET48
public string Y { get; set; }
#else
public string? Y { get; set; }
#endif
/// <remarks>aspectx, Numeric?</remarks>
#if NET48
public string AspectX { get; set; }
#else
public string? AspectX { get; set; }
#endif
/// <remarks>aspecty, Numeric?</remarks>
#if NET48
public string AspectY { get; set; }
#else
public string? AspectY { get; set; }
#endif
/// <remarks>freq, Numeric?</remarks>
#if NET48
public string Freq { get; set; }
#else
public string? Freq { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public object[] ADDITIONAL_ELEMENTS { get; set; }
#else
public object[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Models.Compression.LZ
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/kernel32/lzexpand.c"/>
public sealed class FileHeaader
{
#if NET48
public string Magic { get; set; }
#else
public string? Magic { get; set; }
#endif
public byte CompressionType { get; set; }

View File

@@ -7,11 +7,7 @@ namespace SabreTools.Models.Compression.LZ
/// <summary>
/// Internal backing stream
/// </summary>
#if NET48
public Stream Source { get; set; }
#else
public Stream? Source { get; set; }
#endif
/// <summary>
/// The last char of the filename for replacement
@@ -36,11 +32,7 @@ namespace SabreTools.Models.Compression.LZ
/// <summary>
/// The rotating LZ table
/// </summary>
#if NET48
public byte[] Table { get; set; }
#else
public byte[]? Table { get; set; }
#endif
/// <summary>
/// CURrent TABle ENTry
@@ -65,11 +57,7 @@ namespace SabreTools.Models.Compression.LZ
/// <summary>
/// GETLEN bytes
/// </summary>
#if NET48
public byte[] Window { get; set; }
#else
public byte[]? Window { get; set; }
#endif
/// <summary>
/// Current read

View File

@@ -5,89 +5,54 @@ namespace SabreTools.Models.Compression.LZX
/// tree preceding the other trees.
/// </summary>
/// <see href="https://interoperability.blob.core.windows.net/files/MS-PATCH/%5bMS-PATCH%5d.pdf"/>
public class AlignedOffsetBlock
public class AlignedOffsetBlockData : BlockData
{
/// <summary>
/// Generic block header
/// </summary>
#if NET48
public BlockHeader Header { get; set; }
#else
public BlockHeader? Header { get; set; }
#endif
/// <summary>
/// Aligned offset tree
/// </summary>
/// <remarks>8 elements, 3 bits each</remarks>
#if NET48
public byte[] AlignedOffsetTree { get; set; }
#else
public byte[]? AlignedOffsetTree { get; set; }
#endif
/// <summary>
/// Pretree for first 256 elements of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeFirst256 { get; set; }
#else
public byte[]? PretreeFirst256 { get; set; }
#endif
/// <summary>
/// Path lengths of first 256 elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsFirst256 { get; set; }
#else
public int[]? PathLengthsFirst256 { get; set; }
#endif
/// <summary>
/// Pretree for remainder of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeRemainder { get; set; }
#else
public byte[]? PretreeRemainder { get; set; }
#endif
/// <summary>
/// Path lengths of remaining elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsRemainder { get; set; }
#else
public int[]? PathLengthsRemainder { get; set; }
#endif
/// <summary>
/// Pretree for length tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeLengthTree { get; set; }
#else
public byte[]? PretreeLengthTree { get; set; }
#endif
/// <summary>
/// Path lengths of elements in length tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsLengthTree { get; set; }
#else
public int[]? PathLengthsLengthTree { get; set; }
#endif
// Entry Comments Size
// ---------------------------------------------------------------------------------------
// Token sequence (matches and literals) Specified in section 2.6 Variable
/// <summary>
/// Token sequence (matches and literals)
/// </summary>
/// <remarks>Variable</remarks>
public byte[]? TokenSequence { get; set; }
}
}

24
Compression/LZX/Block.cs Normal file
View File

@@ -0,0 +1,24 @@
namespace SabreTools.Models.Compression.LZX
{
/// <summary>
/// An LZXD block represents a sequence of compressed data that is encoded with the same set of
/// Huffman trees, or a sequence of uncompressed data. There can be one or more LZXD blocks in a
/// compressed stream, each with its own set of Huffman trees. Blocks do not have to start or end on a
/// chunk boundary; blocks can span multiple chunks, or a single chunk can contain multiple blocks. The
/// number of chunks is related to the size of the data being compressed, while the number of blocks is
/// related to how well the data is compressed.
/// </summary>
/// <see href="https://interoperability.blob.core.windows.net/files/MS-PATCH/%5bMS-PATCH%5d.pdf"/>
public class Block
{
/// <summary>
/// Block header
/// </summary>
public BlockHeader? Header { get; set; }
/// <summary>
/// Block data
/// </summary>
public BlockData? BlockData { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace SabreTools.Models.Compression.LZX
{
/// <see href="https://interoperability.blob.core.windows.net/files/MS-PATCH/%5bMS-PATCH%5d.pdf"/>
public abstract class BlockData
{
// No common fields between all block data
}
}

View File

@@ -1,14 +1,9 @@
namespace SabreTools.Models.Compression.LZX
{
/// <summary>
/// An LZXD block represents a sequence of compressed data that is encoded with the same set of
/// Huffman trees, or a sequence of uncompressed data. There can be one or more LZXD blocks in a
/// compressed stream, each with its own set of Huffman trees. Blocks do not have to start or end on a
/// chunk boundary; blocks can span multiple chunks, or a single chunk can contain multiple blocks. The
/// number of chunks is related to the size of the data being compressed, while the number of blocks is
/// related to how well the data is compressed. The Block Type field, as specified in section 2.3.1.1,
/// indicates which type of block follows, and the Block Size field, as specified in section 2.3.1.2,
/// indicates the number of uncompressed bytes represented by the block. Following the generic block
/// The Block Type field, as specified in section 2.3.1.1, indicates which type of block follows,
/// and the Block Size field, as specified in section 2.3.1.2, indicates the number of
/// uncompressed bytes represented by the block. Following the generic block
/// header is a type-specific header that describes the remainder of the block.
/// </summary>
/// <see href="https://interoperability.blob.core.windows.net/files/MS-PATCH/%5bMS-PATCH%5d.pdf"/>

25
Compression/LZX/Chunk.cs Normal file
View File

@@ -0,0 +1,25 @@
namespace SabreTools.Models.Compression.LZX
{
/// <summary>
/// The LZXD compressor emits chunks of compressed data. A chunk represents exactly 32 KB of
/// uncompressed data until the last chunk in the stream, which can represent less than 32 KB. To
/// ensure that an exact number of input bytes represent an exact number of output bytes for each
/// chunk, after each 32 KB of uncompressed data is represented in the output compressed bitstream, the
/// output bitstream is padded with up to 15 bits of zeros to realign the bitstream on a 16-bit boundary
/// (even byte boundary) for the next 32 KB of data. This results in a compressed chunk of a byte-aligned
/// size. The compressed chunk could be smaller than 32 KB or larger than 32 KB if the data is
/// incompressible when the chunk is not the last one.
/// </summary>
public class Chunk
{
/// <summary>
/// Chunk header
/// </summary>
public ChunkHeader? Header { get; set; }
/// <summary>
/// Block headers and data
/// </summary>
public Block[]? Blocks { get; set; }
}
}

View File

@@ -0,0 +1,46 @@
namespace SabreTools.Models.Compression.LZX
{
/// <summary>
/// The LZXD compressor emits chunks of compressed data. A chunk represents exactly 32 KB of
/// uncompressed data until the last chunk in the stream, which can represent less than 32 KB. To
/// ensure that an exact number of input bytes represent an exact number of output bytes for each
/// chunk, after each 32 KB of uncompressed data is represented in the output compressed bitstream, the
/// output bitstream is padded with up to 15 bits of zeros to realign the bitstream on a 16-bit boundary
/// (even byte boundary) for the next 32 KB of data. This results in a compressed chunk of a byte-aligned
/// size. The compressed chunk could be smaller than 32 KB or larger than 32 KB if the data is
/// incompressible when the chunk is not the last one.
/// </summary>
public class ChunkHeader
{
/// <summary>
/// The LZXD engine encodes a compressed, chunk-size prefix field preceding each compressed chunk in
/// the compressed byte stream. The compressed, chunk-size prefix field is a byte aligned, little-endian,
/// 16-bit field. The chunk prefix chain could be followed in the compressed stream without
/// decompressing any data. The next chunk prefix is at a location computed by the absolute byte offset
/// location of this chunk prefix plus 2 (for the size of the chunk-size prefix field) plus the current chunk
/// size.
/// </summary>
public ushort ChunkSize { get; set; }
/// <summary>
/// The first bit in the first chunk in the LZXD bitstream (following the 2-byte, chunk-size prefix described
/// in section 2.2.1) indicates the presence or absence of two 16-bit fields immediately following the
/// single bit. If the bit is set, E8 translation is enabled for all the following chunks in the stream using the
/// 32-bit value derived from the two 16-bit fields as the E8_file_size provided to the compressor when E8
/// translation was enabled. Note that E8_file_size is completely independent of the length of the
/// uncompressed data. E8 call translation is disabled after the 32,768th chunk (after 1 gigabyte (GB) of
/// uncompressed data).
/// </summary>
public byte E8Translation { get; set; }
/// <summary>
/// E8 translation size, high WORD
/// </summary>
public ushort? TranslationSizeHighWord { get; set; }
/// <summary>
/// E8 translation size, low WORD
/// </summary>
public ushort? TranslationSizeLowWord { get; set; }
}
}

View File

@@ -3,44 +3,36 @@ namespace SabreTools.Models.Compression.LZX
public static class Constants
{
/* some constants defined by the LZX specification */
public const int LZX_MIN_MATCH = (2);
public const int LZX_MAX_MATCH = (257);
public const int LZX_NUM_CHARS = (256);
/// <summary>
/// also blocktypes 4-7 invalid
/// </summary>
public const int LZX_BLOCKTYPE_INVALID = (0);
public const int LZX_BLOCKTYPE_VERBATIM = (1);
public const int LZX_BLOCKTYPE_ALIGNED = (2);
public const int LZX_BLOCKTYPE_UNCOMPRESSED = (3);
public const int LZX_PRETREE_NUM_ELEMENTS = (20);
public const int LZX_MIN_MATCH = 2;
public const int LZX_MAX_MATCH = 257;
public const int LZX_NUM_CHARS = 256;
public const int LZX_PRETREE_NUM_ELEMENTS = 20;
/// <summary>
/// aligned offset tree #elements
/// </summary>
public const int LZX_ALIGNED_NUM_ELEMENTS = (8);
public const int LZX_ALIGNED_NUM_ELEMENTS = 8;
/// <summary>
/// this one missing from spec!
/// </summary>
public const int LZX_NUM_PRIMARY_LENGTHS = (7);
public const int LZX_NUM_PRIMARY_LENGTHS = 7;
/// <summary>
/// length tree #elements
/// </summary>
public const int LZX_NUM_SECONDARY_LENGTHS = (249);
public const int LZX_NUM_SECONDARY_LENGTHS = 249;
/* 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_TABLEBITS = (12);
public const int LZX_LENGTH_MAXSYMBOLS = (LZX_NUM_SECONDARY_LENGTHS + 1);
public const int LZX_LENGTH_TABLEBITS = (12);
public const int LZX_ALIGNED_MAXSYMBOLS = (LZX_ALIGNED_NUM_ELEMENTS);
public const int LZX_ALIGNED_TABLEBITS = (7);
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_TABLEBITS = 12;
public const int LZX_LENGTH_MAXSYMBOLS = LZX_NUM_SECONDARY_LENGTHS + 1;
public const int LZX_LENGTH_TABLEBITS = 12;
public const int LZX_ALIGNED_MAXSYMBOLS = LZX_ALIGNED_NUM_ELEMENTS;
public const int LZX_ALIGNED_TABLEBITS = 7;
public const int LZX_LENTABLE_SAFETY = (64); /* we allow length table decoding overruns */
public const int LZX_LENTABLE_SAFETY = 64; /* we allow length table decoding overruns */
}
}

View File

@@ -1,102 +0,0 @@
namespace SabreTools.Models.Compression.LZX
{
public class Header
{
/*
2.2 Header
2.2.1 Chunk Size
The LZXD compressor emits chunks of compressed data. A chunk represents exactly 32 KB of
uncompressed data until the last chunk in the stream, which can represent less than 32 KB. To
ensure that an exact number of input bytes represent an exact number of output bytes for each
chunk, after each 32 KB of uncompressed data is represented in the output compressed bitstream, the
output bitstream is padded with up to 15 bits of zeros to realign the bitstream on a 16-bit boundary
(even byte boundary) for the next 32 KB of data. This results in a compressed chunk of a byte-aligned
size. The compressed chunk could be smaller than 32 KB or larger than 32 KB if the data is
incompressible when the chunk is not the last one.
The LZXD engine encodes a compressed, chunk-size prefix field preceding each compressed chunk in
the compressed byte stream. The compressed, chunk-size prefix field is a byte aligned, little-endian,
16-bit field. The chunk prefix chain could be followed in the compressed stream without
decompressing any data. The next chunk prefix is at a location computed by the absolute byte offset
location of this chunk prefix plus 2 (for the size of the chunk-size prefix field) plus the current chunk
size.
2.2.2 E8 Call Translation
E8 call translation is an optional feature that can be used when the data to compress contains x86
instruction sequences. E8 translation operates as a preprocessing stage before compressing each
chunk, and the compressed stream header contains a bit that indicates whether the decoder shall
reverse the translation as a postprocessing step after decompressing each chunk.
The x86 instruction beginning with a byte value of 0xE8 is followed by a 32-bit, little-endian relative
displacement to the call target. When E8 call translation is enabled, the following preprocessing steps
are performed on the uncompressed input before compression (assuming little-endian byte ordering):
Let chunk_offset refer to the total number of uncompressed bytes preceding this chunk.
Let E8_file_size refer to the caller-specified value given to the compressor or decoded from the header
of the compressed stream during decompression.
The following example shows how E8 translation is performed for each 32-KB chunk of uncompressed
data (or less than 32 KB if last chunk to compress).
if (( chunk_offset < 0x40000000 ) && ( chunk_size > 10 ))
for ( i = 0; i < (chunk_size 10); i++ )
if ( chunk_byte[ i ] == 0xE8 )
long current_pointer = chunk_offset + i;
long displacement = chunk_byte[ i+1 ] |
chunk_byte[ i+2 ] << 8 |
chunk_byte[ i+3 ] << 16 |
chunk_byte[ i+4 ] << 24;
long target = current_pointer + displacement;
if (( target >= 0 ) && ( target < E8_file_size+current_pointer))
if ( target >= E8_file_size )
target = displacement E8_file_size;
endif
chunk_byte[ i+1 ] = (byte)( target );
chunk_byte[ i+2 ] = (byte)( target >> 8 );
chunk_byte[ i+3 ] = (byte)( target >> 16 );
chunk_byte[ i+4 ] = (byte)( target >> 24 );
endif
i += 4;
endif
endfor
endif
After decompression, the E8 scanning algorithm is the same. The following example shows how E8
translation reversal is performed.
long value = chunk_byte[ i+1 ] |
chunk_byte[ i+2 ] << 8 |
chunk_byte[ i+3 ] << 16 |
chunk_byte[ i+4 ] << 24;
if (( value >= -current_pointer ) && ( value < E8_file_size ))
if ( value >= 0 )
displacement = value current_pointer;
else
displacement = value + E8_file_size;
endif
chunk_byte[ i+1 ] = (byte)( displacement );
chunk_byte[ i+2 ] = (byte)( displacement >> 8 );
chunk_byte[ i+3 ] = (byte)( displacement >> 16 );
chunk_byte[ i+4 ] = (byte)( displacement >> 24 );
endif
The first bit in the first chunk in the LZXD bitstream (following the 2-byte, chunk-size prefix described
in section 2.2.1) indicates the presence or absence of two 16-bit fields immediately following the
single bit. If the bit is set, E8 translation is enabled for all the following chunks in the stream using the
32-bit value derived from the two 16-bit fields as the E8_file_size provided to the compressor when E8
translation was enabled. Note that E8_file_size is completely independent of the length of the
uncompressed data. E8 call translation is disabled after the 32,768th chunk (after 1 gigabyte (GB) of
uncompressed data).
Field Comments Size
----------------------------------------------------------------
E8 translation 0-disabled, 1-enabled 1 bit
Translation size high word Only present if enabled 0 or 16 bits
Translation size low word Only present if enabled 0 or 16 bits
*/
}
}

View File

@@ -14,17 +14,8 @@ namespace SabreTools.Models.Compression.LZX
/// subsequent compressed block if present.
/// </summary>
/// <see href="https://interoperability.blob.core.windows.net/files/MS-PATCH/%5bMS-PATCH%5d.pdf"/>
public class UncompressedBlock
public class UncompressedBlockData : BlockData
{
/// <summary>
/// Generic block header
/// </summary>
#if NET48
public BlockHeader Header { get; set; }
#else
public BlockHeader? Header { get; set; }
#endif
/// <summary>
/// Padding to align following field on 16-bit boundary
/// </summary>
@@ -53,11 +44,7 @@ namespace SabreTools.Models.Compression.LZX
/// Can use the direct memcpy function, as specified in [IEEE1003.1]
/// </summary>
/// <remarks>Encoded directly in the byte stream, not in the bitstream of byte-swapped 16-bit words</remarks>
#if NET48
public byte[] RawDataBytes { get; set; }
#else
public byte[]? RawDataBytes { get; set; }
#endif
/// <summary>
/// Only if uncompressed size is odd

View File

@@ -4,79 +4,48 @@ namespace SabreTools.Models.Compression.LZX
/// The fields of a verbatim block that follow the generic block header
/// </summary>
/// <see href="https://interoperability.blob.core.windows.net/files/MS-PATCH/%5bMS-PATCH%5d.pdf"/>
public class VerbatimBlock
public class VerbatimBlockData : BlockData
{
/// <summary>
/// Generic block header
/// </summary>
#if NET48
public BlockHeader Header { get; set; }
#else
public BlockHeader? Header { get; set; }
#endif
/// <summary>
/// Pretree for first 256 elements of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeFirst256 { get; set; }
#else
public byte[]? PretreeFirst256 { get; set; }
#endif
/// <summary>
/// Path lengths of first 256 elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsFirst256 { get; set; }
#else
public int[]? PathLengthsFirst256 { get; set; }
#endif
/// <summary>
/// Pretree for remainder of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeRemainder { get; set; }
#else
public byte[]? PretreeRemainder { get; set; }
#endif
/// <summary>
/// Path lengths of remaining elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsRemainder { get; set; }
#else
public int[]? PathLengthsRemainder { get; set; }
#endif
/// <summary>
/// Pretree for length tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeLengthTree { get; set; }
#else
public byte[]? PretreeLengthTree { get; set; }
#endif
/// <summary>
/// Path lengths of elements in length tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsLengthTree { get; set; }
#else
public int[]? PathLengthsLengthTree { get; set; }
#endif
// Entry Comments Size
// ---------------------------------------------------------------------------------------
// Token sequence (matches and literals) Specified in section 2.6 Variable
/// <summary>
/// Token sequence (matches and literals)
/// </summary>
/// <remarks>Variable</remarks>
public byte[]? TokenSequence { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
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; }
}
}

View File

@@ -4,18 +4,6 @@ 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

View File

@@ -1,27 +1,20 @@
namespace SabreTools.Models.Compression.MSZIP
{
/// <summary>
/// Compression with dynamic Huffman codes (BTYPE=10)
/// 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 class DynamicHuffmanCompressedBlockHeader
public abstract class CompressedDataHeader : DataHeader
{
/// <summary>
/// Huffman code lengths for the literal / length alphabet
/// </summary>
#if NET48
public int[] LiteralLengths { get; set; }
#else
public int[]? LiteralLengths { get; set; }
#endif
public virtual uint[]? LiteralLengths { get; set; }
/// <summary>
/// Huffman distance codes for the literal / length alphabet
/// </summary>
#if NET48
public int[] DistanceCodes { get; set; }
#else
public int[]? DistanceCodes { get; set; }
#endif
public virtual uint[]? DistanceCodes { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.Compression.MSZIP
{
/// <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
}
}

View File

@@ -0,0 +1,35 @@
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 DeflateBlockHeader? Header { get; set; }
/// <summary>
/// Compression-specific data header
/// </summary>
public 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; }
}
}

View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.Compression.MSZIP
{
/// <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
}
}

View File

@@ -7,18 +7,14 @@ namespace SabreTools.Models.Compression.MSZIP
/// </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 FixedHuffmanCompressedBlockHeader
public class FixedCompressedDataHeader : CompressedDataHeader
{
#region Properties
/// <summary>
/// Huffman code lengths for the literal / length alphabet
/// </summary>
#if NET48
public uint[] LiteralLengths
#else
public uint[]? LiteralLengths
#endif
public override uint[]? LiteralLengths
{
get
{
@@ -56,11 +52,7 @@ namespace SabreTools.Models.Compression.MSZIP
/// <summary>
/// Huffman distance codes for the literal / length alphabet
/// </summary>
#if NET48
public uint[] DistanceCodes
#else
public uint[]? DistanceCodes
#endif
public override uint[]? DistanceCodes
{
get
{
@@ -90,20 +82,12 @@ namespace SabreTools.Models.Compression.MSZIP
/// <summary>
/// Huffman code lengths for the literal / length alphabet
/// </summary>
#if NET48
private uint[] _literalLengths = null;
#else
private uint[]? _literalLengths = null;
#endif
/// <summary>
/// Huffman distance codes for the literal / length alphabet
/// </summary>
#if NET48
private uint[] _distanceCodes = null;
#else
private uint[]? _distanceCodes = null;
#endif
#endregion
}

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Models.Compression.MSZIP
/// Non-compressed blocks (BTYPE=00)
/// </summary>
/// <see href="https://www.rfc-editor.org/rfc/rfc1951"/>
public class NonCompressedBlockHeader
public class NonCompressedBlockHeader : DataHeader
{
/// <summary>
/// The number of data bytes in the block

View File

@@ -1,45 +1,50 @@
namespace SabreTools.Models.Compression.Quantum
{
/// <see href="www.russotto.net/quantumcomp.html"/>
public static class Constants
{
/// <summary>
/// Mask for Quantum Compression Level
/// </summary>
public const ushort MASK_QUANTUM_LEVEL = 0x00F0;
public static readonly int[] PositionSlot = new int[]
{
0x00000, 0x00001, 0x00002, 0x00003, 0x00004, 0x00006, 0x00008, 0x0000c,
0x00010, 0x00018, 0x00020, 0x00030, 0x00040, 0x00060, 0x00080, 0x000c0,
0x00100, 0x00180, 0x00200, 0x00300, 0x00400, 0x00600, 0x00800, 0x00c00,
0x01000, 0x01800, 0x02000, 0x03000, 0x04000, 0x06000, 0x08000, 0x0c000,
0x10000, 0x18000, 0x20000, 0x30000, 0x40000, 0x60000, 0x80000, 0xc0000,
0x100000, 0x180000
};
public static readonly int[] PositionExtraBits = 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, 14, 14,
15, 15, 16, 16, 17, 17, 18, 18,
19, 19
};
public static readonly int[] LengthSlot = new int[]
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
0x0a, 0x0c, 0x0e, 0x12, 0x16, 0x1a, 0x1e, 0x26,
0x2e, 0x36, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, 0x9e,
0xbe, 0xde, 0xfe
};
public static readonly int[] LengthExtraBits = new int[]
{
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>
/// Lowest Quantum Level (1)
/// Number of position slots for (tsize - 10)
/// </summary>
public const ushort QUANTUM_LEVEL_LO = 0x0010;
/// <summary>
/// Highest Quantum Level (7)
/// </summary>
public const ushort QUANTUM_LEVEL_HI = 0x0070;
/// <summary>
/// Amount to shift over to get int
/// </summary>
public const ushort SHIFT_QUANTUM_LEVEL = 4;
/// <summary>
/// Mask for Quantum Compression Memory
/// </summary>
public const ushort MASK_QUANTUM_MEM = 0x1F00;
/// <summary>
/// Lowest Quantum Memory (10)
/// </summary>
public const ushort QUANTUM_MEM_LO = 0x0A00;
/// <summary>
/// Highest Quantum Memory (21)
/// </summary>
public const ushort QUANTUM_MEM_HI = 0x1500;
/// <summary>
/// Amount to shift over to get int
/// </summary>
public const ushort SHIFT_QUANTUM_MEM = 8;
public static readonly int[] NumPositionSlots = new int[]
{
20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42
};
}
}

View File

@@ -1,23 +1,24 @@
namespace SabreTools.Models.Compression.Quantum
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
/// <see href="http://www.russotto.net/quantumcomp.html"/>
public sealed class Model
{
public int TimeToReorder { get; set; }
public int Entries { get; set; }
#if NET48
public ModelSymbol[] Symbols { get; set; }
#else
/// <remarks>
/// All the models are initialized with the symbols in symbol
/// order in the table, and with every symbol in the table
/// having a frequency of 1
/// </remarks>
public ModelSymbol?[]? Symbols { get; set; }
#endif
#if NET48
public ushort[] LookupTable { get; set; } = new ushort[256];
#else
public ushort[]? LookupTable { get; set; } = new ushort[256];
#endif
/// <remarks>
/// The initial total frequency is equal to the number of entries
/// in the table
/// </remarks>
public int TotalFrequency { get; set; }
/// <remarks>The initial time_to_reorder value is 4</remarks>
public int TimeToReorder { get; set; }
}
}

View File

@@ -1,11 +1,15 @@
namespace SabreTools.Models.Compression.Quantum
{
/// <see href="https://github.com/wine-mirror/wine/blob/master/dlls/cabinet/cabinet.h"/>
/// <see href="http://www.russotto.net/quantumcomp.html"/>
public sealed class ModelSymbol
{
public ushort Symbol { get; set; }
/// <summary>
/// The cumulative frequency is the frequency of all the symbols
/// which are at a higher index in the table than that symbol —
/// thus the last entry in the table has a cumulative frequency of 0.
/// </summary>
public ushort CumulativeFrequency { get; set; }
}
}

30
CueSheets/CueFile.cs Normal file
View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.IO;
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// Represents a single FILE in a cuesheet
/// </summary>
public class CueFile
{
/// <summary>
/// filename
/// </summary>
public string? FileName { get; set; }
/// <summary>
/// filetype
/// </summary>
public CueFileType FileType { get; set; }
/// <summary>
/// List of TRACK in FILE
/// </summary>
public CueTrack?[]? Tracks { get; set; }
}
}

33
CueSheets/CueIndex.cs Normal file
View File

@@ -0,0 +1,33 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// Represents a single INDEX in a TRACK
/// </summary>
public class CueIndex
{
/// <summary>
/// INDEX number, between 0 and 99
/// </summary>
public int Index { get; set; }
/// <summary>
/// Starting time of INDEX in minutes
/// </summary>
public int Minutes { get; set; }
/// <summary>
/// Starting time of INDEX in seconds
/// </summary>
/// <remarks>There are 60 seconds in a minute</remarks>
public int Seconds { get; set; }
/// <summary>
/// Starting time of INDEX in frames.
/// </summary>
/// <remarks>There are 75 frames per second</remarks>
public int Frames { get; set; }
}
}

41
CueSheets/CueSheet.cs Normal file
View File

@@ -0,0 +1,41 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// Represents a single cuesheet
/// </summary>
public class CueSheet
{
/// <summary>
/// CATALOG
/// </summary>
public string? Catalog { get; set; }
/// <summary>
/// CDTEXTFILE
/// </summary>
public string? CdTextFile { get; set; }
/// <summary>
/// PERFORMER
/// </summary>
public string? Performer { get; set; }
/// <summary>
/// SONGWRITER
/// </summary>
public string? Songwriter { get; set; }
/// <summary>
/// TITLE
/// </summary>
public string? Title { get; set; }
/// <summary>
/// List of FILE in cuesheet
/// </summary>
public CueFile?[]? Files { get; set; }
}
}

63
CueSheets/CueTrack.cs Normal file
View File

@@ -0,0 +1,63 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// Represents a single TRACK in a FILE
/// </summary>
public class CueTrack
{
/// <summary>
/// Track number. The range is 1 to 99.
/// </summary>
public int Number { get; set; }
/// <summary>
/// Track datatype
/// </summary>
public CueTrackDataType DataType { get; set; }
/// <summary>
/// FLAGS
/// </summary>
public CueTrackFlag Flags { get; set; }
/// <summary>
/// ISRC
/// </summary>
/// <remarks>12 characters in length</remarks>
public string? ISRC { get; set; }
/// <summary>
/// PERFORMER
/// </summary>
public string? Performer { get; set; }
/// <summary>
/// SONGWRITER
/// </summary>
public string? Songwriter { get; set; }
/// <summary>
/// TITLE
/// </summary>
public string? Title { get; set; }
/// <summary>
/// PREGAP
/// </summary>
public PreGap? PreGap { get; set; }
/// <summary>
/// List of INDEX in TRACK
/// </summary>
/// <remarks>Must start with 0 or 1 and then sequential</remarks>
public CueIndex?[]? Indices { get; set; }
/// <summary>
/// POSTGAP
/// </summary>
public PostGap? PostGap { get; set; }
}
}

116
CueSheets/Enums.cs Normal file
View File

@@ -0,0 +1,116 @@
using System;
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// The audio or data files filetype
/// </summary>
public enum CueFileType
{
/// <summary>
/// Intel binary file (least significant byte first). Use for data files.
/// </summary>
BINARY,
/// <summary>
/// Motorola binary file (most significant byte first). Use for data files.
/// </summary>
MOTOROLA,
/// <summary>
/// Audio AIFF file (44.1KHz 16-bit stereo)
/// </summary>
AIFF,
/// <summary>
/// Audio WAVE file (44.1KHz 16-bit stereo)
/// </summary>
WAVE,
/// <summary>
/// Audio MP3 file (44.1KHz 16-bit stereo)
/// </summary>
MP3,
}
/// <summary>
/// Track datatype
/// </summary>
public enum CueTrackDataType
{
/// <summary>
/// AUDIO, Audio/Music (2352)
/// </summary>
AUDIO,
/// <summary>
/// CDG, Karaoke CD+G (2448)
/// </summary>
CDG,
/// <summary>
/// MODE1/2048, CD-ROM Mode1 Data (cooked)
/// </summary>
MODE1_2048,
/// <summary>
/// MODE1/2352 CD-ROM Mode1 Data (raw)
/// </summary>
MODE1_2352,
/// <summary>
/// MODE2/2336, CD-ROM XA Mode2 Data
/// </summary>
MODE2_2336,
/// <summary>
/// MODE2/2352, CD-ROM XA Mode2 Data
/// </summary>
MODE2_2352,
/// <summary>
/// CDI/2336, CD-I Mode2 Data
/// </summary>
CDI_2336,
/// <summary>
/// CDI/2352, CD-I Mode2 Data
/// </summary>
CDI_2352,
}
/// <summary>
/// Special subcode flags within a track
/// </summary>
[Flags]
public enum CueTrackFlag
{
/// <summary>
/// DCP, Digital copy permitted
/// </summary>
DCP = 1 << 0,
/// <summary>
/// 4CH, Four channel audio
/// </summary>
FourCH = 1 << 1,
/// <summary>
/// PRE, Pre-emphasis enabled (audio tracks only)
/// </summary>
PRE = 1 << 2,
/// <summary>
/// SCMS, Serial Copy Management System (not supported by all recorders)
/// </summary>
SCMS = 1 << 3,
/// <summary>
/// DATA, set for data files. This flag is set automatically based on the tracks filetype
/// </summary>
DATA = 1 << 4,
}
}

28
CueSheets/PostGap.cs Normal file
View File

@@ -0,0 +1,28 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// Represents POSTGAP information of a track
/// </summary>
public class PostGap
{
/// <summary>
/// Length of POSTGAP in minutes
/// </summary>
public int Minutes { get; set; }
/// <summary>
/// Length of POSTGAP in seconds
/// </summary>
/// <remarks>There are 60 seconds in a minute</remarks>
public int Seconds { get; set; }
/// <summary>
/// Length of POSTGAP in frames.
/// </summary>
/// <remarks>There are 75 frames per second</remarks>
public int Frames { get; set; }
}
}

28
CueSheets/PreGap.cs Normal file
View File

@@ -0,0 +1,28 @@
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace SabreTools.Models.CueSheets
{
/// <summary>
/// Represents PREGAP information of a track
/// </summary>
public class PreGap
{
/// <summary>
/// Length of PREGAP in minutes
/// </summary>
public int Minutes { get; set; }
/// <summary>
/// Length of PREGAP in seconds
/// </summary>
/// <remarks>There are 60 seconds in a minute</remarks>
public int Seconds { get; set; }
/// <summary>
/// Length of PREGAP in frames.
/// </summary>
/// <remarks>There are 75 frames per second</remarks>
public int Frames { get; set; }
}
}

View File

@@ -11,11 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// End address (last byte of last VTS_ATRT)
@@ -25,19 +21,11 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Offset to VTS_ATRT n
/// </summary>
#if NET48
public uint[] Offsets { get; set; }
#else
public uint[]? Offsets { get; set; }
#endif
/// <summary>
/// Entries
/// </summary>
#if NET48
public AudioSubPictureAttributesTableEntry[] Entries { get; set; }
#else
public AudioSubPictureAttributesTableEntry?[]? Entries { get; set; }
#endif
}
}

View File

@@ -18,10 +18,6 @@ namespace SabreTools.Models.DVD
/// Copy of VTS attributes (offset 100 and on from the VTS IFO
/// file, usually 0x300 bytes long)
/// </summary>
#if NET48
public byte[] AttributesCopy { get; set; }
#else
public byte[]? AttributesCopy { get; set; }
#endif
}
}

View File

@@ -11,11 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// End address (last byte of last entry)
@@ -25,10 +21,6 @@ namespace SabreTools.Models.DVD
/// <summary>
/// 12-byte entries
/// </summary>
#if NET48
public CellAddressTableEntry[] Entries { get; set; }
#else
public CellAddressTableEntry?[]? Entries { get; set; }
#endif
}
}

View File

@@ -11,11 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// End address (last byte of last PGC in last LU)
@@ -26,19 +22,11 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Language Units
/// </summary>
#if NET48
public LanguageUnitTableEntry[] Entries { get; set; }
#else
public LanguageUnitTableEntry?[]? Entries { get; set; }
#endif
/// <summary>
/// Program Chains
/// </summary>
#if NET48
public ProgramChainTable[] ProgramChains { get; set; }
#else
public ProgramChainTable?[]? ProgramChains { get; set; }
#endif
}
}

View File

@@ -25,21 +25,13 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Entries
/// </summary>
#if NET48
public ParentalManagementMasksTableEntry[] Entries { get; set; }
#else
public ParentalManagementMasksTableEntry?[]? Entries { get; set; }
#endif
/// <summary>
/// The PTL_MAIT contains the 16-bit masks for the VMG and
/// all title sets for parental management level 8 followed
/// by the masks for level 7, and so on to level 1.
/// </summary>
#if NET48
public byte[][] BitMasks { get; set; }
#else
public byte[][]? BitMasks { get; set; }
#endif
}
}

View File

@@ -11,11 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// Offset to PTL_MAIT

View File

@@ -11,11 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// End address (last byte of last PGC in this LU)
@@ -26,10 +22,6 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Program Chains
/// </summary>
#if NET48
public ProgramChainTableEntry[] Entries { get; set; }
#else
public ProgramChainTableEntry?[]? Entries { get; set; }
#endif
}
}

View File

@@ -11,11 +11,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
/// <summary>
/// End address (last byte of last entry)
@@ -25,10 +21,6 @@ namespace SabreTools.Models.DVD
/// <summary>
/// 12-byte entries
/// </summary>
#if NET48
public TitlesTableEntry[] Entries { get; set; }
#else
public TitlesTableEntry?[]? Entries { get; set; }
#endif
}
}

View File

@@ -11,10 +11,6 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Starting sector within VOB of nth VOBU
/// </summary>
#if NET48
public uint[] StartingSectors { get; set; }
#else
public uint[]? StartingSectors { get; set; }
#endif
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// "DVDVIDEO-VMG"
/// </summary>
#if NET48
public string Signature { get; set; }
#else
public string? Signature { get; set; }
#endif
/// <summary>
/// Last sector of VMG set (last sector of BUP)
@@ -59,11 +55,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Provider ID
/// </summary>
#if NET48
public byte[] ProviderID { get; set; }
#else
public byte[]? ProviderID { get; set; }
#endif
/// <summary>
/// VMG POS
@@ -123,11 +115,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Video attributes of VMGM_VOBS
/// </summary>
#if NET48
public byte[] VideoAttributes { get; set; }
#else
public byte[]? VideoAttributes { get; set; }
#endif
/// <summary>
/// Number of audio streams in VMGM_VOBS
@@ -137,20 +125,12 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Audio attributes of VMGM_VOBS
/// </summary>
#if NET48
public byte[][] AudioAttributes { get; set; }
#else
public byte[][]? AudioAttributes { get; set; }
#endif
/// <summary>
/// Unknown
/// </summary>
#if NET48
public byte[] Unknown { get; set; }
#else
public byte[]? Unknown { get; set; }
#endif
/// <summary>
/// Number of subpicture streams in VMGM_VOBS (0 or 1)
@@ -160,19 +140,11 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Subpicture attributes of VMGM_VOBS
/// </summary>
#if NET48
public byte[] SubpictureAttributes { get; set; }
#else
public byte[]? SubpictureAttributes { get; set; }
#endif
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
}
}

View File

@@ -6,11 +6,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// "DVDVIDEO-VTS"
/// </summary>
#if NET48
public string Signature { get; set; }
#else
public string? Signature { get; set; }
#endif
/// <summary>
/// Last sector of title set (last sector of BUP)
@@ -59,11 +55,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Provider ID
/// </summary>
#if NET48
public byte[] ProviderID { get; set; }
#else
public byte[]? ProviderID { get; set; }
#endif
/// <summary>
/// VMG POS
@@ -133,11 +125,7 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Video attributes of VTSM_VOBS
/// </summary>
#if NET48
public byte[] VideoAttributes { get; set; }
#else
public byte[]? VideoAttributes { get; set; }
#endif
/// <summary>
/// Number of audio streams in VTSM_VOBS
@@ -147,20 +135,12 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Audio attributes of VTSM_VOBS
/// </summary>
#if NET48
public byte[][] AudioAttributes { get; set; }
#else
public byte[][]? AudioAttributes { get; set; }
#endif
/// <summary>
/// Unknown
/// </summary>
#if NET48
public byte[] Unknown { get; set; }
#else
public byte[]? Unknown { get; set; }
#endif
/// <summary>
/// Number of subpicture streams in VTSM_VOBS (0 or 1)
@@ -170,19 +150,11 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Subpicture attributes of VTSM_VOBS
/// </summary>
#if NET48
public byte[] SubpictureAttributes { get; set; }
#else
public byte[]? SubpictureAttributes { get; set; }
#endif
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved { get; set; }
#else
public byte[]? Reserved { get; set; }
#endif
}
}

View File

@@ -4,62 +4,30 @@ namespace SabreTools.Models.DosCenter
public class DosCenter
{
/// <remarks>name</remarks>
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>description</remarks>
#if NET48
public string Description { get; set; }
#else
public string? Description { get; set; }
#endif
/// <remarks>version</remarks>
#if NET48
public string Version { get; set; }
#else
public string? Version { get; set; }
#endif
/// <remarks>date</remarks>
#if NET48
public string Date { get; set; }
#else
public string? Date { get; set; }
#endif
/// <remarks>author</remarks>
#if NET48
public string Author { get; set; }
#else
public string? Author { get; set; }
#endif
/// <remarks>homepage</remarks>
#if NET48
public string Homepage { get; set; }
#else
public string? Homepage { get; set; }
#endif
/// <remarks>comment</remarks>
#if NET48
public string Comment { get; set; }
#else
public string? Comment { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,43 +5,23 @@ namespace SabreTools.Models.DosCenter
{
/// <remarks>name, attribute</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>size, attribute, numeric</remarks>
[Required]
#if NET48
public string Size { get; set; }
#else
public string? Size { get; set; }
#endif
/// <remarks>crc, attribute</remarks>
[Required]
#if NET48
public string CRC { get; set; }
#else
public string? CRC { get; set; }
#endif
/// <remarks>date, attribute</remarks>
#if NET48
public string Date { get; set; }
#else
public string? Date { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

View File

@@ -5,27 +5,15 @@ namespace SabreTools.Models.DosCenter
{
/// <remarks>name</remarks>
[Required]
#if NET48
public string Name { get; set; }
#else
public string? Name { get; set; }
#endif
/// <remarks>file</remarks>
#if NET48
public File[] File { get; set; }
#else
public File[]? File { get; set; }
#endif
#region DO NOT USE IN PRODUCTION
/// <remarks>Should be empty</remarks>
#if NET48
public string[] ADDITIONAL_ELEMENTS { get; set; }
#else
public string[]? ADDITIONAL_ELEMENTS { get; set; }
#endif
#endregion
}

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