Fix nullability warnings

This commit is contained in:
Matt Nadareski
2023-09-10 17:32:03 -04:00
parent ae4c6ed7f7
commit c9481c761c
37 changed files with 1054 additions and 78 deletions

View File

@@ -156,7 +156,11 @@ namespace SabreTools.Serialization
/// <param name="data">Data to parse into overlay data</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled SecuROM AddD overlay data on success, null on error</returns>
#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
/// <param name="data">Data to parse into a database</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled NB10 Program Database on success, null on error</returns>
#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
/// <param name="data">Data to parse into a database</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled RSDS Program Database on success, null on error</returns>
#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
/// <param name="data">Data to parse into a resource header</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled resource header on success, null on error</returns>
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into an accelerator table resource</param>
/// <returns>A filled accelerator table resource on success, null on error</returns>
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into a side-by-side assembly manifest</param>
/// <returns>A filled side-by-side assembly manifest on success, null on error</returns>
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into a dialog box</param>
/// <returns>A filled dialog box on success, null on error</returns>
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into a font group</param>
/// <returns>A filled font group on success, null on error</returns>
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into a menu</param>
/// <returns>A filled menu on success, null on error</returns>
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into a message table resource</param>
/// <returns>A filled message table resource on success, null on error</returns>
#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<uint, Models.PortableExecutable.MessageResourceEntry>();
#else
var messageResourceEntries = new Dictionary<uint, Models.PortableExecutable.MessageResourceEntry?>();
#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
/// </summary>
/// <param name="entry">Resource data entry to parse into a string table resource</param>
/// <returns>A filled string table resource on success, null on error</returns>
#if NET48
public static Dictionary<int, string> AsStringTable(this Models.PortableExecutable.ResourceDataEntry entry)
#else
public static Dictionary<int, string?>? 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<int, string>();
#else
var stringTable = new Dictionary<int, string?>();
#endif
// Loop through and add
while (offset < entry.Data.Length)
@@ -1171,7 +1230,11 @@ namespace SabreTools.Serialization
/// </summary>
/// <param name="entry">Resource data entry to parse into a version info resource</param>
/// <returns>A filled version info resource on success, null on error</returns>
#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
/// <param name="data">Data to parse into a string file info</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled string file info resource on success, null on error</returns>
#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
/// <param name="data">Data to parse into a var file info</param>
/// <param name="offset">Offset into the byte array</param>
/// <returns>A filled var file info resource on success, null on error</returns>
#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;
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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<T>().Serialize(obj, name, pubid, sysid, subset))
{
if (stream == null)

View File

@@ -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

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled media key data record on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled subset-difference index record on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled type and version record on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled drive revocation list record on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled host revocation list record on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled verify media key record on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled copyright record on success, null on error</returns>
#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;

View File

@@ -35,12 +35,23 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled SVM on success, null on error</returns>
#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;

View File

@@ -72,12 +72,23 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled header on success, null on error</returns>
#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();

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Level header on success, null on error</returns>
#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];

View File

@@ -49,7 +49,8 @@ namespace SabreTools.Serialization.Streams
var difatSectors = new List<SectorNumber>();
// 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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled file header on success, null on error</returns>
#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
/// <param name="sectorShift">Sector shift from the header</param>
/// <param name="majorVersion">Major version from the header</param>
/// <returns>Filled sector full of directory entries on success, null on error</returns>
#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();

View File

@@ -172,7 +172,11 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled certificate on success, null on error</returns>
#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
/// <param name="data">Stream to parse</param>
/// <param name="fromCdn">Indicates if the ticket is from CDN</param>
/// <returns>Filled ticket on success, null on error</returns>
#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
/// <param name="data">Stream to parse</param>
/// <param name="fromCdn">Indicates if the ticket is from CDN</param>
/// <returns>Filled title metadata on success, null on error</returns>
#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);

View File

@@ -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<long, string>();
#else
file.DirectoryNames = new Dictionary<long, string?>();
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Game Cache on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Game Cache directory map header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Game Cache checksum header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Game Cache checksum map header on success, null on error</returns>
#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();

View File

@@ -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<long, OffsetList>();
for (int i = 0; i < descriptor.FileGroupOffsets.Length; i++)
#else
cabinet.FileGroupOffsets = new Dictionary<long, OffsetList?>();
#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<long, OffsetList>();
for (int i = 0; i < descriptor.ComponentOffsets.Length; i++)
#else
cabinet.ComponentOffsets = new Dictionary<long, OffsetList?>();
#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<long, OffsetList> kvp in cabinet.ComponentOffsets)
#else
foreach (KeyValuePair<long, OffsetList?> 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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled common header on success, null on error</returns>
#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
/// <param name="data">Stream to parse</param>
/// <param name="majorVersion">Major version of the cabinet</param>
/// <returns>Filled directory name on success, null on error</returns>
#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)

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled information block on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled entry table bundle on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled fix-up record table entry on success, null on error</returns>
#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
/// <param name="data">Stream to parse</param>
/// <param name="size">Total size of the debug information</param>
/// <returns>Filled debug information on success, null on error</returns>
#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;

View File

@@ -68,14 +68,25 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled executable header on success, null on error</returns>
#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;

View File

@@ -94,11 +94,22 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled cabinet header on success, null on error</returns>
#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;

View File

@@ -276,7 +276,7 @@ namespace SabreTools.Serialization.Streams
// Read in the hi-block table
var hiBlockTable = new List<short>();
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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled archive header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled user data on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled HET table on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled BET table on success, null on error</returns>
#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

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled NCSD header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled development card info header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled initial data on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled NCCH extended header on success, null on error</returns>
#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<byte>();
}
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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled RomFS header on success, null on error</returns>
#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;

View File

@@ -81,17 +81,29 @@ namespace SabreTools.Serialization.Streams
long directoryNamesEnd = data.Position + directoryHeader.NameSize;
// Create the string dictionary
#if NET48
file.DirectoryNames = new Dictionary<long, string>();
#else
file.DirectoryNames = new Dictionary<long, string?>();
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life No Cache header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life No Cache directory header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life No Cache unknown header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life No Cache checksum header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life No Cache checksum map header on success, null on error</returns>
#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();

View File

@@ -216,12 +216,23 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled executable header on success, null on error</returns>
#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<ushort, ResourceTypeAndNameString>();
#else
resourceTable.TypeAndNameStrings = new Dictionary<ushort, ResourceTypeAndNameString?>();
#endif
for (int i = 0; i < stringOffsets.Count; i++)
{
int stringOffset = (int)(stringOffsets[i] + initialOffset);
@@ -397,10 +412,18 @@ namespace SabreTools.Serialization.Streams
/// <param name="data">Stream to parse</param>
/// <param name="endOffset">First address not part of the imported-name table</param>
/// <returns>Filled imported-name table on success, null on error</returns>
#if NET48
private static Dictionary<ushort, ImportedNameTableEntry> ParseImportedNameTable(Stream data, int endOffset)
#else
private static Dictionary<ushort, ImportedNameTableEntry?> ParseImportedNameTable(Stream data, int endOffset)
#endif
{
// TODO: Use marshalling here instead of building
#if NET48
var importedNameTable = new Dictionary<ushort, ImportedNameTableEntry>();
#else
var importedNameTable = new Dictionary<ushort, ImportedNameTableEntry?>();
#endif
while (data.Position < endOffset)
{

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled name list entry on success, null on error</returns>
#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)

View File

@@ -71,12 +71,23 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Package header on success, null on error</returns>
#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();

View File

@@ -94,13 +94,24 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled header on success, null on error</returns>
#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)

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled audio header on success, null on error</returns>
#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);

View File

@@ -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<int, ImportLookupTableEntry[]>();
#else
var importLookupTables = new Dictionary<int, ImportLookupTableEntry?[]?>();
#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<int, ImportAddressTableEntry[]>();
#else
var importAddressTables = new Dictionary<int, ImportAddressTableEntry?[]?>();
#endif
for (int i = 0; i < importTable.ImportDirectoryTable.Length; i++)
{
@@ -1170,7 +1205,11 @@ namespace SabreTools.Serialization.Streams
/// <param name="sections">Section table to use for virtual address translation</param>
/// <param name="topLevel">Indicates if this is the top level or not</param>
/// <returns>Filled resource directory table on success, null on error</returns>
#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();

View File

@@ -75,12 +75,23 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled header on success, null on error</returns>
#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;

View File

@@ -61,10 +61,21 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled SGA header on success, null on error</returns>
#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
/// <param name="data">Stream to parse</param>
/// <param name="majorVersion">SGA major version</param>
/// <returns>Filled SGA directory on success, null on error</returns>
#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<long, string> strings = new Dictionary<long, string>((int)stringCount);
#else
Dictionary<long, string?> strings = new Dictionary<long, string?>((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
/// <param name="data">Stream to parse</param>
/// <param name="majorVersion">SGA major version</param>
/// <returns>Filled SGA directory header on success, null on error</returns>
#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();

View File

@@ -49,12 +49,23 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life 2 Level header on success, null on error</returns>
#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;

View File

@@ -96,7 +96,11 @@ namespace SabreTools.Serialization.Streams
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Valve Package header on success, null on error</returns>
#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

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled Half-Life Texture Package header on success, null on error</returns>
#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
/// <param name="type">Lump type</param>
/// <param name="mipmap">Mipmap level</param>
/// <returns>Filled Half-Life Texture Package lump info on success, null on error</returns>
#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));

View File

@@ -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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled XBox Package File header on success, null on error</returns>
#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
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled XBox Package File footer on success, null on error</returns>
#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;