diff --git a/SabreTools.DatFiles/DatFile.MetadataConverter.cs b/SabreTools.DatFiles/DatFile.MetadataConverter.cs
index 196d3832..729a774c 100644
--- a/SabreTools.DatFiles/DatFile.MetadataConverter.cs
+++ b/SabreTools.DatFiles/DatFile.MetadataConverter.cs
@@ -5,7 +5,6 @@ using SabreTools.Core.Tools;
namespace SabreTools.DatFiles
{
- // TODO: Convert nested items (e.g. Configuration, DipLocation)
public partial class DatFile
{
#region Converters
@@ -646,32 +645,6 @@ namespace SabreTools.DatFiles
}
}
- ///
- /// Convert DataArea information
- ///
- /// Array of internal items to convert
- /// Machine to use with the converted items
- /// Name of the file to be parsed
- /// Index ID for the DAT
- /// True to only add item statistics while parsing, false otherwise
- private void ProcessItems(Models.Metadata.DataArea[]? items, DatItems.Machine machine, string filename, int indexId, bool statsOnly)
- {
- // If the array is null or empty, return without processing
- if (items == null || items.Length == 0)
- return;
-
- // TODO: Extract Roms
-
- // Loop through the items and add
- foreach (var item in items)
- {
- var datItem = new DatItems.Formats.DataArea(item);
- datItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
- datItem.CopyMachineInformation(machine);
- ParseAddHelper(datItem, statsOnly);
- }
- }
-
///
/// Convert Device information
///
@@ -742,30 +715,6 @@ namespace SabreTools.DatFiles
}
}
- ///
- /// Convert DipLocation information
- ///
- /// Array of internal items to convert
- /// Machine to use with the converted items
- /// Name of the file to be parsed
- /// Index ID for the DAT
- /// True to only add item statistics while parsing, false otherwise
- private void ProcessItems(Models.Metadata.DipLocation[]? items, DatItems.Machine machine, string filename, int indexId, bool statsOnly)
- {
- // If the array is null or empty, return without processing
- if (items == null || items.Length == 0)
- return;
-
- // Loop through the items and add
- foreach (var item in items)
- {
- var datItem = new DatItems.Formats.DipLocation(item);
- datItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
- datItem.CopyMachineInformation(machine);
- ParseAddHelper(datItem, statsOnly);
- }
- }
-
///
/// Convert DipSwitch information
///
@@ -833,30 +782,6 @@ namespace SabreTools.DatFiles
}
}
- ///
- /// Convert DipValue information
- ///
- /// Array of internal items to convert
- /// Machine to use with the converted items
- /// Name of the file to be parsed
- /// Index ID for the DAT
- /// True to only add item statistics while parsing, false otherwise
- private void ProcessItems(Models.Metadata.DipValue[]? items, DatItems.Machine machine, string filename, int indexId, bool statsOnly)
- {
- // If the array is null or empty, return without processing
- if (items == null || items.Length == 0)
- return;
-
- // Loop through the items and add
- foreach (var item in items)
- {
- var datItem = new DatItems.Formats.DipValue(item);
- datItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
- datItem.CopyMachineInformation(machine);
- ParseAddHelper(datItem, statsOnly);
- }
- }
-
///
/// Convert Disk information
///
@@ -881,32 +806,6 @@ namespace SabreTools.DatFiles
}
}
- ///
- /// Convert DiskArea information
- ///
- /// Array of internal items to convert
- /// Machine to use with the converted items
- /// Name of the file to be parsed
- /// Index ID for the DAT
- /// True to only add item statistics while parsing, false otherwise
- private void ProcessItems(Models.Metadata.DiskArea[]? items, DatItems.Machine machine, string filename, int indexId, bool statsOnly)
- {
- // If the array is null or empty, return without processing
- if (items == null || items.Length == 0)
- return;
-
- // TODO: Extract Disks
-
- // Loop through the items and add
- foreach (var item in items)
- {
- var datItem = new DatItems.Formats.DiskArea(item);
- datItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
- datItem.CopyMachineInformation(machine);
- ParseAddHelper(datItem, statsOnly);
- }
- }
-
///
/// Convert Display information
///
@@ -1147,17 +1046,81 @@ namespace SabreTools.DatFiles
if (items == null || items.Length == 0)
return;
- // TODO: Extract DataAreas
- // TODO: Extract DiskAreas
- // TODO: Extract DipSwitches
-
// Loop through the items and add
foreach (var item in items)
{
- var datItem = new DatItems.Formats.Part(item);
- datItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
- datItem.CopyMachineInformation(machine);
- ParseAddHelper(datItem, statsOnly);
+ var partItem = new DatItems.Formats.Part(item);
+
+ // Handle subitems
+ var dataAreas = ReadItemArray(item, Models.Metadata.Part.DataAreaKey);
+ if (dataAreas != null)
+ {
+ foreach (var dataArea in dataAreas)
+ {
+ var dataAreaItem = new DatItems.Formats.DataArea(dataArea);
+ var roms = ReadItemArray(dataArea, Models.Metadata.DataArea.RomKey);
+ if (roms == null)
+ continue;
+
+ foreach (var rom in roms)
+ {
+ var romItem = new DatItems.Formats.Rom(rom);
+ romItem.SetFieldValue(DatItems.Formats.Rom.DataAreaKey, dataAreaItem);
+ romItem.SetFieldValue(DatItems.Formats.Rom.PartKey, partItem);
+ romItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
+ romItem.CopyMachineInformation(machine);
+ ParseAddHelper(romItem, statsOnly);
+ }
+ }
+ }
+
+ var diskAreas = ReadItemArray(item, Models.Metadata.Part.DiskAreaKey);
+ if (diskAreas != null)
+ {
+ foreach (var diskArea in diskAreas)
+ {
+ var diskAreaitem = new DatItems.Formats.DiskArea(diskArea);
+ var disks = ReadItemArray(diskArea, Models.Metadata.DiskArea.DiskKey);
+ if (disks == null)
+ continue;
+
+ foreach (var disk in disks)
+ {
+ var diskItem = new DatItems.Formats.Disk(disk);
+ diskItem.SetFieldValue(DatItems.Formats.Disk.DiskAreaKey, diskAreaitem);
+ diskItem.SetFieldValue(DatItems.Formats.Disk.PartKey, partItem);
+ diskItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
+ diskItem.CopyMachineInformation(machine);
+ ParseAddHelper(diskItem, statsOnly);
+ }
+ }
+
+ var dipSwitches = ReadItemArray(item, Models.Metadata.Part.DipSwitchKey);
+ if (dipSwitches != null)
+ {
+ foreach (var dipSwitch in dipSwitches)
+ {
+ var dipSwitchItem = new DatItems.Formats.DipSwitch(dipSwitch);
+ dipSwitchItem.SetFieldValue(DatItems.DatItem.SourceKey, new DatItems.Source { Index = indexId, Name = filename });
+ dipSwitchItem.CopyMachineInformation(machine);
+
+ var dipValues = ReadItemArray(dipSwitch, Models.Metadata.DipSwitch.DipValueKey);
+ if (dipValues != null)
+ {
+ var subValues = new List();
+ foreach (var value in dipValues)
+ {
+ var subItem = new DatItems.Formats.DipValue(value);
+ subValues.Add(subItem);
+ }
+
+ dipSwitchItem.SetFieldValue(Models.Metadata.DipSwitch.DipValueKey, [.. subValues]);
+ }
+
+ ParseAddHelper(dipSwitchItem, statsOnly);
+ }
+ }
+ }
}
}
diff --git a/SabreTools.DatFiles/Formats/SoftwareList.Reader.cs b/SabreTools.DatFiles/Formats/SoftwareList.Reader.cs
index ad39518a..fa8fa8b5 100644
--- a/SabreTools.DatFiles/Formats/SoftwareList.Reader.cs
+++ b/SabreTools.DatFiles/Formats/SoftwareList.Reader.cs
@@ -1,10 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using SabreTools.Core;
-using SabreTools.Core.Tools;
-using SabreTools.DatItems;
-using SabreTools.DatItems.Formats;
namespace SabreTools.DatFiles.Formats
{
@@ -20,12 +14,10 @@ namespace SabreTools.DatFiles.Formats
{
// Deserialize the input file
var softwarelist = new Serialization.Files.SoftwareList().Deserialize(filename);
+ var metadata = new Serialization.CrossModel.SoftwareList().Serialize(softwarelist);
- // Convert the header to the internal format
- ConvertHeader(softwarelist, keep);
-
- // Convert the software data to the internal format
- ConvertSoftware(softwarelist?.Software, filename, indexId, statsOnly);
+ // Convert to the internal format
+ ConvertMetadata(metadata, filename, indexId, keep, statsOnly);
}
catch (Exception ex) when (!throwOnError)
{
@@ -33,369 +25,5 @@ namespace SabreTools.DatFiles.Formats
logger.Error(ex, message);
}
}
-
- #region Converters
-
- ///
- /// Convert header information
- ///
- /// Deserialized model to convert
- /// True if full pathnames are to be kept, false otherwise (default)
- private void ConvertHeader(Models.SoftwareList.SoftwareList? softwarelist, bool keep)
- {
- // If the datafile is missing, we can't do anything
- if (softwarelist == null)
- return;
-
- if (Header.GetFieldValue(Models.Metadata.Header.NameKey) == null)
- Header.SetFieldValue(Models.Metadata.Header.NameKey, softwarelist.Name);
- if (Header.GetFieldValue(Models.Metadata.Header.DescriptionKey) == null)
- Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, softwarelist.Description);
- if (Header.GetFieldValue(Models.Metadata.Header.CommentKey) == null)
- Header.SetFieldValue(Models.Metadata.Header.CommentKey, softwarelist.Notes);
-
- // Handle implied SuperDAT
- if (Header.GetFieldValue(Models.Metadata.Header.NameKey)?.Contains(" - SuperDAT") == true && keep)
- {
- if (Header.GetFieldValue(Models.Metadata.Header.TypeKey) == null)
- Header.SetFieldValue(Models.Metadata.Header.TypeKey, "SuperDAT");
- }
- }
-
- ///
- /// Convert software 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 ConvertSoftware(Models.SoftwareList.Software[]? software, string filename, int indexId, bool statsOnly)
- {
- // If the game array is missing, we can't do anything
- if (software == null || !software.Any())
- return;
-
- // Loop through the software and add
- foreach (var sw in software)
- {
- ConvertSoftware(sw, 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.SoftwareList.Software software, string filename, int indexId, bool statsOnly)
- {
- // If the game 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.CloneOfKey, software.CloneOf);
- machine.SetFieldValue(Models.Metadata.Machine.CommentKey, software.Notes);
- machine.SetFieldValue(Models.Metadata.Machine.DescriptionKey, software.Description);
- machine.SetFieldValue(Models.Metadata.Machine.NameKey, software.Name);
- machine.SetFieldValue(Models.Metadata.Machine.PublisherKey, software.Publisher);
- machine.SetFieldValue(Models.Metadata.Machine.SupportedKey, software.Supported.AsEnumValue());
- machine.SetFieldValue(Models.Metadata.Machine.YearKey, software.Year);
-
- // Add all Info objects
- foreach (var info in software.Info ?? [])
- {
- var infoItem = new Info();
- infoItem.SetName(info.Name);
- infoItem.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- infoItem.SetFieldValue(Models.Metadata.Info.ValueKey, info.Value);
-
- infoItem.CopyMachineInformation(machine);
- ParseAddHelper(infoItem, statsOnly);
- }
-
- // Add all SharedFeat objects
- foreach (var sharedfeat in software.SharedFeat ?? [])
- {
- var sharedfeatItem = new SharedFeat();
- sharedfeatItem.SetName(sharedfeat.Name);
- sharedfeatItem.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- sharedfeatItem.SetFieldValue(Models.Metadata.SharedFeat.ValueKey, sharedfeat.Value);
-
- sharedfeatItem.CopyMachineInformation(machine);
- ParseAddHelper(sharedfeatItem, statsOnly);
- }
-
- // Check if there are any items
- bool containsItems = false;
-
- // Loop through each type of item
- ConvertPart(software.Part, 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 Part 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 ConvertPart(Models.SoftwareList.Part[]? parts, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
- {
- // If the parts array is missing, we can't do anything
- if (parts == null || !parts.Any())
- return;
-
- foreach (var part in parts)
- {
- var item = new Part();
- item.SetName(part.Name);
- item.SetFieldValue(Models.Metadata.Part.InterfaceKey, part.Interface);
- item.SetFieldValue(Models.Metadata.Part.FeatureKey, CreateFeatures(part.Feature, machine, filename, indexId, statsOnly));
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
-
- item.CopyMachineInformation(machine);
-
- ConvertDataArea(part.DataArea, item, machine, filename, indexId, statsOnly, ref containsItems);
- ConvertDiskArea(part.DiskArea, item, machine, filename, indexId, statsOnly, ref containsItems);
- ConvertDipSwitch(part.DipSwitch, item, machine, filename, indexId, statsOnly, ref containsItems);
- }
- }
-
- ///
- /// Convert Feature 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
- private static PartFeature[]? CreateFeatures(Models.SoftwareList.Feature[]? features, Machine machine, string filename, int indexId, bool statsOnly)
- {
- // If the feature array is missing, we can't do anything
- if (features == null || !features.Any())
- return null;
-
- var partFeatures = new List();
- foreach (var feature in features)
- {
- var item = new PartFeature();
- item.SetName(feature.Name);
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- item.SetFieldValue(Models.Metadata.Feature.ValueKey, feature.Value);
-
- item.CopyMachineInformation(machine);
- partFeatures.Add(item);
- }
-
- return [.. partFeatures];
- }
-
- ///
- /// Convert DataArea information
- ///
- /// Array of deserialized models to convert
- /// Parent Part to use
- /// 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 ConvertDataArea(Models.SoftwareList.DataArea[]? dataareas, Part part, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
- {
- // If the dataarea array is missing, we can't do anything
- if (dataareas == null || !dataareas.Any())
- return;
-
- foreach (var dataarea in dataareas)
- {
- var item = new DataArea();
- item.SetName(dataarea.Name);
- item.SetFieldValue(Models.Metadata.DataArea.EndiannessKey, dataarea.Endianness.AsEnumValue());
- item.SetFieldValue(Models.Metadata.DataArea.SizeKey, NumberHelper.ConvertToInt64(dataarea.Size));
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- item.SetFieldValue(Models.Metadata.DataArea.WidthKey, NumberHelper.ConvertToInt64(dataarea.Width));
-
- item.CopyMachineInformation(machine);
- ConvertRoms(dataarea.Rom, part, item, machine, filename, indexId, statsOnly, ref containsItems);
- }
- }
-
- ///
- /// Convert Rom information
- ///
- /// Array of deserialized models to convert
- /// Parent Part to use
- /// Parent DataArea to use
- /// 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 ConvertRoms(Models.SoftwareList.Rom[]? roms, Part part, DataArea dataarea, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
- {
- // If the rom array is missing, we can't do anything
- if (roms == null || !roms.Any())
- return;
-
- containsItems = true;
- foreach (var rom in roms)
- {
- var item = new Rom();
- item.SetName(rom.Name);
- item.SetFieldValue(Models.Metadata.Rom.CRCKey, rom.CRC);
- item.SetFieldValue(Rom.DataAreaKey, dataarea);
- item.SetFieldValue(Models.Metadata.Rom.LoadFlagKey, rom.LoadFlag.AsEnumValue());
- item.SetFieldValue(Models.Metadata.Rom.OffsetKey, rom.Offset);
- item.SetFieldValue(Rom.PartKey, part);
- item.SetFieldValue(Models.Metadata.Rom.SHA1Key, rom.SHA1);
- item.SetFieldValue(Models.Metadata.Rom.SizeKey, NumberHelper.ConvertToInt64(rom.Size ?? rom.Length));
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- item.SetFieldValue(Models.Metadata.Rom.StatusKey, rom.Status.AsEnumValue());
- item.SetFieldValue(Models.Metadata.Rom.ValueKey, rom.Value);
-
- item.CopyMachineInformation(machine);
- ParseAddHelper(item, statsOnly);
- }
- }
-
- ///
- /// Convert DiskArea information
- ///
- /// Array of deserialized models to convert
- /// Parent Part to use
- /// 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 ConvertDiskArea(Models.SoftwareList.DiskArea[]? diskareas, Part part, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
- {
- // If the diskarea array is missing, we can't do anything
- if (diskareas == null || !diskareas.Any())
- return;
-
- foreach (var diskarea in diskareas)
- {
- var item = new DiskArea();
- item.SetName(diskarea.Name);
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
-
- item.CopyMachineInformation(machine);
- ConvertDisks(diskarea.Disk, part, item, machine, filename, indexId, statsOnly, ref containsItems);
- }
- }
-
- ///
- /// Convert Disk information
- ///
- /// Array of deserialized models to convert
- /// Parent Part to use
- /// Parent DiskArea to use
- /// 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 ConvertDisks(Models.SoftwareList.Disk[]? disks, Part part, DiskArea diskarea, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
- {
- // If the rom array is missing, we can't do anything
- if (disks == null || !disks.Any())
- return;
-
- containsItems = true;
- foreach (var disk in disks)
- {
- var item = new Disk();
- item.SetName(disk.Name);
- item.SetFieldValue(Disk.DiskAreaKey, diskarea);
- item.SetFieldValue(Models.Metadata.Disk.StatusKey, disk.Status?.AsEnumValue() ?? ItemStatus.NULL);
- item.SetFieldValue(Models.Metadata.Disk.MD5Key, disk.MD5);
- item.SetFieldValue(Disk.PartKey, part);
- item.SetFieldValue(Models.Metadata.Disk.SHA1Key, disk.SHA1);
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- item.SetFieldValue(Models.Metadata.Disk.WritableKey, disk.Writeable.AsYesNo());
-
- item.CopyMachineInformation(machine);
- ParseAddHelper(item, statsOnly);
- }
- }
-
- ///
- /// Convert DipSwitch information
- ///
- /// Array of deserialized models to convert
- /// Parent Part to use
- /// 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 ConvertDipSwitch(Models.SoftwareList.DipSwitch[]? dipswitches, Part part, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
- {
- // If the dipswitch array is missing, we can't do anything
- if (dipswitches == null || !dipswitches.Any())
- return;
-
- foreach (var dipswitch in dipswitches)
- {
- var item = new DipSwitch();
- item.SetName(dipswitch.Name);
- item.SetFieldValue(Models.Metadata.DipSwitch.DipValueKey, CreateDipValues(dipswitch.DipValue, machine, filename, indexId)?.ToArray());
- item.SetFieldValue(DipSwitch.PartKey, part);
- item.SetFieldValue(Models.Metadata.DipSwitch.MaskKey, dipswitch.Mask);
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- item.SetFieldValue(Models.Metadata.DipSwitch.TagKey, dipswitch.Tag);
-
- item.CopyMachineInformation(machine);
- ParseAddHelper(item, statsOnly);
- }
- }
-
- ///
- /// Convert DipValue information
- ///
- /// Array of deserialized models to convert
- /// Prefilled machine to use
- /// Name of the file to be parsed
- /// Index ID for the DAT
- private static List? CreateDipValues(Models.SoftwareList.DipValue[]? dipvalues, Machine machine, string filename, int indexId)
- {
- // If the feature array is missing, we can't do anything
- if (dipvalues == null || !dipvalues.Any())
- return null;
-
- var settings = new List();
- foreach (var dipvalue in dipvalues)
- {
- var item = new DipValue();
- item.SetName(dipvalue.Name);
- item.SetFieldValue(Models.Metadata.DipValue.DefaultKey, dipvalue.Default.AsYesNo());
- item.SetFieldValue(DatItem.SourceKey, new Source { Index = indexId, Name = filename });
- item.SetFieldValue(Models.Metadata.DipValue.ValueKey, dipvalue.Value);
-
- item.CopyMachineInformation(machine);
- settings.Add(item);
- }
-
- return settings;
- }
-
- #endregion
}
}