53 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
Matt Nadareski
43ff569ae3 Bump version 2023-09-10 21:40:05 -04:00
Matt Nadareski
970d2bddf9 Remove some lingering layout 2023-09-10 21:37:44 -04:00
Matt Nadareski
41a90278d5 Remove LayoutKind.Sequential
This may be replaced in the future when byte-serialzable types are more well-defined
2023-09-10 21:33:22 -04:00
Matt Nadareski
670b8428c2 Ensure explicit getters and setters 2023-09-10 21:24:10 -04:00
Matt Nadareski
e3c5c76ee5 Ensure more correct nullability 2023-09-10 20:47:25 -04:00
Matt Nadareski
89ba5f4508 Ensure more correct nullability 2023-09-10 20:27:14 -04:00
Matt Nadareski
ce072691bb Add first set of CHD models 2023-09-08 13:33:50 -04:00
Matt Nadareski
c52226cd3e Add Nuget link 2023-09-04 21:58:17 -04:00
497 changed files with 4431 additions and 9690 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;
#else
public string? Copyright;
#endif
public string? Copyright { get; set; }
}
}

View File

@@ -9,17 +9,13 @@ namespace SabreTools.Models.AACS
/// field indicates that only one ID is being revoked, a value of one
/// in the Range field indicates two IDs are being revoked, and so on.
/// </summary>
public ushort Range;
public ushort Range { get; set; }
/// <summary>
/// A 6-byte Drive ID value identifying the Licensed Drive being revoked
/// (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;
#else
public byte[]? DriveID;
#endif
public byte[]? DriveID { get; set; }
}
}

View File

@@ -16,15 +16,11 @@ namespace SabreTools.Models.AACS
/// <summary>
/// The total number of Drive Revocation List Entry fields that follow.
/// </summary>
public uint TotalNumberOfEntries;
public uint TotalNumberOfEntries { get; set; }
/// <summary>
/// Revocation list entries
/// </summary>
#if NET48
public DriveRevocationSignatureBlock[] SignatureBlocks;
#else
public DriveRevocationSignatureBlock[]? SignatureBlocks;
#endif
public DriveRevocationSignatureBlock?[]? SignatureBlocks { get; set; }
}
}

View File

@@ -6,16 +6,12 @@ namespace SabreTools.Models.AACS
/// <summary>
/// The number of Drive Revocation List Entry fields in the signature block.
/// </summary>
public uint NumberOfEntries;
public uint NumberOfEntries { get; set; }
/// <summary>
/// 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;
#else
public DriveRevocationListEntry[]? EntryFields;
#endif
public DriveRevocationListEntry?[]? EntryFields { get; set; }
}
}

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;
#else
public byte[]? SignatureData;
#endif
public byte[]? SignatureData { get; set; }
}
}

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;
#else
public SubsetDifference[]? SubsetDifferences;
#endif
public SubsetDifference?[]? SubsetDifferences { get; set; }
}
}

View File

@@ -9,17 +9,13 @@ namespace SabreTools.Models.AACS
/// field indicates that only one ID is being revoked, a value of one
/// in the Range field indicates two IDs are being revoked, and so on.
/// </summary>
public ushort Range;
public ushort Range { get; set; }
/// <summary>
/// A 6-byte Host ID value identifying the host being revoked (or the
/// first in a range of hosts being revoked, in the case of a non-zero
/// Range value).
/// </summary>
#if NET48
public byte[] HostID;
#else
public byte[]? HostID;
#endif
public byte[]? HostID { get; set; }
}
}

View File

@@ -19,15 +19,11 @@ namespace SabreTools.Models.AACS
/// <summary>
/// The total number of Host Revocation List Entry fields that follow.
/// </summary>
public uint TotalNumberOfEntries;
public uint TotalNumberOfEntries { get; set; }
/// <summary>
/// Revocation list entries
/// </summary>
#if NET48
public HostRevocationSignatureBlock[] SignatureBlocks;
#else
public HostRevocationSignatureBlock[]? SignatureBlocks;
#endif
public HostRevocationSignatureBlock?[]? SignatureBlocks { get; set; }
}
}

View File

@@ -6,16 +6,12 @@ namespace SabreTools.Models.AACS
/// <summary>
/// The number of Host Revocation List Entry fields in the signature block.
/// </summary>
public uint NumberOfEntries;
public uint NumberOfEntries { get; set; }
/// <summary>
/// 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;
#else
public HostRevocationListEntry[]? EntryFields;
#endif
public HostRevocationListEntry?[]? EntryFields { get; set; }
}
}

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
public Record?[]? Records { get; set; }
}
}

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;
#else
public byte[][]? MediaKeyData;
#endif
public byte[][]? MediaKeyData { get; set; }
}
}

View File

@@ -15,7 +15,7 @@ namespace SabreTools.Models.AACS
/// <summary>
/// The Record Type field value indicates the type of the Record.
/// </summary>
public RecordType RecordType;
public RecordType RecordType { get; set; }
/// <summary>
/// The Record Length field value indicates the number of bytes in
@@ -23,6 +23,6 @@ namespace SabreTools.Models.AACS
/// fields themselves. Record lengths are always multiples of 4 bytes.
/// </summary>
// <remarks>UInt24 not UInt32</remarks>
public uint RecordLength;
public uint RecordLength { get; set; }
}
}

View File

@@ -9,12 +9,12 @@ namespace SabreTools.Models.AACS
/// the mask. For example, the value 0x01 denotes a mask of
/// 0xFFFFFFFE; value 0x0A denotes a mask of 0xFFFFFC00.
/// </summary>
public byte Mask;
public byte Mask { get; set; }
/// <summary>
/// The last 4 bytes are the uv number, most significant
/// byte first.
/// </summary>
public uint Number;
public uint Number { get; set; }
}
}

View File

@@ -14,17 +14,13 @@ namespace SabreTools.Models.AACS
/// <summary>
/// The number of devices per index offset.
/// </summary>
public uint Span;
public uint Span { get; set; }
/// <summary>
/// These offsets refer to the offset within the following Explicit
/// Subset-Difference record, with 0 being the start of the record.
/// </summary>
// <remarks>UInt24 not UInt32</remarks>
#if NET48
public uint[] Offsets;
#else
public uint[]? Offsets;
#endif
public uint[]? Offsets { get; set; }
}
}

View File

@@ -17,7 +17,7 @@ namespace SabreTools.Models.AACS
/// controlling access to AACS Content on pre- recorded media. In
/// this case, the device shall not use the KCD.
/// </summary>
public MediaKeyBlockType MediaKeyBlockType;
public MediaKeyBlockType MediaKeyBlockType { get; set; }
/// <summary>
/// The Version Number is a 32-bit unsigned integer. Each time the
@@ -27,6 +27,6 @@ namespace SabreTools.Models.AACS
/// Version Numbers begin at 1; 0 is a special value used for test
/// Media Key Blocks.
/// </summary>
public uint VersionNumber;
public uint VersionNumber { get; set; }
}
}

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;
#else
public byte[]? CiphertextValue;
#endif
public byte[]? CiphertextValue { get; set; }
}
}

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
public File?[]? File { get; set; }
#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
public Row?[]? Row { get; set; }
}
}

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,57 +6,41 @@ namespace SabreTools.Models.BDPlus
/// <summary>
/// "BDSVM_CC"
/// </summary>
#if NET48
public string Signature;
#else
public string? Signature;
#endif
public string? Signature { get; set; }
/// <summary>
/// 5 bytes of unknown data
/// </summary>
#if NET48
public byte[] Unknown1;
#else
public byte[]? Unknown1;
#endif
public byte[]? Unknown1 { get; set; }
/// <summary>
/// Version year
/// </summary>
public ushort Year;
public ushort Year { get; set; }
/// <summary>
/// Version month
/// </summary>
public byte Month;
public byte Month { get; set; }
/// <summary>
/// Version day
/// </summary>
public byte Day;
public byte Day { get; set; }
/// <summary>
/// 4 bytes of unknown data
/// </summary>
#if NET48
public byte[] Unknown2;
#else
public byte[]? Unknown2;
#endif
public byte[]? Unknown2 { get; set; }
/// <summary>
/// Length
/// </summary>
public uint Length;
public uint Length { get; set; }
/// <summary>
/// Length bytes of data
/// </summary>
#if NET48
public byte[] Data;
#else
public byte[]? Data;
#endif
public byte[]? Data { get; set; }
}
}

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
public FileEntry?[]? Files { get; set; }
}
}

View File

@@ -9,30 +9,26 @@
/// <summary>
/// Name size
/// </summary>
public int NameSize;
public int NameSize { get; set; }
/// <summary>
/// Name
/// </summary>
#if NET48
public string Name;
#else
public string? Name;
#endif
public string? Name { get; set; }
/// <summary>
/// Uncompressed size
/// </summary>
public int UncompressedSize;
public int UncompressedSize { get; set; }
/// <summary>
/// Offset
/// </summary>
public int Offset;
public int Offset { get; set; }
/// <summary>
/// Compressed size
/// </summary>
public int CompressedSize;
public int CompressedSize { get; set; }
}
}

View File

@@ -1,31 +1,24 @@
using System.Runtime.InteropServices;
namespace SabreTools.Models.BFPK
namespace SabreTools.Models.BFPK
{
/// <summary>
/// Header
/// </summary>
/// <see cref="https://forum.xentax.com/viewtopic.php?t=5102"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class Header
{
/// <summary>
/// "BFPK"
/// </summary>
#if NET48
public string Magic;
#else
public string? Magic;
#endif
public string? Magic { get; set; }
/// <summary>
/// Version
/// </summary>
public int Version;
public int Version { get; set; }
/// <summary>
/// Files
/// </summary>
public int Files;
public int Files { get; set; }
}
}

View File

@@ -10,26 +10,26 @@ namespace SabreTools.Models.BMP
/// <summary>
/// The file type; must be BM.
/// </summary>
public ushort Type;
public ushort Type { get; set; }
/// <summary>
/// The size, in bytes, of the bitmap file.
/// </summary>
public uint Size;
public uint Size { get; set; }
/// <summary>
/// Reserved; must be zero.
/// </summary>
public ushort Reserved1;
public ushort Reserved1 { get; set; }
/// <summary>
/// Reserved; must be zero.
/// </summary>
public ushort Reserved2;
public ushort Reserved2 { get; set; }
/// <summary>
/// The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
/// </summary>
public uint OffBits;
public uint OffBits { get; set; }
}
}

View File

@@ -11,12 +11,12 @@ namespace SabreTools.Models.BMP
/// not include the size of the color table or the size of the color masks,
/// if they are appended to the end of structure.
/// </summary>
public uint Size;
public uint Size { get; set; }
/// <summary>
/// Specifies the width of the bitmap, in pixels.
/// </summary>
public int Width;
public int Width { get; set; }
/// <summary>
/// Specifies the height of the bitmap, in pixels.
@@ -30,19 +30,19 @@ namespace SabreTools.Models.BMP
/// or negative biHeight.
/// - For compressed formats, biHeight must be positive, regardless of image orientation.
/// </summary>
public int Height;
public int Height { get; set; }
/// <summary>
/// Specifies the number of planes for the target device. This value must be set to 1.
/// </summary>
public ushort Planes;
public ushort Planes { get; set; }
/// <summary>
/// Specifies the number of bits per pixel (bpp). For uncompressed formats, this value
/// is the average number of bits per pixel. For compressed formats, this value is the
/// implied bit depth of the uncompressed image, after the image has been decoded.
/// </summary>
public ushort BitCount;
public ushort BitCount { get; set; }
/// <summary>
/// For compressed video and YUV formats, this member is a FOURCC code, specified as a
@@ -59,36 +59,36 @@ namespace SabreTools.Models.BMP
/// If biCompression equals BI_BITFIELDS, the format is either RGB 555 or RGB 565. Use
/// the subtype GUID in the AM_MEDIA_TYPE structure to determine the specific RGB type.
/// </summary>
public uint Compression;
public uint Compression { get; set; }
/// <summary>
/// Specifies the size, in bytes, of the image. This can be set to 0 for uncompressed
/// RGB bitmaps.
/// </summary>
public uint SizeImage;
public uint SizeImage { get; set; }
/// <summary>
/// Specifies the horizontal resolution, in pixels per meter, of the target device for
/// the bitmap.
/// </summary>
public int XPelsPerMeter;
public int XPelsPerMeter { get; set; }
/// <summary>
/// Specifies the vertical resolution, in pixels per meter, of the target device for
/// the bitmap.
/// </summary>
public int YPelsPerMeter;
public int YPelsPerMeter { get; set; }
/// <summary>
/// Specifies the number of color indices in the color table that are actually used by
/// the bitmap.
/// </summary>
public uint ClrUsed;
public uint ClrUsed { get; set; }
/// <summary>
/// Specifies the number of color indices that are considered important for displaying
/// the bitmap. If this value is zero, all colors are important.
/// </summary>
public uint ClrImportant;
public uint ClrImportant { get; set; }
}
}

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
public Lump?[]? Lumps { get; set; }
/// <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
public Texture?[]? Textures { get; set; }
}
}

View File

@@ -6,6 +6,6 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Version
/// </summary>
public uint Version;
public uint Version { get; set; }
}
}

View File

@@ -6,11 +6,11 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Offset
/// </summary>
public uint Offset;
public uint Offset { get; set; }
/// <summary>
/// Length
/// </summary>
public uint Length;
public uint Length { get; set; }
}
}

View File

@@ -6,52 +6,36 @@ namespace SabreTools.Models.BSP
/// <summary>
/// Name
/// </summary>
#if NET48
public string Name;
#else
public string? Name;
#endif
public string? Name { get; set; }
/// <summary>
/// Width
/// </summary>
public uint Width;
public uint Width { get; set; }
/// <summary>
/// Height
/// </summary>
public uint Height;
public uint Height { get; set; }
/// <summary>
/// Offsets
/// </summary>
#if NET48
public uint[] Offsets;
#else
public uint[]? Offsets;
#endif
public uint[]? Offsets { get; set; }
/// <summary>
/// Texture data
/// </summary>
#if NET48
public byte[] TextureData;
#else
public byte[]? TextureData;
#endif
public byte[]? TextureData { get; set; }
/// <summary>
/// Palette size
/// </summary>
public uint PaletteSize;
public uint PaletteSize { get; set; }
/// <summary>
/// Palette data
/// </summary>
#if NET48
public byte[] PaletteData;
#else
public byte[]? PaletteData;
#endif
public byte[]? PaletteData { get; set; }
}
}

View File

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

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
public SectorNumber?[]? FATSectorNumbers { get; set; }
/// <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
public SectorNumber?[]? MiniFATSectorNumbers { get; set; }
/// <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
public SectorNumber?[]? DIFATSectorNumbers { get; set; }
/// <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
public DirectoryEntry?[]? DirectoryEntries { get; set; }
}
}

View File

@@ -16,17 +16,13 @@ namespace SabreTools.Models.CFB
/// The following characters are illegal and MUST NOT be part of the
/// name: '/', '\', ':', '!'.
/// </summary>
#if NET48
public string Name;
#else
public string? Name;
#endif
public string? Name { get; set; }
/// <summary>
/// This field MUST be 0x00, 0x01, 0x02, or 0x05, depending on the
/// actual type of object. All other values are not valid.
/// </summary>
public ushort NameLength;
public ushort NameLength { get; set; }
/// <summary>
/// This field MUST match the length of the Directory Entry Name Unicode
@@ -34,31 +30,31 @@ namespace SabreTools.Models.CFB
/// terminating null character in the count. This length MUST NOT exceed 64,
/// the maximum size of the Directory Entry Name field.
/// </summary>
public ObjectType ObjectType;
public ObjectType ObjectType { get; set; }
/// <summary>
/// This field MUST be 0x00 (red) or 0x01 (black). All other values are not valid.
/// </summary>
public ColorFlag ColorFlag;
public ColorFlag ColorFlag { get; set; }
/// <summary>
/// This field contains the stream ID of the left sibling. If there
/// is no left sibling, the field MUST be set to NOSTREAM (0xFFFFFFFF).
/// </summary>
public StreamID LeftSiblingID;
public StreamID LeftSiblingID { get; set; }
/// <summary>
/// This field contains the stream ID of the right sibling. If there
/// is no right sibling, the field MUST be set to NOSTREAM (0xFFFFFFFF).
/// </summary>
public StreamID RightSiblingID;
public StreamID RightSiblingID { get; set; }
/// <summary>
/// This field contains the stream ID of a child object. If there is no
/// child object, including all entries for stream objects, the field
/// MUST be set to NOSTREAM (0xFFFFFFFF).
/// </summary>
public StreamID ChildID;
public StreamID ChildID { get; set; }
/// <summary>
/// This field contains an object class GUID, if this entry is for a
@@ -71,7 +67,7 @@ namespace SabreTools.Models.CFB
/// this value is not all zeroes, the object class GUID can be used as a
/// parameter to start applications.
/// </summary>
public Guid CLSID;
public Guid CLSID { get; set; }
/// <summary>
/// This field contains the user-defined flags if this entry is for a storage
@@ -82,7 +78,7 @@ namespace SabreTools.Models.CFB
/// objects without explicitly setting state bits, it MUST write all zeroes
/// by default.
/// </summary>
public uint StateBits;
public uint StateBits { get; set; }
/// <summary>
/// This field contains the creation time for a storage object, or all zeroes
@@ -92,7 +88,7 @@ namespace SabreTools.Models.CFB
/// object, this field MUST be all zeroes, and the creation time is retrieved
/// or set on the compound file itself.
/// </summary>
public ulong CreationTime;
public ulong CreationTime { get; set; }
/// <summary>
/// This field contains the modification time for a storage object, or all
@@ -102,7 +98,7 @@ namespace SabreTools.Models.CFB
/// storage object, this field MAY<2> be set to all zeroes, and the modified
/// time is retrieved or set on the compound file itself.
/// </summary>
public ulong ModifiedTime;
public ulong ModifiedTime { get; set; }
/// <summary>
/// This field contains the first sector location if this is a stream object.
@@ -110,7 +106,7 @@ namespace SabreTools.Models.CFB
/// mini stream, if the mini stream exists. For a storage object, this field MUST
/// be set to all zeroes.
/// </summary>
public uint StartingSectorLocation;
public uint StartingSectorLocation { get; set; }
/// <summary>
/// This 64-bit integer field contains the size of the user-defined data if this
@@ -132,6 +128,6 @@ namespace SabreTools.Models.CFB
/// unless there is a specific reason to do otherwise (for example, a parser whose
/// purpose is to verify the correctness of a compound file).
/// </remarks>
public ulong StreamSize;
public ulong StreamSize { get; set; }
}
}

View File

@@ -9,30 +9,30 @@ namespace SabreTools.Models.CFB
/// Iddentification signature for the compound file structure, and MUST be
/// set to the value 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.
/// </summary>
public ulong Signature;
public ulong Signature { get; set; }
/// <summary>
/// Reserved and unused class ID that MUST be set to all zeroes (CLSID_NULL)
/// </summary>
public Guid CLSID;
public Guid CLSID { get; set; }
/// <summary>
/// Version number for nonbreaking changes. This field SHOULD be set to
/// 0x003E if the major version field is either 0x0003 or 0x0004.
/// </summary>
public ushort MinorVersion;
public ushort MinorVersion { get; set; }
/// <summary>
/// Version number for breaking changes. This field MUST be set to either
/// 0x0003 (version 3) or 0x0004 (version 4).
/// </summary>
public ushort MajorVersion;
public ushort MajorVersion { get; set; }
/// <summary>
/// This field MUST be set to 0xFFFE. This field is a byte order mark for
/// all integer fields, specifying little-endian byte order.
/// </summary>
public ushort ByteOrder;
public ushort ByteOrder { get; set; }
/// <summary>
/// This field MUST be set to 0x0009, or 0x000c, depending on the Major
@@ -45,23 +45,19 @@ namespace SabreTools.Models.CFB
/// If Major Version is 4, the Sector Shift MUST be 0x000C, specifying a
/// sector size of 4096 bytes.
/// </summary>
public ushort SectorShift;
public ushort SectorShift { get; set; }
/// <summary>
/// This field MUST be set to 0x0006. This field specifies the sector size
/// of the Mini Stream as a power of 2. The sector size of the Mini Stream
/// MUST be 64 bytes.
/// </summary>
public ushort MiniSectorShift;
public ushort MiniSectorShift { get; set; }
/// <summary>
/// This field MUST be set to all zeroes.
/// </summary>
#if NET48
public byte[] Reserved;
#else
public byte[]? Reserved;
#endif
public byte[]? Reserved { get; set; }
/// <summary>
/// This integer field contains the count of the number of directory sectors
@@ -70,18 +66,18 @@ namespace SabreTools.Models.CFB
/// If Major Version is 3, the Number of Directory Sectors MUST be zero. This
/// field is not supported for version 3 compound files.
/// </summary>
public uint NumberOfDirectorySectors;
public uint NumberOfDirectorySectors { get; set; }
/// <summary>
/// This integer field contains the count of the number of FAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfFATSectors;
public uint NumberOfFATSectors { get; set; }
/// <summary>
/// This integer field contains the starting sector number for the directory stream.
/// </summary>
public uint FirstDirectorySectorLocation;
public uint FirstDirectorySectorLocation { get; set; }
/// <summary>
/// This integer field MAY contain a sequence number that is incremented every time
@@ -89,7 +85,7 @@ namespace SabreTools.Models.CFB
/// This is the field that MUST be set to all zeroes if file transactions are not
/// implemented.
/// </summary>
public uint TransactionSignatureNumber;
public uint TransactionSignatureNumber { get; set; }
/// <summary>
/// This integer field MUST be set to 0x00001000. This field specifies the maximum
@@ -98,38 +94,34 @@ namespace SabreTools.Models.CFB
/// greater than or equal to this cutoff size must be allocated as normal sectors from
/// the FAT.
/// </summary>
public uint MiniStreamCutoffSize;
public uint MiniStreamCutoffSize { get; set; }
/// <summary>
/// This integer field contains the starting sector number for the mini FAT.
/// </summary>
public uint FirstMiniFATSectorLocation;
public uint FirstMiniFATSectorLocation { get; set; }
/// <summary>
/// This integer field contains the count of the number of mini FAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfMiniFATSectors;
public uint NumberOfMiniFATSectors { get; set; }
/// <summary>
/// This integer field contains the starting sector number for the DIFAT.
/// </summary>
public uint FirstDIFATSectorLocation;
public uint FirstDIFATSectorLocation { get; set; }
/// <summary>
/// This integer field contains the count of the number of DIFAT sectors in the
/// compound file.
/// </summary>
public uint NumberOfDIFATSectors;
public uint NumberOfDIFATSectors { get; set; }
/// <summary>
/// This array of 32-bit integer fields contains the first 109 FAT sector
/// locations of the compound file
/// </summary>
#if NET48
public SectorNumber[] DIFAT;
#else
public SectorNumber[]? DIFAT;
#endif
public SectorNumber?[]? DIFAT { get; set; }
}
}

View File

@@ -11,36 +11,32 @@ namespace SabreTools.Models.CFB
/// This field MUST be set to 0xFFFE. This field is a byte order mark for
/// all integer fields, specifying little-endian byte order.
/// </summary>
public ushort ByteOrder;
public ushort ByteOrder { get; set; }
/// <summary>
/// Format
/// </summary>
public ushort Format;
public ushort Format { get; set; }
/// <summary>
/// Build
/// </summary>
public ushort Build;
public ushort Build { get; set; }
/// <summary>
/// Platform ID
/// </summary>
public ushort PlatformID;
public ushort PlatformID { get; set; }
/// <summary>
/// CLSID
/// </summary>
public Guid CLSID;
public Guid CLSID { get; set; }
/// <summary>
/// 4 bytes of reserved data
/// </summary>
#if NET48
public byte[] Reserved;
#else
public byte[]? Reserved;
#endif
public byte[]? Reserved { get; set; }
#endregion
@@ -49,16 +45,12 @@ namespace SabreTools.Models.CFB
/// <summary>
/// Format ID, should be <see cref="Constants.FMTID_SummaryInformation"/>
/// </summary>
public Guid FormatID;
public Guid FormatID { get; set; }
/// <summary>
/// 16 bytes of unknown data
/// </summary>
#if NET48
public byte[] Unknown;
#else
public byte[]? Unknown;
#endif
public byte[]? Unknown { get; set; }
#endregion
@@ -67,27 +59,23 @@ namespace SabreTools.Models.CFB
/// <summary>
/// Location of the section
/// </summary>
public uint Offset;
public uint Offset { get; set; }
/// <summary>
/// Section count(?)
/// </summary>
public uint SectionCount;
public uint SectionCount { get; set; }
/// <summary>
/// Property count
/// </summary>
public uint PropertyCount;
public uint PropertyCount { get; set; }
/// <summary>
/// Properties
/// </summary>
/// <remarks>Each Variant might be followed by an index and offset value</remarks>
#if NET48
public Variant[] Properties;
#else
public Variant[]? Properties;
#endif
public Variant?[]? Properties { get; set; }
#endregion
}

View File

@@ -9,41 +9,37 @@ namespace SabreTools.Models.CFB
/// <summary>
/// MUST be set to the size, in quad words (64 bits), of the structure.
/// </summary>
public uint Size;
public uint Size { get; set; }
/// <summary>
/// MUST be set to 0 and MUST be ignored by the recipient.
/// </summary>
public uint RpcReserved;
public uint RpcReserved { get; set; }
/// <summary>
/// MUST be set to one of the values specified with a "V".
/// </summary>
public VariantType VariantType;
public VariantType VariantType { get; set; }
/// <summary>
/// MAY be set to 0 and MUST be ignored by the recipient.
/// </summary>
public ushort Reserved1;
public ushort Reserved1 { get; set; }
/// <summary>
/// MAY be set to 0 and MUST be ignored by the recipient.
/// </summary>
public ushort Reserved2;
public ushort Reserved2 { get; set; }
/// <summary>
/// MAY be set to 0 and MUST be ignored by the recipient.
/// </summary>
public ushort Reserved3;
public ushort Reserved3 { get; set; }
/// <summary>
/// MUST contain an instance of the type, according to the value
/// in the <see cref="VariantType"/> field.
/// </summary>
#if NET48
public object Union;
#else
public object? Union;
#endif
public object? Union { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class CompressedMapEntryV5
{
/// <summary>
/// Compression type
/// </summary>
public byte Compression { get; set; }
/// <summary>
/// Compressed length
/// </summary>
/// <remarks>Actually UInt24</remarks>
public uint CompLength { get; set; }
/// <summary>
/// Offset
/// </summary>
/// <remarks>Actually UInt48</remarks>
public ulong Offset { get; set; }
/// <summary>
/// CRC-16 of the data
/// </summary>
public ushort CRC { get; set; }
}
}

View File

@@ -0,0 +1,42 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class CompressedMapHeaderV5
{
/// <summary>
/// Length of compressed map
/// </summary>
public uint Length { get; set; }
/// <summary>
/// Offset of first block
/// </summary>
/// <remarks>Actually UInt48</remarks>
public ulong DataStart { get; set; }
/// <summary>
/// CRC-16 of the map
/// </summary>
public ushort CRC { get; set; }
/// <summary>
/// Bits used to encode complength
/// </summary>
public byte LengthBits { get; set; }
/// <summary>
/// Bits used to encode self-refs
/// </summary>
public byte HunkBits { get; set; }
/// <summary>
/// Bits used to encode parent unit refs
/// </summary>
public byte ParentUnitBits { get; set; }
/// <summary>
/// Future use
/// </summary>
public byte Reserved { get; set; }
}
}

42
CHD/Enums.cs Normal file
View File

@@ -0,0 +1,42 @@
using System;
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public enum CompressionType : uint
{
#region V1
CHDCOMPRESSION_NONE = 0,
CHDCOMPRESSION_ZLIB = 1,
#endregion
#region V3
CHDCOMPRESSION_ZLIB_PLUS = 2,
#endregion
#region V4
CHDCOMPRESSION_AV = 3,
#endregion
}
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
[Flags]
public enum Flags : uint
{
/// <summary>
/// Set if this drive has a parent
/// </summary>
DriveHasParent = 0x00000001,
/// <summary>
/// Set if this drive allows writes
/// </summary>
DriveAllowsWrites = 0x00000002,
}
}

21
CHD/Header.cs Normal file
View File

@@ -0,0 +1,21 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public abstract class Header
{
/// <summary>
/// 'MComprHD'
/// </summary>
public string? Tag { get; set; }
/// <summary>
/// Length of header (including tag and length fields)
/// </summary>
public uint Length { get; set; }
/// <summary>
/// Drive format version
/// </summary>
public uint Version { get; set; }
}
}

51
CHD/HeaderV1.cs Normal file
View File

@@ -0,0 +1,51 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class HeaderV1 : Header
{
/// <summary>
/// Flags
/// </summary>
public Flags Flags { get; set; }
/// <summary>
/// Compression type
/// </summary>
public CompressionType Compression { get; set; }
/// <summary>
/// 512-byte sectors per hunk
/// </summary>
public uint HunkSize { get; set; }
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks { get; set; }
/// <summary>
/// Number of cylinders on hard disk
/// </summary>
public uint Cylinders { get; set; }
/// <summary>
/// Number of heads on hard disk
/// </summary>
public uint Heads { get; set; }
/// <summary>
/// Number of sectors on hard disk
/// </summary>
public uint Sectors { get; set; }
/// <summary>
/// MD5 checksum of raw data
/// </summary>
public byte[]? MD5 { get; set; } = new byte[16];
/// <summary>
/// MD5 checksum of parent file
/// </summary>
public byte[]? ParentMD5 { get; set; } = new byte[16];
}
}

56
CHD/HeaderV2.cs Normal file
View File

@@ -0,0 +1,56 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class HeaderV2 : Header
{
/// <summary>
/// Flags
/// </summary>
public Flags Flags { get; set; }
/// <summary>
/// Compression type
/// </summary>
public CompressionType Compression { get; set; }
/// <summary>
/// Seclen-byte sectors per hunk
/// </summary>
public uint HunkSize { get; set; }
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks { get; set; }
/// <summary>
/// Number of cylinders on hard disk
/// </summary>
public uint Cylinders { get; set; }
/// <summary>
/// Number of heads on hard disk
/// </summary>
public uint Heads { get; set; }
/// <summary>
/// Number of sectors on hard disk
/// </summary>
public uint Sectors { get; set; }
/// <summary>
/// MD5 checksum of raw data
/// </summary>
public byte[]? MD5 { get; set; } = new byte[16];
/// <summary>
/// MD5 checksum of parent file
/// </summary>
public byte[]? ParentMD5 { get; set; } = new byte[16];
/// <summary>
/// Number of bytes per sector
/// </summary>
public uint BytesPerSector { get; set; }
}
}

56
CHD/HeaderV3.cs Normal file
View File

@@ -0,0 +1,56 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class HeaderV3 : Header
{
/// <summary>
/// Flags
/// </summary>
public Flags Flags { get; set; }
/// <summary>
/// Compression type
/// </summary>
public CompressionType Compression { get; set; }
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks { get; set; }
/// <summary>
/// Logical size of the data (in bytes)
/// </summary>
public ulong LogicalBytes { get; set; }
/// <summary>
/// Offset to the first blob of metadata
/// </summary>
public ulong MetaOffset { get; set; }
/// <summary>
/// MD5 checksum of raw data
/// </summary>
public byte[]? MD5 { get; set; } = new byte[16];
/// <summary>
/// MD5 checksum of parent file
/// </summary>
public byte[]? ParentMD5 { get; set; } = new byte[16];
/// <summary>
/// Number of bytes per hunk
/// </summary>
public uint HunkBytes { get; set; }
/// <summary>
/// SHA1 checksum of raw data
/// </summary>
public byte[]? SHA1 { get; set; } = new byte[20];
/// <summary>
/// SHA1 checksum of parent file
/// </summary>
public byte[]? ParentSHA1 { get; set; } = new byte[20];
}
}

51
CHD/HeaderV4.cs Normal file
View File

@@ -0,0 +1,51 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class HeaderV4 : Header
{
/// <summary>
/// Flags
/// </summary>
public Flags Flags { get; set; }
/// <summary>
/// Compression type
/// </summary>
public CompressionType Compression { get; set; }
/// <summary>
/// Total # of hunks represented
/// </summary>
public uint TotalHunks { get; set; }
/// <summary>
/// Logical size of the data (in bytes)
/// </summary>
public ulong LogicalBytes { get; set; }
/// <summary>
/// Offset to the first blob of metadata
/// </summary>
public ulong MetaOffset { get; set; }
/// <summary>
/// Number of bytes per hunk
/// </summary>
public uint HunkBytes { get; set; }
/// <summary>
/// Combined raw+meta SHA1
/// </summary>
public byte[]? SHA1 { get; set; } = new byte[20];
/// <summary>
/// Combined raw+meta SHA1 of parent
/// </summary>
public byte[]? ParentSHA1 { get; set; } = new byte[20];
/// <summary>
/// Raw data SHA1
/// </summary>
public byte[]? RawSHA1 { get; set; } = new byte[20];
}
}

51
CHD/HeaderV5.cs Normal file
View File

@@ -0,0 +1,51 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class HeaderV5 : Header
{
/// <summary>
/// Which custom compressors are used?
/// </summary>
public uint[] Compressors { get; set; } = new uint[4];
/// <summary>
/// Logical size of the data (in bytes)
/// </summary>
public ulong LogicalBytes { get; set; }
/// <summary>
/// Offset to the map
/// </summary>
public ulong MapOffset { get; set; }
/// <summary>
/// Offset to the first blob of metadata
/// </summary>
public ulong MetaOffset { get; set; }
/// <summary>
/// Number of bytes per hunk (512k maximum)
/// </summary>
public uint HunkBytes { get; set; }
/// <summary>
/// Number of bytes per unit within each hunk
/// </summary>
public uint UnitBytes { get; set; }
/// <summary>
/// Raw data SHA1
/// </summary>
public byte[]? RawSHA1 { get; set; }
/// <summary>
/// Combined raw+meta SHA1
/// </summary>
public byte[]? SHA1 { get; set; }
/// <summary>
/// Combined raw+meta SHA1 of parent
/// </summary>
public byte[]? ParentSHA1 { get; set; }
}
}

16
CHD/MapV1.cs Normal file
View File

@@ -0,0 +1,16 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class MapV1
{
/// <summary>
/// Starting offset within the file
/// </summary>
public ulong StartingOffset { get; set; }
/// <summary>
/// Length of data; If == hunksize, data is uncompressed
/// </summary>
public ulong Length { get; set; }
}
}

31
CHD/MapV3.cs Normal file
View File

@@ -0,0 +1,31 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class MapV3
{
/// <summary>
/// Starting offset within the file
/// </summary>
public ulong StartingOffset { get; set; }
/// <summary>
/// 32-bit CRC of the uncompressed data
/// </summary>
public uint CRC32 { get; set; }
/// <summary>
/// Lower 16 bits of length
/// </summary>
public ushort LengthLo { get; set; }
/// <summary>
/// Upper 8 bits of length
/// </summary>
public byte LengthHi { get; set; }
/// <summary>
/// Flags, indicating compression info
/// </summary>
public byte Flags { get; set; }
}
}

11
CHD/UncompressedMapV5.cs Normal file
View File

@@ -0,0 +1,11 @@
namespace SabreTools.Models.CHD
{
/// <see href="https://github.com/mamedev/mame/blob/master/src/lib/util/chd.h"/>
public class UncompressedMapV5
{
/// <summary>
/// Starting offset / hunk size
/// </summary>
public uint StartingOffset { get; set; }
}
}

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
public Dictionary<string, (string? Name, string? UnlockId)>? Sections { get; set; }
}
}

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
public GameBase?[]? Game { get; set; }
#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,16 +6,12 @@ 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;
#else
public string? Magic;
#endif
public string? Magic { get; set; }
public byte CompressionType;
public byte CompressionType { get; set; }
public char LastChar;
public char LastChar { get; set; }
public uint RealLength;
public uint RealLength { 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;
#else
public BlockHeader? Header;
#endif
/// <summary>
/// Aligned offset tree
/// </summary>
/// <remarks>8 elements, 3 bits each</remarks>
#if NET48
public byte[] AlignedOffsetTree;
#else
public byte[]? AlignedOffsetTree;
#endif
public byte[]? AlignedOffsetTree { get; set; }
/// <summary>
/// Pretree for first 256 elements of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeFirst256;
#else
public byte[]? PretreeFirst256;
#endif
public byte[]? PretreeFirst256 { get; set; }
/// <summary>
/// Path lengths of first 256 elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsFirst256;
#else
public int[]? PathLengthsFirst256;
#endif
public int[]? PathLengthsFirst256 { get; set; }
/// <summary>
/// Pretree for remainder of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeRemainder;
#else
public byte[]? PretreeRemainder;
#endif
public byte[]? PretreeRemainder { get; set; }
/// <summary>
/// Path lengths of remaining elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsRemainder;
#else
public int[]? PathLengthsRemainder;
#endif
public int[]? PathLengthsRemainder { get; set; }
/// <summary>
/// Pretree for length tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeLengthTree;
#else
public byte[]? PretreeLengthTree;
#endif
public byte[]? PretreeLengthTree { get; set; }
/// <summary>
/// Path lengths of elements in length tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsLengthTree;
#else
public int[]? PathLengthsLengthTree;
#endif
public int[]? PathLengthsLengthTree { get; set; }
// 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,38 +1,33 @@
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"/>
public class BlockHeader
{
/// <remarks>3 bits</remarks>
public BlockType BlockType;
public BlockType BlockType { get; set; }
/// <summary>
/// Block size is the high 8 bits of 24
/// </summary>
/// <remarks>8 bits</remarks>
public byte BlockSizeMSB;
public byte BlockSizeMSB { get; set; }
/// <summary>
/// Block size is the middle 8 bits of 24
/// </summary>
/// <remarks>8 bits</remarks>
public byte BlockSizeByte2;
public byte BlockSizeByte2 { get; set; }
/// <summary>
/// Block size is the low 8 bits of 24
/// </summary>
/// <remarks>8 bits</remarks>
public byte BlocksizeLSB;
public byte BlocksizeLSB { get; set; }
}
}

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,54 +14,41 @@ 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;
#else
public BlockHeader? Header;
#endif
/// <summary>
/// Padding to align following field on 16-bit boundary
/// </summary>
/// <remarks>Bits have a value of zero</remarks>
public ushort PaddingBits;
public ushort PaddingBits { get; set; }
/// <summary>
/// Least significant to most significant byte (little-endian DWORD ([MS-DTYP]))
/// </summary>
/// <remarks>Encoded directly in the byte stream, not in the bitstream of byte-swapped 16-bit words</remarks>
public uint R0;
public uint R0 { get; set; }
/// <summary>
/// Least significant to most significant byte (little-endian DWORD)
/// </summary>
/// <remarks>Encoded directly in the byte stream, not in the bitstream of byte-swapped 16-bit words</remarks>
public uint R1;
public uint R1 { get; set; }
/// <summary>
/// Least significant to most significant byte (little-endian DWORD)
/// </summary>
/// <remarks>Encoded directly in the byte stream, not in the bitstream of byte-swapped 16-bit words</remarks>
public uint R2;
public uint R2 { get; set; }
/// <summary>
/// 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;
#else
public byte[]? RawDataBytes;
#endif
public byte[]? RawDataBytes { get; set; }
/// <summary>
/// Only if uncompressed size is odd
/// </summary>
public byte AlignmentByte;
public byte AlignmentByte { get; set; }
}
}

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;
#else
public BlockHeader? Header;
#endif
/// <summary>
/// Pretree for first 256 elements of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeFirst256;
#else
public byte[]? PretreeFirst256;
#endif
public byte[]? PretreeFirst256 { get; set; }
/// <summary>
/// Path lengths of first 256 elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsFirst256;
#else
public int[]? PathLengthsFirst256;
#endif
public int[]? PathLengthsFirst256 { get; set; }
/// <summary>
/// Pretree for remainder of main tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeRemainder;
#else
public byte[]? PretreeRemainder;
#endif
public byte[]? PretreeRemainder { get; set; }
/// <summary>
/// Path lengths of remaining elements of main tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsRemainder;
#else
public int[]? PathLengthsRemainder;
#endif
public int[]? PathLengthsRemainder { get; set; }
/// <summary>
/// Pretree for length tree
/// </summary>
/// <remarks>20 elements, 4 bits each</remarks>
#if NET48
public byte[] PretreeLengthTree;
#else
public byte[]? PretreeLengthTree;
#endif
public byte[]? PretreeLengthTree { get; set; }
/// <summary>
/// Path lengths of elements in length tree
/// </summary>
/// <remarks>Encoded using pretree</remarks>
#if NET48
public int[] PathLengthsLengthTree;
#else
public int[]? PathLengthsLengthTree;
#endif
public int[]? PathLengthsLengthTree { get; set; }
// 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
@@ -23,6 +11,6 @@ namespace SabreTools.Models.Compression.MSZIP
/// <summary>
/// 'CK'
/// </summary>
public ushort Signature;
public ushort Signature { get; set; }
}
}

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;
#else
public int[]? LiteralLengths;
#endif
public virtual uint[]? LiteralLengths { get; set; }
/// <summary>
/// Huffman distance codes for the literal / length alphabet
/// </summary>
#if NET48
public int[] DistanceCodes;
#else
public int[]? DistanceCodes;
#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,18 +4,18 @@ 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
/// </summary>
/// <remarks>Bytes 0-1</remarks>
public ushort LEN;
public ushort LEN { get; set; }
/// <summary>
/// The one's complement of LEN
/// </summary>
/// <remarks>Bytes 2-3</remarks>
public ushort NLEN;
public ushort NLEN { get; set; }
}
}

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;
public int Entries { get; set; }
public int Entries;
/// <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; }
#if NET48
public ModelSymbol[] Symbols;
#else
public ModelSymbol[]? Symbols;
#endif
/// <remarks>
/// The initial total frequency is equal to the number of entries
/// in the table
/// </remarks>
public int TotalFrequency { get; set; }
#if NET48
public ushort[] LookupTable = new ushort[256];
#else
public ushort[]? LookupTable = new ushort[256];
#endif
/// <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;
public ushort Symbol { get; set; }
public ushort CumulativeFrequency;
/// <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

@@ -6,38 +6,26 @@ namespace SabreTools.Models.DVD
/// <summary>
/// Number of title sets
/// </summary>
public ushort NumberOfTitleSets;
public ushort NumberOfTitleSets { get; set; }
/// <summary>
/// Reserved
/// </summary>
#if NET48
public byte[] Reserved;
#else
public byte[]? Reserved;
#endif
public byte[]? Reserved { get; set; }
/// <summary>
/// End address (last byte of last VTS_ATRT)
/// </summary>
public uint EndAddress;
public uint EndAddress { get; set; }
/// <summary>
/// Offset to VTS_ATRT n
/// </summary>
#if NET48
public uint[] Offsets;
#else
public uint[]? Offsets;
#endif
public uint[]? Offsets { get; set; }
/// <summary>
/// Entries
/// </summary>
#if NET48
public AudioSubPictureAttributesTableEntry[] Entries;
#else
public AudioSubPictureAttributesTableEntry[]? Entries;
#endif
public AudioSubPictureAttributesTableEntry?[]? Entries { get; set; }
}
}

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