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; if (Header.GetFieldValue(Models.Metadata.Header.NameKey) == null) Header.SetFieldValue(Models.Metadata.Header.NameKey, "openMSX Software List"); if (Header.GetFieldValue(Models.Metadata.Header.DescriptionKey) == null) Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, Header.GetFieldValue(Models.Metadata.Header.NameKey)); if (Header.GetFieldValue(Models.Metadata.Header.DateKey) == null) Header.SetFieldValue(Models.Metadata.Header.DateKey, 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(); blank.SetFieldValue(DatItem.SourceKey, 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(); 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); item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename }); 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 } }