diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-03-22 19:52:42 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-03-22 19:52:42 -0400 |
commit | 7ca5efbbc576f3c6c43493654b2a0ac040fd4f31 (patch) | |
tree | fae7a4e06a14ff7f8d709e2f4d5b8b92b8784a37 /src/SMAPI.Web/Framework | |
parent | 5ae640dc91adff8dfb0827e2a3c3f6b54be7c612 (diff) | |
parent | 6d1494a56c5d04e7bc1ee406810a5a53dea2229a (diff) | |
download | SMAPI-7ca5efbbc576f3c6c43493654b2a0ac040fd4f31.tar.gz SMAPI-7ca5efbbc576f3c6c43493654b2a0ac040fd4f31.tar.bz2 SMAPI-7ca5efbbc576f3c6c43493654b2a0ac040fd4f31.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI.Web/Framework')
-rw-r--r-- | src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs | 89 | ||||
-rw-r--r-- | src/SMAPI.Web/Framework/LogParsing/LogParser.cs | 66 |
2 files changed, 124 insertions, 31 deletions
diff --git a/src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs b/src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs new file mode 100644 index 00000000..42e283a9 --- /dev/null +++ b/src/SMAPI.Web/Framework/LogParsing/LogMessageBuilder.cs @@ -0,0 +1,89 @@ +using System; +using System.Text; +using StardewModdingAPI.Web.Framework.LogParsing.Models; + +namespace StardewModdingAPI.Web.Framework.LogParsing +{ + /// <summary>Handles constructing log message instances with minimal memory allocation.</summary> + internal class LogMessageBuilder + { + /********* + ** Fields + *********/ + /// <summary>The local time when the next log was posted.</summary> + public string Time { get; set; } + + /// <summary>The log level for the next log message.</summary> + public LogLevel Level { get; set; } + + /// <summary>The mod name for the next log message.</summary> + public string Mod { get; set; } + + /// <summary>The text for the next log message.</summary> + private readonly StringBuilder Text = new StringBuilder(); + + + /********* + ** Accessors + *********/ + /// <summary>Whether the next log message has been started.</summary> + public bool Started { get; private set; } + + + /********* + ** Public methods + *********/ + /// <summary>Start accumulating values for a new log message.</summary> + /// <param name="time">The local time when the log was posted.</param> + /// <param name="level">The log level.</param> + /// <param name="mod">The mod name.</param> + /// <param name="text">The initial log text.</param> + /// <exception cref="InvalidOperationException">A log message is already started; call <see cref="Clear"/> before starting a new message.</exception> + public void Start(string time, LogLevel level, string mod, string text) + { + if (this.Started) + throw new InvalidOperationException("Can't start new message, previous log message isn't done yet."); + + this.Started = true; + + this.Time = time; + this.Level = level; + this.Mod = mod; + this.Text.Append(text); + } + + /// <summary>Add a new line to the next log message being built.</summary> + /// <param name="text">The line to add.</param> + /// <exception cref="InvalidOperationException">A log message hasn't been started yet.</exception> + public void AddLine(string text) + { + if (!this.Started) + throw new InvalidOperationException("Can't add text, no log message started yet."); + + this.Text.Append("\n"); + this.Text.Append(text); + } + + /// <summary>Get a log message for the accumulated values.</summary> + public LogMessage Build() + { + if (!this.Started) + return null; + + return new LogMessage + { + Time = this.Time, + Level = this.Level, + Mod = this.Mod, + Text = this.Text.ToString() + }; + } + + /// <summary>Reset to start a new log message.</summary> + public void Clear() + { + this.Started = false; + this.Text.Clear(); + } + } +} diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index cc91ec51..cce80816 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -201,7 +201,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing } // mod path line - else if (message.Level == LogLevel.Debug && this.ModPathPattern.IsMatch(message.Text)) + else if (message.Level == LogLevel.Info && this.ModPathPattern.IsMatch(message.Text)) { Match match = this.ModPathPattern.Match(message.Text); log.ModPath = match.Groups["path"].Value; @@ -282,43 +282,47 @@ namespace StardewModdingAPI.Web.Framework.LogParsing /// <exception cref="LogParseException">The log text can't be parsed successfully.</exception> private IEnumerable<LogMessage> GetMessages(string logText) { - LogMessage message = new LogMessage(); - using (StringReader reader = new StringReader(logText)) + LogMessageBuilder builder = new LogMessageBuilder(); + using StringReader reader = new StringReader(logText); + while (true) { - while (true) - { - // read data - string line = reader.ReadLine(); - if (line == null) - break; - Match header = this.MessageHeaderPattern.Match(line); - - // validate - if (message.Text == null && !header.Success) - throw new LogParseException("Found a log message with no SMAPI metadata. Is this a SMAPI log file?"); + // read line + string line = reader.ReadLine(); + if (line == null) + break; - // start or continue message - if (header.Success) - { - if (message.Text != null) - yield return message; + // match header + Match header = this.MessageHeaderPattern.Match(line); + bool isNewMessage = header.Success; - message = new LogMessage - { - Time = header.Groups["time"].Value, - Level = Enum.Parse<LogLevel>(header.Groups["level"].Value, ignoreCase: true), - Mod = header.Groups["modName"].Value, - Text = line.Substring(header.Length) - }; + // start/continue message + if (isNewMessage) + { + if (builder.Started) + { + yield return builder.Build(); + builder.Clear(); } - else - message.Text += "\n" + line; + + builder.Start( + time: header.Groups["time"].Value, + level: Enum.Parse<LogLevel>(header.Groups["level"].Value, ignoreCase: true), + mod: header.Groups["modName"].Value, + text: line.Substring(header.Length) + ); } + else + { + if (!builder.Started) + throw new LogParseException("Found a log message with no SMAPI metadata. Is this a SMAPI log file?"); - // end last message - if (message.Text != null) - yield return message; + builder.AddLine(line); + } } + + // end last message + if (builder.Started) + yield return builder.Build(); } } } |