diff --git a/CrossModel/SoftwareList.Deserializer.cs b/CrossModel/SoftwareList.Deserializer.cs new file mode 100644 index 00000000..c79ade96 --- /dev/null +++ b/CrossModel/SoftwareList.Deserializer.cs @@ -0,0 +1,303 @@ +using System.Linq; +using SabreTools.Models.SoftwareList; + +namespace SabreTools.Serialization.CrossModel +{ + public partial class SoftwareList : IModelSerializer + { + /// +#if NET48 + public Models.SoftwareList.SoftwareList Deserialize(Models.Metadata.MetadataFile obj) +#else + public Models.SoftwareList.SoftwareList? Deserialize(Models.Metadata.MetadataFile? obj) +#endif + { + if (obj == null) + return null; + + var header = obj.Read(Models.Metadata.MetadataFile.HeaderKey); + var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new Models.SoftwareList.SoftwareList(); + + var machines = obj.Read(Models.Metadata.MetadataFile.MachineKey); + if (machines != null && machines.Any()) + { + metadataFile.Software = machines + .Where(m => m != null) + .Select(ConvertMachineFromInternalModel) + .ToArray(); + } + + return metadataFile; + } + + /// + /// Convert from to + /// + private static Models.SoftwareList.SoftwareList ConvertHeaderFromInternalModel(Models.Metadata.Header item) + { + var softwareList = new Models.SoftwareList.SoftwareList + { + Name = item.ReadString(Models.Metadata.Header.NameKey), + Description = item.ReadString(Models.Metadata.Header.DescriptionKey), + Notes = item.ReadString(Models.Metadata.Header.NotesKey), + }; + return softwareList; + } + + /// + /// Convert from to + /// + private static Software ConvertMachineFromInternalModel(Models.Metadata.Machine item) + { + var software = new Software + { + Name = item.ReadString(Models.Metadata.Machine.NameKey), + CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey), + Supported = item.ReadString(Models.Metadata.Machine.SupportedKey), + Description = item.ReadString(Models.Metadata.Machine.DescriptionKey), + Year = item.ReadString(Models.Metadata.Machine.YearKey), + Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey), + Notes = item.ReadString(Models.Metadata.Machine.NotesKey), + }; + + var infos = item.Read(Models.Metadata.Machine.InfoKey); + if (infos != null && infos.Any()) + { + software.Info = infos + .Where(i => i != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + var sharedFeats = item.Read(Models.Metadata.Machine.SharedFeatKey); + if (sharedFeats != null && sharedFeats.Any()) + { + software.SharedFeat = sharedFeats + .Where(s => s != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + var parts = item.Read(Models.Metadata.Machine.PartKey); + if (parts != null && parts.Any()) + { + software.Part = parts + .Where(p => p != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + return software; + } + + /// + /// Convert from to + /// + private static DataArea ConvertFromInternalModel(Models.Metadata.DataArea item) + { + var dataArea = new DataArea + { + Name = item.ReadString(Models.Metadata.DataArea.NameKey), + Size = item.ReadString(Models.Metadata.DataArea.SizeKey), + Width = item.ReadString(Models.Metadata.DataArea.WidthKey), + Endianness = item.ReadString(Models.Metadata.DataArea.EndiannessKey), + }; + + var roms = item.Read(Models.Metadata.DataArea.RomKey); + if (roms != null && roms.Any()) + { + dataArea.Rom = roms + .Where(r => r != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + return dataArea; + } + + /// + /// Convert from to + /// + private static DipSwitch ConvertFromInternalModel(Models.Metadata.DipSwitch item) + { + var dipSwitch = new DipSwitch + { + Name = item.ReadString(Models.Metadata.DipSwitch.NameKey), + Tag = item.ReadString(Models.Metadata.DipSwitch.TagKey), + Mask = item.ReadString(Models.Metadata.DipSwitch.MaskKey), + }; + + var dipValues = item.Read(Models.Metadata.DipSwitch.DipValueKey); + if (dipValues != null && dipValues.Any()) + { + dipSwitch.DipValue = dipValues + .Where(d => d != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + return dipSwitch; + } + + /// + /// Convert from to + /// + private static DipValue ConvertFromInternalModel(Models.Metadata.DipValue item) + { + var dipValue = new DipValue + { + Name = item.ReadString(Models.Metadata.DipValue.NameKey), + Value = item.ReadString(Models.Metadata.DipValue.ValueKey), + Default = item.ReadString(Models.Metadata.DipValue.DefaultKey), + }; + return dipValue; + } + + /// + /// Convert from to + /// + private static Disk ConvertFromInternalModel(Models.Metadata.Disk item) + { + var disk = new Disk + { + Name = item.ReadString(Models.Metadata.Disk.NameKey), + MD5 = item.ReadString(Models.Metadata.Disk.MD5Key), + SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key), + Status = item.ReadString(Models.Metadata.Disk.StatusKey), + Writeable = item.ReadString(Models.Metadata.Disk.WritableKey), + }; + return disk; + } + + /// + /// Convert from to + /// + private static DiskArea ConvertFromInternalModel(Models.Metadata.DiskArea item) + { + var diskArea = new DiskArea + { + Name = item.ReadString(Models.Metadata.DiskArea.NameKey), + }; + + var disks = item.Read(Models.Metadata.DiskArea.DiskKey); + if (disks != null && disks.Any()) + { + diskArea.Disk = disks + .Where(d => d != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + return diskArea; + } + + /// + /// Convert from to + /// + private static Feature ConvertFromInternalModel(Models.Metadata.Feature item) + { + var feature = new Feature + { + Name = item.ReadString(Models.Metadata.Feature.NameKey), + Value = item.ReadString(Models.Metadata.Feature.ValueKey), + }; + return feature; + } + + /// + /// Convert from to + /// + private static Info ConvertFromInternalModel(Models.Metadata.Info item) + { + var info = new Info + { + Name = item.ReadString(Models.Metadata.Info.NameKey), + Value = item.ReadString(Models.Metadata.Info.ValueKey), + }; + return info; + } + + /// + /// Convert from to + /// + private static Part ConvertFromInternalModel(Models.Metadata.Part item) + { + var part = new Part + { + Name = item.ReadString(Models.Metadata.Part.NameKey), + Interface = item.ReadString(Models.Metadata.Part.InterfaceKey), + }; + + var features = item.Read(Models.Metadata.Part.FeatureKey); + if (features != null && features.Any()) + { + part.Feature = features + .Where(f => f != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + var dataAreas = item.Read(Models.Metadata.Part.DataAreaKey); + if (dataAreas != null && dataAreas.Any()) + { + part.DataArea = dataAreas + .Where(d => d != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + var diskAreas = item.Read(Models.Metadata.Part.DiskAreaKey); + if (diskAreas != null && diskAreas.Any()) + { + part.DiskArea = diskAreas + .Where(d => d != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + var dipSwitches = item.Read(Models.Metadata.Part.DipSwitchKey); + if (dipSwitches != null && dipSwitches.Any()) + { + part.DipSwitch = dipSwitches + .Where(d => d != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + return part; + } + + /// + /// Convert from to + /// + private static Rom ConvertFromInternalModel(Models.Metadata.Rom item) + { + var rom = new Rom + { + Name = item.ReadString(Models.Metadata.Rom.NameKey), + Size = item.ReadString(Models.Metadata.Rom.SizeKey), + Length = item.ReadString(Models.Metadata.Rom.LengthKey), + CRC = item.ReadString(Models.Metadata.Rom.CRCKey), + SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key), + Offset = item.ReadString(Models.Metadata.Rom.OffsetKey), + Value = item.ReadString(Models.Metadata.Rom.ValueKey), + Status = item.ReadString(Models.Metadata.Rom.StatusKey), + LoadFlag = item.ReadString(Models.Metadata.Rom.LoadFlagKey), + }; + return rom; + } + + /// + /// Convert from to + /// + private static SharedFeat ConvertFromInternalModel(Models.Metadata.SharedFeat item) + { + var sharedFeat = new SharedFeat + { + Name = item.ReadString(Models.Metadata.SharedFeat.NameKey), + Value = item.ReadString(Models.Metadata.SharedFeat.ValueKey), + }; + return sharedFeat; + } + } +} \ No newline at end of file diff --git a/CrossModel/SoftwareList.Serializer.cs b/CrossModel/SoftwareList.Serializer.cs new file mode 100644 index 00000000..67f2a574 --- /dev/null +++ b/CrossModel/SoftwareList.Serializer.cs @@ -0,0 +1,244 @@ +using System.Linq; +using SabreTools.Models.SoftwareList; + +namespace SabreTools.Serialization.CrossModel +{ + public partial class SoftwareList : IModelSerializer + { + /// +#if NET48 + public Models.Metadata.MetadataFile Serialize(Models.SoftwareList.SoftwareList item) +#else + public Models.Metadata.MetadataFile? Serialize(Models.SoftwareList.SoftwareList? item) +#endif + { + if (item == null) + return null; + + var metadataFile = new Models.Metadata.MetadataFile + { + [Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), + }; + + if (item?.Software != null && item.Software.Any()) + { + metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Software + .Where(s => s != null) + .Select(ConvertMachineToInternalModel) + .ToArray(); + } + + return metadataFile; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.SoftwareList.SoftwareList item) + { + var header = new Models.Metadata.Header + { + [Models.Metadata.Header.NameKey] = item.Name, + [Models.Metadata.Header.DescriptionKey] = item.Description, + [Models.Metadata.Header.NotesKey] = item.Notes, + }; + return header; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Machine ConvertMachineToInternalModel(Software item) + { + var machine = new Models.Metadata.Machine + { + [Models.Metadata.Machine.NameKey] = item.Name, + [Models.Metadata.Machine.CloneOfKey] = item.CloneOf, + [Models.Metadata.Machine.SupportedKey] = item.Supported, + [Models.Metadata.Machine.DescriptionKey] = item.Description, + [Models.Metadata.Machine.YearKey] = item.Year, + [Models.Metadata.Machine.PublisherKey] = item.Publisher, + [Models.Metadata.Machine.NotesKey] = item.Notes, + }; + + if (item.Info != null && item.Info.Any()) + machine[Models.Metadata.Machine.InfoKey] = item.Info.Select(ConvertToInternalModel).ToArray(); + + if (item.SharedFeat != null && item.SharedFeat.Any()) + machine[Models.Metadata.Machine.SharedFeatKey] = item.SharedFeat.Select(ConvertToInternalModel).ToArray(); + + if (item.Part != null && item.Part.Any()) + machine[Models.Metadata.Machine.PartKey] = item.Part.Select(ConvertToInternalModel).ToArray(); + + return machine; + } + + /// + /// Convert from to + /// + private static Models.Metadata.DataArea ConvertToInternalModel(DataArea item) + { + var dataArea = new Models.Metadata.DataArea + { + [Models.Metadata.DataArea.NameKey] = item.Name, + [Models.Metadata.DataArea.SizeKey] = item.Size, + [Models.Metadata.DataArea.WidthKey] = item.Width, + [Models.Metadata.DataArea.EndiannessKey] = item.Endianness, + }; + + if (item.Rom != null && item.Rom.Any()) + dataArea[Models.Metadata.DataArea.RomKey] = item.Rom.Select(ConvertToInternalModel).ToArray(); + + return dataArea; + } + + /// + /// Convert from to + /// + private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item) + { + var dipSwitch = new Models.Metadata.DipSwitch + { + [Models.Metadata.DipSwitch.NameKey] = item.Name, + [Models.Metadata.DipSwitch.TagKey] = item.Tag, + [Models.Metadata.DipSwitch.MaskKey] = item.Mask, + }; + + if (item.DipValue != null && item.DipValue.Any()) + dipSwitch[Models.Metadata.DipSwitch.DipValueKey] = item.DipValue.Select(ConvertToInternalModel).ToArray(); + + return dipSwitch; + } + + /// + /// Convert from to + /// + private static Models.Metadata.DipValue ConvertToInternalModel(DipValue item) + { + var dipValue = new Models.Metadata.DipValue + { + [Models.Metadata.DipValue.NameKey] = item.Name, + [Models.Metadata.DipValue.ValueKey] = item.Value, + [Models.Metadata.DipValue.DefaultKey] = item.Default, + }; + return dipValue; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Disk ConvertToInternalModel(Disk item) + { + var disk = new Models.Metadata.Disk + { + [Models.Metadata.Disk.NameKey] = item.Name, + [Models.Metadata.Disk.MD5Key] = item.MD5, + [Models.Metadata.Disk.SHA1Key] = item.SHA1, + [Models.Metadata.Disk.StatusKey] = item.Status, + [Models.Metadata.Disk.WritableKey] = item.Writeable, + }; + return disk; + } + + /// + /// Convert from to + /// + private static Models.Metadata.DiskArea ConvertToInternalModel(DiskArea item) + { + var diskArea = new Models.Metadata.DiskArea + { + [Models.Metadata.DiskArea.NameKey] = item.Name, + }; + + if (item.Disk != null && item.Disk.Any()) + diskArea[Models.Metadata.DiskArea.DiskKey] = item.Disk.Select(ConvertToInternalModel).ToArray(); + + return diskArea; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Feature ConvertToInternalModel(Feature item) + { + var feature = new Models.Metadata.Feature + { + [Models.Metadata.Feature.NameKey] = item.Name, + [Models.Metadata.Feature.ValueKey] = item.Value, + }; + return feature; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Info ConvertToInternalModel(Info item) + { + var info = new Models.Metadata.Info + { + [Models.Metadata.Info.NameKey] = item.Name, + [Models.Metadata.Info.ValueKey] = item.Value, + }; + return info; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Part ConvertToInternalModel(Part item) + { + var part = new Models.Metadata.Part + { + [Models.Metadata.Part.NameKey] = item.Name, + [Models.Metadata.Part.InterfaceKey] = item.Interface, + }; + + if (item.Feature != null && item.Feature.Any()) + part[Models.Metadata.Part.FeatureKey] = item.Feature.Select(ConvertToInternalModel).ToArray(); + + if (item.DataArea != null && item.DataArea.Any()) + part[Models.Metadata.Part.DataAreaKey] = item.DataArea.Select(ConvertToInternalModel).ToArray(); + + if (item.DiskArea != null && item.DiskArea.Any()) + part[Models.Metadata.Part.DiskAreaKey] = item.DiskArea.Select(ConvertToInternalModel).ToArray(); + + if (item.DipSwitch != null && item.DipSwitch.Any()) + part[Models.Metadata.Part.DipSwitchKey] = item.DipSwitch.Select(ConvertToInternalModel).ToArray(); + + return part; + } + + /// + /// Convert from to + /// + private static Models.Metadata.Rom ConvertToInternalModel(Rom item) + { + var rom = new Models.Metadata.Rom + { + [Models.Metadata.Rom.NameKey] = item.Name, + [Models.Metadata.Rom.SizeKey] = item.Size, + [Models.Metadata.Rom.LengthKey] = item.Length, + [Models.Metadata.Rom.CRCKey] = item.CRC, + [Models.Metadata.Rom.SHA1Key] = item.SHA1, + [Models.Metadata.Rom.OffsetKey] = item.Offset, + [Models.Metadata.Rom.ValueKey] = item.Value, + [Models.Metadata.Rom.StatusKey] = item.Status, + [Models.Metadata.Rom.LoadFlagKey] = item.LoadFlag, + }; + return rom; + } + + /// + /// Convert from to + /// + private static Models.Metadata.SharedFeat ConvertToInternalModel(SharedFeat item) + { + var sharedFeat = new Models.Metadata.SharedFeat + { + [Models.Metadata.SharedFeat.NameKey] = item.Name, + [Models.Metadata.SharedFeat.ValueKey] = item.Value, + }; + return sharedFeat; + } + } +} \ No newline at end of file diff --git a/Files/SoftwareList.Deserializer.cs b/Files/SoftwareList.Deserializer.cs new file mode 100644 index 00000000..42e01a9b --- /dev/null +++ b/Files/SoftwareList.Deserializer.cs @@ -0,0 +1,7 @@ +namespace SabreTools.Serialization.Files +{ + public partial class SoftwareList : XmlFile + { + // All serialization logic is in the base class + } +} \ No newline at end of file diff --git a/Files/SoftwareList.Serializer.cs b/Files/SoftwareList.Serializer.cs new file mode 100644 index 00000000..3bba5747 --- /dev/null +++ b/Files/SoftwareList.Serializer.cs @@ -0,0 +1,9 @@ +namespace SabreTools.Serialization.Files +{ + public partial class SoftwareList : XmlFile + { + /// + public bool SerializeToFileWithDocType(Models.SoftwareList.SoftwareList obj, string path) + => Serialize(obj, path, Serialization.SoftawreList.DocTypeName, Serialization.SoftawreList.DocTypePubId, Serialization.SoftawreList.DocTypeSysId, Serialization.SoftawreList.DocTypeSysId); + } +} \ No newline at end of file diff --git a/SoftwareList.cs b/SoftwareList.cs new file mode 100644 index 00000000..27924d76 --- /dev/null +++ b/SoftwareList.cs @@ -0,0 +1,36 @@ +namespace SabreTools.Serialization +{ + /// + /// XML deserializer for MAME softwarelist files + /// + public static class SoftawreList + { + /// + /// name field for DOCTYPE + /// + public const string DocTypeName = "softwarelist"; + + /// + /// pubid field for DOCTYPE + /// +#if NET48 + public const string DocTypePubId = null; +#else + public const string? DocTypePubId = null; +#endif + + /// + /// sysid field for DOCTYPE + /// + public const string DocTypeSysId = "softwarelist.dtd"; + + /// + /// subset field for DOCTYPE + /// +#if NET48 + public const string DocTypeSubset = null; +#else + public const string? DocTypeSubset = null; +#endif + } +} \ No newline at end of file diff --git a/Streams/SoftwareList.Deserializer.cs b/Streams/SoftwareList.Deserializer.cs new file mode 100644 index 00000000..9f03499c --- /dev/null +++ b/Streams/SoftwareList.Deserializer.cs @@ -0,0 +1,7 @@ +namespace SabreTools.Serialization.Streams +{ + public partial class SoftwareList : XmlFile + { + // All serialization logic is in the base class + } +} \ No newline at end of file diff --git a/Streams/SoftwareList.Serializer.cs b/Streams/SoftwareList.Serializer.cs new file mode 100644 index 00000000..2e270edb --- /dev/null +++ b/Streams/SoftwareList.Serializer.cs @@ -0,0 +1,15 @@ +using System.IO; + +namespace SabreTools.Serialization.Streams +{ + public partial class SoftwareList : XmlFile + { + /// +#if NET48 + public Stream SerializeToStreamWithDocType(Models.SoftwareList.SoftwareList obj, string path) +#else + public Stream? SerializeToStreamWithDocType(Models.SoftwareList.SoftwareList? obj, string path) +#endif + => Serialize(obj, Serialization.SoftawreList.DocTypeName, Serialization.SoftawreList.DocTypePubId, Serialization.SoftawreList.DocTypeSysId, Serialization.SoftawreList.DocTypeSysId); + } +} \ No newline at end of file