using System.IO; using System.Text; using SabreTools.Data.Extensions; using SabreTools.Data.Models.SeparatedValue; using SabreTools.IO.Extensions; using SabreTools.Text.SeparatedValue; #pragma warning disable CA1822 // Mark members as static namespace SabreTools.Serialization.Writers { public class SeparatedValue : BaseBinaryWriter { #region Constants public static readonly string[] HeaderArrayStandard = [ "File Name", "Internal Name", "Description", "Game Name", "Game Description", "Type", "Rom Name", "Disk Name", "Size", "CRC", "MD5", "SHA1", "SHA256", "Status", ]; public static readonly string[] HeaderArrayExtended = [ "File Name", "Internal Name", "Description", "Game Name", "Game Description", "Type", "Rom Name", "Disk Name", "Size", "CRC", "MD5", "SHA1", "SHA256", "SHA384", "SHA512", "SpamSum", "Status", ]; #endregion #region IByteWriter /// public override byte[]? SerializeArray(MetadataFile? obj) => SerializeArray(obj, ',', false); /// public byte[]? SerializeArray(MetadataFile? obj, char delim, bool longHeader) { using var stream = SerializeStream(obj, delim, longHeader); 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(MetadataFile? obj, string? path) => SerializeFile(obj, path, ',', false); /// public bool SerializeFile(MetadataFile? obj, string? path, char delim, bool longHeader) { if (string.IsNullOrEmpty(path)) return false; using var stream = SerializeStream(obj, delim, longHeader); 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(MetadataFile? obj) => SerializeStream(obj, ',', false); /// public Stream? SerializeStream(MetadataFile? obj, char delim, bool longHeader) { // If the metadata file is null if (obj is null) return null; // Setup the writer and output var stream = new MemoryStream(); var writer = new Writer(stream, Encoding.UTF8) { Separator = delim, Quotes = true }; // Write the header WriteHeader(writer, longHeader); // Write out the rows, if they exist WriteRows(obj.Row, writer, longHeader); // Return the stream stream.SeekIfPossible(0, SeekOrigin.Begin); return stream; } /// /// Write header information to the current writer /// /// Writer representing the output /// True if the long variant of the row should be written, false otherwise private static void WriteHeader(Writer writer, bool longHeader) { string[] headerArray = longHeader ? HeaderArrayExtended : HeaderArrayStandard; writer.WriteHeader(headerArray); writer.Flush(); } /// /// Write rows information to the current writer /// /// Array of Row objects representing the rows information /// Writer representing the output /// True if the long variant of the row should be written, false otherwise private static void WriteRows(Row[]? rows, Writer writer, bool longHeader) { // If the games information is missing, we can't do anything if (rows is null || rows.Length == 0) return; // Loop through and write out the rows foreach (var row in rows) { string?[] rowArray; if (longHeader) { rowArray = [ row.FileName, row.InternalName, row.Description, row.GameName, row.GameDescription, row.Type, row.RomName, row.DiskName, row.Size?.ToString(), row.CRC, row.MD5, row.SHA1, row.SHA256, row.SHA384, row.SHA512, row.SpamSum, row.Status?.AsStringValue(), ]; } else { rowArray = [ row.FileName, row.InternalName, row.Description, row.GameName, row.GameDescription, row.Type, row.RomName, row.DiskName, row.Size?.ToString(), row.CRC, row.MD5, row.SHA1, row.SHA256, row.Status?.AsStringValue(), ]; } writer.WriteValues(rowArray); writer.Flush(); } } #endregion } }