From c9481c761c8b4e624bb20b3a9eefddfe90c2fc5c Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sun, 10 Sep 2023 17:32:03 -0400 Subject: [PATCH] Fix nullability warnings --- Extensions.cs | 99 ++++++++++- Files/AttractMode.Serializer.cs | 3 + Files/ClrMamePro.Serializer.cs | 3 + Files/DosCenter.Serializer.cs | 3 + Files/EverdriveSMDB.Serializer.cs | 3 + Files/Hashfile.Serializer.cs | 3 + Files/Listrom.Serializer.cs | 3 + Files/RomCenter.Serializer.cs | 3 + Files/SeparatedValue.Serializer.cs | 3 + Files/XmlFile.Serializer.cs | 3 + PathProcessor.cs | 2 +- Streams/AACS.Deserializer.cs | 49 +++++- Streams/BDPlus.Deserializer.cs | 11 ++ Streams/BFPK.Deserializer.cs | 18 +- Streams/BSP.Deserializer.cs | 17 +- Streams/CFB.Deserializer.cs | 18 +- Streams/CIA.Deserializer.cs | 62 ++++++- Streams/GCF.Deserializer.cs | 34 +++- Streams/InstallShieldCabinet.Deserializer.cs | 58 ++++++- Streams/LinearExecutable.Deserializer.cs | 67 ++++++- Streams/MSDOS.Deserializer.cs | 11 ++ Streams/MicrosoftCabinet.Deserializer.cs | 11 ++ Streams/MoPaQ.Deserializer.cs | 53 +++++- Streams/N3DS.Deserializer.cs | 88 +++++++++- Streams/NCF.Deserialization.cs | 34 +++- Streams/NewExecutable.Deserializer.cs | 23 +++ Streams/Nitro.Deserializer.cs | 25 ++- Streams/PAK.Deserializer.cs | 18 +- Streams/PFF.Deserializer.cs | 25 ++- Streams/PlayJAudio.Deserializer.cs | 44 ++++- Streams/PortableExecutable.Deserializer.cs | 47 ++++- Streams/Quantum.Deserializer.cs | 27 ++- Streams/SGA.Deserializer.cs | 174 ++++++++++++++++++- Streams/VBSP.Deserializer.cs | 11 ++ Streams/VPK.Deserializer.cs | 20 +++ Streams/WAD.Deserializer.cs | 35 +++- Streams/XCP.Deserializer.cs | 24 ++- 37 files changed, 1054 insertions(+), 78 deletions(-) diff --git a/Extensions.cs b/Extensions.cs index 895e93b6..a4148ddf 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -156,7 +156,11 @@ namespace SabreTools.Serialization /// Data to parse into overlay data /// Offset into the byte array /// A filled SecuROM AddD overlay data on success, null on error +#if NET48 public static Models.PortableExecutable.SecuROMAddD AsSecuROMAddD(this byte[] data, ref int offset) +#else + public static Models.PortableExecutable.SecuROMAddD? AsSecuROMAddD(this byte[]? data, ref int offset) +#endif { // If we have data that's invalid, we can't do anything if (data == null) @@ -176,7 +180,7 @@ namespace SabreTools.Serialization if (string.IsNullOrWhiteSpace(addD.Version)) offset = originalOffset + 0x10; - addD.Build = data.ReadBytes(ref offset, 4).Select(b => (char)b).ToArray(); + addD.Build = data.ReadBytes(ref offset, 4)?.Select(b => (char)b)?.ToArray(); // Distinguish between v1 and v2 int bytesToRead = 112; // v2 @@ -219,7 +223,11 @@ namespace SabreTools.Serialization /// Data to parse into a database /// Offset into the byte array /// A filled NB10 Program Database on success, null on error +#if NET48 public static Models.PortableExecutable.NB10ProgramDatabase AsNB10ProgramDatabase(this byte[] data, ref int offset) +#else + public static Models.PortableExecutable.NB10ProgramDatabase? AsNB10ProgramDatabase(this byte[] data, ref int offset) +#endif { // If we have data that's invalid, we can't do anything if (data == null) @@ -245,7 +253,11 @@ namespace SabreTools.Serialization /// Data to parse into a database /// Offset into the byte array /// A filled RSDS Program Database on success, null on error +#if NET48 public static Models.PortableExecutable.RSDSProgramDatabase AsRSDSProgramDatabase(this byte[] data, ref int offset) +#else + public static Models.PortableExecutable.RSDSProgramDatabase? AsRSDSProgramDatabase(this byte[]? data, ref int offset) +#endif { // If we have data that's invalid, we can't do anything if (data == null) @@ -257,7 +269,9 @@ namespace SabreTools.Serialization if (rsdsProgramDatabase.Signature != 0x53445352) return null; - rsdsProgramDatabase.GUID = new Guid(data.ReadBytes(ref offset, 0x10)); + var guid = data.ReadBytes(ref offset, 0x10); + if (guid != null) + rsdsProgramDatabase.GUID = new Guid(guid); rsdsProgramDatabase.Age = data.ReadUInt32(ref offset); rsdsProgramDatabase.PathAndFileName = data.ReadString(ref offset, Encoding.ASCII); // TODO: Actually null-terminated UTF-8 @@ -275,7 +289,11 @@ namespace SabreTools.Serialization /// Data to parse into a resource header /// Offset into the byte array /// A filled resource header on success, null on error +#if NET48 public static Models.PortableExecutable.ResourceHeader AsResourceHeader(this byte[] data, ref int offset) +#else + public static Models.PortableExecutable.ResourceHeader? AsResourceHeader(this byte[]? data, ref int offset) +#endif { // If we have data that's invalid, we can't do anything if (data == null) @@ -301,7 +319,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into an accelerator table resource /// A filled accelerator table resource on success, null on error +#if NET48 public static Models.PortableExecutable.AcceleratorTableEntry[] AsAcceleratorTableResource(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.AcceleratorTableEntry[]? AsAcceleratorTableResource(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have data that's invalid for this resource type, we can't do anything if (entry?.Data == null || entry.Data.Length % 8 != 0) @@ -337,7 +359,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a side-by-side assembly manifest /// A filled side-by-side assembly manifest on success, null on error +#if NET48 public static Models.PortableExecutable.AssemblyManifest AsAssemblyManifest(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.AssemblyManifest? AsAssemblyManifest(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -359,7 +385,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a dialog box /// A filled dialog box on success, null on error +#if NET48 public static Models.PortableExecutable.DialogBoxResource AsDialogBox(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.DialogBoxResource? AsDialogBox(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -868,7 +898,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a font group /// A filled font group on success, null on error +#if NET48 public static Models.PortableExecutable.FontGroupHeader AsFontGroup(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.FontGroupHeader? AsFontGroup(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -919,7 +953,7 @@ namespace SabreTools.Serialization dirEntry.Entry.Device = entry.Data.ReadUInt32(ref offset); dirEntry.Entry.Face = entry.Data.ReadUInt32(ref offset); dirEntry.Entry.Reserved = entry.Data.ReadUInt32(ref offset); - + // TODO: Determine how to read these two? Immediately after? dirEntry.Entry.DeviceName = entry.Data.ReadString(ref offset); dirEntry.Entry.FaceName = entry.Data.ReadString(ref offset); @@ -937,7 +971,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a menu /// A filled menu on success, null on error +#if NET48 public static Models.PortableExecutable.MenuResource AsMenu(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.MenuResource? AsMenu(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -1060,7 +1098,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a message table resource /// A filled message table resource on success, null on error +#if NET48 public static Models.PortableExecutable.MessageResourceData AsMessageResourceData(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.MessageResourceData? AsMessageResourceData(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -1095,7 +1137,11 @@ namespace SabreTools.Serialization // Message resource entries if (messageResourceData.Blocks != null && messageResourceData.Blocks.Length != 0) { +#if NET48 var messageResourceEntries = new Dictionary(); +#else + var messageResourceEntries = new Dictionary(); +#endif for (int i = 0; i < messageResourceData.Blocks.Length; i++) { @@ -1110,8 +1156,13 @@ namespace SabreTools.Serialization messageResourceEntry.Flags = entry.Data.ReadUInt16(ref offset); Encoding textEncoding = messageResourceEntry.Flags == 0x0001 ? Encoding.Unicode : Encoding.ASCII; +#if NET48 byte[] textArray = entry.Data.ReadBytes(ref offset, messageResourceEntry.Length - 4); - messageResourceEntry.Text = textEncoding.GetString(textArray); +#else + byte[]? textArray = entry.Data.ReadBytes(ref offset, messageResourceEntry.Length - 4); +#endif + if (textArray != null) + messageResourceEntry.Text = textEncoding.GetString(textArray); messageResourceEntries[j] = messageResourceEntry; } @@ -1128,7 +1179,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a string table resource /// A filled string table resource on success, null on error +#if NET48 public static Dictionary AsStringTable(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Dictionary? AsStringTable(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -1138,7 +1193,11 @@ namespace SabreTools.Serialization int offset = 0, stringIndex = 0; // Create the output table +#if NET48 var stringTable = new Dictionary(); +#else + var stringTable = new Dictionary(); +#endif // Loop through and add while (offset < entry.Data.Length) @@ -1171,7 +1230,11 @@ namespace SabreTools.Serialization /// /// Resource data entry to parse into a version info resource /// A filled version info resource on success, null on error +#if NET48 public static Models.PortableExecutable.VersionInfo AsVersionInfo(this Models.PortableExecutable.ResourceDataEntry entry) +#else + public static Models.PortableExecutable.VersionInfo? AsVersionInfo(this Models.PortableExecutable.ResourceDataEntry? entry) +#endif { // If we have an invalid entry, just skip if (entry?.Data == null) @@ -1228,8 +1291,11 @@ namespace SabreTools.Serialization int currentOffset = offset; offset += 6; - +#if NET48 string nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode); +#else + string? nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode); +#endif offset = currentOffset; if (nextKey == "StringFileInfo") @@ -1251,7 +1317,11 @@ namespace SabreTools.Serialization int currentOffset = offset; offset += 6; +#if NET48 string nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode); +#else + string? nextKey = entry.Data.ReadString(ref offset, Encoding.Unicode); +#endif offset = currentOffset; if (nextKey == "StringFileInfo") @@ -1275,7 +1345,11 @@ namespace SabreTools.Serialization /// Data to parse into a string file info /// Offset into the byte array /// A filled string file info resource on success, null on error +#if NET48 private static Models.PortableExecutable.StringFileInfo AsStringFileInfo(byte[] data, ref int offset) +#else + private static Models.PortableExecutable.StringFileInfo? AsStringFileInfo(byte[] data, ref int offset) +#endif { var stringFileInfo = new Models.PortableExecutable.StringFileInfo(); @@ -1288,7 +1362,7 @@ namespace SabreTools.Serialization stringFileInfo.Key = data.ReadString(ref offset, Encoding.Unicode); if (stringFileInfo.Key != "StringFileInfo") { - offset -= 6 + ((stringFileInfo.Key.Length + 1) * 2); + offset -= 6 + ((stringFileInfo.Key?.Length ?? 0 + 1) * 2); return null; } @@ -1335,8 +1409,13 @@ namespace SabreTools.Serialization if (stringData.ValueLength > 0) { +#if NET48 byte[] valueBytes = data.ReadBytes(ref offset, stringData.ValueLength * sizeof(ushort)); - stringData.Value = Encoding.Unicode.GetString(valueBytes); +#else + byte[]? valueBytes = data.ReadBytes(ref offset, stringData.ValueLength * sizeof(ushort)); +#endif + if (valueBytes != null) + stringData.Value = Encoding.Unicode.GetString(valueBytes); } // Align to the DWORD boundary if we're not at the end @@ -1365,7 +1444,11 @@ namespace SabreTools.Serialization /// Data to parse into a var file info /// Offset into the byte array /// A filled var file info resource on success, null on error +#if NET48 private static Models.PortableExecutable.VarFileInfo AsVarFileInfo(byte[] data, ref int offset) +#else + private static Models.PortableExecutable.VarFileInfo? AsVarFileInfo(byte[] data, ref int offset) +#endif { var varFileInfo = new Models.PortableExecutable.VarFileInfo(); @@ -1397,7 +1480,7 @@ namespace SabreTools.Serialization varData.Key = data.ReadString(ref offset, Encoding.Unicode); if (varData.Key != "Translation") { - offset -= 6 + ((varData.Key.Length + 1) * 2); + offset -= 6 + ((varData.Key?.Length ?? 0 + 1) * 2); return null; } diff --git a/Files/AttractMode.Serializer.cs b/Files/AttractMode.Serializer.cs index 0b973607..beebf9a7 100644 --- a/Files/AttractMode.Serializer.cs +++ b/Files/AttractMode.Serializer.cs @@ -12,6 +12,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.AttractMode().Serialize(obj)) { if (stream == null) diff --git a/Files/ClrMamePro.Serializer.cs b/Files/ClrMamePro.Serializer.cs index d67de58c..652d0c6b 100644 --- a/Files/ClrMamePro.Serializer.cs +++ b/Files/ClrMamePro.Serializer.cs @@ -19,6 +19,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path, bool quotes) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.ClrMamePro().Serialize(obj, quotes)) { if (stream == null) diff --git a/Files/DosCenter.Serializer.cs b/Files/DosCenter.Serializer.cs index d0de8429..12b9d50f 100644 --- a/Files/DosCenter.Serializer.cs +++ b/Files/DosCenter.Serializer.cs @@ -11,6 +11,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.DosCenter().Serialize(obj)) { if (stream == null) diff --git a/Files/EverdriveSMDB.Serializer.cs b/Files/EverdriveSMDB.Serializer.cs index 82e4088d..e2fd2aef 100644 --- a/Files/EverdriveSMDB.Serializer.cs +++ b/Files/EverdriveSMDB.Serializer.cs @@ -11,6 +11,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.EverdriveSMDB().Serialize(obj)) { if (stream == null) diff --git a/Files/Hashfile.Serializer.cs b/Files/Hashfile.Serializer.cs index 3122c0cd..eb4754d0 100644 --- a/Files/Hashfile.Serializer.cs +++ b/Files/Hashfile.Serializer.cs @@ -9,6 +9,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(Models.Hashfile.Hashfile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.Hashfile().Serialize(obj)) { if (stream == null) diff --git a/Files/Listrom.Serializer.cs b/Files/Listrom.Serializer.cs index 466061c3..af405dbd 100644 --- a/Files/Listrom.Serializer.cs +++ b/Files/Listrom.Serializer.cs @@ -11,6 +11,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.Listrom().Serialize(obj)) { if (stream == null) diff --git a/Files/RomCenter.Serializer.cs b/Files/RomCenter.Serializer.cs index 1f71d15a..d054b252 100644 --- a/Files/RomCenter.Serializer.cs +++ b/Files/RomCenter.Serializer.cs @@ -11,6 +11,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.RomCenter().Serialize(obj)) { if (stream == null) diff --git a/Files/SeparatedValue.Serializer.cs b/Files/SeparatedValue.Serializer.cs index c50cfd03..7dc937c8 100644 --- a/Files/SeparatedValue.Serializer.cs +++ b/Files/SeparatedValue.Serializer.cs @@ -11,6 +11,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(MetadataFile? obj, string? path) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.SeparatedValue().Serialize(obj)) { if (stream == null) diff --git a/Files/XmlFile.Serializer.cs b/Files/XmlFile.Serializer.cs index e3ff5024..d48890a7 100644 --- a/Files/XmlFile.Serializer.cs +++ b/Files/XmlFile.Serializer.cs @@ -33,6 +33,9 @@ namespace SabreTools.Serialization.Files public bool Serialize(T? obj, string? path, string? name = null, string? pubid = null, string? sysid = null, string? subset = null) #endif { + if (string.IsNullOrWhiteSpace(path)) + return false; + using (var stream = new Streams.XmlFile().Serialize(obj, name, pubid, sysid, subset)) { if (stream == null) diff --git a/PathProcessor.cs b/PathProcessor.cs index dee59422..7e1ed323 100644 --- a/PathProcessor.cs +++ b/PathProcessor.cs @@ -14,7 +14,7 @@ namespace SabreTools.Serialization #if NET48 public static Stream OpenStream(string path) #else - public static Stream? OpenStream(string path) + public static Stream? OpenStream(string? path) #endif { try diff --git a/Streams/AACS.Deserializer.cs b/Streams/AACS.Deserializer.cs index 8b77c15c..d6f8d3bc 100644 --- a/Streams/AACS.Deserializer.cs +++ b/Streams/AACS.Deserializer.cs @@ -84,7 +84,14 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building // The first 4 bytes make up the type and length +#if NET48 byte[] typeAndLength = data.ReadBytes(4); +#else + byte[]? typeAndLength = data.ReadBytes(4); +#endif + if (typeAndLength == null) + return null; + RecordType type = (RecordType)typeAndLength[0]; // Remove the first byte and parse as big-endian @@ -191,7 +198,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled media key data record on success, null on error +#if NET48 private static MediaKeyDataRecord ParseMediaKeyDataRecord(Stream data, RecordType type, uint length) +#else + private static MediaKeyDataRecord? ParseMediaKeyDataRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.MediaKeyData) @@ -212,8 +223,13 @@ namespace SabreTools.Serialization.Streams // Try to parse the media keys while (data.Position < initialOffset + length) { +#if NET48 byte[] mediaKey = data.ReadBytes(0x10); - mediaKeys.Add(mediaKey); +#else + byte[]? mediaKey = data.ReadBytes(0x10); +#endif + if (mediaKey != null) + mediaKeys.Add(mediaKey); } // Set the media keys @@ -227,7 +243,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled subset-difference index record on success, null on error +#if NET48 private static SubsetDifferenceIndexRecord ParseSubsetDifferenceIndexRecord(Stream data, RecordType type, uint length) +#else + private static SubsetDifferenceIndexRecord? ParseSubsetDifferenceIndexRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.SubsetDifferenceIndex) @@ -265,7 +285,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled type and version record on success, null on error +#if NET48 private static TypeAndVersionRecord ParseTypeAndVersionRecord(Stream data, RecordType type, uint length) +#else + private static TypeAndVersionRecord? ParseTypeAndVersionRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.TypeAndVersion) @@ -287,7 +311,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled drive revocation list record on success, null on error +#if NET48 private static DriveRevocationListRecord ParseDriveRevocationListRecord(Stream data, RecordType type, uint length) +#else + private static DriveRevocationListRecord? ParseDriveRevocationListRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.DriveRevocationList) @@ -348,7 +376,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled host revocation list record on success, null on error +#if NET48 private static HostRevocationListRecord ParseHostRevocationListRecord(Stream data, RecordType type, uint length) +#else + private static HostRevocationListRecord? ParseHostRevocationListRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.HostRevocationList) @@ -409,7 +441,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled verify media key record on success, null on error +#if NET48 private static VerifyMediaKeyRecord ParseVerifyMediaKeyRecord(Stream data, RecordType type, uint length) +#else + private static VerifyMediaKeyRecord? ParseVerifyMediaKeyRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.VerifyMediaKey) @@ -430,7 +466,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled copyright record on success, null on error +#if NET48 private static CopyrightRecord ParseCopyrightRecord(Stream data, RecordType type, uint length) +#else + private static CopyrightRecord? ParseCopyrightRecord(Stream data, RecordType type, uint length) +#endif { // Verify we're calling the right parser if (type != RecordType.Copyright) @@ -443,8 +483,13 @@ namespace SabreTools.Serialization.Streams record.RecordLength = length; if (length > 4) { +#if NET48 byte[] copyright = data.ReadBytes((int)(length - 4)); - record.Copyright = Encoding.ASCII.GetString(copyright).TrimEnd('\0'); +#else + byte[]? copyright = data.ReadBytes((int)(length - 4)); +#endif + if (copyright != null) + record.Copyright = Encoding.ASCII.GetString(copyright).TrimEnd('\0'); } return record; diff --git a/Streams/BDPlus.Deserializer.cs b/Streams/BDPlus.Deserializer.cs index dd3ab023..f5c21d83 100644 --- a/Streams/BDPlus.Deserializer.cs +++ b/Streams/BDPlus.Deserializer.cs @@ -35,12 +35,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled SVM on success, null on error +#if NET48 private static SVM ParseSVMData(Stream data) +#else + private static SVM? ParseSVMData(Stream data) +#endif { // TODO: Use marshalling here instead of building var svm = new SVM(); +#if NET48 byte[] signature = data.ReadBytes(8); +#else + byte[]? signature = data.ReadBytes(8); +#endif + if (signature == null) + return null; + svm.Signature = Encoding.ASCII.GetString(signature); if (svm.Signature != SignatureString) return null; diff --git a/Streams/BFPK.Deserializer.cs b/Streams/BFPK.Deserializer.cs index d423d4f7..49ec576f 100644 --- a/Streams/BFPK.Deserializer.cs +++ b/Streams/BFPK.Deserializer.cs @@ -72,12 +72,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); +#if NET48 byte[] magic = data.ReadBytes(4); +#else + byte[]? magic = data.ReadBytes(4); +#endif + if (magic == null) + return null; + header.Magic = Encoding.ASCII.GetString(magic); if (header.Magic != SignatureString) return null; @@ -101,8 +112,13 @@ namespace SabreTools.Serialization.Streams fileEntry.NameSize = data.ReadInt32(); if (fileEntry.NameSize > 0) { +#if NET48 byte[] name = data.ReadBytes(fileEntry.NameSize); - fileEntry.Name = Encoding.ASCII.GetString(name); +#else + byte[]? name = data.ReadBytes(fileEntry.NameSize); +#endif + if (name != null) + fileEntry.Name = Encoding.ASCII.GetString(name); } fileEntry.UncompressedSize = data.ReadInt32(); diff --git a/Streams/BSP.Deserializer.cs b/Streams/BSP.Deserializer.cs index cb0ecf2a..4a73f675 100644 --- a/Streams/BSP.Deserializer.cs +++ b/Streams/BSP.Deserializer.cs @@ -85,7 +85,11 @@ namespace SabreTools.Serialization.Streams for (int i = 0; i < textureHeader.TextureCount; i++) { // Get the texture offset +#if NET48 int offset = (int)(textureHeader.Offsets[i] + file.Lumps[HL_BSP_LUMP_TEXTUREDATA].Offset); +#else + int offset = (int)(textureHeader.Offsets![i] + file.Lumps[HL_BSP_LUMP_TEXTUREDATA].Offset); +#endif if (offset < 0 || offset >= data.Length) continue; @@ -106,7 +110,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Level header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); @@ -170,8 +178,13 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building Texture texture = new Texture(); - byte[] name = data.ReadBytes(16).TakeWhile(c => c != '\0').ToArray(); - texture.Name = Encoding.ASCII.GetString(name); +#if NET48 + byte[] name = data.ReadBytes(16)?.TakeWhile(c => c != '\0')?.ToArray(); +#else + byte[]? name = data.ReadBytes(16)?.TakeWhile(c => c != '\0')?.ToArray(); +#endif + if (name != null) + texture.Name = Encoding.ASCII.GetString(name); texture.Width = data.ReadUInt32(); texture.Height = data.ReadUInt32(); texture.Offsets = new uint[4]; diff --git a/Streams/CFB.Deserializer.cs b/Streams/CFB.Deserializer.cs index 89eed96f..728c4029 100644 --- a/Streams/CFB.Deserializer.cs +++ b/Streams/CFB.Deserializer.cs @@ -49,7 +49,8 @@ namespace SabreTools.Serialization.Streams var difatSectors = new List(); // Add the sectors from the header - difatSectors.AddRange(fileHeader.DIFAT); + if (fileHeader.DIFAT != null) + difatSectors.AddRange(fileHeader.DIFAT); // Loop through and add the DIFAT sectors SectorNumber currentSector = (SectorNumber)fileHeader.FirstDIFATSectorLocation; @@ -230,7 +231,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled file header on success, null on error +#if NET48 private static FileHeader ParseFileHeader(Stream data) +#else + private static FileHeader? ParseFileHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building FileHeader header = new FileHeader(); @@ -309,7 +314,11 @@ namespace SabreTools.Serialization.Streams /// Sector shift from the header /// Major version from the header /// Filled sector full of directory entries on success, null on error +#if NET48 private static DirectoryEntry[] ParseDirectoryEntries(Stream data, ushort sectorShift, ushort majorVersion) +#else + private static DirectoryEntry[]? ParseDirectoryEntries(Stream data, ushort sectorShift, ushort majorVersion) +#endif { // TODO: Use marshalling here instead of building const int directoryEntrySize = 64 + 2 + 1 + 1 + 4 + 4 + 4 + 16 + 4 + 8 + 8 + 4 + 8; @@ -339,8 +348,13 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building DirectoryEntry directoryEntry = new DirectoryEntry(); +#if NET48 byte[] name = data.ReadBytes(64); - directoryEntry.Name = Encoding.Unicode.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(64); +#endif + if (name != null) + directoryEntry.Name = Encoding.Unicode.GetString(name).TrimEnd('\0'); directoryEntry.NameLength = data.ReadUInt16(); directoryEntry.ObjectType = (ObjectType)data.ReadByteValue(); directoryEntry.ColorFlag = (ColorFlag)data.ReadByteValue(); diff --git a/Streams/CIA.Deserializer.cs b/Streams/CIA.Deserializer.cs index e3d1949e..0a61e12c 100644 --- a/Streams/CIA.Deserializer.cs +++ b/Streams/CIA.Deserializer.cs @@ -172,7 +172,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled certificate on success, null on error +#if NET48 private static Certificate ParseCertificate(Stream data) +#else + private static Certificate? ParseCertificate(Stream data) +#endif { // TODO: Use marshalling here instead of building Certificate certificate = new Certificate(); @@ -210,11 +214,21 @@ namespace SabreTools.Serialization.Streams certificate.Signature = data.ReadBytes(certificate.SignatureSize); certificate.Padding = data.ReadBytes(certificate.PaddingSize); +#if NET48 byte[] issuer = data.ReadBytes(0x40); - certificate.Issuer = Encoding.ASCII.GetString(issuer).TrimEnd('\0'); +#else + byte[]? issuer = data.ReadBytes(0x40); +#endif + if (issuer != null) + certificate.Issuer = Encoding.ASCII.GetString(issuer).TrimEnd('\0'); certificate.KeyType = (PublicKeyType)data.ReadUInt32(); +#if NET48 byte[] name = data.ReadBytes(0x40); - certificate.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(0x40); +#endif + if (name != null) + certificate.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); certificate.ExpirationTime = data.ReadUInt32(); switch (certificate.KeyType) @@ -246,7 +260,11 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// Indicates if the ticket is from CDN /// Filled ticket on success, null on error +#if NET48 private static Ticket ParseTicket(Stream data, bool fromCdn = false) +#else + private static Ticket? ParseTicket(Stream data, bool fromCdn = false) +#endif { // TODO: Use marshalling here instead of building Ticket ticket = new Ticket(); @@ -284,8 +302,13 @@ namespace SabreTools.Serialization.Streams ticket.Signature = data.ReadBytes(ticket.SignatureSize); ticket.Padding = data.ReadBytes(ticket.PaddingSize); +#if NET48 byte[] issuer = data.ReadBytes(0x40); - ticket.Issuer = Encoding.ASCII.GetString(issuer).TrimEnd('\0'); +#else + byte[]? issuer = data.ReadBytes(0x40); +#endif + if (issuer != null) + ticket.Issuer = Encoding.ASCII.GetString(issuer).TrimEnd('\0'); ticket.ECCPublicKey = data.ReadBytes(0x3C); ticket.Version = data.ReadByteValue(); ticket.CaCrlVersion = data.ReadByteValue(); @@ -315,9 +338,16 @@ namespace SabreTools.Serialization.Streams data.Seek(4, SeekOrigin.Current); // Read the size (big-endian) +#if NET48 byte[] contentIndexSize = data.ReadBytes(4); - Array.Reverse(contentIndexSize); - ticket.ContentIndexSize = BitConverter.ToUInt32(contentIndexSize, 0); +#else + byte[]? contentIndexSize = data.ReadBytes(4); +#endif + if (contentIndexSize != null) + { + Array.Reverse(contentIndexSize); + ticket.ContentIndexSize = BitConverter.ToUInt32(contentIndexSize, 0); + } // Seek back to the start of the content index data.Seek(-8, SeekOrigin.Current); @@ -347,7 +377,11 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// Indicates if the ticket is from CDN /// Filled title metadata on success, null on error +#if NET48 private static TitleMetadata ParseTitleMetadata(Stream data, bool fromCdn = false) +#else + private static TitleMetadata? ParseTitleMetadata(Stream data, bool fromCdn = false) +#endif { // TODO: Use marshalling here instead of building TitleMetadata titleMetadata = new TitleMetadata(); @@ -385,8 +419,13 @@ namespace SabreTools.Serialization.Streams titleMetadata.Signature = data.ReadBytes(titleMetadata.SignatureSize); titleMetadata.Padding1 = data.ReadBytes(titleMetadata.PaddingSize); +#if NET48 byte[] issuer = data.ReadBytes(0x40); - titleMetadata.Issuer = Encoding.ASCII.GetString(issuer).TrimEnd('\0'); +#else + byte[]? issuer = data.ReadBytes(0x40); +#endif + if (issuer != null) + titleMetadata.Issuer = Encoding.ASCII.GetString(issuer).TrimEnd('\0'); titleMetadata.Version = data.ReadByteValue(); titleMetadata.CaCrlVersion = data.ReadByteValue(); titleMetadata.SignerCrlVersion = data.ReadByteValue(); @@ -404,9 +443,16 @@ namespace SabreTools.Serialization.Streams titleMetadata.TitleVersion = data.ReadUInt16(); // Read the content count (big-endian) +#if NET48 byte[] contentCount = data.ReadBytes(2); - Array.Reverse(contentCount); - titleMetadata.ContentCount = BitConverter.ToUInt16(contentCount, 0); +#else + byte[]? contentCount = data.ReadBytes(2); +#endif + if (contentCount != null) + { + Array.Reverse(contentCount); + titleMetadata.ContentCount = BitConverter.ToUInt16(contentCount, 0); + } titleMetadata.BootContent = data.ReadUInt16(); titleMetadata.Padding2 = data.ReadBytes(2); diff --git a/Streams/GCF.Deserializer.cs b/Streams/GCF.Deserializer.cs index 4e35c446..455bb089 100644 --- a/Streams/GCF.Deserializer.cs +++ b/Streams/GCF.Deserializer.cs @@ -113,7 +113,11 @@ namespace SabreTools.Serialization.Streams if (header.MinorVersion < 6) { // Create the block entry map array +#if NET48 file.BlockEntryMaps = new BlockEntryMap[file.BlockEntryMapHeader.BlockCount]; +#else + file.BlockEntryMaps = new BlockEntryMap[file.BlockEntryMapHeader!.BlockCount]; +#endif // Try to parse the block entry maps for (int i = 0; i < file.BlockEntryMapHeader.BlockCount; i++) @@ -165,17 +169,29 @@ namespace SabreTools.Serialization.Streams long directoryNamesEnd = data.Position + directoryHeader.NameSize; // Create the string dictionary +#if NET48 file.DirectoryNames = new Dictionary(); +#else + file.DirectoryNames = new Dictionary(); +#endif // Loop and read the null-terminated strings while (data.Position < directoryNamesEnd) { long nameOffset = data.Position - directoryNamesStart; +#if NET48 string directoryName = data.ReadString(Encoding.ASCII); +#else + string? directoryName = data.ReadString(Encoding.ASCII); +#endif if (data.Position > directoryNamesEnd) { - data.Seek(-directoryName.Length, SeekOrigin.Current); + data.Seek(-directoryName?.Length ?? 0, SeekOrigin.Current); +#if NET48 byte[] endingData = data.ReadBytes((int)(directoryNamesEnd - data.Position)); +#else + byte[]? endingData = data.ReadBytes((int)(directoryNamesEnd - data.Position)); +#endif if (endingData != null) directoryName = Encoding.ASCII.GetString(endingData); else @@ -360,7 +376,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Game Cache on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); @@ -614,7 +634,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Game Cache directory map header on success, null on error +#if NET48 private static DirectoryMapHeader ParseDirectoryMapHeader(Stream data) +#else + private static DirectoryMapHeader? ParseDirectoryMapHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building DirectoryMapHeader directoryMapHeader = new DirectoryMapHeader(); @@ -650,7 +674,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Game Cache checksum header on success, null on error +#if NET48 private static ChecksumHeader ParseChecksumHeader(Stream data) +#else + private static ChecksumHeader? ParseChecksumHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building ChecksumHeader checksumHeader = new ChecksumHeader(); @@ -669,7 +697,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Game Cache checksum map header on success, null on error +#if NET48 private static ChecksumMapHeader ParseChecksumMapHeader(Stream data) +#else + private static ChecksumMapHeader? ParseChecksumMapHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building ChecksumMapHeader checksumMapHeader = new ChecksumMapHeader(); diff --git a/Streams/InstallShieldCabinet.Deserializer.cs b/Streams/InstallShieldCabinet.Deserializer.cs index 04a5a41c..96e0a91c 100644 --- a/Streams/InstallShieldCabinet.Deserializer.cs +++ b/Streams/InstallShieldCabinet.Deserializer.cs @@ -120,8 +120,13 @@ namespace SabreTools.Serialization.Streams data.Seek(offset, SeekOrigin.Begin); // Create and add the file descriptor +#if NET48 string directoryName = ParseDirectoryName(data, GetMajorVersion(commonHeader)); - cabinet.DirectoryNames[i] = directoryName; +#else + string? directoryName = ParseDirectoryName(data, GetMajorVersion(commonHeader)); +#endif + if (directoryName != null) + cabinet.DirectoryNames[i] = directoryName; } #endregion @@ -165,11 +170,19 @@ namespace SabreTools.Serialization.Streams #region File Group Offsets // Create and fill the file group offsets +#if NET48 cabinet.FileGroupOffsets = new Dictionary(); - for (int i = 0; i < descriptor.FileGroupOffsets.Length; i++) +#else + cabinet.FileGroupOffsets = new Dictionary(); +#endif + for (int i = 0; i < (descriptor.FileGroupOffsets?.Length ?? 0); i++) { // Get the file group offset +#if NET48 uint offset = descriptor.FileGroupOffsets[i]; +#else + uint offset = descriptor.FileGroupOffsets![i]; +#endif if (offset == 0) continue; @@ -216,7 +229,11 @@ namespace SabreTools.Serialization.Streams foreach (var kvp in cabinet.FileGroupOffsets) { // Get the offset +#if NET48 OffsetList list = kvp.Value; +#else + OffsetList? list = kvp.Value; +#endif if (list == null) { fileGroupId++; @@ -247,11 +264,19 @@ namespace SabreTools.Serialization.Streams #region Component Offsets // Create and fill the component offsets +#if NET48 cabinet.ComponentOffsets = new Dictionary(); - for (int i = 0; i < descriptor.ComponentOffsets.Length; i++) +#else + cabinet.ComponentOffsets = new Dictionary(); +#endif + for (int i = 0; i < (descriptor.ComponentOffsets?.Length ?? 0); i++) { // Get the component offset +#if NET48 uint offset = descriptor.ComponentOffsets[i]; +#else + uint offset = descriptor.ComponentOffsets![i]; +#endif if (offset == 0) continue; @@ -295,10 +320,18 @@ namespace SabreTools.Serialization.Streams // Create and fill the components int componentId = 0; +#if NET48 foreach (KeyValuePair kvp in cabinet.ComponentOffsets) +#else + foreach (KeyValuePair kvp in cabinet.ComponentOffsets) +#endif { // Get the offset +#if NET48 OffsetList list = kvp.Value; +#else + OffsetList? list = kvp.Value; +#endif if (list == null) { componentId++; @@ -336,11 +369,22 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled common header on success, null on error +#if NET48 private static CommonHeader ParseCommonHeader(Stream data) +#else + private static CommonHeader? ParseCommonHeader(Stream data) +#endif { CommonHeader commonHeader = new CommonHeader(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + commonHeader.Signature = Encoding.ASCII.GetString(signature); if (commonHeader.Signature != SignatureString) return null; @@ -656,9 +700,9 @@ namespace SabreTools.Serialization.Streams data.Seek(nameOffset + descriptorOffset, SeekOrigin.Begin); if (majorVersion >= 17) - component.FileGroupNames[j] = data.ReadString(Encoding.Unicode); + component.FileGroupNames[j] = data.ReadString(Encoding.Unicode) ?? string.Empty; else - component.FileGroupNames[j] = data.ReadString(Encoding.ASCII); + component.FileGroupNames[j] = data.ReadString(Encoding.ASCII) ?? string.Empty; // Seek back to the original position data.Seek(preNameOffset, SeekOrigin.Begin); @@ -677,7 +721,11 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// Major version of the cabinet /// Filled directory name on success, null on error +#if NET48 private static string ParseDirectoryName(Stream data, int majorVersion) +#else + private static string? ParseDirectoryName(Stream data, int majorVersion) +#endif { // Read the string if (majorVersion >= 17) diff --git a/Streams/LinearExecutable.Deserializer.cs b/Streams/LinearExecutable.Deserializer.cs index 1020ff1e..8833ff1e 100644 --- a/Streams/LinearExecutable.Deserializer.cs +++ b/Streams/LinearExecutable.Deserializer.cs @@ -190,10 +190,11 @@ namespace SabreTools.Serialization.Streams while (true) { var bundle = ParseEntryTableBundle(data); - entryTable.Add(bundle); + if (bundle != null) + entryTable.Add(bundle); // If we have a 0-length entry - if (bundle.Entries == 0) + if (bundle == null || bundle.Entries == 0) break; } @@ -246,7 +247,7 @@ namespace SabreTools.Serialization.Streams data.Seek(offset, SeekOrigin.Begin); // Create the fix-up page table - executable.FixupPageTable = new FixupPageTableEntry[executable.ObjectPageMap.Length + 1]; + executable.FixupPageTable = new FixupPageTableEntry[executable.ObjectPageMap?.Length ?? 0 + 1]; // Try to parse the fix-up page table for (int i = 0; i < executable.FixupPageTable.Length; i++) @@ -271,7 +272,7 @@ namespace SabreTools.Serialization.Streams data.Seek(offset, SeekOrigin.Begin); // Create the fix-up record table - executable.FixupRecordTable = new FixupRecordTableEntry[executable.ObjectPageMap.Length + 1]; + executable.FixupRecordTable = new FixupRecordTableEntry[executable.ObjectPageMap?.Length ?? 0 + 1]; // Try to parse the fix-up record table for (int i = 0; i < executable.FixupRecordTable.Length; i++) @@ -426,12 +427,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled information block on success, null on error +#if NET48 private static InformationBlock ParseInformationBlock(Stream data) +#else + private static InformationBlock? ParseInformationBlock(Stream data) +#endif { // TODO: Use marshalling here instead of building var informationBlock = new InformationBlock(); +#if NET48 byte[] magic = data.ReadBytes(2); +#else + byte[]? magic = data.ReadBytes(2); +#endif + if (magic == null) + return null; + informationBlock.Signature = Encoding.ASCII.GetString(magic); if (informationBlock.Signature != LESignatureString && informationBlock.Signature != LXSignatureString) return null; @@ -554,8 +566,13 @@ namespace SabreTools.Serialization.Streams entry.Length = data.ReadByteValue(); if (entry.Length > 0) { +#if NET48 byte[] name = data.ReadBytes(entry.Length); - entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(entry.Length); +#endif + if (name != null) + entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); } entry.OrdinalNumber = data.ReadUInt16(); @@ -567,7 +584,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled entry table bundle on success, null on error +#if NET48 private static EntryTableBundle ParseEntryTableBundle(Stream data) +#else + private static EntryTableBundle? ParseEntryTableBundle(Stream data) +#endif { // TODO: Use marshalling here instead of building var bundle = new EntryTableBundle(); @@ -683,7 +704,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled fix-up record table entry on success, null on error +#if NET48 private static FixupRecordTableEntry ParseFixupRecordTableEntry(Stream data) +#else + private static FixupRecordTableEntry? ParseFixupRecordTableEntry(Stream data) +#endif { // TODO: Use marshalling here instead of building var entry = new FixupRecordTableEntry(); @@ -826,8 +851,13 @@ namespace SabreTools.Serialization.Streams entry.Length = data.ReadByteValue(); if (entry.Length > 0) { +#if NET48 byte[] name = data.ReadBytes(entry.Length); - entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(entry.Length); +#endif + if (name != null) + entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); } return entry; @@ -846,8 +876,13 @@ namespace SabreTools.Serialization.Streams entry.Length = data.ReadByteValue(); if (entry.Length > 0) { +#if NET48 byte[] name = data.ReadBytes(entry.Length); - entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(entry.Length); +#endif + if (name != null) + entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); } return entry; @@ -881,8 +916,13 @@ namespace SabreTools.Serialization.Streams entry.Length = data.ReadByteValue(); if (entry.Length > 0) { +#if NET48 byte[] name = data.ReadBytes(entry.Length); - entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(entry.Length); +#endif + if (name != null) + entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); } entry.OrdinalNumber = data.ReadUInt16(); @@ -895,12 +935,23 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// Total size of the debug information /// Filled debug information on success, null on error +#if NET48 private static DebugInformation ParseDebugInformation(Stream data, long size) +#else + private static DebugInformation? ParseDebugInformation(Stream data, long size) +#endif { // TODO: Use marshalling here instead of building var debugInformation = new DebugInformation(); +#if NET48 byte[] signature = data.ReadBytes(3); +#else + byte[]? signature = data.ReadBytes(3); +#endif + if (signature == null) + return null; + debugInformation.Signature = Encoding.ASCII.GetString(signature); if (debugInformation.Signature != DebugInformationSignatureString) return null; diff --git a/Streams/MSDOS.Deserializer.cs b/Streams/MSDOS.Deserializer.cs index 52b930a7..74d6d39b 100644 --- a/Streams/MSDOS.Deserializer.cs +++ b/Streams/MSDOS.Deserializer.cs @@ -68,14 +68,25 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled executable header on success, null on error +#if NET48 private static ExecutableHeader ParseExecutableHeader(Stream data) +#else + private static ExecutableHeader? ParseExecutableHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building var header = new ExecutableHeader(); #region Standard Fields +#if NET48 byte[] magic = data.ReadBytes(2); +#else + byte[]? magic = data.ReadBytes(2); +#endif + if (magic == null) + return null; + header.Magic = Encoding.ASCII.GetString(magic); if (header.Magic != SignatureString) return null; diff --git a/Streams/MicrosoftCabinet.Deserializer.cs b/Streams/MicrosoftCabinet.Deserializer.cs index 515ce4b3..ac20f87d 100644 --- a/Streams/MicrosoftCabinet.Deserializer.cs +++ b/Streams/MicrosoftCabinet.Deserializer.cs @@ -94,11 +94,22 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled cabinet header on success, null on error +#if NET48 private static CFHEADER ParseCabinetHeader(Stream data) +#else + private static CFHEADER? ParseCabinetHeader(Stream data) +#endif { CFHEADER header = new CFHEADER(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); if (header.Signature != SignatureString) return null; diff --git a/Streams/MoPaQ.Deserializer.cs b/Streams/MoPaQ.Deserializer.cs index cd7a8cce..af585bc4 100644 --- a/Streams/MoPaQ.Deserializer.cs +++ b/Streams/MoPaQ.Deserializer.cs @@ -276,7 +276,7 @@ namespace SabreTools.Serialization.Streams // Read in the hi-block table var hiBlockTable = new List(); - for (int i = 0; i < archive.BlockTable.Length; i++) + for (int i = 0; i < (archive.BlockTable?.Length ?? 0); i++) { short hiBlockEntry = data.ReadInt16(); hiBlockTable.Add(hiBlockEntry); @@ -342,12 +342,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled archive header on success, null on error +#if NET48 private static ArchiveHeader ParseArchiveHeader(Stream data) +#else + private static ArchiveHeader? ParseArchiveHeader(Stream data) +#endif { ArchiveHeader archiveHeader = new ArchiveHeader(); // V1 - Common +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + archiveHeader.Signature = Encoding.ASCII.GetString(signature); if (archiveHeader.Signature != ArchiveHeaderSignatureString) return null; @@ -403,11 +414,22 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled user data on success, null on error +#if NET48 private static UserData ParseUserData(Stream data) +#else + private static UserData? ParseUserData(Stream data) +#endif { UserData userData = new UserData(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + userData.Signature = Encoding.ASCII.GetString(signature); if (userData.Signature != UserDataSignatureString) return null; @@ -424,12 +446,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled HET table on success, null on error +#if NET48 private static HetTable ParseHetTable(Stream data) +#else + private static HetTable? ParseHetTable(Stream data) +#endif { HetTable hetTable = new HetTable(); // Common Headers +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + hetTable.Signature = Encoding.ASCII.GetString(signature); if (hetTable.Signature != HetTableSignatureString) return null; @@ -458,12 +491,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled BET table on success, null on error +#if NET48 private static BetTable ParseBetTable(Stream data) +#else + private static BetTable? ParseBetTable(Stream data) +#endif { BetTable betTable = new BetTable(); // Common Headers +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + betTable.Signature = Encoding.ASCII.GetString(signature); if (betTable.Signature != BetTableSignatureString) return null; @@ -496,8 +540,13 @@ namespace SabreTools.Serialization.Streams betTable.FlagCount = data.ReadUInt32(); betTable.FlagsArray = new uint[betTable.FlagCount]; +#if NET48 byte[] flagsArray = data.ReadBytes((int)betTable.FlagCount * 4); - Buffer.BlockCopy(flagsArray, 0, betTable.FlagsArray, 0, (int)betTable.FlagCount * 4); +#else + byte[]? flagsArray = data.ReadBytes((int)betTable.FlagCount * 4); +#endif + if (flagsArray != null) + Buffer.BlockCopy(flagsArray, 0, betTable.FlagsArray, 0, (int)betTable.FlagCount * 4); // TODO: Populate the file table // TODO: Populate the hash table diff --git a/Streams/N3DS.Deserializer.cs b/Streams/N3DS.Deserializer.cs index e18c004e..6069c7d7 100644 --- a/Streams/N3DS.Deserializer.cs +++ b/Streams/N3DS.Deserializer.cs @@ -80,7 +80,9 @@ namespace SabreTools.Serialization.Streams #endregion // Cache the media unit size for further use - long mediaUnitSize = (uint)(0x200 * Math.Pow(2, header.PartitionFlags[(int)NCSDFlags.MediaUnitSize])); + long mediaUnitSize = 0; + if (header.PartitionFlags != null) + mediaUnitSize = (uint)(0x200 * Math.Pow(2, header.PartitionFlags[(int)NCSDFlags.MediaUnitSize])); #region Extended Headers @@ -94,6 +96,10 @@ namespace SabreTools.Serialization.Streams if (cart.Partitions[i].MagicID != NCCHMagicNumber) continue; + // If we have no partitions table + if (cart.Header.PartitionsTable == null) + continue; + // Get the extended header offset long offset = (cart.Header.PartitionsTable[i].Offset * mediaUnitSize) + 0x200; if (offset < 0 || offset >= data.Length) @@ -103,7 +109,9 @@ namespace SabreTools.Serialization.Streams data.Seek(offset, SeekOrigin.Begin); // Parse the extended header - cart.ExtendedHeaders[i] = ParseNCCHExtendedHeader(data); + var extendedHeader = ParseNCCHExtendedHeader(data); + if (extendedHeader != null) + cart.ExtendedHeaders[i] = extendedHeader; } #endregion @@ -120,6 +128,10 @@ namespace SabreTools.Serialization.Streams if (cart.Partitions[i].MagicID != NCCHMagicNumber) continue; + // If we have no partitions table + if (cart.Header.PartitionsTable == null) + continue; + // Get the ExeFS header offset long offset = (cart.Header.PartitionsTable[i].Offset + cart.Partitions[i].ExeFSOffsetInMediaUnits) * mediaUnitSize; if (offset < 0 || offset >= data.Length) @@ -146,6 +158,10 @@ namespace SabreTools.Serialization.Streams if (cart.Partitions[i].MagicID != NCCHMagicNumber) continue; + // If we have no partitions table + if (cart.Header.PartitionsTable == null) + continue; + // Get the RomFS header offset long offset = (cart.Header.PartitionsTable[i].Offset + cart.Partitions[i].RomFSOffsetInMediaUnits) * mediaUnitSize; if (offset < 0 || offset >= data.Length) @@ -155,7 +171,9 @@ namespace SabreTools.Serialization.Streams data.Seek(offset, SeekOrigin.Begin); // Parse the RomFS header - cart.RomFSHeaders[i] = ParseRomFSHeader(data); + var romFsHeader = ParseRomFSHeader(data); + if (romFsHeader != null) + cart.RomFSHeaders[i] = romFsHeader; } #endregion @@ -168,13 +186,24 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled NCSD header on success, null on error +#if NET48 private static NCSDHeader ParseNCSDHeader(Stream data) +#else + private static NCSDHeader? ParseNCSDHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building NCSDHeader header = new NCSDHeader(); header.RSA2048Signature = data.ReadBytes(0x100); +#if NET48 byte[] magicNumber = data.ReadBytes(4); +#else + byte[]? magicNumber = data.ReadBytes(4); +#endif + if (magicNumber == null) + return null; + header.MagicNumber = Encoding.ASCII.GetString(magicNumber).TrimEnd('\0'); ; if (header.MagicNumber != NCSDMagicNumber) return null; @@ -263,7 +292,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled development card info header on success, null on error +#if NET48 private static DevelopmentCardInfoHeader ParseDevelopmentCardInfoHeader(Stream data) +#else + private static DevelopmentCardInfoHeader? ParseDevelopmentCardInfoHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building DevelopmentCardInfoHeader developmentCardInfoHeader = new DevelopmentCardInfoHeader(); @@ -288,7 +321,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled initial data on success, null on error +#if NET48 private static InitialData ParseInitialData(Stream data) +#else + private static InitialData? ParseInitialData(Stream data) +#endif { // TODO: Use marshalling here instead of building InitialData initialData = new InitialData(); @@ -319,8 +356,13 @@ namespace SabreTools.Serialization.Streams if (!skipSignature) header.RSA2048Signature = data.ReadBytes(0x100); +#if NET48 byte[] magicId = data.ReadBytes(4); - header.MagicID = Encoding.ASCII.GetString(magicId).TrimEnd('\0'); +#else + byte[]? magicId = data.ReadBytes(4); +#endif + if (magicId != null) + header.MagicID = Encoding.ASCII.GetString(magicId).TrimEnd('\0'); header.ContentSizeInMediaUnits = data.ReadUInt32(); header.PartitionId = data.ReadUInt64(); header.MakerCode = data.ReadUInt16(); @@ -329,8 +371,13 @@ namespace SabreTools.Serialization.Streams header.ProgramId = data.ReadBytes(8); header.Reserved1 = data.ReadBytes(0x10); header.LogoRegionHash = data.ReadBytes(0x20); +#if NET48 byte[] productCode = data.ReadBytes(0x10); - header.ProductCode = Encoding.ASCII.GetString(productCode).TrimEnd('\0'); +#else + byte[]? productCode = data.ReadBytes(0x10); +#endif + if (productCode != null) + header.ProductCode = Encoding.ASCII.GetString(productCode).TrimEnd('\0'); header.ExtendedHeaderHash = data.ReadBytes(0x20); header.ExtendedHeaderSizeInBytes = data.ReadUInt32(); header.Reserved2 = data.ReadBytes(4); @@ -405,7 +452,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled NCCH extended header on success, null on error +#if NET48 private static NCCHExtendedHeader ParseNCCHExtendedHeader(Stream data) +#else + private static NCCHExtendedHeader? ParseNCCHExtendedHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building NCCHExtendedHeader extendedHeader = new NCCHExtendedHeader(); @@ -438,8 +489,13 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building SystemControlInfo systemControlInfo = new SystemControlInfo(); +#if NET48 byte[] applicationTitle = data.ReadBytes(8); - systemControlInfo.ApplicationTitle = Encoding.ASCII.GetString(applicationTitle).TrimEnd('\0'); +#else + byte[]? applicationTitle = data.ReadBytes(8); +#endif + if (applicationTitle != null) + systemControlInfo.ApplicationTitle = Encoding.ASCII.GetString(applicationTitle).TrimEnd('\0'); systemControlInfo.Reserved1 = data.ReadBytes(5); systemControlInfo.Flag = data.ReadByteValue(); systemControlInfo.RemasterVersion = data.ReadUInt16(); @@ -622,7 +678,7 @@ namespace SabreTools.Serialization.Streams exeFSHeader.FileHashes = new byte[10][]; for (int i = 0; i < 10; i++) { - exeFSHeader.FileHashes[i] = data.ReadBytes(0x20); + exeFSHeader.FileHashes[i] = data.ReadBytes(0x20) ?? Array.Empty(); } return exeFSHeader; @@ -638,8 +694,13 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building ExeFSFileHeader exeFSFileHeader = new ExeFSFileHeader(); +#if NET48 byte[] fileName = data.ReadBytes(8); - exeFSFileHeader.FileName = Encoding.ASCII.GetString(fileName).TrimEnd('\0'); +#else + byte[]? fileName = data.ReadBytes(8); +#endif + if (fileName != null) + exeFSFileHeader.FileName = Encoding.ASCII.GetString(fileName).TrimEnd('\0'); exeFSFileHeader.FileOffset = data.ReadUInt32(); exeFSFileHeader.FileSize = data.ReadUInt32(); @@ -651,12 +712,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled RomFS header on success, null on error +#if NET48 private static RomFSHeader ParseRomFSHeader(Stream data) +#else + private static RomFSHeader? ParseRomFSHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building RomFSHeader romFSHeader = new RomFSHeader(); +#if NET48 byte[] magicString = data.ReadBytes(4); +#else + byte[]? magicString = data.ReadBytes(4); +#endif + if (magicString == null) + return null; + romFSHeader.MagicString = Encoding.ASCII.GetString(magicString).TrimEnd('\0'); if (romFSHeader.MagicString != RomFSMagicNumber) return null; diff --git a/Streams/NCF.Deserialization.cs b/Streams/NCF.Deserialization.cs index f6862950..64cf36f3 100644 --- a/Streams/NCF.Deserialization.cs +++ b/Streams/NCF.Deserialization.cs @@ -81,17 +81,29 @@ namespace SabreTools.Serialization.Streams long directoryNamesEnd = data.Position + directoryHeader.NameSize; // Create the string dictionary +#if NET48 file.DirectoryNames = new Dictionary(); +#else + file.DirectoryNames = new Dictionary(); +#endif // Loop and read the null-terminated strings while (data.Position < directoryNamesEnd) { long nameOffset = data.Position - directoryNamesStart; +#if NET48 string directoryName = data.ReadString(Encoding.ASCII); +#else + string? directoryName = data.ReadString(Encoding.ASCII); +#endif if (data.Position > directoryNamesEnd) { - data.Seek(-directoryName.Length, SeekOrigin.Current); + data.Seek(-directoryName?.Length ?? 0, SeekOrigin.Current); +#if NET48 byte[] endingData = data.ReadBytes((int)(directoryNamesEnd - data.Position)); +#else + byte[]? endingData = data.ReadBytes((int)(directoryNamesEnd - data.Position)); +#endif if (endingData != null) directoryName = Encoding.ASCII.GetString(endingData); else @@ -261,7 +273,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life No Cache header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); @@ -295,7 +311,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life No Cache directory header on success, null on error +#if NET48 private static DirectoryHeader ParseDirectoryHeader(Stream data) +#else + private static DirectoryHeader? ParseDirectoryHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building DirectoryHeader directoryHeader = new DirectoryHeader(); @@ -407,7 +427,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life No Cache unknown header on success, null on error +#if NET48 private static UnknownHeader ParseUnknownHeader(Stream data) +#else + private static UnknownHeader? ParseUnknownHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building UnknownHeader unknownHeader = new UnknownHeader(); @@ -443,7 +467,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life No Cache checksum header on success, null on error +#if NET48 private static ChecksumHeader ParseChecksumHeader(Stream data) +#else + private static ChecksumHeader? ParseChecksumHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building ChecksumHeader checksumHeader = new ChecksumHeader(); @@ -462,7 +490,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life No Cache checksum map header on success, null on error +#if NET48 private static ChecksumMapHeader ParseChecksumMapHeader(Stream data) +#else + private static ChecksumMapHeader? ParseChecksumMapHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building ChecksumMapHeader checksumMapHeader = new ChecksumMapHeader(); diff --git a/Streams/NewExecutable.Deserializer.cs b/Streams/NewExecutable.Deserializer.cs index 50444311..ad2ebbb4 100644 --- a/Streams/NewExecutable.Deserializer.cs +++ b/Streams/NewExecutable.Deserializer.cs @@ -216,12 +216,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled executable header on success, null on error +#if NET48 private static ExecutableHeader ParseExecutableHeader(Stream data) +#else + private static ExecutableHeader? ParseExecutableHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building var header = new ExecutableHeader(); +#if NET48 byte[] magic = data.ReadBytes(2); +#else + byte[]? magic = data.ReadBytes(2); +#endif + if (magic == null) + return null; + header.Magic = Encoding.ASCII.GetString(magic); if (header.Magic != SignatureString) return null; @@ -333,7 +344,11 @@ namespace SabreTools.Serialization.Streams .ToList(); // Populate the type and name string dictionary +#if NET48 resourceTable.TypeAndNameStrings = new Dictionary(); +#else + resourceTable.TypeAndNameStrings = new Dictionary(); +#endif for (int i = 0; i < stringOffsets.Count; i++) { int stringOffset = (int)(stringOffsets[i] + initialOffset); @@ -397,10 +412,18 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// First address not part of the imported-name table /// Filled imported-name table on success, null on error +#if NET48 private static Dictionary ParseImportedNameTable(Stream data, int endOffset) +#else + private static Dictionary ParseImportedNameTable(Stream data, int endOffset) +#endif { // TODO: Use marshalling here instead of building +#if NET48 var importedNameTable = new Dictionary(); +#else + var importedNameTable = new Dictionary(); +#endif while (data.Position < endOffset) { diff --git a/Streams/Nitro.Deserializer.cs b/Streams/Nitro.Deserializer.cs index 4aa1f18e..030f5ee2 100644 --- a/Streams/Nitro.Deserializer.cs +++ b/Streams/Nitro.Deserializer.cs @@ -131,11 +131,21 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building CommonHeader commonHeader = new CommonHeader(); +#if NET48 byte[] gameTitle = data.ReadBytes(12); - commonHeader.GameTitle = Encoding.ASCII.GetString(gameTitle).TrimEnd('\0'); +#else + byte[]? gameTitle = data.ReadBytes(12); +#endif + if (gameTitle != null) + commonHeader.GameTitle = Encoding.ASCII.GetString(gameTitle).TrimEnd('\0'); commonHeader.GameCode = data.ReadUInt32(); +#if NET48 byte[] makerCode = data.ReadBytes(2); - commonHeader.MakerCode = Encoding.ASCII.GetString(bytes: makerCode).TrimEnd('\0'); +#else + byte[]? makerCode = data.ReadBytes(2); +#endif + if (makerCode != null) + commonHeader.MakerCode = Encoding.ASCII.GetString(bytes: makerCode).TrimEnd('\0'); commonHeader.UnitCode = (Unitcode)data.ReadByteValue(); commonHeader.EncryptionSeedSelect = data.ReadByteValue(); commonHeader.DeviceCapacity = data.ReadByteValue(); @@ -321,7 +331,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled name list entry on success, null on error +#if NET48 private static NameListEntry ParseNameListEntry(Stream data) +#else + private static NameListEntry? ParseNameListEntry(Stream data) +#endif { // TODO: Use marshalling here instead of building NameListEntry entry = new NameListEntry(); @@ -335,8 +349,13 @@ namespace SabreTools.Serialization.Streams byte size = (byte)(flagAndSize & ~0x80); if (size > 0) { +#if NET48 byte[] name = data.ReadBytes(size); - entry.Name = Encoding.UTF8.GetString(name); +#else + byte[]? name = data.ReadBytes(size); +#endif + if (name != null) + entry.Name = Encoding.UTF8.GetString(name); } if (entry.Folder) diff --git a/Streams/PAK.Deserializer.cs b/Streams/PAK.Deserializer.cs index 6918dcbc..6c9e4433 100644 --- a/Streams/PAK.Deserializer.cs +++ b/Streams/PAK.Deserializer.cs @@ -71,12 +71,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Package header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); if (header.Signature != SignatureString) return null; @@ -97,8 +108,13 @@ namespace SabreTools.Serialization.Streams // TODO: Use marshalling here instead of building DirectoryItem directoryItem = new DirectoryItem(); +#if NET48 byte[] itemName = data.ReadBytes(56); - directoryItem.ItemName = Encoding.ASCII.GetString(itemName).TrimEnd('\0'); +#else + byte[]? itemName = data.ReadBytes(56); +#endif + if (itemName != null) + directoryItem.ItemName = Encoding.ASCII.GetString(itemName).TrimEnd('\0'); directoryItem.ItemOffset = data.ReadUInt32(); directoryItem.ItemLength = data.ReadUInt32(); diff --git a/Streams/PFF.Deserializer.cs b/Streams/PFF.Deserializer.cs index 3a7bb71f..768aa719 100644 --- a/Streams/PFF.Deserializer.cs +++ b/Streams/PFF.Deserializer.cs @@ -94,13 +94,24 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); header.HeaderSize = data.ReadUInt32(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); header.NumberOfFiles = data.ReadUInt32(); header.FileSegmentSize = data.ReadUInt32(); @@ -148,8 +159,13 @@ namespace SabreTools.Serialization.Streams footer.SystemIP = data.ReadUInt32(); footer.Reserved = data.ReadUInt32(); +#if NET48 byte[] kingTag = data.ReadBytes(4); - footer.KingTag = Encoding.ASCII.GetString(kingTag); +#else + byte[]? kingTag = data.ReadBytes(4); +#endif + if (kingTag != null) + footer.KingTag = Encoding.ASCII.GetString(kingTag); return footer; } @@ -169,8 +185,13 @@ namespace SabreTools.Serialization.Streams segment.FileLocation = data.ReadUInt32(); segment.FileSize = data.ReadUInt32(); segment.PackedDate = data.ReadUInt32(); +#if NET48 byte[] fileName = data.ReadBytes(0x10); - segment.FileName = Encoding.ASCII.GetString(fileName).TrimEnd('\0'); +#else + byte[]? fileName = data.ReadBytes(0x10); +#endif + if (fileName != null) + segment.FileName = Encoding.ASCII.GetString(fileName).TrimEnd('\0'); if (segmentSize > Version2SegmentSize) segment.ModifiedDate = data.ReadUInt32(); if (segmentSize > Version3SegmentSize) diff --git a/Streams/PlayJAudio.Deserializer.cs b/Streams/PlayJAudio.Deserializer.cs index 45636e82..f2a0c4af 100644 --- a/Streams/PlayJAudio.Deserializer.cs +++ b/Streams/PlayJAudio.Deserializer.cs @@ -52,8 +52,8 @@ namespace SabreTools.Serialization.Streams #region Unknown Block 1 uint unknownOffset1 = (audioHeader.Version == 0x00000000) - ? (audioHeader as AudioHeaderV1).UnknownOffset1 - : (audioHeader as AudioHeaderV2).UnknownOffset1 + 0x54; + ? (audioHeader as AudioHeaderV1)?.UnknownOffset1 ?? 0 + : ((audioHeader as AudioHeaderV2)?.UnknownOffset1 ?? 0) + 0x54; // If we have an unknown block 1 offset if (unknownOffset1 > 0) @@ -175,7 +175,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled audio header on success, null on error +#if NET48 private static AudioHeader ParseAudioHeader(Stream data) +#else + private static AudioHeader? ParseAudioHeader(Stream data) +#endif { // Cache the current offset long initialOffset = data.Position; @@ -187,7 +191,7 @@ namespace SabreTools.Serialization.Streams uint signature = data.ReadUInt32(); if (signature != SignatureUInt32) return null; - + uint version = data.ReadUInt32(); // Build the header according to version @@ -214,7 +218,7 @@ namespace SabreTools.Serialization.Streams audioHeader = v1; unknownOffset1 = v1.UnknownOffset1; break; - + // Version 2 case 0x0000000A: AudioHeaderV2 v2 = new AudioHeaderV2(); @@ -255,39 +259,67 @@ namespace SabreTools.Serialization.Streams } audioHeader.TrackLength = data.ReadUInt16(); +#if NET48 byte[] track = data.ReadBytes(audioHeader.TrackLength); +#else + byte[]? track = data.ReadBytes(audioHeader.TrackLength); +#endif if (track != null) audioHeader.Track = Encoding.ASCII.GetString(track); audioHeader.ArtistLength = data.ReadUInt16(); +#if NET48 byte[] artist = data.ReadBytes(audioHeader.ArtistLength); +#else + byte[]? artist = data.ReadBytes(audioHeader.ArtistLength); +#endif if (artist != null) audioHeader.Artist = Encoding.ASCII.GetString(artist); audioHeader.AlbumLength = data.ReadUInt16(); +#if NET48 byte[] album = data.ReadBytes(audioHeader.AlbumLength); +#else + byte[]? album = data.ReadBytes(audioHeader.AlbumLength); +#endif if (album != null) audioHeader.Album = Encoding.ASCII.GetString(album); audioHeader.WriterLength = data.ReadUInt16(); +#if NET48 byte[] writer = data.ReadBytes(audioHeader.WriterLength); +#else + byte[]? writer = data.ReadBytes(audioHeader.WriterLength); +#endif if (writer != null) audioHeader.Writer = Encoding.ASCII.GetString(writer); audioHeader.PublisherLength = data.ReadUInt16(); +#if NET48 byte[] publisher = data.ReadBytes(audioHeader.PublisherLength); +#else + byte[]? publisher = data.ReadBytes(audioHeader.PublisherLength); +#endif if (publisher != null) audioHeader.Publisher = Encoding.ASCII.GetString(publisher); audioHeader.LabelLength = data.ReadUInt16(); +#if NET48 byte[] label = data.ReadBytes(audioHeader.LabelLength); +#else + byte[]? label = data.ReadBytes(audioHeader.LabelLength); +#endif if (label != null) audioHeader.Label = Encoding.ASCII.GetString(label); if (data.Position - initialOffset < unknownOffset1) { audioHeader.CommentsLength = data.ReadUInt16(); +#if NET48 byte[] comments = data.ReadBytes(audioHeader.CommentsLength); +#else + byte[]? comments = data.ReadBytes(audioHeader.CommentsLength); +#endif if (comments != null) audioHeader.Comments = Encoding.ASCII.GetString(comments); } @@ -337,7 +369,11 @@ namespace SabreTools.Serialization.Streams DataFile dataFile = new DataFile(); dataFile.FileNameLength = data.ReadUInt16(); +#if NET48 byte[] fileName = data.ReadBytes(dataFile.FileNameLength); +#else + byte[]? fileName = data.ReadBytes(dataFile.FileNameLength); +#endif if (fileName != null) dataFile.FileName = Encoding.ASCII.GetString(fileName); diff --git a/Streams/PortableExecutable.Deserializer.cs b/Streams/PortableExecutable.Deserializer.cs index 5072535f..b04419d8 100644 --- a/Streams/PortableExecutable.Deserializer.cs +++ b/Streams/PortableExecutable.Deserializer.cs @@ -47,7 +47,14 @@ namespace SabreTools.Serialization.Streams #region Signature data.Seek(initialOffset + stub.Header.NewExeHeaderAddr, SeekOrigin.Begin); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + executable.Signature = Encoding.ASCII.GetString(signature); if (executable.Signature != SignatureString) return null; @@ -539,10 +546,14 @@ namespace SabreTools.Serialization.Streams { var entry = new COFFSymbolTableEntry(); entry.ShortName = data.ReadBytes(8); - entry.Zeroes = BitConverter.ToUInt32(entry.ShortName, 0); + if (entry.ShortName != null) + entry.Zeroes = BitConverter.ToUInt32(entry.ShortName, 0); + if (entry.Zeroes == 0) { - entry.Offset = BitConverter.ToUInt32(entry.ShortName, 4); + if (entry.ShortName != null) + entry.Offset = BitConverter.ToUInt32(entry.ShortName, 4); + entry.ShortName = null; } entry.Value = data.ReadUInt32(); @@ -692,8 +703,12 @@ namespace SabreTools.Serialization.Streams while (totalSize > 0 && data.Position < data.Length) { long initialPosition = data.Position; +#if NET48 string str = data.ReadString(); - strings.Add(str); +#else + string? str = data.ReadString(); +#endif + strings.Add(str ?? string.Empty); totalSize -= (uint)(data.Position - initialPosition); } @@ -868,7 +883,11 @@ namespace SabreTools.Serialization.Streams uint nameAddress = exportDirectoryTable.NameRVA.ConvertVirtualAddress(sections); data.Seek(nameAddress, SeekOrigin.Begin); +#if NET48 string name = data.ReadString(Encoding.ASCII); +#else + string? name = data.ReadString(Encoding.ASCII); +#endif exportDirectoryTable.Name = name; } @@ -941,8 +960,12 @@ namespace SabreTools.Serialization.Streams exportNameTable.Strings = new string[exportDirectoryTable.NumberOfNamePointers]; for (int i = 0; i < exportDirectoryTable.NumberOfNamePointers; i++) { +#if NET48 string str = data.ReadString(Encoding.ASCII); - exportNameTable.Strings[i] = str; +#else + string? str = data.ReadString(Encoding.ASCII); +#endif + exportNameTable.Strings[i] = str ?? string.Empty; } exportTable.ExportNameTable = exportNameTable; @@ -1000,12 +1023,20 @@ namespace SabreTools.Serialization.Streams uint nameAddress = importDirectoryTableEntry.NameRVA.ConvertVirtualAddress(sections); data.Seek(nameAddress, SeekOrigin.Begin); +#if NET48 string name = data.ReadString(Encoding.ASCII); +#else + string? name = data.ReadString(Encoding.ASCII); +#endif importDirectoryTableEntry.Name = name; } // Lookup tables +#if NET48 var importLookupTables = new Dictionary(); +#else + var importLookupTables = new Dictionary(); +#endif for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++) { @@ -1056,7 +1087,11 @@ namespace SabreTools.Serialization.Streams importTable.ImportLookupTables = importLookupTables; // Address tables +#if NET48 var importAddressTables = new Dictionary(); +#else + var importAddressTables = new Dictionary(); +#endif for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++) { @@ -1170,7 +1205,11 @@ namespace SabreTools.Serialization.Streams /// Section table to use for virtual address translation /// Indicates if this is the top level or not /// Filled resource directory table on success, null on error +#if NET48 private static ResourceDirectoryTable ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader[] sections, bool topLevel = false) +#else + private static ResourceDirectoryTable? ParseResourceDirectoryTable(Stream data, long initialOffset, SectionHeader[] sections, bool topLevel = false) +#endif { // TODO: Use marshalling here instead of building var resourceDirectoryTable = new ResourceDirectoryTable(); diff --git a/Streams/Quantum.Deserializer.cs b/Streams/Quantum.Deserializer.cs index 1e0f37e5..25eccf40 100644 --- a/Streams/Quantum.Deserializer.cs +++ b/Streams/Quantum.Deserializer.cs @@ -75,12 +75,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); +#if NET48 byte[] signature = data.ReadBytes(2); +#else + byte[]? signature = data.ReadBytes(2); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); if (header.Signature != SignatureString) return null; @@ -108,15 +119,25 @@ namespace SabreTools.Serialization.Streams fileDescriptor.FileNameSize = ReadVariableLength(data); if (fileDescriptor.FileNameSize > 0) { +#if NET48 byte[] fileName = data.ReadBytes(fileDescriptor.FileNameSize); - fileDescriptor.FileName = Encoding.ASCII.GetString(fileName); +#else + byte[]? fileName = data.ReadBytes(fileDescriptor.FileNameSize); +#endif + if (fileName != null) + fileDescriptor.FileName = Encoding.ASCII.GetString(fileName); } fileDescriptor.CommentFieldSize = ReadVariableLength(data); if (fileDescriptor.CommentFieldSize > 0) { +#if NET48 byte[] commentField = data.ReadBytes(fileDescriptor.CommentFieldSize); - fileDescriptor.CommentField = Encoding.ASCII.GetString(commentField); +#else + byte[]? commentField = data.ReadBytes(fileDescriptor.CommentFieldSize); +#endif + if (commentField != null) + fileDescriptor.CommentField = Encoding.ASCII.GetString(commentField); } fileDescriptor.ExpandedFileSize = data.ReadUInt32(); @@ -146,7 +167,7 @@ namespace SabreTools.Serialization.Streams byte b0 = data.ReadByteValue(); if (b0 < 0x7F) return b0; - + b0 &= 0x7F; byte b1 = data.ReadByteValue(); return (b0 << 8) | b1; diff --git a/Streams/SGA.Deserializer.cs b/Streams/SGA.Deserializer.cs index 51bea8e2..99d05e1f 100644 --- a/Streams/SGA.Deserializer.cs +++ b/Streams/SGA.Deserializer.cs @@ -61,10 +61,21 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled SGA header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building +#if NET48 byte[] signatureBytes = data.ReadBytes(8); +#else + byte[]? signatureBytes = data.ReadBytes(8); +#endif + if (signatureBytes == null) + return null; + string signature = Encoding.ASCII.GetString(signatureBytes); if (signature != SignatureString) return null; @@ -85,8 +96,13 @@ namespace SabreTools.Serialization.Streams header4.MajorVersion = majorVersion; header4.MinorVersion = minorVersion; header4.FileMD5 = data.ReadBytes(0x10); +#if NET48 byte[] header4Name = data.ReadBytes(count: 128); - header4.Name = Encoding.Unicode.GetString(header4Name).TrimEnd('\0'); +#else + byte[]? header4Name = data.ReadBytes(count: 128); +#endif + if (header4Name != null) + header4.Name = Encoding.Unicode.GetString(header4Name).TrimEnd('\0'); header4.HeaderMD5 = data.ReadBytes(0x10); header4.HeaderLength = data.ReadUInt32(); header4.FileDataOffset = data.ReadUInt32(); @@ -102,8 +118,13 @@ namespace SabreTools.Serialization.Streams header6.Signature = signature; header6.MajorVersion = majorVersion; header6.MinorVersion = minorVersion; +#if NET48 byte[] header6Name = data.ReadBytes(count: 128); - header6.Name = Encoding.Unicode.GetString(header6Name).TrimEnd('\0'); +#else + byte[]? header6Name = data.ReadBytes(count: 128); +#endif + if (header6Name != null) + header6.Name = Encoding.Unicode.GetString(header6Name).TrimEnd('\0'); header6.HeaderLength = data.ReadUInt32(); header6.FileDataOffset = data.ReadUInt32(); header6.Dummy0 = data.ReadUInt32(); @@ -122,7 +143,11 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// SGA major version /// Filled SGA directory on success, null on error +#if NET48 private static Models.SGA.Directory ParseDirectory(Stream data, ushort majorVersion) +#else + private static Models.SGA.Directory? ParseDirectory(Stream data, ushort majorVersion) +#endif { #region Directory @@ -152,10 +177,17 @@ namespace SabreTools.Serialization.Streams // Set the directory header switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).DirectoryHeader = directoryHeader as DirectoryHeader4; break; case 5: (directory as Directory5).DirectoryHeader = directoryHeader as DirectoryHeader5; break; case 6: (directory as Directory6).DirectoryHeader = directoryHeader as DirectoryHeader5; break; case 7: (directory as Directory7).DirectoryHeader = directoryHeader as DirectoryHeader7; break; +#else + case 4: (directory as Directory4)!.DirectoryHeader = directoryHeader as DirectoryHeader4; break; + case 5: (directory as Directory5)!.DirectoryHeader = directoryHeader as DirectoryHeader5; break; + case 6: (directory as Directory6)!.DirectoryHeader = directoryHeader as DirectoryHeader5; break; + case 7: (directory as Directory7)!.DirectoryHeader = directoryHeader as DirectoryHeader7; break; +#endif default: return null; } @@ -167,10 +199,17 @@ namespace SabreTools.Serialization.Streams long sectionOffset; switch (majorVersion) { +#if NET48 case 4: sectionOffset = (directoryHeader as DirectoryHeader4).SectionOffset; break; case 5: case 6: sectionOffset = (directoryHeader as DirectoryHeader5).SectionOffset; break; case 7: sectionOffset = (directoryHeader as DirectoryHeader7).SectionOffset; break; +#else + case 4: sectionOffset = (directoryHeader as DirectoryHeader4)!.SectionOffset; break; + case 5: + case 6: sectionOffset = (directoryHeader as DirectoryHeader5)!.SectionOffset; break; + case 7: sectionOffset = (directoryHeader as DirectoryHeader7)!.SectionOffset; break; +#endif default: return null; } @@ -188,10 +227,17 @@ namespace SabreTools.Serialization.Streams uint sectionCount; switch (majorVersion) { +#if NET48 case 4: sectionCount = (directoryHeader as DirectoryHeader4).SectionCount; break; case 5: case 6: sectionCount = (directoryHeader as DirectoryHeader5).SectionCount; break; case 7: sectionCount = (directoryHeader as DirectoryHeader7).SectionCount; break; +#else + case 4: sectionCount = (directoryHeader as DirectoryHeader4)!.SectionCount; break; + case 5: + case 6: sectionCount = (directoryHeader as DirectoryHeader5)!.SectionCount; break; + case 7: sectionCount = (directoryHeader as DirectoryHeader7)!.SectionCount; break; +#endif default: return null; } @@ -222,10 +268,17 @@ namespace SabreTools.Serialization.Streams // Assign the sections switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).Sections = sections as Section4[]; break; case 5: (directory as Directory5).Sections = sections as Section5[]; break; case 6: (directory as Directory6).Sections = sections as Section5[]; break; case 7: (directory as Directory7).Sections = sections as Section5[]; break; +#else + case 4: (directory as Directory4)!.Sections = sections as Section4[]; break; + case 5: (directory as Directory5)!.Sections = sections as Section5[]; break; + case 6: (directory as Directory6)!.Sections = sections as Section5[]; break; + case 7: (directory as Directory7)!.Sections = sections as Section5[]; break; +#endif default: return null; } @@ -237,10 +290,17 @@ namespace SabreTools.Serialization.Streams long folderOffset; switch (majorVersion) { +#if NET48 case 4: folderOffset = (directoryHeader as DirectoryHeader4).FolderOffset; break; case 5: folderOffset = (directoryHeader as DirectoryHeader5).FolderOffset; break; case 6: folderOffset = (directoryHeader as DirectoryHeader5).FolderOffset; break; case 7: folderOffset = (directoryHeader as DirectoryHeader7).FolderOffset; break; +#else + case 4: folderOffset = (directoryHeader as DirectoryHeader4)!.FolderOffset; break; + case 5: folderOffset = (directoryHeader as DirectoryHeader5)!.FolderOffset; break; + case 6: folderOffset = (directoryHeader as DirectoryHeader5)!.FolderOffset; break; + case 7: folderOffset = (directoryHeader as DirectoryHeader7)!.FolderOffset; break; +#endif default: return null; } @@ -258,10 +318,17 @@ namespace SabreTools.Serialization.Streams uint folderCount; switch (majorVersion) { +#if NET48 case 4: folderCount = (directoryHeader as DirectoryHeader4).FolderCount; break; case 5: folderCount = (directoryHeader as DirectoryHeader5).FolderCount; break; case 6: folderCount = (directoryHeader as DirectoryHeader5).FolderCount; break; case 7: folderCount = (directoryHeader as DirectoryHeader7).FolderCount; break; +#else + case 4: folderCount = (directoryHeader as DirectoryHeader4)!.FolderCount; break; + case 5: folderCount = (directoryHeader as DirectoryHeader5)!.FolderCount; break; + case 6: folderCount = (directoryHeader as DirectoryHeader5)!.FolderCount; break; + case 7: folderCount = (directoryHeader as DirectoryHeader7)!.FolderCount; break; +#endif default: return null; } @@ -292,10 +359,17 @@ namespace SabreTools.Serialization.Streams // Assign the folders switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).Folders = folders as Folder4[]; break; case 5: (directory as Directory5).Folders = folders as Folder5[]; break; case 6: (directory as Directory6).Folders = folders as Folder5[]; break; case 7: (directory as Directory7).Folders = folders as Folder5[]; break; +#else + case 4: (directory as Directory4)!.Folders = folders as Folder4[]; break; + case 5: (directory as Directory5)!.Folders = folders as Folder5[]; break; + case 6: (directory as Directory6)!.Folders = folders as Folder5[]; break; + case 7: (directory as Directory7)!.Folders = folders as Folder5[]; break; +#endif default: return null; } @@ -307,10 +381,17 @@ namespace SabreTools.Serialization.Streams long fileOffset; switch (majorVersion) { +#if NET48 case 4: fileOffset = (directoryHeader as DirectoryHeader4).FileOffset; break; case 5: fileOffset = (directoryHeader as DirectoryHeader5).FileOffset; break; case 6: fileOffset = (directoryHeader as DirectoryHeader5).FileOffset; break; case 7: fileOffset = (directoryHeader as DirectoryHeader7).FileOffset; break; +#else + case 4: fileOffset = (directoryHeader as DirectoryHeader4)!.FileOffset; break; + case 5: fileOffset = (directoryHeader as DirectoryHeader5)!.FileOffset; break; + case 6: fileOffset = (directoryHeader as DirectoryHeader5)!.FileOffset; break; + case 7: fileOffset = (directoryHeader as DirectoryHeader7)!.FileOffset; break; +#endif default: return null; } @@ -328,10 +409,17 @@ namespace SabreTools.Serialization.Streams uint fileCount; switch (majorVersion) { +#if NET48 case 4: fileCount = (directoryHeader as DirectoryHeader4).FileCount; break; case 5: fileCount = (directoryHeader as DirectoryHeader5).FileCount; break; case 6: fileCount = (directoryHeader as DirectoryHeader5).FileCount; break; case 7: fileCount = (directoryHeader as DirectoryHeader7).FileCount; break; +#else + case 4: fileCount = (directoryHeader as DirectoryHeader4)!.FileCount; break; + case 5: fileCount = (directoryHeader as DirectoryHeader5)!.FileCount; break; + case 6: fileCount = (directoryHeader as DirectoryHeader5)!.FileCount; break; + case 7: fileCount = (directoryHeader as DirectoryHeader7)!.FileCount; break; +#endif default: return null; } @@ -362,10 +450,17 @@ namespace SabreTools.Serialization.Streams // Assign the files switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).Files = files as File4[]; break; case 5: (directory as Directory5).Files = files as File4[]; break; case 6: (directory as Directory6).Files = files as File6[]; break; case 7: (directory as Directory7).Files = files as File7[]; break; +#else + case 4: (directory as Directory4)!.Files = files as File4[]; break; + case 5: (directory as Directory5)!.Files = files as File4[]; break; + case 6: (directory as Directory6)!.Files = files as File6[]; break; + case 7: (directory as Directory7)!.Files = files as File7[]; break; +#endif default: return null; } @@ -377,10 +472,17 @@ namespace SabreTools.Serialization.Streams long stringTableOffset; switch (majorVersion) { +#if NET48 case 4: stringTableOffset = (directoryHeader as DirectoryHeader4).StringTableOffset; break; case 5: stringTableOffset = (directoryHeader as DirectoryHeader5).StringTableOffset; break; case 6: stringTableOffset = (directoryHeader as DirectoryHeader5).StringTableOffset; break; case 7: stringTableOffset = (directoryHeader as DirectoryHeader7).StringTableOffset; break; +#else + case 4: stringTableOffset = (directoryHeader as DirectoryHeader4)!.StringTableOffset; break; + case 5: stringTableOffset = (directoryHeader as DirectoryHeader5)!.StringTableOffset; break; + case 6: stringTableOffset = (directoryHeader as DirectoryHeader5)!.StringTableOffset; break; + case 7: stringTableOffset = (directoryHeader as DirectoryHeader7)!.StringTableOffset; break; +#endif default: return null; } @@ -398,10 +500,17 @@ namespace SabreTools.Serialization.Streams uint stringCount; switch (majorVersion) { +#if NET48 case 4: stringCount = (directoryHeader as DirectoryHeader4).StringTableCount; break; case 5: stringCount = (directoryHeader as DirectoryHeader5).StringTableCount; break; case 6: stringCount = (directoryHeader as DirectoryHeader5).StringTableCount; break; case 7: stringCount = (directoryHeader as DirectoryHeader7).StringTableCount; break; +#else + case 4: stringCount = (directoryHeader as DirectoryHeader4)!.StringTableCount; break; + case 5: stringCount = (directoryHeader as DirectoryHeader5)!.StringTableCount; break; + case 6: stringCount = (directoryHeader as DirectoryHeader5)!.StringTableCount; break; + case 7: stringCount = (directoryHeader as DirectoryHeader7)!.StringTableCount; break; +#endif default: return null; } @@ -409,7 +518,11 @@ namespace SabreTools.Serialization.Streams // TODO: If indexed by position, I think it needs to be adjusted by start of table // Create the strings dictionary +#if NET48 Dictionary strings = new Dictionary((int)stringCount); +#else + Dictionary strings = new Dictionary((int)stringCount); +#endif // Get the current position to adjust the offsets long stringTableStart = data.Position; @@ -424,10 +537,17 @@ namespace SabreTools.Serialization.Streams // Assign the files switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).StringTable = strings; break; case 5: (directory as Directory5).StringTable = strings; break; case 6: (directory as Directory6).StringTable = strings; break; case 7: (directory as Directory7).StringTable = strings; break; +#else + case 4: (directory as Directory4)!.StringTable = strings; break; + case 5: (directory as Directory5)!.StringTable = strings; break; + case 6: (directory as Directory6)!.StringTable = strings; break; + case 7: (directory as Directory7)!.StringTable = strings; break; +#endif default: return null; } @@ -436,10 +556,17 @@ namespace SabreTools.Serialization.Streams { switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).Folders[i].Name = strings[(directory as Directory4).Folders[i].NameOffset]; break; case 5: (directory as Directory5).Folders[i].Name = strings[(directory as Directory5).Folders[i].NameOffset]; break; case 6: (directory as Directory6).Folders[i].Name = strings[(directory as Directory6).Folders[i].NameOffset]; break; case 7: (directory as Directory7).Folders[i].Name = strings[(directory as Directory7).Folders[i].NameOffset]; break; +#else + case 4: (directory as Directory4)!.Folders[i]!.Name = strings[(directory as Directory4)!.Folders[i]!.NameOffset] ?? string.Empty; break; + case 5: (directory as Directory5)!.Folders[i]!.Name = strings[(directory as Directory5)!.Folders[i]!.NameOffset] ?? string.Empty; break; + case 6: (directory as Directory6)!.Folders[i]!.Name = strings[(directory as Directory6)!.Folders[i]!.NameOffset] ?? string.Empty; break; + case 7: (directory as Directory7)!.Folders[i]!.Name = strings[(directory as Directory7)!.Folders[i]!.NameOffset] ?? string.Empty; break; +#endif default: return null; } } @@ -449,10 +576,17 @@ namespace SabreTools.Serialization.Streams { switch (majorVersion) { +#if NET48 case 4: (directory as Directory4).Files[i].Name = strings[(directory as Directory4).Files[i].NameOffset]; break; case 5: (directory as Directory5).Files[i].Name = strings[(directory as Directory5).Files[i].NameOffset]; break; case 6: (directory as Directory6).Files[i].Name = strings[(directory as Directory6).Files[i].NameOffset]; break; case 7: (directory as Directory7).Files[i].Name = strings[(directory as Directory7).Files[i].NameOffset]; break; +#else + case 4: (directory as Directory4)!.Files[i]!.Name = strings[(directory as Directory4)!.Files[i]!.NameOffset] ?? string.Empty; break; + case 5: (directory as Directory5)!.Files[i]!.Name = strings[(directory as Directory5)!.Files[i]!.NameOffset] ?? string.Empty; break; + case 6: (directory as Directory6)!.Files[i]!.Name = strings[(directory as Directory6)!.Files[i]!.NameOffset] ?? string.Empty; break; + case 7: (directory as Directory7)!.Files[i]!.Name = strings[(directory as Directory7)!.Files[i]!.NameOffset] ?? string.Empty; break; +#endif default: return null; } } @@ -468,7 +602,11 @@ namespace SabreTools.Serialization.Streams /// Stream to parse /// SGA major version /// Filled SGA directory header on success, null on error +#if NET48 private static object ParseDirectoryHeader(Stream data, ushort majorVersion) +#else + private static object? ParseDirectoryHeader(Stream data, ushort majorVersion) +#endif { switch (majorVersion) { @@ -555,10 +693,20 @@ namespace SabreTools.Serialization.Streams { Section4 section4 = new Section4(); - byte[] section4Alias = data.ReadBytes(count: 64); - section4.Alias = Encoding.ASCII.GetString(section4Alias).TrimEnd('\0'); +#if NET48 + byte[] section4Alias = data.ReadBytes(64); +#else + byte[]? section4Alias = data.ReadBytes(64); +#endif + if (section4Alias != null) + section4.Alias = Encoding.ASCII.GetString(section4Alias).TrimEnd('\0'); +#if NET48 byte[] section4Name = data.ReadBytes(64); - section4.Name = Encoding.ASCII.GetString(section4Name).TrimEnd('\0'); +#else + byte[]? section4Name = data.ReadBytes(64); +#endif + if (section4Name != null) + section4.Name = Encoding.ASCII.GetString(section4Name).TrimEnd('\0'); section4.FolderStartIndex = data.ReadUInt16(); section4.FolderEndIndex = data.ReadUInt16(); section4.FileStartIndex = data.ReadUInt16(); @@ -578,10 +726,20 @@ namespace SabreTools.Serialization.Streams { Section5 section5 = new Section5(); - byte[] section5Alias = data.ReadBytes(count: 64); - section5.Alias = Encoding.ASCII.GetString(section5Alias).TrimEnd('\0'); +#if NET48 + byte[] section5Alias = data.ReadBytes(64); +#else + byte[]? section5Alias = data.ReadBytes(64); +#endif + if (section5Alias != null) + section5.Alias = Encoding.ASCII.GetString(section5Alias).TrimEnd('\0'); +#if NET48 byte[] section5Name = data.ReadBytes(64); - section5.Name = Encoding.ASCII.GetString(section5Name).TrimEnd('\0'); +#else + byte[]? section5Name = data.ReadBytes(64); +#endif + if (section5Name != null) + section5.Name = Encoding.ASCII.GetString(section5Name).TrimEnd('\0'); section5.FolderStartIndex = data.ReadUInt32(); section5.FolderEndIndex = data.ReadUInt32(); section5.FileStartIndex = data.ReadUInt32(); diff --git a/Streams/VBSP.Deserializer.cs b/Streams/VBSP.Deserializer.cs index 6dc5be8a..22beb617 100644 --- a/Streams/VBSP.Deserializer.cs +++ b/Streams/VBSP.Deserializer.cs @@ -49,12 +49,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life 2 Level header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); if (header.Signature != SignatureString) return null; diff --git a/Streams/VPK.Deserializer.cs b/Streams/VPK.Deserializer.cs index 4f11f0dd..f8a6351c 100644 --- a/Streams/VPK.Deserializer.cs +++ b/Streams/VPK.Deserializer.cs @@ -96,7 +96,11 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Valve Package header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); @@ -163,7 +167,11 @@ namespace SabreTools.Serialization.Streams while (true) { // Get the extension +#if NET48 string extensionString = data.ReadString(Encoding.ASCII); +#else + string? extensionString = data.ReadString(Encoding.ASCII); +#endif if (string.IsNullOrEmpty(extensionString)) break; @@ -176,7 +184,11 @@ namespace SabreTools.Serialization.Streams while (true) { // Get the path +#if NET48 string pathString = data.ReadString(Encoding.ASCII); +#else + string? pathString = data.ReadString(Encoding.ASCII); +#endif if (string.IsNullOrEmpty(pathString)) break; @@ -189,7 +201,11 @@ namespace SabreTools.Serialization.Streams while (true) { // Get the name +#if NET48 string nameString = data.ReadString(Encoding.ASCII); +#else + string? nameString = data.ReadString(Encoding.ASCII); +#endif if (string.IsNullOrEmpty(nameString)) break; @@ -244,7 +260,11 @@ namespace SabreTools.Serialization.Streams } // If we had a valid preload data pointer +#if NET48 byte[] preloadData = null; +#else + byte[]? preloadData = null; +#endif if (preloadDataPointer >= 0 && preloadDataLength > 0) { // Cache the current offset diff --git a/Streams/WAD.Deserializer.cs b/Streams/WAD.Deserializer.cs index 8aa7aeff..e5dea820 100644 --- a/Streams/WAD.Deserializer.cs +++ b/Streams/WAD.Deserializer.cs @@ -64,7 +64,11 @@ namespace SabreTools.Serialization.Streams #region Lump Infos // Create the lump info array + #if NET48 file.LumpInfos = new LumpInfo[header.LumpCount]; + #else + file.LumpInfos = new LumpInfo?[header.LumpCount]; + #endif for (int i = 0; i < header.LumpCount; i++) { var lump = file.Lumps[i]; @@ -100,12 +104,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled Half-Life Texture Package header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); if (header.Signature != SignatureString) return null; @@ -133,8 +148,13 @@ namespace SabreTools.Serialization.Streams lump.Compression = data.ReadByteValue(); lump.Padding0 = data.ReadByteValue(); lump.Padding1 = data.ReadByteValue(); +#if NET48 byte[] name = data.ReadBytes(16); - lump.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); +#else + byte[]? name = data.ReadBytes(16); +#endif + if (name != null) + lump.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); return lump; } @@ -146,7 +166,11 @@ namespace SabreTools.Serialization.Streams /// Lump type /// Mipmap level /// Filled Half-Life Texture Package lump info on success, null on error +#if NET48 private static LumpInfo ParseLumpInfo(Stream data, byte type, uint mipmap = 0) +#else + private static LumpInfo? ParseLumpInfo(Stream data, byte type, uint mipmap = 0) +#endif { // TODO: Use marshalling here instead of building LumpInfo lumpInfo = new LumpInfo(); @@ -170,8 +194,13 @@ namespace SabreTools.Serialization.Streams if (mipmap > 3) return null; +#if NET48 byte[] name = data.ReadBytes(16); - lumpInfo.Name = Encoding.ASCII.GetString(name); +#else + byte[]? name = data.ReadBytes(16); +#endif + if (name != null) + lumpInfo.Name = Encoding.ASCII.GetString(name); lumpInfo.Width = data.ReadUInt32(); lumpInfo.Height = data.ReadUInt32(); lumpInfo.PixelOffset = data.ReadUInt32(); @@ -182,7 +211,7 @@ namespace SabreTools.Serialization.Streams // Seek to the pixel data data.Seek(initialOffset + lumpInfo.PixelOffset, SeekOrigin.Begin); - + // Read the pixel data lumpInfo.PixelData = data.ReadBytes((int)(lumpInfo.Width * lumpInfo.Height)); diff --git a/Streams/XCP.Deserializer.cs b/Streams/XCP.Deserializer.cs index 1ebc1d4c..754a2485 100644 --- a/Streams/XCP.Deserializer.cs +++ b/Streams/XCP.Deserializer.cs @@ -97,7 +97,7 @@ namespace SabreTools.Serialization.Streams uint directoryItemOffset = header.DirectoryItemOffset; if (directoryItemOffset < 0 || directoryItemOffset >= data.Length) return null; - + // Seek to the directory items data.Seek(directoryItemOffset, SeekOrigin.Begin); @@ -137,12 +137,23 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled XBox Package File header on success, null on error +#if NET48 private static Header ParseHeader(Stream data) +#else + private static Header? ParseHeader(Stream data) +#endif { // TODO: Use marshalling here instead of building Header header = new Header(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + header.Signature = Encoding.ASCII.GetString(signature); if (header.Signature != HeaderSignatureString) return null; @@ -228,13 +239,24 @@ namespace SabreTools.Serialization.Streams /// /// Stream to parse /// Filled XBox Package File footer on success, null on error +#if NET48 private static Footer ParseFooter(Stream data) +#else + private static Footer? ParseFooter(Stream data) +#endif { // TODO: Use marshalling here instead of building Footer footer = new Footer(); footer.FileLength = data.ReadUInt32(); +#if NET48 byte[] signature = data.ReadBytes(4); +#else + byte[]? signature = data.ReadBytes(4); +#endif + if (signature == null) + return null; + footer.Signature = Encoding.ASCII.GetString(signature); if (footer.Signature != FooterSignatureString) return null;