using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; using SabreTools.IO.Extensions; namespace SabreTools.Serialization.Writers { /// /// Base class for other XML serializers /// /// public class XmlFile : BaseBinaryWriter { #region IByteWriter /// public override byte[]? SerializeArray(T? obj) => SerializeArray(obj, null, null, null, null); /// /// Serializes the defined type to a byte array /// /// Data to serialize /// Optional DOCTYPE name /// Optional DOCTYPE pubid /// Optional DOCTYPE sysid /// Optional DOCTYPE name /// Byte array containing serialized data on success, null otherwise public byte[]? SerializeArray(T? obj, string? name = null, string? pubid = null, string? sysid = null, string? subset = null) { using var stream = Serialize(obj, name, pubid, sysid, subset); if (stream is null) return null; byte[] bytes = new byte[stream.Length]; int read = stream.Read(bytes, 0, bytes.Length); return bytes; } #endregion #region IFileWriter /// public override bool SerializeFile(T? obj, string? path) => Serialize(obj, path, null, null, null, null); /// /// Serializes the defined type to an XML file /// /// Data to serialize /// Path to the file to serialize to /// Optional DOCTYPE name /// Optional DOCTYPE pubid /// Optional DOCTYPE sysid /// Optional DOCTYPE name /// True on successful serialization, false otherwise public bool Serialize(T? obj, string? path, string? name = null, string? pubid = null, string? sysid = null, string? subset = null) { if (string.IsNullOrEmpty(path)) return false; using var stream = Serialize(obj, name, pubid, sysid, subset); if (stream is null) return false; using var fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None); stream.BlockCopy(fs); fs.Flush(); return true; } #endregion #region IStreamWriter /// public override Stream? SerializeStream(T? obj) => Serialize(obj, null, null, null, null); /// /// Serializes the defined type to a stream /// /// Data to serialize /// Optional DOCTYPE name /// Optional DOCTYPE pubid /// Optional DOCTYPE sysid /// Optional DOCTYPE name /// Stream containing serialized data on success, null otherwise public Stream? Serialize(T? obj, string? name = null, string? pubid = null, string? sysid = null, string? subset = null) { // If the object is null if (obj is null) return null; // Setup the serializer and the writer var serializer = new XmlSerializer(typeof(T)); var namespaces = new XmlSerializerNamespaces(); namespaces.Add("", ""); var settings = new XmlWriterSettings { CheckCharacters = false, Encoding = Encoding.UTF8, Indent = true, IndentChars = "\t", #if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER NamespaceHandling = NamespaceHandling.OmitDuplicates, #endif NewLineChars = "\n", }; var stream = new MemoryStream(); var streamWriter = new StreamWriter(stream); var xmlWriter = XmlWriter.Create(streamWriter, settings); // Write the doctype if provided if (!string.IsNullOrEmpty(name)) xmlWriter.WriteDocType(name, pubid, sysid, subset); // Perform the deserialization and return serializer.Serialize(xmlWriter, obj, namespaces); stream.SeekIfPossible(0, SeekOrigin.Begin); return stream; } #endregion } }