diff --git a/Covid19Radar/Tests/Covid19Radar.UnitTests/Services/Logs/LoggerServiceTests.cs b/Covid19Radar/Tests/Covid19Radar.UnitTests/Services/Logs/LoggerServiceTests.cs index 4b8f9aa5f..8be14dc12 100644 --- a/Covid19Radar/Tests/Covid19Radar.UnitTests/Services/Logs/LoggerServiceTests.cs +++ b/Covid19Radar/Tests/Covid19Radar.UnitTests/Services/Logs/LoggerServiceTests.cs @@ -3,8 +3,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ using System; +using System.Collections.Generic; using System.IO; -using System.Text.RegularExpressions; +using System.Linq; +using System.Text; using System.Threading.Tasks; using Covid19Radar.Services; using Covid19Radar.Services.Logs; @@ -753,10 +755,82 @@ private void RecreateLogsFile() private string[] ParseLogRow(string logRow) { - var pattern = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); - return pattern.Split(logRow); + return ParseCsv(logRow, false) + .Select(s => $"\"{s}\"") + .ToArray(); } #endregion + + #region CocoaLogViewer Code + + // このコードは CocoaLogViewer からコピーしました。MITライセンスに基づいて配布されています。 + // This source code is copied from CocoaLogViewer and distributed under the MIT License. + // https://github.com/YigtyORG/CocoaLogViewer/blob/00862602b739d3c4f6c9c129e9fe0a6ad32cbeed/src/Covid19Radar.LogViewer/Models/LogFileModel.cs#L64-L123 + // Copyright (C) 2020-2021 Yigty.ORG; all rights reserved. + // Copyright (C) 2020-2021 Takym. + + private static List ParseCsv(string line, bool allowEscape) + { + var result = new List(); + var sb = new StringBuilder(); // This line was modified. + int i = 0; + bool dq = false; + while (i < line.Length) { + char ch = line[i]; + switch (ch) { + case '\"': + ++i; + if (i < line.Length && line[i] == '\"') { + ++i; + sb.Append('\"'); + } else { + dq = !dq; + } + break; + case '\\' when allowEscape: + ++i; + if (i < line.Length) { + ch = line[i]; + ++i; + sb.Append(ch switch { + 't' => '\t', + 'v' => '\v', + 'r' => '\r', + 'n' => '\n', + _ => ch + }); + } else { + sb.Append('\\'); + } + break; + case ',': + ++i; + if (dq) { + sb.Append(','); + } else { + result.Add(sb.ToString()); + sb.Clear(); + } + break; + case ' ': case '\0': case '\t': case '\v': case '\r': case '\n': + ++i; + if (dq) { + sb.Append(ch); + } + break; + default: + ++i; + sb.Append(ch); + break; + } + } + if (sb.Length > 0) { + result.Add(sb.ToString()); + } + return result; + } + + #endregion } }