using System.IO; using System.Text; using System.Xml; using SabreTools.Data.Extensions; using SabreTools.Data.Models.SoftwareList; using SabreTools.IO.Extensions; using SabreTools.Text.Extensions; namespace SabreTools.Serialization.Writers { public class SoftwareList : BaseBinaryWriter { #region Constants /// /// name field for DOCTYPE /// public const string DocTypeName = "softwarelist"; /// /// pubid field for DOCTYPE /// public const string? DocTypePubId = null; /// /// sysid field for DOCTYPE /// public const string DocTypeSysId = "softwarelist.dtd"; /// /// subset field for DOCTYPE /// public const string? DocTypeSubset = null; #endregion /// public override Stream? SerializeStream(Data.Models.SoftwareList.SoftwareList? 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 WriteSoftwareList(obj, writer); writer.Flush(); // Return the stream stream.SeekIfPossible(0, SeekOrigin.Begin); return stream; } /// /// Write a SoftwareList to an XmlTextWriter /// /// SoftwareList to write /// XmlTextReader to write to private static void WriteSoftwareList(Data.Models.SoftwareList.SoftwareList obj, XmlTextWriter writer) { writer.WriteStartElement("softwarelist"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("description", obj.Description); writer.WriteOptionalElementString("notes", obj.Notes); if (obj.Software is not null && obj.Software.Length > 0) { foreach (var software in obj.Software) { WriteSoftware(software, writer); } } writer.WriteEndElement(); } #region Items /// /// Write a DataArea to an XmlTextWriter /// /// DataArea to write /// XmlTextReader to write to private static void WriteDataArea(DataArea obj, XmlTextWriter writer) { writer.WriteStartElement("dataarea"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteRequiredAttributeString("size", obj.Size); writer.WriteOptionalAttributeString("width", obj.Width); writer.WriteOptionalAttributeString("endianness", obj.Endianness?.AsStringValue()); if (obj.Rom is not null && obj.Rom.Length > 0) { foreach (var rom in obj.Rom) { WriteRom(rom, writer); } } writer.WriteEndElement(); } /// /// Write a DipSwitch to an XmlTextWriter /// /// DipSwitch to write /// XmlTextReader to write to private static void WriteDipSwitch(DipSwitch obj, XmlTextWriter writer) { writer.WriteStartElement("dipswitch"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteRequiredAttributeString("tag", obj.Tag); writer.WriteOptionalAttributeString("mask", obj.Mask); if (obj.DipValue is not null && obj.DipValue.Length > 0) { foreach (var dipValue in obj.DipValue) { WriteDipValue(dipValue, writer); } } writer.WriteEndElement(); } /// /// Write a DipValue to an XmlTextWriter /// /// DipValue to write /// XmlTextReader to write to private static void WriteDipValue(DipValue obj, XmlTextWriter writer) { writer.WriteStartElement("dipvalue"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteRequiredAttributeString("value", obj.Value); writer.WriteOptionalAttributeString("default", obj.Default.FromYesNo()); writer.WriteEndElement(); } /// /// Write a Disk to an XmlTextWriter /// /// Disk to write /// XmlTextReader to write to private static void WriteDisk(Disk obj, XmlTextWriter writer) { writer.WriteStartElement("disk"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("md5", obj.MD5); writer.WriteOptionalAttributeString("sha1", obj.SHA1); writer.WriteOptionalAttributeString("status", obj.Status?.AsStringValue()); writer.WriteOptionalAttributeString("writable", obj.Writeable.FromYesNo()); writer.WriteEndElement(); } /// /// Write a DiskArea to an XmlTextWriter /// /// DiskArea to write /// XmlTextReader to write to private static void WriteDiskArea(DiskArea obj, XmlTextWriter writer) { writer.WriteStartElement("diskarea"); writer.WriteRequiredAttributeString("name", obj.Name); if (obj.Disk is not null && obj.Disk.Length > 0) { foreach (var disk in obj.Disk) { WriteDisk(disk, writer); } } writer.WriteEndElement(); } /// /// Write a Feature to an XmlTextWriter /// /// Feature to write /// XmlTextReader to write to private static void WriteFeature(Feature obj, XmlTextWriter writer) { writer.WriteStartElement("feature"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("value", obj.Value); writer.WriteEndElement(); } /// /// Write a Info to an XmlTextWriter /// /// Info to write /// XmlTextReader to write to private static void WriteInfo(Info obj, XmlTextWriter writer) { writer.WriteStartElement("info"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("value", obj.Value); writer.WriteEndElement(); } /// /// Write a Part to an XmlTextWriter /// /// Part to write /// XmlTextReader to write to private static void WritePart(Part obj, XmlTextWriter writer) { writer.WriteStartElement("part"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteRequiredAttributeString("interface", obj.Interface); if (obj.Feature is not null && obj.Feature.Length > 0) { foreach (var feature in obj.Feature) { WriteFeature(feature, writer); } } if (obj.DataArea is not null && obj.DataArea.Length > 0) { foreach (var dataArea in obj.DataArea) { WriteDataArea(dataArea, writer); } } if (obj.DiskArea is not null && obj.DiskArea.Length > 0) { foreach (var diskArea in obj.DiskArea) { WriteDiskArea(diskArea, writer); } } if (obj.DipSwitch is not null && obj.DipSwitch.Length > 0) { foreach (var dipSwitch in obj.DipSwitch) { WriteDipSwitch(dipSwitch, writer); } } writer.WriteEndElement(); } /// /// Write a Rom to an XmlTextWriter /// /// Rom to write /// XmlTextReader to write to private static void WriteRom(Rom obj, XmlTextWriter writer) { writer.WriteStartElement("rom"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("size", obj.Size); writer.WriteOptionalAttributeString("length", obj.Length); writer.WriteOptionalAttributeString("crc", obj.CRC); writer.WriteOptionalAttributeString("sha1", obj.SHA1); writer.WriteOptionalAttributeString("offset", obj.Offset); writer.WriteOptionalAttributeString("value", obj.Value); writer.WriteOptionalAttributeString("status", obj.Status?.AsStringValue()); writer.WriteOptionalAttributeString("loadflag", obj.LoadFlag?.AsStringValue()); writer.WriteEndElement(); } /// /// Write a SharedFeat to an XmlTextWriter /// /// SharedFeat to write /// XmlTextReader to write to private static void WriteSharedFeat(SharedFeat obj, XmlTextWriter writer) { writer.WriteStartElement("sharedfeat"); writer.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("value", obj.Value); 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.WriteRequiredAttributeString("name", obj.Name); writer.WriteOptionalAttributeString("cloneof", obj.CloneOf); writer.WriteOptionalAttributeString("supported", obj.Supported?.AsStringValue()); writer.WriteRequiredElementString("description", obj.Description); writer.WriteRequiredElementString("year", obj.Year); writer.WriteRequiredElementString("publisher", obj.Publisher); writer.WriteOptionalElementString("notes", obj.Notes); if (obj.Info is not null && obj.Info.Length > 0) { foreach (var info in obj.Info) { WriteInfo(info, writer); } } if (obj.SharedFeat is not null && obj.SharedFeat.Length > 0) { foreach (var sharedFeat in obj.SharedFeat) { WriteSharedFeat(sharedFeat, writer); } } if (obj.Part is not null && obj.Part.Length > 0) { foreach (var part in obj.Part) { WritePart(part, writer); } } writer.WriteEndElement(); } #endregion } }