using System;
using System.Linq;
using SabreTools.Core;
using SabreTools.Core.Tools;
using SabreTools.DatItems;
using SabreTools.DatItems.Formats;
namespace SabreTools.DatFiles.Formats
{
///
/// Represents parsing an openMSX softawre list XML DAT
///
internal partial class OpenMSX : DatFile
{
///
public override void ParseFile(string filename, int indexId, bool keep, bool statsOnly = false, bool throwOnError = false)
{
try
{
// Deserialize the input file
var softwareDb = new Serialization.Files.OpenMSX().Deserialize(filename);
// Convert the header to the internal format
ConvertHeader(softwareDb);
// Convert the software data to the internal format
ConvertSoftwares(softwareDb?.Software, filename, indexId, statsOnly);
}
catch (Exception ex) when (!throwOnError)
{
string message = $"'{filename}' - An error occurred during parsing";
logger.Error(ex, message);
}
}
#region Converters
///
/// Convert header information
///
/// Deserialized model to convert
private void ConvertHeader(Models.OpenMSX.SoftwareDb? softwaredb)
{
// If the datafile is missing, we can't do anything
if (softwaredb == null)
return;
Header.Name ??= "openMSX Software List";
Header.Description ??= Header.Name;
Header.Date ??= softwaredb.Timestamp;
}
///
/// Convert softwares information
///
/// Array of deserialized models to convert
/// Name of the file to be parsed
/// Index ID for the DAT
/// True to only add item statistics while parsing, false otherwise
private void ConvertSoftwares(Models.OpenMSX.Software[]? softwares, string filename, int indexId, bool statsOnly)
{
// If the software array is missing, we can't do anything
if (softwares == null || !softwares.Any())
return;
// Loop through the software and add
foreach (var software in softwares)
{
ConvertSoftware(software, filename, indexId, statsOnly);
}
}
///
/// Convert software information
///
/// Deserialized model to convert
/// Name of the file to be parsed
/// Index ID for the DAT
/// True to only add item statistics while parsing, false otherwise
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)
return;
// Create the machine for copying information
var machine = new Machine();
machine.SetFieldValue(Models.Metadata.Machine.CountryKey, software.Country);
machine.SetFieldValue(Models.Metadata.Machine.GenMSXIDKey, software.GenMSXID);
machine.SetFieldValue(Models.Metadata.Machine.ManufacturerKey, software.Company);
machine.SetFieldValue(Models.Metadata.Machine.SystemKey, software.System);
machine.SetFieldValue(Models.Metadata.Machine.NameKey, software.Title);
machine.SetFieldValue(Models.Metadata.Machine.YearKey, software.Year);
// Check if there are any items
bool containsItems = false;
ConvertDumps(software.Dump, machine, filename, indexId, statsOnly, ref containsItems);
// If we had no items, create a Blank placeholder
if (!containsItems)
{
var blank = new Blank
{
Source = new Source { Index = indexId, Name = filename },
};
blank.CopyMachineInformation(machine);
ParseAddHelper(blank, statsOnly);
}
}
///
/// Convert Dump information
///
/// Array of deserialized models to convert
/// Prefilled machine to use
/// Name of the file to be parsed
/// Index ID for the DAT
/// True to only add item statistics while parsing, false otherwise
/// True if there were any items in the array, false otherwise
private void ConvertDumps(Models.OpenMSX.Dump[]? dumps, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
{
// If the dumps array is missing, we can't do anything
if (dumps == null || !dumps.Any())
return;
containsItems = true;
int index = 0;
foreach (var dump in dumps)
{
// If we don't have rom data, we can't do anything
if (dump?.Rom == null)
continue;
var rom = dump.Rom;
string name = $"{machine.GetFieldValue(Models.Metadata.Machine.NameKey)}_{index++}{(!string.IsNullOrEmpty(rom.Remark) ? $" {rom.Remark}" : string.Empty)}";
var item = new Rom
{
Source = new Source { Index = indexId, Name = filename },
};
item.SetName(name);
item.SetFieldValue(Models.Metadata.Rom.OffsetKey, dump.Rom?.Start);
item.SetFieldValue(Models.Metadata.Rom.OpenMSXType, rom.Type);
item.SetFieldValue(Models.Metadata.Rom.RemarkKey, rom.Remark);
item.SetFieldValue(Models.Metadata.Rom.SHA1Key, rom.Hash);
if (dump.Original != null)
{
item.SetFieldValue("ORIGINAL", new Original
{
Value = dump.Original.Value.AsYesNo(),
Content = dump.Original.Content,
});
}
switch (dump.Rom)
{
case Models.OpenMSX.Rom:
item.SetFieldValue(Models.Metadata.Rom.OpenMSXMediaType, OpenMSXSubType.Rom);
break;
case Models.OpenMSX.MegaRom:
item.SetFieldValue(Models.Metadata.Rom.OpenMSXMediaType, OpenMSXSubType.MegaRom);
break;
case Models.OpenMSX.SCCPlusCart:
item.SetFieldValue(Models.Metadata.Rom.OpenMSXMediaType, OpenMSXSubType.SCCPlusCart);
break;
}
item.CopyMachineInformation(machine);
ParseAddHelper(item, statsOnly);
}
}
#endregion
}
}