Add startup drill tape parameter cleanup
This commit is contained in:
162
DrillTapeParameterCleaner.cs
Normal file
162
DrillTapeParameterCleaner.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace DrillTools
|
||||
{
|
||||
internal static class DrillTapeParameterCleaner
|
||||
{
|
||||
private const int Gb2312CodePage = 936;
|
||||
private static readonly char[] LineEndChars = { '\r', '\n' };
|
||||
private static readonly Regex HeaderToolDefinitionStartPattern = new(
|
||||
@"^T\d+C",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
private static readonly Regex ToolDefinitionPattern = new(
|
||||
@"^(?<prefix>\s*T\d+C\d+(?:\.\d+)?)(?<parameters>H.+)$",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static bool CanClearParameters(string drillTapeContent)
|
||||
{
|
||||
var lines = SplitLines(drillTapeContent);
|
||||
if (lines.Count < 2)
|
||||
return false;
|
||||
|
||||
string secondLine = lines[1].Text.Trim();
|
||||
if (!secondLine.StartsWith(";") || secondLine.Length == 1)
|
||||
return false;
|
||||
|
||||
var toolDefinitionLines = GetHeaderToolDefinitionLines(lines);
|
||||
if (toolDefinitionLines.Count == 0)
|
||||
return false;
|
||||
|
||||
foreach (var line in toolDefinitionLines)
|
||||
{
|
||||
if (!ToolDefinitionPattern.IsMatch(line.Text.TrimEnd()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string ClearParameters(string drillTapeContent)
|
||||
{
|
||||
if (!CanClearParameters(drillTapeContent))
|
||||
throw new InvalidOperationException("钻带文件不符合清空参数条件");
|
||||
|
||||
var lines = SplitLines(drillTapeContent);
|
||||
var builder = new StringBuilder(drillTapeContent.Length);
|
||||
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
continue;
|
||||
|
||||
string text = lines[i].Text;
|
||||
var match = ToolDefinitionPattern.Match(text.TrimEnd());
|
||||
if (match.Success && IsBeforeHeaderEnd(lines, i))
|
||||
{
|
||||
int trailingWhitespaceLength = text.Length - text.TrimEnd().Length;
|
||||
string trailingWhitespace = trailingWhitespaceLength > 0 ? text[^trailingWhitespaceLength..] : string.Empty;
|
||||
text = match.Groups["prefix"].Value + trailingWhitespace;
|
||||
}
|
||||
|
||||
builder.Append(text);
|
||||
builder.Append(lines[i].LineEnding);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static void ClearParametersAndSave(string filePath)
|
||||
{
|
||||
string content = CommandTypeFileReader.ReadAllText(filePath);
|
||||
string cleanedContent = ClearParameters(content);
|
||||
|
||||
string backupFilePath = filePath + ".bak";
|
||||
File.Copy(filePath, backupFilePath, true);
|
||||
|
||||
using var writer = new StreamWriter(filePath, false, CreateAnsiEncoding());
|
||||
writer.Write(cleanedContent);
|
||||
}
|
||||
|
||||
private static List<DrillTapeLine> SplitLines(string content)
|
||||
{
|
||||
var lines = new List<DrillTapeLine>();
|
||||
int index = 0;
|
||||
|
||||
while (index < content.Length)
|
||||
{
|
||||
int lineEndIndex = content.IndexOfAny(LineEndChars, index);
|
||||
if (lineEndIndex < 0)
|
||||
{
|
||||
lines.Add(new DrillTapeLine(content[index..], string.Empty));
|
||||
return lines;
|
||||
}
|
||||
|
||||
string text = content[index..lineEndIndex];
|
||||
string lineEnding;
|
||||
if (content[lineEndIndex] == '\r' && lineEndIndex + 1 < content.Length && content[lineEndIndex + 1] == '\n')
|
||||
{
|
||||
lineEnding = "\r\n";
|
||||
index = lineEndIndex + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lineEnding = content[lineEndIndex].ToString();
|
||||
index = lineEndIndex + 1;
|
||||
}
|
||||
|
||||
lines.Add(new DrillTapeLine(text, lineEnding));
|
||||
}
|
||||
|
||||
if (content.Length == 0)
|
||||
lines.Add(new DrillTapeLine(string.Empty, string.Empty));
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static List<DrillTapeLine> GetHeaderToolDefinitionLines(IReadOnlyList<DrillTapeLine> lines)
|
||||
{
|
||||
var toolDefinitionLines = new List<DrillTapeLine>();
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
string trimmedLine = line.Text.Trim();
|
||||
if (trimmedLine == "%")
|
||||
break;
|
||||
|
||||
if (HeaderToolDefinitionStartPattern.IsMatch(trimmedLine))
|
||||
toolDefinitionLines.Add(line);
|
||||
}
|
||||
|
||||
return toolDefinitionLines;
|
||||
}
|
||||
|
||||
private static bool IsBeforeHeaderEnd(IReadOnlyList<DrillTapeLine> lines, int lineIndex)
|
||||
{
|
||||
for (int i = 0; i < lineIndex; i++)
|
||||
{
|
||||
if (lines[i].Text.Trim() == "%")
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Encoding CreateAnsiEncoding()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Encoding.GetEncoding(Gb2312CodePage);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Encoding.Default;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly record struct DrillTapeLine(string Text, string LineEnding);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user