From d5fb8414d4ee2ea31943d6683f94a596408b0a1d Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 14 Apr 2025 21:16:45 -0400 Subject: [PATCH] Make report writing work with streams --- SabreTools.DatTools.Test/ParserTests.cs | 4 +- SabreTools.DatTools/Parser.cs | 6 +-- SabreTools.DatTools/Writer.cs | 2 +- SabreTools.Reports/BaseReport.cs | 47 +++++++++++++++++++- SabreTools.Reports/Formats/Html.cs | 20 +-------- SabreTools.Reports/Formats/SeparatedValue.cs | 20 +-------- SabreTools.Reports/Formats/Textfile.cs | 40 +---------------- 7 files changed, 57 insertions(+), 82 deletions(-) diff --git a/SabreTools.DatTools.Test/ParserTests.cs b/SabreTools.DatTools.Test/ParserTests.cs index d62e032e..ab8edff2 100644 --- a/SabreTools.DatTools.Test/ParserTests.cs +++ b/SabreTools.DatTools.Test/ParserTests.cs @@ -234,13 +234,13 @@ namespace SabreTools.DatTools.Test } [Theory] - [InlineData(StatReportFormat.None, typeof(Reports.Formats.ConsoleOutput))] + [InlineData(StatReportFormat.None, typeof(Reports.Formats.Textfile))] [InlineData(StatReportFormat.Textfile, typeof(Reports.Formats.Textfile))] [InlineData(StatReportFormat.CSV, typeof(Reports.Formats.CommaSeparatedValue))] [InlineData(StatReportFormat.HTML, typeof(Reports.Formats.Html))] [InlineData(StatReportFormat.SSV, typeof(Reports.Formats.SemicolonSeparatedValue))] [InlineData(StatReportFormat.TSV, typeof(Reports.Formats.TabSeparatedValue))] - [InlineData((StatReportFormat)0xFF, typeof(Reports.Formats.ConsoleOutput))] + [InlineData((StatReportFormat)0xFF, typeof(Reports.Formats.Textfile))] public void CreateReportTest(StatReportFormat reportFormat, Type expected) { var report = Parser.CreateReport(reportFormat, []); diff --git a/SabreTools.DatTools/Parser.cs b/SabreTools.DatTools/Parser.cs index 47ad68e8..7ff79c46 100644 --- a/SabreTools.DatTools/Parser.cs +++ b/SabreTools.DatTools/Parser.cs @@ -536,15 +536,15 @@ namespace SabreTools.DatTools { return statReportFormat switch { - StatReportFormat.None => new Reports.Formats.ConsoleOutput(statsList), + StatReportFormat.None => new Reports.Formats.Textfile(statsList), StatReportFormat.Textfile => new Reports.Formats.Textfile(statsList), StatReportFormat.CSV => new Reports.Formats.CommaSeparatedValue(statsList), StatReportFormat.HTML => new Reports.Formats.Html(statsList), StatReportFormat.SSV => new Reports.Formats.SemicolonSeparatedValue(statsList), StatReportFormat.TSV => new Reports.Formats.TabSeparatedValue(statsList), - // We use console output as a backup for generic BaseReport - _ => new Reports.Formats.ConsoleOutput(statsList), + // We use textfile output as a backup for generic BaseReport + _ => new Reports.Formats.Textfile(statsList), }; } diff --git a/SabreTools.DatTools/Writer.cs b/SabreTools.DatTools/Writer.cs index e5077c11..7c15fbc5 100644 --- a/SabreTools.DatTools/Writer.cs +++ b/SabreTools.DatTools/Writer.cs @@ -220,7 +220,7 @@ namespace SabreTools.DatTools datFile.DatStatistics, ]; var consoleOutput = Parser.CreateReport(StatReportFormat.None, statsList); - consoleOutput!.WriteToFile(null, true, true); + consoleOutput!.WriteToStream(Console.OpenStandardOutput(), true, true); } /// diff --git a/SabreTools.Reports/BaseReport.cs b/SabreTools.Reports/BaseReport.cs index ac20e39e..c80ea8dc 100644 --- a/SabreTools.Reports/BaseReport.cs +++ b/SabreTools.Reports/BaseReport.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.IO; using SabreTools.DatFiles; using SabreTools.IO.Logging; @@ -40,6 +42,47 @@ namespace SabreTools.Reports /// True if nodumps should be included in output, false otherwise /// True if the error that is thrown should be thrown back to the caller, false otherwise /// True if the report was written correctly, false otherwise - public abstract bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false); + public bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false) + { + InternalStopwatch watch = new($"Writing statistics to '{outfile}"); + + try + { + // Try to create the output file + FileStream stream = File.Create(outfile ?? string.Empty); + if (stream == null) + { + _logger.Warning($"File '{outfile}' could not be created for writing! Please check to see if the file is writable"); + return false; + } + + // Write to the stream + bool result = WriteToStream(stream, baddumpCol, nodumpCol, throwOnError); + + // Dispose of the stream + stream.Dispose(); + } + catch (Exception ex) when (!throwOnError) + { + _logger.Error(ex); + return false; + } + finally + { + watch.Stop(); + } + + return true; + } + + /// + /// Write a set of statistics to an input stream + /// + /// Stream to write to + /// True if baddumps should be included in output, false otherwise + /// True if nodumps should be included in output, false otherwise + /// True if the error that is thrown should be thrown back to the caller, false otherwise + /// True if the report was written correctly, false otherwise + public abstract bool WriteToStream(Stream stream, bool baddumpCol, bool nodumpCol, bool throwOnError = false); } } diff --git a/SabreTools.Reports/Formats/Html.cs b/SabreTools.Reports/Formats/Html.cs index be69947e..c28ae2ce 100644 --- a/SabreTools.Reports/Formats/Html.cs +++ b/SabreTools.Reports/Formats/Html.cs @@ -10,7 +10,6 @@ using SabreTools.Core.Tools; using SabreTools.DatFiles; using SabreTools.DatItems; using SabreTools.Hashing; -using SabreTools.IO.Logging; namespace SabreTools.Reports.Formats { @@ -30,21 +29,11 @@ namespace SabreTools.Reports.Formats } /// - public override bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false) + public override bool WriteToStream(Stream stream, bool baddumpCol, bool nodumpCol, bool throwOnError = false) { - InternalStopwatch watch = new($"Writing statistics to '{outfile}"); - try { - // Try to create the output file - FileStream fs = File.Create(outfile ?? string.Empty); - if (fs == null) - { - _logger.Warning($"File '{outfile}' could not be created for writing! Please check to see if the file is writable"); - return false; - } - - XmlTextWriter xtw = new(fs, Encoding.UTF8) + XmlTextWriter xtw = new(stream, Encoding.UTF8) { Formatting = Formatting.Indented, IndentChar = '\t', @@ -85,17 +74,12 @@ namespace SabreTools.Reports.Formats #if NET452_OR_GREATER xtw.Dispose(); #endif - fs.Dispose(); } catch (Exception ex) when (!throwOnError) { _logger.Error(ex); return false; } - finally - { - watch.Stop(); - } return true; } diff --git a/SabreTools.Reports/Formats/SeparatedValue.cs b/SabreTools.Reports/Formats/SeparatedValue.cs index 17c15387..1d219189 100644 --- a/SabreTools.Reports/Formats/SeparatedValue.cs +++ b/SabreTools.Reports/Formats/SeparatedValue.cs @@ -5,7 +5,6 @@ using System.Text; using SabreTools.DatFiles; using SabreTools.DatItems; using SabreTools.Hashing; -using SabreTools.IO.Logging; using SabreTools.IO.Writers; namespace SabreTools.Reports.Formats @@ -30,21 +29,11 @@ namespace SabreTools.Reports.Formats } /// - public override bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false) + public override bool WriteToStream(Stream stream, bool baddumpCol, bool nodumpCol, bool throwOnError = false) { - InternalStopwatch watch = new($"Writing statistics to '{outfile}"); - try { - // Try to create the output file - FileStream fs = File.Create(outfile ?? string.Empty); - if (fs == null) - { - _logger.Warning($"File '{outfile}' could not be created for writing! Please check to see if the file is writable"); - return false; - } - - SeparatedValueWriter svw = new(fs, Encoding.UTF8) + SeparatedValueWriter svw = new(stream, Encoding.UTF8) { Separator = _delim, Quotes = true, @@ -77,17 +66,12 @@ namespace SabreTools.Reports.Formats } svw.Dispose(); - fs.Dispose(); } catch (Exception ex) when (!throwOnError) { _logger.Error(ex); return false; } - finally - { - watch.Stop(); - } return true; } diff --git a/SabreTools.Reports/Formats/Textfile.cs b/SabreTools.Reports/Formats/Textfile.cs index 258febcc..9b670d08 100644 --- a/SabreTools.Reports/Formats/Textfile.cs +++ b/SabreTools.Reports/Formats/Textfile.cs @@ -6,7 +6,6 @@ using SabreTools.Core.Tools; using SabreTools.DatFiles; using SabreTools.DatItems; using SabreTools.Hashing; -using SabreTools.IO.Logging; namespace SabreTools.Reports.Formats { @@ -15,11 +14,6 @@ namespace SabreTools.Reports.Formats /// public class Textfile : BaseReport { - /// - /// Represents if the output goes to console or to a file - /// - protected bool _writeToConsole = false; - /// /// Create a new report from the filename /// @@ -30,21 +24,11 @@ namespace SabreTools.Reports.Formats } /// - public override bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false) + public override bool WriteToStream(Stream stream, bool baddumpCol, bool nodumpCol, bool throwOnError = false) { - InternalStopwatch watch = new($"Writing statistics to '{outfile}"); - try { - // Try to create the output file - Stream fs = _writeToConsole ? Console.OpenStandardOutput() : File.Create(outfile ?? string.Empty); - if (fs == null) - { - _logger.Warning($"File '{outfile}' could not be created for writing! Please check to see if the file is writable"); - return false; - } - - StreamWriter sw = new(fs); + StreamWriter sw = new(stream); // Now process each of the statistics for (int i = 0; i < _statistics.Count; i++) @@ -70,17 +54,12 @@ namespace SabreTools.Reports.Formats } sw.Dispose(); - fs.Dispose(); } catch (Exception ex) when (!throwOnError) { _logger.Error(ex); return false; } - finally - { - watch.Stop(); - } return true; } @@ -133,19 +112,4 @@ namespace SabreTools.Reports.Formats sw.Flush(); } } - - /// - /// Console report format - /// - public sealed class ConsoleOutput : Textfile - { - /// - /// Create a new report from the filename - /// - /// List of statistics objects to set - public ConsoleOutput(List statsList) : base(statsList) - { - _writeToConsole = true; - } - } }