From e90074f6115447deeef98ef8b7352e147ef61124 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 9 Sep 2023 01:12:21 -0400 Subject: [PATCH] Add and convert OpenMSX --- CrossModel/OpenMSX.Deserializer.cs | 156 +++++++++++++++++++++++++++++ CrossModel/OpenMSX.Serializer.cs | 131 ++++++++++++++++++++++++ Files/OpenMSX.Deserializer.cs | 7 ++ Files/OpenMSX.Serializer.cs | 11 ++ OpenMSX.cs | 36 +++++++ Streams/OpenMSX.Deserializer.cs | 7 ++ Streams/OpenMSX.Serializer.cs | 16 +++ 7 files changed, 364 insertions(+) create mode 100644 CrossModel/OpenMSX.Deserializer.cs create mode 100644 CrossModel/OpenMSX.Serializer.cs create mode 100644 Files/OpenMSX.Deserializer.cs create mode 100644 Files/OpenMSX.Serializer.cs create mode 100644 OpenMSX.cs create mode 100644 Streams/OpenMSX.Deserializer.cs create mode 100644 Streams/OpenMSX.Serializer.cs diff --git a/CrossModel/OpenMSX.Deserializer.cs b/CrossModel/OpenMSX.Deserializer.cs new file mode 100644 index 00000000..4b86d15f --- /dev/null +++ b/CrossModel/OpenMSX.Deserializer.cs @@ -0,0 +1,156 @@ +using System.Linq; +using SabreTools.Models.OpenMSX; + +namespace SabreTools.Serialization.CrossModel +{ + public partial class OpenMSX : IModelSerializer + { + /// +#if NET48 + public SoftwareDb Deserialize(Models.Metadata.MetadataFile obj) +#else + public SoftwareDb? Deserialize(Models.Metadata.MetadataFile? obj) +#endif + { + if (obj == null) + return null; + + var header = obj.Read(Models.Metadata.MetadataFile.HeaderKey); + var softwareDb = header != null ? ConvertHeaderFromInternalModel(header) : new SoftwareDb(); + + var machines = obj.Read(Models.Metadata.MetadataFile.MachineKey); + if (machines != null && machines.Any()) + { + softwareDb.Software = machines + .Where(m => m != null) + .Select(ConvertMachineFromInternalModel) + .ToArray(); + } + + return softwareDb; + } + + /// + /// Convert from to + /// + private static SoftwareDb ConvertHeaderFromInternalModel(Models.Metadata.Header item) + { + var softwareDb = new SoftwareDb + { + Timestamp = item.ReadString(Models.Metadata.Header.TimestampKey), + }; + return softwareDb; + } + + /// + /// Convert from to + /// + private static Software ConvertMachineFromInternalModel(Models.Metadata.Machine item) + { + var game = new Software + { + Title = item.ReadString(Models.Metadata.Machine.NameKey), + GenMSXID = item.ReadString(Models.Metadata.Machine.GenMSXIDKey), + System = item.ReadString(Models.Metadata.Machine.SystemKey), + Company = item.ReadString(Models.Metadata.Machine.CompanyKey), + Year = item.ReadString(Models.Metadata.Machine.YearKey), + Country = item.ReadString(Models.Metadata.Machine.CountryKey), + }; + + var dumps = item.Read(Models.Metadata.Machine.DumpKey); + if (dumps != null && dumps.Any()) + { + game.Dump = dumps + .Where(d => d != null) + .Select(ConvertFromInternalModel) + .ToArray(); + } + + return game; + } + + /// + /// Convert from to + /// + private static Dump ConvertFromInternalModel(Models.Metadata.Dump item) + { + var dump = new Dump(); + + var original = item.Read(Models.Metadata.Dump.OriginalKey); + if (original != null) + dump.Original = ConvertFromInternalModel(original); + + var rom = item.Read(Models.Metadata.Dump.RomKey); + if (rom != null) + dump.Rom = ConvertRomFromInternalModel(rom); + + var megaRom = item.Read(Models.Metadata.Dump.MegaRomKey); + if (megaRom != null) + dump.Rom = ConvertMegaRomFromInternalModel(megaRom); + + var sccPlusCart = item.Read(Models.Metadata.Dump.SCCPlusCartKey); + if (sccPlusCart != null) + dump.Rom = ConvertSCCPlusCartFromInternalModel(sccPlusCart); + + return dump; + } + + /// + /// Convert from to + /// + private static MegaRom ConvertMegaRomFromInternalModel(Models.Metadata.Rom item) + { + var megaRom = new MegaRom + { + Start = item.ReadString(Models.Metadata.Rom.StartKey), + Type = item.ReadString(Models.Metadata.Rom.TypeKey), + Hash = item.ReadString(Models.Metadata.Rom.SHA1Key), + Remark = item.ReadString(Models.Metadata.Rom.RemarkKey), + }; + return megaRom; + } + + /// + /// Convert from to + /// + private static Original ConvertFromInternalModel(Models.Metadata.Original item) + { + var original = new Original + { + Value = item.ReadString(Models.Metadata.Original.ValueKey), + Content = item.ReadString(Models.Metadata.Original.ContentKey), + }; + return original; + } + + /// + /// Convert from to + /// + private static Rom ConvertRomFromInternalModel(Models.Metadata.Rom item) + { + var rom = new Rom + { + Start = item.ReadString(Models.Metadata.Rom.StartKey), + Type = item.ReadString(Models.Metadata.Rom.TypeKey), + Hash = item.ReadString(Models.Metadata.Rom.SHA1Key), + Remark = item.ReadString(Models.Metadata.Rom.RemarkKey), + }; + return rom; + } + + /// + /// Convert from to + /// + private static SCCPlusCart ConvertSCCPlusCartFromInternalModel(Models.Metadata.Rom item) + { + var sccPlusCart = new SCCPlusCart + { + Start = item.ReadString(Models.Metadata.Rom.StartKey), + Type = item.ReadString(Models.Metadata.Rom.TypeKey), + Hash = item.ReadString(Models.Metadata.Rom.SHA1Key), + Remark = item.ReadString(Models.Metadata.Rom.RemarkKey), + }; + return sccPlusCart; + } + } +} \ No newline at end of file diff --git a/CrossModel/OpenMSX.Serializer.cs b/CrossModel/OpenMSX.Serializer.cs new file mode 100644 index 00000000..e54a9fac --- /dev/null +++ b/CrossModel/OpenMSX.Serializer.cs @@ -0,0 +1,131 @@ +using System.Linq; +using SabreTools.Models.OpenMSX; + +namespace SabreTools.Serialization.CrossModel +{ + public partial class OpenMSX : IModelSerializer + { + /// +#if NET48 + public Models.Metadata.MetadataFile Serialize(SoftwareDb item) +#else + public Models.Metadata.MetadataFile? Serialize(SoftwareDb? 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 + /// + public static Models.Metadata.Header ConvertHeaderToInternalModel(SoftwareDb item) + { + var header = new Models.Metadata.Header + { + [Models.Metadata.Header.TimestampKey] = item.Timestamp, + }; + return header; + } + + /// + /// Convert from to + /// + public static Models.Metadata.Machine ConvertMachineToInternalModel(Software item) + { + var machine = new Models.Metadata.Machine + { + [Models.Metadata.Machine.NameKey] = item.Title, + [Models.Metadata.Machine.GenMSXIDKey] = item.GenMSXID, + [Models.Metadata.Machine.SystemKey] = item.System, + [Models.Metadata.Machine.CompanyKey] = item.Company, + [Models.Metadata.Machine.YearKey] = item.Year, + [Models.Metadata.Machine.CountryKey] = item.Country, + }; + + if (item.Dump != null && item.Dump.Any()) + { + machine[Models.Metadata.Machine.DumpKey] = item.Dump + .Where(d => d != null) + .Select(ConvertToInternalModel) + .ToArray(); + } + + return machine; + } + + /// + /// Convert from to + /// + public static Models.Metadata.Dump ConvertToInternalModel(Dump item) + { + var dump = new Models.Metadata.Dump(); + + if (item.Original != null) + dump[Models.Metadata.Dump.OriginalKey] = ConvertToInternalModel(item.Original); + + if (item.Rom != null) + { + switch (item.Rom) + { + case Rom rom: + dump[Models.Metadata.Dump.RomKey] = ConvertToInternalModel(rom); + break; + + case MegaRom megaRom: + dump[Models.Metadata.Dump.MegaRomKey] = ConvertToInternalModel(megaRom); + break; + + case SCCPlusCart sccPlusCart: + dump[Models.Metadata.Dump.SCCPlusCartKey] = ConvertToInternalModel(sccPlusCart); + break; + } + } + + return dump; + } + + /// + /// Convert from to + /// + public static Models.Metadata.Original ConvertToInternalModel(Original item) + { + var original = new Models.Metadata.Original + { + [Models.Metadata.Original.ValueKey] = item.Value, + [Models.Metadata.Original.ContentKey] = item.Content, + }; + return original; + } + + /// + /// Convert from to + /// + public static Models.Metadata.Rom ConvertToInternalModel(RomBase item) + { + var rom = new Models.Metadata.Rom + { + [Models.Metadata.Rom.StartKey] = item.Start, + [Models.Metadata.Rom.TypeKey] = item.Type, + [Models.Metadata.Rom.SHA1Key] = item.Hash, + [Models.Metadata.Rom.RemarkKey] = item.Remark, + }; + return rom; + } + } +} \ No newline at end of file diff --git a/Files/OpenMSX.Deserializer.cs b/Files/OpenMSX.Deserializer.cs new file mode 100644 index 00000000..4a553a31 --- /dev/null +++ b/Files/OpenMSX.Deserializer.cs @@ -0,0 +1,7 @@ +namespace SabreTools.Serialization.Files +{ + public partial class OpenMSX : XmlFile + { + // All serialization logic is in the base class + } +} \ No newline at end of file diff --git a/Files/OpenMSX.Serializer.cs b/Files/OpenMSX.Serializer.cs new file mode 100644 index 00000000..44c6ec66 --- /dev/null +++ b/Files/OpenMSX.Serializer.cs @@ -0,0 +1,11 @@ +using SabreTools.Models.OpenMSX; + +namespace SabreTools.Serialization.Files +{ + public partial class OpenMSX : XmlFile + { + /// + public bool SerializeToFileWithDocType(SoftwareDb obj, string path) + => Serialize(obj, path, Serialization.OpenMSX.DocTypeName, Serialization.OpenMSX.DocTypePubId, Serialization.OpenMSX.DocTypeSysId, Serialization.OpenMSX.DocTypeSysId); + } +} \ No newline at end of file diff --git a/OpenMSX.cs b/OpenMSX.cs new file mode 100644 index 00000000..94b819d4 --- /dev/null +++ b/OpenMSX.cs @@ -0,0 +1,36 @@ +namespace SabreTools.Serialization +{ + /// + /// XML deserializer for OpenMSX software database files + /// + public static class OpenMSX + { + /// + /// name field for DOCTYPE + /// + public const string DocTypeName = "softwaredb"; + + /// + /// 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 = "softwaredb1.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/OpenMSX.Deserializer.cs b/Streams/OpenMSX.Deserializer.cs new file mode 100644 index 00000000..fcdba79e --- /dev/null +++ b/Streams/OpenMSX.Deserializer.cs @@ -0,0 +1,7 @@ +namespace SabreTools.Serialization.Streams +{ + public partial class OpenMSX : XmlFile + { + // All serialization logic is in the base class + } +} \ No newline at end of file diff --git a/Streams/OpenMSX.Serializer.cs b/Streams/OpenMSX.Serializer.cs new file mode 100644 index 00000000..ee29a588 --- /dev/null +++ b/Streams/OpenMSX.Serializer.cs @@ -0,0 +1,16 @@ +using System.IO; +using SabreTools.Models.OpenMSX; + +namespace SabreTools.Serialization.Streams +{ + public partial class OpenMSX : XmlFile + { + /// +#if NET48 + public Stream SerializeToStreamWithDocType(SoftwareDb obj, string path) +#else + public Stream? SerializeToStreamWithDocType(SoftwareDb? obj, string path) +#endif + => Serialize(obj, Serialization.OpenMSX.DocTypeName, Serialization.OpenMSX.DocTypePubId, Serialization.OpenMSX.DocTypeSysId, Serialization.OpenMSX.DocTypeSysId); + } +} \ No newline at end of file