using System.IO; using System.Text; using System.Xml; using SabreTools.Data.Models.OpenMSX; using SabreTools.IO.Extensions; using SabreTools.Text.Extensions; namespace SabreTools.Serialization.Writers { public class OpenMSX : BaseBinaryWriter { #region Constants /// /// name field for DOCTYPE /// public const string DocTypeName = "softwaredb"; /// /// pubid field for DOCTYPE /// public const string? DocTypePubId = null; /// /// sysid field for DOCTYPE /// public const string DocTypeSysId = "softwaredb1.dtd"; /// /// subset field for DOCTYPE /// public const string? DocTypeSubset = null; #endregion /// public override Stream? SerializeStream(SoftwareDb? obj) { // If the metadata file is null if (obj is null) return null; // Setup the writer and output var stream = new MemoryStream(); var writer = new XmlTextWriter(stream, Encoding.UTF8) { Formatting = Formatting.Indented, IndentChar = '\t', Indentation = 1 }; writer.Settings?.CheckCharacters = false; writer.Settings?.NewLineChars = "\n"; // Write document start writer.WriteStartDocument(); // Write document type writer.WriteDocType(DocTypeName, DocTypePubId, DocTypeSysId, DocTypeSubset); // Write the SoftwareDb, if it exists WriteSoftwareDb(obj, writer); writer.Flush(); // Return the stream stream.SeekIfPossible(0, SeekOrigin.Begin); return stream; } /// /// Write a SoftwareDb to an XmlTextWriter /// /// SoftwareDb to write /// XmlTextReader to write to private static void WriteSoftwareDb(SoftwareDb obj, XmlTextWriter writer) { writer.WriteStartElement("softwaredb"); writer.WriteOptionalAttributeString("timestamp", obj.Timestamp); if (obj.Software is not null && obj.Software.Length > 0) { foreach (var software in obj.Software) { WriteSoftware(software, writer); } } writer.WriteEndElement(); } /// /// Write a Dump to an XmlTextWriter /// /// Dump to write /// XmlTextReader to write to private static void WriteDump(Dump obj, XmlTextWriter writer) { writer.WriteStartElement("dump"); if (obj.Original is not null) WriteOriginal(obj.Original, writer); writer.WriteOptionalElementString("boot", obj.Boot); if (obj.Rom is not null) WriteRomBase(obj.Rom, writer); writer.WriteEndElement(); } /// /// Write a Original to an XmlTextWriter /// /// Original to write /// XmlTextReader to write to private static void WriteOriginal(Original obj, XmlTextWriter writer) { writer.WriteStartElement("original"); writer.WriteOptionalAttributeString("value", obj.Value?.ToString().ToLowerInvariant()); if (obj.Content is not null) writer.WriteRaw(obj.Content); writer.WriteEndElement(); } /// /// Write a RomBase to an XmlTextWriter /// /// RomBase to write /// XmlTextReader to write to private static void WriteRomBase(RomBase obj, XmlTextWriter writer) { if (obj is MegaRom) writer.WriteStartElement("megarom"); else if (obj is Rom) writer.WriteStartElement("rom"); else if (obj is SCCPlusCart) writer.WriteStartElement("sccpluscart"); else return; writer.WriteOptionalElementString("start", obj.Start); writer.WriteOptionalElementString("type", obj.Type); writer.WriteOptionalElementString("hash", obj.Hash); writer.WriteOptionalElementString("remark", obj.Remark); writer.WriteEndElement(); } /// /// Write a Software to an XmlTextWriter /// /// Software to write /// XmlTextReader to write to private static void WriteSoftware(Software obj, XmlTextWriter writer) { writer.WriteStartElement("software"); writer.WriteRequiredElementString("title", obj.Title); writer.WriteOptionalElementString("genmsxid", obj.GenMSXID); writer.WriteRequiredElementString("system", obj.System); writer.WriteRequiredElementString("company", obj.Company); writer.WriteRequiredElementString("year", obj.Year); writer.WriteRequiredElementString("country", obj.Country); if (obj.Dump is not null && obj.Dump.Length > 0) { foreach (var dump in obj.Dump) { WriteDump(dump, writer); } } writer.WriteEndElement(); } } }