mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Add nullable context to SabreTools.DatFiles
This commit is contained in:
@@ -38,7 +38,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename to derive from</param>
|
||||
/// <returns>Filled machine and new filename on success, null on error</returns>
|
||||
private static (Machine?, string?) DeriveMachine(string filename)
|
||||
private static (Machine?, string?) DeriveMachine(string? filename)
|
||||
{
|
||||
// If the filename is missing, we can't do anything
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
@@ -95,9 +95,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
if (file == null)
|
||||
return;
|
||||
|
||||
(var machine, string name) = DeriveMachine(file.Name);
|
||||
if (machine == null)
|
||||
machine = new Machine { Name = Path.GetFileNameWithoutExtension(file.Name) };
|
||||
(var machine, string? name) = DeriveMachine(file.Name);
|
||||
machine ??= new Machine { Name = Path.GetFileNameWithoutExtension(file.Name) };
|
||||
|
||||
machine.Publisher = file.Publisher;
|
||||
machine.Comment = file.Comment;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// Create a Files from the current internal information
|
||||
/// <summary>
|
||||
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise</param>
|
||||
private Models.ArchiveDotOrg.Files CreateFiles(bool ignoreblanks)
|
||||
private Models.ArchiveDotOrg.Files? CreateFiles(bool ignoreblanks)
|
||||
{
|
||||
// If we don't have items, we can't do anything
|
||||
if (this.Items == null || !this.Items.Any())
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public ArchiveDotOrg(DatFile datFile)
|
||||
public ArchiveDotOrg(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public AttractMode(DatFile datFile)
|
||||
public AttractMode(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// </summary>
|
||||
public class OfflineListInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
[Models.Required]
|
||||
public string? Name { get; set; }
|
||||
public bool? Visible { get; set; }
|
||||
public bool? InNamingOption { get; set; }
|
||||
public bool? Default { get; set; }
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
Header.ForcePacking = cmp.ForcePacking.AsPackingFlag();
|
||||
|
||||
// Handle implied SuperDAT
|
||||
if (cmp.Name.Contains(" - SuperDAT") && keep)
|
||||
if (cmp.Name?.Contains(" - SuperDAT") == true && keep)
|
||||
Header.Type ??= "SuperDAT";
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
var missingFields = new List<DatItemField>();
|
||||
switch (datItem)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
/// <param name="quotes">Enable quotes on read and write, false otherwise</param>
|
||||
public ClrMamePro(DatFile datFile, bool quotes)
|
||||
public ClrMamePro(DatFile? datFile, bool quotes)
|
||||
: base(datFile)
|
||||
{
|
||||
Quotes = quotes;
|
||||
|
||||
@@ -92,8 +92,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
return;
|
||||
|
||||
// Create the machine for copying information
|
||||
string machineName = game.Name.Trim('"');
|
||||
if (machineName.EndsWith(".zip"))
|
||||
string? machineName = game.Name?.Trim('"');
|
||||
if (machineName?.EndsWith(".zip") == true)
|
||||
machineName = System.IO.Path.GetFileNameWithoutExtension(machineName);
|
||||
|
||||
var machine = new Machine { Name = machineName };
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public DosCenter(DatFile datFile)
|
||||
public DosCenter(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename to derive from</param>
|
||||
/// <returns>Filled machine and new filename on success, null on error</returns>
|
||||
private static (Machine?, string?) DeriveMachine(string filename)
|
||||
private static (Machine?, string?) DeriveMachine(string? filename)
|
||||
{
|
||||
// If the filename is missing, we can't do anything
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
@@ -95,9 +95,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
if (row == null)
|
||||
return;
|
||||
|
||||
(var machine, string name) = DeriveMachine(row.Name);
|
||||
if (machine == null)
|
||||
machine = new Machine { Name = Path.GetFileNameWithoutExtension(row.Name) };
|
||||
(var machine, string? name) = DeriveMachine(row.Name);
|
||||
machine ??= new Machine { Name = Path.GetFileNameWithoutExtension(row.Name) };
|
||||
|
||||
var rom = new Rom()
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public EverdriveSMDB(DatFile datFile)
|
||||
public EverdriveSMDB(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename to derive from</param>
|
||||
/// <returns>Filled machine and new filename on success, null on error</returns>
|
||||
private static (Machine?, string?) DeriveMachine(string filename)
|
||||
private static (Machine?, string?) DeriveMachine(string? filename)
|
||||
{
|
||||
// If the filename is missing, we can't do anything
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
@@ -89,7 +89,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename to derive from</param>
|
||||
/// <returns>ItemType representing the item (Rom by default), ItemType.NULL on error</returns>
|
||||
private static ItemType DeriveItemType(string filename)
|
||||
private static ItemType DeriveItemType(string? filename)
|
||||
{
|
||||
// If the filename is missing, we can't do anything
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
@@ -129,12 +129,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var sfv in sfvs)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (sfv == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(sfv.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(sfv.File);
|
||||
(var machine, string? itemName) = DeriveMachine(sfv.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Disk: // Should not happen with CRC32 hashes
|
||||
@@ -179,12 +183,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var md5 in md5s)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (md5 == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(md5.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(md5.File);
|
||||
(var machine, string? itemName) = DeriveMachine(md5.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Disk:
|
||||
@@ -261,12 +269,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var sha1 in sha1s)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (sha1 == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(sha1.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(sha1.File);
|
||||
(var machine, string? itemName) = DeriveMachine(sha1.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Disk:
|
||||
@@ -343,12 +355,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var sha256 in sha256s)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (sha256 == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(sha256.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(sha256.File);
|
||||
(var machine, string? itemName) = DeriveMachine(sha256.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Media:
|
||||
@@ -409,12 +425,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var sha384 in sha384s)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (sha384 == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(sha384.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(sha384.File);
|
||||
(var machine, string? itemName) = DeriveMachine(sha384.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Disk: // Should not happen with SHA-384 hashes
|
||||
@@ -459,12 +479,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var sha512 in sha512s)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (sha512 == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(sha512.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(sha512.File);
|
||||
(var machine, string? itemName) = DeriveMachine(sha512.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Disk: // Should not happen with SHA-512 hashes
|
||||
@@ -509,12 +533,16 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Loop through and add the items
|
||||
foreach (var spamsum in spamsums)
|
||||
{
|
||||
// Skip if we have an invalid item
|
||||
if (spamsum == null)
|
||||
continue;
|
||||
|
||||
// Get the item type
|
||||
ItemType itemType = DeriveItemType(spamsum.File);
|
||||
if (itemType == ItemType.NULL)
|
||||
continue;
|
||||
|
||||
(var machine, string itemName) = DeriveMachine(spamsum.File);
|
||||
(var machine, string? itemName) = DeriveMachine(spamsum.File);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.Media:
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
@@ -232,6 +232,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -241,7 +243,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
@@ -281,6 +283,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -290,7 +294,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
@@ -346,6 +350,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -355,7 +361,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
@@ -411,6 +417,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -420,7 +428,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
@@ -468,6 +476,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -477,7 +487,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
@@ -517,6 +527,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -526,7 +538,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
@@ -566,6 +578,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
// Get the item
|
||||
var item = items[index];
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
// Check for a "null" item
|
||||
item = ProcessNullifiedItem(item);
|
||||
@@ -575,7 +589,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
continue;
|
||||
|
||||
string name = string.Empty;
|
||||
if (Header.GameName)
|
||||
if (Header.GameName && item.Machine != null)
|
||||
name = $"{item.Machine.Name}{Path.DirectorySeparatorChar}";
|
||||
|
||||
switch (item)
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
/// <param name="hash">Type of hash that is associated with this DAT</param>
|
||||
public Hashfile(DatFile datFile, Hash hash)
|
||||
public Hashfile(DatFile? datFile, Hash hash)
|
||||
: base(datFile)
|
||||
{
|
||||
_hash = hash;
|
||||
|
||||
@@ -88,12 +88,10 @@ namespace SabreTools.DatFiles.Formats
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var row in set.Row)
|
||||
foreach (var row in set.Row ?? Array.Empty<Models.Listrom.Row>())
|
||||
{
|
||||
ConvertRow(row, machine, filename, indexId, statsOnly);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -109,8 +107,6 @@ namespace SabreTools.DatFiles.Formats
|
||||
if (row == null)
|
||||
return;
|
||||
|
||||
DatItem item = null;
|
||||
|
||||
// Normal CHD
|
||||
if (row.Size == null
|
||||
&& !row.NoGoodDumpKnown
|
||||
@@ -118,7 +114,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
&& (!string.IsNullOrWhiteSpace(row.MD5)
|
||||
|| !string.IsNullOrWhiteSpace(row.SHA1)))
|
||||
{
|
||||
item = new Disk
|
||||
var disk = new Disk
|
||||
{
|
||||
Name = row.Name,
|
||||
ItemStatus = ItemStatus.None,
|
||||
@@ -131,9 +127,13 @@ namespace SabreTools.DatFiles.Formats
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(row.MD5))
|
||||
(item as Disk).MD5 = row.MD5;
|
||||
disk.MD5 = row.MD5;
|
||||
else
|
||||
(item as Disk).SHA1 = row.SHA1;
|
||||
disk.SHA1 = row.SHA1;
|
||||
|
||||
// Now process and add the item
|
||||
disk.CopyMachineInformation(machine);
|
||||
ParseAddHelper(disk, statsOnly);
|
||||
}
|
||||
|
||||
// Normal ROM
|
||||
@@ -141,7 +141,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
&& !row.NoGoodDumpKnown
|
||||
&& !row.Bad)
|
||||
{
|
||||
item = new Rom
|
||||
var rom = new Rom
|
||||
{
|
||||
Name = row.Name,
|
||||
Size = Utilities.CleanLong(row.Size),
|
||||
@@ -155,6 +155,10 @@ namespace SabreTools.DatFiles.Formats
|
||||
Name = filename,
|
||||
},
|
||||
};
|
||||
|
||||
// Now process and add the item
|
||||
rom.CopyMachineInformation(machine);
|
||||
ParseAddHelper(rom, statsOnly);
|
||||
}
|
||||
|
||||
// Bad CHD
|
||||
@@ -164,7 +168,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
&& (!string.IsNullOrWhiteSpace(row.MD5)
|
||||
|| !string.IsNullOrWhiteSpace(row.SHA1)))
|
||||
{
|
||||
item = new Disk
|
||||
var disk = new Disk
|
||||
{
|
||||
Name = row.Name,
|
||||
ItemStatus = ItemStatus.BadDump,
|
||||
@@ -177,16 +181,20 @@ namespace SabreTools.DatFiles.Formats
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(row.MD5))
|
||||
(item as Disk).MD5 = row.MD5;
|
||||
disk.MD5 = row.MD5;
|
||||
else
|
||||
(item as Disk).SHA1 = row.SHA1;
|
||||
disk.SHA1 = row.SHA1;
|
||||
|
||||
// Now process and add the item
|
||||
disk.CopyMachineInformation(machine);
|
||||
ParseAddHelper(disk, statsOnly);
|
||||
}
|
||||
|
||||
// Nodump CHD
|
||||
else if (row.Size == null
|
||||
&& row.NoGoodDumpKnown)
|
||||
{
|
||||
item = new Disk
|
||||
var disk = new Disk
|
||||
{
|
||||
Name = row.Name,
|
||||
MD5 = null,
|
||||
@@ -199,6 +207,10 @@ namespace SabreTools.DatFiles.Formats
|
||||
Name = filename,
|
||||
},
|
||||
};
|
||||
|
||||
// Now process and add the item
|
||||
disk.CopyMachineInformation(machine);
|
||||
ParseAddHelper(disk, statsOnly);
|
||||
}
|
||||
|
||||
// Bad ROM
|
||||
@@ -206,7 +218,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
&& !row.NoGoodDumpKnown
|
||||
&& row.Bad)
|
||||
{
|
||||
item = new Rom
|
||||
var rom = new Rom
|
||||
{
|
||||
Name = row.Name,
|
||||
Size = Utilities.CleanLong(row.Size),
|
||||
@@ -220,13 +232,17 @@ namespace SabreTools.DatFiles.Formats
|
||||
Name = filename,
|
||||
},
|
||||
};
|
||||
|
||||
// Now process and add the item
|
||||
rom.CopyMachineInformation(machine);
|
||||
ParseAddHelper(rom, statsOnly);
|
||||
}
|
||||
|
||||
// Nodump ROM
|
||||
else if (row.Size != null
|
||||
&& row.NoGoodDumpKnown)
|
||||
{
|
||||
item = new Rom
|
||||
var rom = new Rom
|
||||
{
|
||||
Name = row.Name,
|
||||
Size = Utilities.CleanLong(row.Size),
|
||||
@@ -240,11 +256,11 @@ namespace SabreTools.DatFiles.Formats
|
||||
Name = filename,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Now process and add the item
|
||||
item.CopyMachineInformation(machine);
|
||||
ParseAddHelper(item, statsOnly);
|
||||
// Now process and add the item
|
||||
rom.CopyMachineInformation(machine);
|
||||
ParseAddHelper(rom, statsOnly);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
@@ -136,10 +136,14 @@ namespace SabreTools.DatFiles.Formats
|
||||
switch (item)
|
||||
{
|
||||
case Disk disk:
|
||||
rows.Add(CreateRow(disk));
|
||||
var diskRow = CreateRow(disk);
|
||||
if (diskRow != null)
|
||||
rows.Add(diskRow);
|
||||
break;
|
||||
case Rom rom:
|
||||
rows.Add(CreateRow(rom));
|
||||
var romRow = CreateRow(rom);
|
||||
if (romRow != null)
|
||||
rows.Add(romRow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public Listrom(DatFile datFile)
|
||||
public Listrom(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
Header.MameConfig ??= mame.MameConfig;
|
||||
|
||||
// Handle implied SuperDAT
|
||||
if (Header.Name.Contains(" - SuperDAT") && keep)
|
||||
if (Header.Name?.Contains(" - SuperDAT") == true && keep)
|
||||
Header.Type ??= "SuperDAT";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Core.Tools;
|
||||
using SabreTools.DatItems;
|
||||
using SabreTools.DatItems.Formats;
|
||||
using SabreTools.IO;
|
||||
|
||||
namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
@@ -45,7 +42,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
var missingFields = new List<DatItemField>();
|
||||
switch (datItem)
|
||||
@@ -205,476 +202,6 @@ namespace SabreTools.DatFiles.Formats
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write out DAT header using the supplied StreamWriter
|
||||
/// </summary>
|
||||
/// <param name="xtw">XmlTextWriter to output to</param>
|
||||
private void WriteHeader(XmlTextWriter xtw)
|
||||
{
|
||||
xtw.WriteStartDocument();
|
||||
|
||||
xtw.WriteStartElement("mame");
|
||||
xtw.WriteRequiredAttributeString("build", Header.Name);
|
||||
xtw.WriteOptionalAttributeString("debug", Header.Debug.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("mameconfig", Header.MameConfig);
|
||||
|
||||
xtw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write out Game start using the supplied StreamWriter
|
||||
/// </summary>
|
||||
/// <param name="xtw">XmlTextWriter to output to</param>
|
||||
/// <param name="datItem">DatItem object to be output</param>
|
||||
/// <returns>True if the data was written, false on error</returns>
|
||||
private void WriteStartGame(XmlTextWriter xtw, DatItem datItem)
|
||||
{
|
||||
// No game should start with a path separator
|
||||
datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar);
|
||||
|
||||
// Build the state
|
||||
xtw.WriteStartElement("machine");
|
||||
xtw.WriteRequiredAttributeString("name", datItem.Machine.Name);
|
||||
xtw.WriteOptionalAttributeString("sourcefile", datItem.Machine.SourceFile);
|
||||
|
||||
if (datItem.Machine.MachineType.HasFlag(MachineType.Bios))
|
||||
xtw.WriteAttributeString("isbios", "yes");
|
||||
if (datItem.Machine.MachineType.HasFlag(MachineType.Device))
|
||||
xtw.WriteAttributeString("isdevice", "yes");
|
||||
if (datItem.Machine.MachineType.HasFlag(MachineType.Mechanical))
|
||||
xtw.WriteAttributeString("ismechanical", "yes");
|
||||
|
||||
xtw.WriteOptionalAttributeString("runnable", datItem.Machine.Runnable.FromRunnable());
|
||||
|
||||
if (!string.Equals(datItem.Machine.Name, datItem.Machine.CloneOf, StringComparison.OrdinalIgnoreCase))
|
||||
xtw.WriteOptionalAttributeString("cloneof", datItem.Machine.CloneOf);
|
||||
if (!string.Equals(datItem.Machine.Name, datItem.Machine.RomOf, StringComparison.OrdinalIgnoreCase))
|
||||
xtw.WriteOptionalAttributeString("romof", datItem.Machine.RomOf);
|
||||
if (!string.Equals(datItem.Machine.Name, datItem.Machine.SampleOf, StringComparison.OrdinalIgnoreCase))
|
||||
xtw.WriteOptionalAttributeString("sampleof", datItem.Machine.SampleOf);
|
||||
|
||||
xtw.WriteOptionalElementString("description", datItem.Machine.Description);
|
||||
xtw.WriteOptionalElementString("year", datItem.Machine.Year);
|
||||
xtw.WriteOptionalElementString("manufacturer", datItem.Machine.Manufacturer);
|
||||
xtw.WriteOptionalElementString("history", datItem.Machine.History);
|
||||
|
||||
xtw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write out Game start using the supplied StreamWriter
|
||||
/// </summary>
|
||||
/// <param name="xtw">XmlTextWriter to output to</param>
|
||||
private void WriteEndGame(XmlTextWriter xtw)
|
||||
{
|
||||
// End machine
|
||||
xtw.WriteEndElement();
|
||||
|
||||
xtw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write out DatItem using the supplied StreamWriter
|
||||
/// </summary>
|
||||
/// <param name="xtw">XmlTextWriter to output to</param>
|
||||
/// <param name="datItem">DatItem object to be output</param>
|
||||
private void WriteDatItem(XmlTextWriter xtw, DatItem datItem)
|
||||
{
|
||||
// Pre-process the item name
|
||||
ProcessItemName(datItem, true);
|
||||
|
||||
// Build the state
|
||||
switch (datItem.ItemType)
|
||||
{
|
||||
case ItemType.Adjuster:
|
||||
var adjuster = datItem as Adjuster;
|
||||
xtw.WriteStartElement("adjuster");
|
||||
xtw.WriteRequiredAttributeString("name", adjuster.Name);
|
||||
xtw.WriteRequiredAttributeString("default", adjuster.Default.FromYesNo());
|
||||
if (adjuster.ConditionsSpecified)
|
||||
{
|
||||
foreach (var adjusterCondition in adjuster.Conditions)
|
||||
{
|
||||
xtw.WriteStartElement("condition");
|
||||
xtw.WriteRequiredAttributeString("tag", adjusterCondition.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", adjusterCondition.Mask);
|
||||
xtw.WriteRequiredAttributeString("relation", adjusterCondition.Relation.FromRelation());
|
||||
xtw.WriteRequiredAttributeString("value", adjusterCondition.Value);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.BiosSet:
|
||||
var biosSet = datItem as BiosSet;
|
||||
xtw.WriteStartElement("biosset");
|
||||
xtw.WriteRequiredAttributeString("name", biosSet.Name);
|
||||
xtw.WriteRequiredAttributeString("description", biosSet.Description);
|
||||
xtw.WriteOptionalAttributeString("default", biosSet.Default?.ToString().ToLowerInvariant());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Chip:
|
||||
var chip = datItem as Chip;
|
||||
xtw.WriteStartElement("chip");
|
||||
xtw.WriteRequiredAttributeString("name", chip.Name);
|
||||
xtw.WriteOptionalAttributeString("tag", chip.Tag);
|
||||
xtw.WriteRequiredAttributeString("type", chip.ChipType.FromChipType());
|
||||
xtw.WriteOptionalAttributeString("clock", chip.Clock?.ToString());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Condition:
|
||||
var condition = datItem as Condition;
|
||||
xtw.WriteStartElement("condition");
|
||||
xtw.WriteRequiredAttributeString("tag", condition.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", condition.Mask);
|
||||
xtw.WriteRequiredAttributeString("relation", condition.Relation.FromRelation());
|
||||
xtw.WriteRequiredAttributeString("value", condition.Value);
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Configuration:
|
||||
var configuration = datItem as Configuration;
|
||||
xtw.WriteStartElement("configuration");
|
||||
xtw.WriteRequiredAttributeString("name", configuration.Name);
|
||||
xtw.WriteRequiredAttributeString("tag", configuration.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", configuration.Mask);
|
||||
|
||||
if (configuration.ConditionsSpecified)
|
||||
{
|
||||
foreach (var configurationCondition in configuration.Conditions)
|
||||
{
|
||||
xtw.WriteStartElement("condition");
|
||||
xtw.WriteRequiredAttributeString("tag", configurationCondition.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", configurationCondition.Mask);
|
||||
xtw.WriteRequiredAttributeString("relation", configurationCondition.Relation.FromRelation());
|
||||
xtw.WriteRequiredAttributeString("value", configurationCondition.Value);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
if (configuration.LocationsSpecified)
|
||||
{
|
||||
foreach (var location in configuration.Locations)
|
||||
{
|
||||
xtw.WriteStartElement("conflocation");
|
||||
xtw.WriteRequiredAttributeString("name", location.Name);
|
||||
xtw.WriteRequiredAttributeString("number", location.Number?.ToString());
|
||||
xtw.WriteOptionalAttributeString("inverted", location.Inverted.FromYesNo());
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
if (configuration.SettingsSpecified)
|
||||
{
|
||||
foreach (var setting in configuration.Settings)
|
||||
{
|
||||
xtw.WriteStartElement("confsetting");
|
||||
xtw.WriteRequiredAttributeString("name", setting.Name);
|
||||
xtw.WriteRequiredAttributeString("value", setting.Value);
|
||||
xtw.WriteOptionalAttributeString("default", setting.Default.FromYesNo());
|
||||
if (setting.ConditionsSpecified)
|
||||
{
|
||||
foreach (var confsettingCondition in setting.Conditions)
|
||||
{
|
||||
xtw.WriteStartElement("condition");
|
||||
xtw.WriteRequiredAttributeString("tag", confsettingCondition.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", confsettingCondition.Mask);
|
||||
xtw.WriteRequiredAttributeString("relation", confsettingCondition.Relation.FromRelation());
|
||||
xtw.WriteRequiredAttributeString("value", confsettingCondition.Value);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Device:
|
||||
var device = datItem as Device;
|
||||
xtw.WriteStartElement("device");
|
||||
xtw.WriteRequiredAttributeString("type", device.DeviceType.FromDeviceType());
|
||||
xtw.WriteOptionalAttributeString("tag", device.Tag);
|
||||
xtw.WriteOptionalAttributeString("fixed_image", device.FixedImage);
|
||||
xtw.WriteOptionalAttributeString("mandatory", device.Mandatory?.ToString());
|
||||
xtw.WriteOptionalAttributeString("interface", device.Interface);
|
||||
if (device.InstancesSpecified)
|
||||
{
|
||||
foreach (var instance in device.Instances)
|
||||
{
|
||||
xtw.WriteStartElement("instance");
|
||||
xtw.WriteRequiredAttributeString("name", instance.Name);
|
||||
xtw.WriteRequiredAttributeString("briefname", instance.BriefName);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
if (device.ExtensionsSpecified)
|
||||
{
|
||||
foreach (var extension in device.Extensions)
|
||||
{
|
||||
xtw.WriteStartElement("extension");
|
||||
xtw.WriteRequiredAttributeString("name", extension.Name);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.DeviceReference:
|
||||
var deviceRef = datItem as DeviceReference;
|
||||
xtw.WriteStartElement("device_ref");
|
||||
xtw.WriteRequiredAttributeString("name", deviceRef.Name);
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.DipSwitch:
|
||||
var dipSwitch = datItem as DipSwitch;
|
||||
xtw.WriteStartElement("dipswitch");
|
||||
xtw.WriteRequiredAttributeString("name", dipSwitch.Name);
|
||||
xtw.WriteRequiredAttributeString("tag", dipSwitch.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", dipSwitch.Mask);
|
||||
if (dipSwitch.ConditionsSpecified)
|
||||
{
|
||||
foreach (var dipSwitchCondition in dipSwitch.Conditions)
|
||||
{
|
||||
xtw.WriteStartElement("condition");
|
||||
xtw.WriteRequiredAttributeString("tag", dipSwitchCondition.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", dipSwitchCondition.Mask);
|
||||
xtw.WriteRequiredAttributeString("relation", dipSwitchCondition.Relation.FromRelation());
|
||||
xtw.WriteRequiredAttributeString("value", dipSwitchCondition.Value);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
if (dipSwitch.LocationsSpecified)
|
||||
{
|
||||
foreach (var location in dipSwitch.Locations)
|
||||
{
|
||||
xtw.WriteStartElement("diplocation");
|
||||
xtw.WriteRequiredAttributeString("name", location.Name);
|
||||
xtw.WriteRequiredAttributeString("number", location.Number?.ToString());
|
||||
xtw.WriteOptionalAttributeString("inverted", location.Inverted.FromYesNo());
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
if (dipSwitch.ValuesSpecified)
|
||||
{
|
||||
foreach (var value in dipSwitch.Values)
|
||||
{
|
||||
xtw.WriteStartElement("dipvalue");
|
||||
xtw.WriteRequiredAttributeString("name", value.Name);
|
||||
xtw.WriteRequiredAttributeString("value", value.Value);
|
||||
xtw.WriteOptionalAttributeString("default", value.Default.FromYesNo());
|
||||
if (value.ConditionsSpecified)
|
||||
{
|
||||
foreach (var dipValueCondition in value.Conditions)
|
||||
{
|
||||
xtw.WriteStartElement("condition");
|
||||
xtw.WriteRequiredAttributeString("tag", dipValueCondition.Tag);
|
||||
xtw.WriteRequiredAttributeString("mask", dipValueCondition.Mask);
|
||||
xtw.WriteRequiredAttributeString("relation", dipValueCondition.Relation.FromRelation());
|
||||
xtw.WriteRequiredAttributeString("value", dipValueCondition.Value);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Disk:
|
||||
var disk = datItem as Disk;
|
||||
xtw.WriteStartElement("disk");
|
||||
xtw.WriteRequiredAttributeString("name", disk.Name);
|
||||
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
|
||||
xtw.WriteOptionalAttributeString("merge", disk.MergeTag);
|
||||
xtw.WriteOptionalAttributeString("region", disk.Region);
|
||||
xtw.WriteOptionalAttributeString("index", disk.Index);
|
||||
xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo());
|
||||
if (disk.ItemStatus != ItemStatus.None)
|
||||
xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false));
|
||||
xtw.WriteOptionalAttributeString("optional", disk.Optional.FromYesNo());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Display:
|
||||
var display = datItem as Display;
|
||||
xtw.WriteStartElement("display");
|
||||
xtw.WriteOptionalAttributeString("tag", display.Tag);
|
||||
xtw.WriteRequiredAttributeString("type", display.DisplayType.FromDisplayType());
|
||||
xtw.WriteOptionalAttributeString("rotate", display.Rotate?.ToString());
|
||||
xtw.WriteOptionalAttributeString("flipx", display.FlipX.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("width", display.Width?.ToString());
|
||||
xtw.WriteOptionalAttributeString("height", display.Height?.ToString());
|
||||
xtw.WriteRequiredAttributeString("refresh", display.Refresh?.ToString("N6"));
|
||||
xtw.WriteOptionalAttributeString("pixclock", display.PixClock?.ToString());
|
||||
xtw.WriteOptionalAttributeString("htotal", display.HTotal?.ToString());
|
||||
xtw.WriteOptionalAttributeString("hbend", display.HBEnd?.ToString());
|
||||
xtw.WriteOptionalAttributeString("hstart", display.HBStart?.ToString());
|
||||
xtw.WriteOptionalAttributeString("vtotal", display.VTotal?.ToString());
|
||||
xtw.WriteOptionalAttributeString("vbend", display.VBEnd?.ToString());
|
||||
xtw.WriteOptionalAttributeString("vbstart", display.VBStart?.ToString());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Driver:
|
||||
var driver = datItem as Driver;
|
||||
xtw.WriteStartElement("driver");
|
||||
xtw.WriteRequiredAttributeString("status", driver.Status.FromSupportStatus());
|
||||
xtw.WriteRequiredAttributeString("emulation", driver.Emulation.FromSupportStatus());
|
||||
xtw.WriteOptionalAttributeString("cocktail", driver.Cocktail.FromSupportStatus());
|
||||
xtw.WriteRequiredAttributeString("savestate", driver.SaveState.FromSupported(true));
|
||||
xtw.WriteOptionalAttributeString("requiresartwork", driver.RequiresArtwork.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("unofficial", driver.Unofficial.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("nosoundhardware", driver.NoSoundHardware.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("incomplete", driver.Incomplete.FromYesNo());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Feature:
|
||||
var feature = datItem as Feature;
|
||||
xtw.WriteStartElement("feature");
|
||||
xtw.WriteRequiredAttributeString("type", feature.Type.FromFeatureType());
|
||||
xtw.WriteOptionalAttributeString("status", feature.Status.FromFeatureStatus());
|
||||
xtw.WriteOptionalAttributeString("overall", feature.Overall.FromFeatureStatus());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Input:
|
||||
var input = datItem as Input;
|
||||
xtw.WriteStartElement("input");
|
||||
xtw.WriteOptionalAttributeString("service", input.Service.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("tilt", input.Tilt.FromYesNo());
|
||||
xtw.WriteRequiredAttributeString("players", input.Players?.ToString());
|
||||
xtw.WriteOptionalAttributeString("coins", input.Coins?.ToString());
|
||||
if (input.ControlsSpecified)
|
||||
{
|
||||
foreach (var control in input.Controls)
|
||||
{
|
||||
xtw.WriteStartElement("control");
|
||||
xtw.WriteRequiredAttributeString("type", control.ControlType.FromControlType());
|
||||
xtw.WriteOptionalAttributeString("player", control.Player?.ToString());
|
||||
xtw.WriteOptionalAttributeString("buttons", control.Buttons?.ToString());
|
||||
xtw.WriteOptionalAttributeString("reqbuttons", control.RequiredButtons?.ToString());
|
||||
xtw.WriteOptionalAttributeString("minimum", control.Minimum?.ToString());
|
||||
xtw.WriteOptionalAttributeString("maximum", control.Maximum?.ToString());
|
||||
xtw.WriteOptionalAttributeString("sensitivity", control.Sensitivity?.ToString());
|
||||
xtw.WriteOptionalAttributeString("keydelta", control.KeyDelta?.ToString());
|
||||
xtw.WriteOptionalAttributeString("reverse", control.Reverse.FromYesNo());
|
||||
xtw.WriteOptionalAttributeString("ways", control.Ways);
|
||||
xtw.WriteOptionalAttributeString("ways2", control.Ways2);
|
||||
xtw.WriteOptionalAttributeString("ways3", control.Ways3);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Port:
|
||||
var port = datItem as Port;
|
||||
xtw.WriteStartElement("port");
|
||||
xtw.WriteRequiredAttributeString("tag", port.Tag);
|
||||
if (port.AnalogsSpecified)
|
||||
{
|
||||
foreach (var analog in port.Analogs)
|
||||
{
|
||||
xtw.WriteStartElement("analog");
|
||||
xtw.WriteRequiredAttributeString("mask", analog.Mask);
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.RamOption:
|
||||
var ramOption = datItem as RamOption;
|
||||
xtw.WriteStartElement("ramoption");
|
||||
xtw.WriteRequiredAttributeString("name", ramOption.Name);
|
||||
xtw.WriteOptionalAttributeString("default", ramOption.Default.FromYesNo());
|
||||
xtw.WriteRaw(ramOption.Content ?? string.Empty);
|
||||
xtw.WriteFullEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Rom:
|
||||
var rom = datItem as Rom;
|
||||
xtw.WriteStartElement("rom");
|
||||
xtw.WriteRequiredAttributeString("name", rom.Name);
|
||||
xtw.WriteOptionalAttributeString("bios", rom.Bios);
|
||||
xtw.WriteRequiredAttributeString("size", rom.Size?.ToString());
|
||||
xtw.WriteOptionalAttributeString("crc", rom.CRC?.ToLowerInvariant());
|
||||
xtw.WriteOptionalAttributeString("sha1", rom.SHA1?.ToLowerInvariant());
|
||||
xtw.WriteOptionalAttributeString("merge", rom.MergeTag);
|
||||
xtw.WriteOptionalAttributeString("region", rom.Region);
|
||||
xtw.WriteOptionalAttributeString("offset", rom.Offset);
|
||||
if (rom.ItemStatus != ItemStatus.None)
|
||||
xtw.WriteOptionalAttributeString("status", rom.ItemStatus.FromItemStatus(false));
|
||||
xtw.WriteOptionalAttributeString("optional", rom.Optional.FromYesNo());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Sample:
|
||||
var sample = datItem as Sample;
|
||||
xtw.WriteStartElement("sample");
|
||||
xtw.WriteRequiredAttributeString("name", sample.Name);
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Slot:
|
||||
var slot = datItem as Slot;
|
||||
xtw.WriteStartElement("slot");
|
||||
xtw.WriteRequiredAttributeString("name", slot.Name);
|
||||
if (slot.SlotOptionsSpecified)
|
||||
{
|
||||
foreach (var slotOption in slot.SlotOptions)
|
||||
{
|
||||
xtw.WriteStartElement("slotoption");
|
||||
xtw.WriteRequiredAttributeString("name", slotOption.Name);
|
||||
xtw.WriteRequiredAttributeString("devname", slotOption.DeviceName);
|
||||
xtw.WriteOptionalAttributeString("default", slotOption.Default.FromYesNo());
|
||||
xtw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.SoftwareList:
|
||||
var softwareList = datItem as DatItems.Formats.SoftwareList;
|
||||
xtw.WriteStartElement("softwarelist");
|
||||
xtw.WriteRequiredAttributeString("tag", softwareList.Tag);
|
||||
xtw.WriteRequiredAttributeString("name", softwareList.Name);
|
||||
if (softwareList.Status != SoftwareListStatus.None)
|
||||
xtw.WriteRequiredAttributeString("status", softwareList.Status.FromSoftwareListStatus());
|
||||
xtw.WriteOptionalAttributeString("filter", softwareList.Filter);
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
|
||||
case ItemType.Sound:
|
||||
var sound = datItem as Sound;
|
||||
xtw.WriteStartElement("sound");
|
||||
xtw.WriteRequiredAttributeString("channels", sound.Channels?.ToString());
|
||||
xtw.WriteEndElement();
|
||||
break;
|
||||
}
|
||||
|
||||
xtw.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write out DAT footer using the supplied StreamWriter
|
||||
/// </summary>
|
||||
/// <param name="xtw">XmlTextWriter to output to</param>
|
||||
private void WriteFooter(XmlTextWriter xtw)
|
||||
{
|
||||
// End machine
|
||||
xtw.WriteEndElement();
|
||||
|
||||
// End mame
|
||||
xtw.WriteEndElement();
|
||||
|
||||
xtw.Flush();
|
||||
}
|
||||
|
||||
#region Converters
|
||||
|
||||
/// <summary>
|
||||
@@ -841,7 +368,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <summary>
|
||||
/// Create a GameBase from the current internal information
|
||||
/// <summary>
|
||||
private Models.Listxml.GameBase? CreateGame(Machine machine)
|
||||
private Models.Listxml.GameBase CreateGame(Machine machine)
|
||||
{
|
||||
var game = new Models.Listxml.Machine
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public Listxml(DatFile datFile)
|
||||
public Listxml(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
ConvertSubheader(header.RomCenter);
|
||||
|
||||
// Handle implied SuperDAT
|
||||
if (header.Name.Contains(" - SuperDAT") && keep)
|
||||
if (header.Name?.Contains(" - SuperDAT") == true && keep)
|
||||
Header.Type ??= "SuperDAT";
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="filename">Name of the file to be parsed</param>
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
|
||||
private void ConvertGame(Models.Logiqx.GameBase game, string filename, int indexId, bool statsOnly, string dirname = null)
|
||||
private void ConvertGame(Models.Logiqx.GameBase game, string filename, int indexId, bool statsOnly, string? dirname = null)
|
||||
{
|
||||
// If the game is missing, we can't do anything
|
||||
if (game == null)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
var missingFields = new List<DatItemField>();
|
||||
switch (datItem)
|
||||
@@ -385,7 +385,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <summary>
|
||||
/// Create a GameBase from the current internal information
|
||||
/// <summary>
|
||||
private Models.Logiqx.GameBase? CreateGame(Machine machine)
|
||||
private Models.Logiqx.GameBase CreateGame(Machine machine)
|
||||
{
|
||||
Models.Logiqx.GameBase game = _deprecated ? new Models.Logiqx.Game() : new Models.Logiqx.Machine();
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
/// <param name="deprecated">True if the output uses "game", false if the output uses "machine"</param>
|
||||
public Logiqx(DatFile datFile, bool deprecated)
|
||||
public Logiqx(DatFile? datFile, bool deprecated)
|
||||
: base(datFile)
|
||||
{
|
||||
_deprecated = deprecated;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
internal partial class Missfile : DatFile
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
// TODO: Check required fields
|
||||
return null;
|
||||
@@ -37,7 +37,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
StreamWriter sw = new(fs, new UTF8Encoding(false));
|
||||
|
||||
// Write out each of the machines and roms
|
||||
string lastgame = null;
|
||||
string? lastgame = null;
|
||||
|
||||
// Use a sorted list of games to output
|
||||
foreach (string key in Items.SortedKeys)
|
||||
@@ -86,7 +86,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="sw">StreamWriter to output to</param>
|
||||
/// <param name="datItem">DatItem object to be output</param>
|
||||
/// <param name="lastgame">The name of the last game to be output</param>
|
||||
private void WriteDatItem(StreamWriter sw, DatItem datItem, string lastgame)
|
||||
private void WriteDatItem(StreamWriter sw, DatItem datItem, string? lastgame)
|
||||
{
|
||||
// Process the item name
|
||||
ProcessItemName(datItem, false, forceRomName: false);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public Missfile(DatFile datFile)
|
||||
public Missfile(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
ConvertHeader(dat);
|
||||
|
||||
// Convert the configuration to the internal format
|
||||
ConvertConfiguration(dat.Configuration, keep);
|
||||
ConvertConfiguration(dat?.Configuration, keep);
|
||||
|
||||
// Convert the games to the internal format
|
||||
ConvertGames(dat?.Games, filename, indexId, statsOnly);
|
||||
@@ -78,7 +78,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
Header.RomTitle = config.RomTitle;
|
||||
|
||||
// Handle implied SuperDAT
|
||||
if (config.DatName.Contains(" - SuperDAT") && keep)
|
||||
if (config.DatName?.Contains(" - SuperDAT") == true && keep)
|
||||
Header.Type ??= "SuperDAT";
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
private void ConvertCanOpen(Models.OfflineList.CanOpen? canOpen)
|
||||
{
|
||||
// If the canOpen is missing, we can't do anything
|
||||
if (canOpen == null)
|
||||
if (canOpen?.Extension == null)
|
||||
return;
|
||||
|
||||
Header.CanOpen = new List<string>(canOpen.Extension);
|
||||
@@ -354,7 +354,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
|
||||
/// <param name="containsItems">True if there were any items in the array, false otherwise</param>
|
||||
private void ConvertFiles(Models.OfflineList.Files? files, Machine machine, long? size, string releaseNumber, string filename, int indexId, bool statsOnly, ref bool containsItems)
|
||||
private void ConvertFiles(Models.OfflineList.Files? files, Machine machine, long? size, string? releaseNumber, string filename, int indexId, bool statsOnly, ref bool containsItems)
|
||||
{
|
||||
// If the files array is missing, we can't do anything
|
||||
if (files?.RomCRC == null || !files.RomCRC.Any())
|
||||
@@ -371,6 +371,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
var item = new Rom
|
||||
{
|
||||
Name = name,
|
||||
Size = size,
|
||||
CRC = crc.Content,
|
||||
ItemStatus = ItemStatus.None,
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
var missingFields = new List<DatItemField>();
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
private Models.OfflineList.Infos? CreateInfos()
|
||||
{
|
||||
// If we don't have infos, we can't do anything
|
||||
if (!Header.InfosSpecified)
|
||||
if (!Header.InfosSpecified || Header.Infos == null)
|
||||
return null;
|
||||
|
||||
var infos = new Models.OfflineList.Infos();
|
||||
@@ -256,7 +256,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
private Models.OfflineList.CanOpen? CreateCanOpen()
|
||||
{
|
||||
// If we don't have a canopen, we can't do anything
|
||||
if (!Header.CanOpenSpecified)
|
||||
if (!Header.CanOpenSpecified || Header.CanOpen == null)
|
||||
return null;
|
||||
|
||||
var canOpen = new Models.OfflineList.CanOpen
|
||||
@@ -360,12 +360,9 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <summary>
|
||||
/// Create a Machine from the current internal information
|
||||
/// <summary>
|
||||
private Models.OfflineList.Game? CreateGame(Machine machine)
|
||||
private Models.OfflineList.Game CreateGame(Machine machine)
|
||||
{
|
||||
// If we don't have a machine, we can't do anything
|
||||
if (machine == null)
|
||||
return null;
|
||||
|
||||
|
||||
var game = new Models.OfflineList.Game
|
||||
{
|
||||
//ImageNumber = machine.ImageNumber, // TODO: Add to internal model
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public OfflineList(DatFile datFile)
|
||||
public OfflineList(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="filename">Name of the file to be parsed</param>
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
|
||||
private void ConvertSoftware(Models.OpenMSX.Software software, string filename, int indexId, bool statsOnly, string dirname = null)
|
||||
private void ConvertSoftware(Models.OpenMSX.Software software, string filename, int indexId, bool statsOnly)
|
||||
{
|
||||
// If the software is missing, we can't do anything
|
||||
if (software == null)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
var missingFields = new List<DatItemField>();
|
||||
|
||||
@@ -149,9 +149,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <summary>
|
||||
private static Models.OpenMSX.Dump CreateDump(Rom item)
|
||||
{
|
||||
|
||||
Models.OpenMSX.Original original = null;
|
||||
if (item.OriginalSpecified)
|
||||
Models.OpenMSX.Original? original = null;
|
||||
if (item.OriginalSpecified && item.Original != null)
|
||||
{
|
||||
original = new Models.OpenMSX.Original { Content = item.Original.Content };
|
||||
if (item.Original.Value != null)
|
||||
|
||||
@@ -40,7 +40,7 @@ The softwaredb.xml file contains information about rom mapper types
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public OpenMSX(DatFile datFile)
|
||||
public OpenMSX(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// Create a Games from the current internal information
|
||||
/// <summary>
|
||||
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise</param>
|
||||
private Models.RomCenter.Games CreateGames(bool ignoreblanks)
|
||||
private Models.RomCenter.Games? CreateGames(bool ignoreblanks)
|
||||
{
|
||||
// If we don't have items, we can't do anything
|
||||
if (this.Items == null || !this.Items.Any())
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public RomCenter(DatFile datFile)
|
||||
public RomCenter(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public SabreJSON(DatFile datFile)
|
||||
public SabreJSON(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
@@ -92,7 +92,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Read in the header and apply any new fields
|
||||
jtr.Read();
|
||||
JsonSerializer js = new();
|
||||
DatHeader header = js.Deserialize<DatHeader>(jtr);
|
||||
DatHeader? header = js.Deserialize<DatHeader>(jtr);
|
||||
Header.ConditionalCopy(header);
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ namespace SabreTools.DatFiles.Formats
|
||||
// Read in the machine array
|
||||
jtr.Read();
|
||||
JsonSerializer js = new();
|
||||
JArray machineArray = js.Deserialize<JArray>(jtr);
|
||||
JArray? machineArray = js.Deserialize<JArray>(jtr);
|
||||
|
||||
// Loop through each machine object and process
|
||||
foreach (JObject machineObj in machineArray)
|
||||
foreach (JObject machineObj in machineArray ?? new JArray())
|
||||
{
|
||||
ReadMachine(machineObj, statsOnly, filename, indexId);
|
||||
}
|
||||
@@ -135,11 +135,11 @@ namespace SabreTools.DatFiles.Formats
|
||||
return;
|
||||
|
||||
// Prepare internal variables
|
||||
Machine machine = null;
|
||||
Machine? machine = null;
|
||||
|
||||
// Read the machine info, if possible
|
||||
if (machineObj.ContainsKey("machine"))
|
||||
machine = machineObj["machine"].ToObject<Machine>();
|
||||
machine = machineObj["machine"]?.ToObject<Machine>();
|
||||
|
||||
// Read items, if possible
|
||||
if (machineObj.ContainsKey("items"))
|
||||
@@ -155,7 +155,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
/// <param name="machine">Machine information to add to the parsed items</param>
|
||||
private void ReadItems(
|
||||
JArray itemsArr,
|
||||
JArray? itemsArr,
|
||||
bool statsOnly,
|
||||
|
||||
// Standard Dat parsing
|
||||
@@ -163,7 +163,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
int indexId,
|
||||
|
||||
// Miscellaneous
|
||||
Machine machine)
|
||||
Machine? machine)
|
||||
{
|
||||
// If the array is invalid, skip
|
||||
if (itemsArr == null)
|
||||
@@ -193,19 +193,22 @@ namespace SabreTools.DatFiles.Formats
|
||||
int indexId,
|
||||
|
||||
// Miscellaneous
|
||||
Machine machine)
|
||||
Machine? machine)
|
||||
{
|
||||
// If we have an empty item, skip it
|
||||
if (itemObj == null)
|
||||
return;
|
||||
|
||||
// Prepare internal variables
|
||||
DatItem datItem = null;
|
||||
DatItem? datItem = null;
|
||||
|
||||
// Read the datitem info, if possible
|
||||
if (itemObj.ContainsKey("datitem"))
|
||||
{
|
||||
JToken datItemObj = itemObj["datitem"];
|
||||
JToken? datItemObj = itemObj["datitem"];
|
||||
if (datItemObj == null)
|
||||
return;
|
||||
|
||||
switch (datItemObj.Value<string>("type").AsItemType())
|
||||
{
|
||||
case ItemType.Adjuster:
|
||||
@@ -367,7 +370,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
WriteHeader(jtw);
|
||||
|
||||
// Write out each of the machines and roms
|
||||
string lastgame = null;
|
||||
string? lastgame = null;
|
||||
|
||||
// Use a sorted list of games to output
|
||||
foreach (string key in Items.SortedKeys)
|
||||
@@ -523,7 +526,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
|
||||
jtw.Flush();
|
||||
}
|
||||
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/728
|
||||
private class BaseFirstContractResolver : DefaultContractResolver
|
||||
{
|
||||
@@ -535,9 +538,11 @@ namespace SabreTools.DatFiles.Formats
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
return base.CreateProperties(type, memberSerialization)
|
||||
.OrderBy(p => BaseTypesAndSelf(p.DeclaringType).Count()).ToList();
|
||||
.Where(p => p != null)
|
||||
.OrderBy(p => BaseTypesAndSelf(p.DeclaringType).Count())
|
||||
.ToList();
|
||||
|
||||
static IEnumerable<Type> BaseTypesAndSelf(Type t)
|
||||
static IEnumerable<Type?> BaseTypesAndSelf(Type? t)
|
||||
{
|
||||
while (t != null)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public SabreXML(DatFile datFile)
|
||||
public SabreXML(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
public override void ParseFile(string filename, int indexId, bool keep, bool statsOnly = false, bool throwOnError = false)
|
||||
{
|
||||
// Prepare all internal variables
|
||||
XmlReader xtr = XmlReader.Create(filename, new XmlReaderSettings
|
||||
XmlReader? xtr = XmlReader.Create(filename, new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
DtdProcessing = DtdProcessing.Ignore,
|
||||
@@ -58,7 +58,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
case "header":
|
||||
XmlSerializer xs = new(typeof(DatHeader));
|
||||
DatHeader header = xs.Deserialize(xtr.ReadSubtree()) as DatHeader;
|
||||
DatHeader? header = xs.Deserialize(xtr.ReadSubtree()) as DatHeader;
|
||||
Header.ConditionalCopy(header);
|
||||
xtr.Skip();
|
||||
break;
|
||||
@@ -78,12 +78,12 @@ namespace SabreTools.DatFiles.Formats
|
||||
catch (Exception ex) when (!throwOnError)
|
||||
{
|
||||
logger.Warning(ex, $"Exception found while parsing '{filename}'");
|
||||
|
||||
|
||||
// For XML errors, just skip the affected node
|
||||
xtr?.Read();
|
||||
}
|
||||
|
||||
xtr.Dispose();
|
||||
xtr?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -100,7 +100,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
return;
|
||||
|
||||
// Prepare internal variables
|
||||
Machine machine = null;
|
||||
Machine? machine = null;
|
||||
|
||||
// Otherwise, read the directory
|
||||
xtr.MoveToContent();
|
||||
@@ -117,7 +117,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
case "machine":
|
||||
XmlSerializer xs = new(typeof(Machine));
|
||||
machine = xs.Deserialize(xtr.ReadSubtree()) as Machine;
|
||||
machine = xs?.Deserialize(xtr.ReadSubtree()) as Machine;
|
||||
xtr.Skip();
|
||||
break;
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
|
||||
/// <param name="filename">Name of the file to be parsed</param>
|
||||
/// <param name="indexId">Index ID for the DAT</param>
|
||||
private void ReadFiles(XmlReader xtr, Machine machine, bool statsOnly, string filename, int indexId)
|
||||
private void ReadFiles(XmlReader xtr, Machine? machine, bool statsOnly, string filename, int indexId)
|
||||
{
|
||||
// If the reader is invalid, skip
|
||||
if (xtr == null)
|
||||
@@ -163,10 +163,12 @@ namespace SabreTools.DatFiles.Formats
|
||||
{
|
||||
case "datitem":
|
||||
XmlSerializer xs = new(typeof(DatItem));
|
||||
DatItem item = xs.Deserialize(xtr.ReadSubtree()) as DatItem;
|
||||
item.CopyMachineInformation(machine);
|
||||
item.Source = new Source { Name = filename, Index = indexId };
|
||||
ParseAddHelper(item, statsOnly);
|
||||
if (xs.Deserialize(xtr.ReadSubtree()) is DatItem item)
|
||||
{
|
||||
item.CopyMachineInformation(machine);
|
||||
item.Source = new Source { Name = filename, Index = indexId };
|
||||
ParseAddHelper(item, statsOnly);
|
||||
}
|
||||
xtr.Skip();
|
||||
break;
|
||||
default:
|
||||
@@ -202,7 +204,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
WriteHeader(xtw);
|
||||
|
||||
// Write out each of the machines and roms
|
||||
string lastgame = null;
|
||||
string? lastgame = null;
|
||||
|
||||
// Use a sorted list of games to output
|
||||
foreach (string key in Items.SortedKeys)
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
};
|
||||
|
||||
// Read item values
|
||||
DatItem item = null;
|
||||
DatItem? item = null;
|
||||
switch (row.Type.AsItemType())
|
||||
{
|
||||
case ItemType.Disk:
|
||||
@@ -137,8 +137,11 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
// Now process and add the item
|
||||
item.CopyMachineInformation(machine);
|
||||
ParseAddHelper(item, statsOnly);
|
||||
if (item != null)
|
||||
{
|
||||
item.CopyMachineInformation(machine);
|
||||
ParseAddHelper(item, statsOnly);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
/// <param name="delim">Delimiter for parsing individual lines</param>
|
||||
public SeparatedValue(DatFile datFile, char delim)
|
||||
public SeparatedValue(DatFile? datFile, char delim)
|
||||
: base(datFile)
|
||||
{
|
||||
_delim = delim;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
Header.Comment ??= softwarelist.Notes;
|
||||
|
||||
// Handle implied SuperDAT
|
||||
if (Header.Name.Contains(" - SuperDAT") && keep)
|
||||
if (Header.Name?.Contains(" - SuperDAT") == true && keep)
|
||||
Header.Type ??= "SuperDAT";
|
||||
}
|
||||
|
||||
|
||||
@@ -27,14 +27,13 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override List<DatItemField> GetMissingRequiredFields(DatItem datItem)
|
||||
protected override List<DatItemField>? GetMissingRequiredFields(DatItem datItem)
|
||||
{
|
||||
List<DatItemField> missingFields = new();
|
||||
var missingFields = new List<DatItemField>();
|
||||
|
||||
switch (datItem.ItemType)
|
||||
switch (datItem)
|
||||
{
|
||||
case ItemType.DipSwitch:
|
||||
DipSwitch dipSwitch = datItem as DipSwitch;
|
||||
case DipSwitch dipSwitch:
|
||||
if (!dipSwitch.PartSpecified)
|
||||
{
|
||||
missingFields.Add(DatItemField.Part_Name);
|
||||
@@ -63,8 +62,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
|
||||
break;
|
||||
|
||||
case ItemType.Disk:
|
||||
Disk disk = datItem as Disk;
|
||||
case Disk disk:
|
||||
if (!disk.PartSpecified)
|
||||
{
|
||||
missingFields.Add(DatItemField.Part_Name);
|
||||
@@ -90,14 +88,12 @@ namespace SabreTools.DatFiles.Formats
|
||||
missingFields.Add(DatItemField.Name);
|
||||
break;
|
||||
|
||||
case ItemType.Info:
|
||||
Info info = datItem as Info;
|
||||
case Info info:
|
||||
if (string.IsNullOrWhiteSpace(info.Name))
|
||||
missingFields.Add(DatItemField.Name);
|
||||
break;
|
||||
|
||||
case ItemType.Rom:
|
||||
Rom rom = datItem as Rom;
|
||||
case Rom rom:
|
||||
if (!rom.PartSpecified)
|
||||
{
|
||||
missingFields.Add(DatItemField.Part_Name);
|
||||
@@ -124,9 +120,8 @@ namespace SabreTools.DatFiles.Formats
|
||||
}
|
||||
break;
|
||||
|
||||
case ItemType.SharedFeature:
|
||||
SharedFeature sharedFeature = datItem as SharedFeature;
|
||||
if (string.IsNullOrWhiteSpace(sharedFeature.Name))
|
||||
case SharedFeature sharedFeat:
|
||||
if (string.IsNullOrWhiteSpace(sharedFeat.Name))
|
||||
missingFields.Add(DatItemField.Name);
|
||||
break;
|
||||
default:
|
||||
@@ -260,7 +255,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// <summary>
|
||||
/// Create a Software from the current internal information
|
||||
/// <summary>
|
||||
private Models.SoftwareList.Software? CreateSoftware(Machine machine)
|
||||
private Models.SoftwareList.Software CreateSoftware(Machine machine)
|
||||
{
|
||||
var software = new Models.SoftwareList.Software
|
||||
{
|
||||
@@ -467,7 +462,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
private static List<Models.SoftwareList.Part> SantitizeParts(List<Models.SoftwareList.Part> parts)
|
||||
{
|
||||
// If we have no parts, we can't do anything
|
||||
if (parts == null || !parts.Any())
|
||||
if (!parts.Any())
|
||||
return parts;
|
||||
|
||||
var grouped = parts.GroupBy(p => p.Name);
|
||||
@@ -521,7 +516,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
private static List<Models.SoftwareList.DataArea> SantitizeDataAreas(List<Models.SoftwareList.DataArea> dataAreas)
|
||||
{
|
||||
// If we have no DataAreas, we can't do anything
|
||||
if (dataAreas == null || !dataAreas.Any())
|
||||
if (!dataAreas.Any())
|
||||
return dataAreas;
|
||||
|
||||
var grouped = dataAreas.GroupBy(p => p.Name);
|
||||
@@ -558,7 +553,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
private static List<Models.SoftwareList.DiskArea> SantitizeDiskAreas(List<Models.SoftwareList.DiskArea> diskAreas)
|
||||
{
|
||||
// If we have no DiskAreas, we can't do anything
|
||||
if (diskAreas == null || !diskAreas.Any())
|
||||
if (!diskAreas.Any())
|
||||
return diskAreas;
|
||||
|
||||
var grouped = diskAreas.GroupBy(p => p.Name);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace SabreTools.DatFiles.Formats
|
||||
/// Constructor designed for casting a base DatFile
|
||||
/// </summary>
|
||||
/// <param name="datFile">Parent DatFile to copy from</param>
|
||||
public SoftwareList(DatFile datFile)
|
||||
public SoftwareList(DatFile? datFile)
|
||||
: base(datFile)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user