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