var excel = "2018/9/10 20:13";\r
PAssert.That(() => "[\"2018-09-10 20:13:00\"" + expected == dateProcessor(excel), "Excelの形式から変換する");\r
}\r
+\r
+ /// <summary>\r
+ /// 壊れたログを取り除く\r
+ /// </summary>\r
+ [TestMethod]\r
+ public void TruncatedLog()\r
+ {\r
+ var processor = new LogProcessor();\r
+ var logs = new[]\r
+ {\r
+ "2014-12-15 23:10:34,29734,29855,28016,41440,1407,1529,2151,13",\r
+ "2014-12-15 23:13:29,29709,29819,28019,41440,1407,1529,21",\r
+ "2014-12-15 23:16:06,29710,29819,28018,41440,1407,1529,2151,13"\r
+ };\r
+ var result = processor.Process(logs, "資材ログ", DateTime.MinValue, DateTime.MaxValue, true);\r
+ PAssert.That(() => result.SequenceEqual(new[]\r
+ {\r
+ "[1418652634000,29734,29855,28016,41440,1407,1529,2151,13]",\r
+ ",\n[1418652966000,29710,29819,28018,41440,1407,1529,2151,13]"\r
+ }));\r
+ }\r
}\r
}
\ No newline at end of file
\r
namespace KancolleSniffer.Log\r
{\r
- public class BattleLogProcessor\r
+ public class BattleLogProcessor : LogProcessor.Processor\r
{\r
private readonly Dictionary<string, string> _mapDictionary;\r
\r
_mapDictionary = mapDictionary ?? new Dictionary<string, string>();\r
}\r
\r
- public string[] Process(string[] data)\r
+ public override string[] Process(string[] data)\r
{\r
string map;\r
switch (data.Length)\r
Array.Copy(data, 24, data, 23, 15);\r
goto case 38;\r
default:\r
- return data;\r
+ Skip = true;\r
+ return null;\r
}\r
+ Skip = false;\r
if (data[5] == "T字戦(有利)")\r
data[5] = "T字有利";\r
if (data[5] == "T字戦(不利)")\r
_battleLogProcessor = new BattleLogProcessor(mapDictionary);\r
}\r
\r
- public IEnumerable<string> Process(IEnumerable<string> lines, string path, DateTime from, DateTime to,\r
- bool number, DateTime now = default)\r
+ public class Processor\r
{\r
- var fields = 0;\r
- var mission = false;\r
- var battle = false;\r
- var material = false;\r
- switch (Path.GetFileNameWithoutExtension(path))\r
+ protected virtual int Fields { get; }\r
+ public bool Skip { get; protected set; }\r
+\r
+ public Processor()\r
{\r
- case "遠征報告書":\r
- mission = true;\r
- fields = 11;\r
- break;\r
- case "改修報告書":\r
- fields = 15;\r
- break;\r
- case "海戦・ドロップ報告書":\r
- fields = 40;\r
- battle = true;\r
- break;\r
- case "開発報告書":\r
- fields = 9;\r
- break;\r
- case "建造報告書":\r
- fields = 12;\r
- break;\r
- case "資材ログ":\r
- fields = 9;\r
- material = true;\r
- break;\r
- case "戦果":\r
- fields = 3;\r
- break;\r
}\r
+\r
+ public Processor(int fields)\r
+ {\r
+ Fields = fields;\r
+ }\r
+\r
+ public virtual string[] Process(string[] data)\r
+ {\r
+ Skip = data.Length != Fields;\r
+ return Skip ? null : data;\r
+ }\r
+ }\r
+\r
+ private class MissionProcessor : Processor\r
+ {\r
+ protected override int Fields { get; } = 11;\r
+\r
+ public override string[] Process(string[] data)\r
+ {\r
+ return data.Concat(new[] {"0"}).Take(Fields).ToArray();\r
+ }\r
+ }\r
+\r
+ private class MaterialProcessor : Processor\r
+ {\r
+ protected override int Fields { get; } = 9;\r
+\r
+ public override string[] Process(string[] data)\r
+ {\r
+ if (data.Length >= Fields)\r
+ Array.Resize(ref data, Fields);\r
+ return base.Process(data);\r
+ }\r
+ }\r
+\r
+ public IEnumerable<string> Process(IEnumerable<string> lines, string path, DateTime from, DateTime to,\r
+ bool number, DateTime now = default)\r
+ {\r
+ var logName = Path.GetFileNameWithoutExtension(path);\r
+ var currentMaterial = logName == "資材ログ" && !number;\r
+ var processor = DecideProcessor(logName);\r
var delimiter = "";\r
foreach (var line in lines)\r
{\r
if (date < from)\r
continue;\r
data[0] = Logger.FormatDateTime(date);\r
- var entries = data;\r
- if (mission)\r
- entries = data.Concat(new[] {"0"}).Take(fields).ToArray();\r
- if (material)\r
- entries = data.Take(fields).ToArray();\r
- if (battle)\r
- entries = _battleLogProcessor.Process(data);\r
- if (entries.Length != fields)\r
+ var entries = processor.Process(data);\r
+ if (processor.Skip)\r
continue;\r
var result =\r
number\r
delimiter = ",\n";\r
yield return result;\r
}\r
- if (material && !number) // 資材の現在値を出力する\r
+ if (currentMaterial) // 資材の現在値を出力する\r
yield return delimiter + "[\"" + Logger.FormatDateTime(now) + "\",\"" +\r
string.Join("\",\"", _materialCount.Select(c => c.Now)) + "\"]";\r
}\r
\r
+ private Processor DecideProcessor(string logName)\r
+ {\r
+ switch (logName)\r
+ {\r
+ case "遠征報告書":\r
+ return new MissionProcessor();\r
+ case "改修報告書":\r
+ return new Processor(15);\r
+ case "海戦・ドロップ報告書":\r
+ return _battleLogProcessor;\r
+ case "開発報告書":\r
+ return new Processor(9);\r
+ case "建造報告書":\r
+ return new Processor(12);\r
+ case "資材ログ":\r
+ return new MaterialProcessor();\r
+ case "戦果":\r
+ return new Processor(3);\r
+ default:\r
+ return new Processor();\r
+ }\r
+ }\r
+\r
private DateTime ParseDateTime(string dateTime)\r
{\r
if (DateTime.TryParseExact(dateTime, Logger.DateTimeFormat, CultureInfo.InvariantCulture,\r