diff --git a/SabreTools.Serialization/XmlSerializer.cs b/SabreTools.Serialization/XmlSerializer.cs index 64bc5297..b4aebb54 100644 --- a/SabreTools.Serialization/XmlSerializer.cs +++ b/SabreTools.Serialization/XmlSerializer.cs @@ -60,5 +60,64 @@ namespace SabreTools.Serialization return default; } } + + /// + /// Serializes the defined type to an XML file + /// + /// Data to serialize + /// Path to the file to serialize to + /// True on successful serialization, false otherwise + public static bool SerializeToFile(T? obj, string path) + { + try + { + using var stream = SerializeToStream(obj); + if (stream == null) + return false; + + using var fs = File.OpenWrite(path); + stream.CopyTo(fs); + return true; + } + catch + { + // TODO: Handle logging the exception + return false; + } + } + + /// + /// Serializes the defined type to a stream + /// + /// Data to serialize + /// Stream containing serialized data on success, null otherwise + public static Stream? SerializeToStream(T? obj) + { + try + { + // If the object is null + if (obj == null) + return null; + + // Setup the serializer and the reader + var serializer = new XmlSerializer(typeof(T)); + var settings = new XmlWriterSettings + { + CheckCharacters = false, + }; + var stream = new MemoryStream(); + var streamWriter = new StreamWriter(stream); + var xmlWriter = XmlWriter.Create(streamWriter, settings); + + // Perform the deserialization and return + serializer.Serialize(xmlWriter, obj); + return stream; + } + catch + { + // TODO: Handle logging the exception + return null; + } + } } } \ No newline at end of file diff --git a/SabreTools.Test/Serialization/SerializationTests.cs b/SabreTools.Test/Serialization/SerializationTests.cs new file mode 100644 index 00000000..d589ed16 --- /dev/null +++ b/SabreTools.Test/Serialization/SerializationTests.cs @@ -0,0 +1,88 @@ +using System; +using Xunit; + +namespace SabreTools.Test.Parser +{ + public class SerializationTests + { + [Fact] + public void OpenMSXSeserializeTest() + { + // Create the object for serialization + var dat = GenerateOpenMSX(); + + // Deserialize the file + var stream = Serialization.OpenMSX.SerializeToStream(dat) as System.IO.MemoryStream; + + // Validate the values + Assert.NotNull(stream); + byte[] hash = System.Security.Cryptography.SHA1.Create().ComputeHash(stream.GetBuffer()); + string hashstr = BitConverter.ToString(hash).Replace("-", string.Empty); + Assert.Equal("195D11C8A93D73F9FBF1ECD8166D80D7BB1B0974", hashstr); + } + + #region Payload Generators + + /// + /// Generate a consistent OpenMSX SoftwareDb for testing + /// + private static Models.OpenMSX.SoftwareDb GenerateOpenMSX() + { + var original = new Models.OpenMSX.Original + { + Value = false, + Content = "Original Name", + }; + + var rom = new Models.OpenMSX.Rom + { + Start = "0x0000", + Type = "Game", + Hash = "da39a3ee5e6b4b0d3255bfef95601890afd80709", + Remark = "Comment", + }; + + var megaRom = new Models.OpenMSX.MegaRom + { + Start = "0x1000", + Type = "Software", + Hash = "da39a3ee5e6b4b0d3255bfef95601890afd80709", + Remark = "Comment", + }; + + var sccPlusCart = new Models.OpenMSX.SCCPlusCart + { + Start = "0x2000", + Type = "Utility", + Hash = "da39a3ee5e6b4b0d3255bfef95601890afd80709", + Remark = "Comment", + }; + + var dump = new Models.OpenMSX.Dump[] + { + new Models.OpenMSX.Dump { Original = original, Rom = rom }, + new Models.OpenMSX.Dump { Rom = megaRom }, + new Models.OpenMSX.Dump { Rom = sccPlusCart }, + }; + + var software = new Models.OpenMSX.Software + { + Title = "Software Title", + GenMSXID = "00000", // Not required + System = "MSX 2", + Company = "Imaginary Company, Inc.", + Year = "19xx", + Country = "Imaginaria", + Dump = dump, + }; + + return new Models.OpenMSX.SoftwareDb + { + Timestamp = "1234567890", + Software = new Models.OpenMSX.Software[] { software }, + }; + } + + #endregion + } +} \ No newline at end of file