From 4d542922086b48b2659b8d1c6c56224cb4cec7d2 Mon Sep 17 00:00:00 2001 From: tznind Date: Sat, 12 Oct 2024 11:07:15 +0100 Subject: [PATCH] Add string version --- .../ConsoleDrivers/AnsiResponseParser.cs | 100 +++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs index f8c54f8454..308c3fa434 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs @@ -204,7 +204,6 @@ public IEnumerable> ProcessInput (params Tuple[] input) held.Add (currentChar); // Check if the held content should be released - if (ShouldReleaseHeldContent ()) { output.AddRange (held); @@ -240,3 +239,102 @@ protected override string HeldToString () return new string (held.Select (h => h.Item1).ToArray ()); } } + + + + +internal class AnsiResponseParser : AnsiResponseParserBase +{ + private readonly StringBuilder held = new (); + + /// + /// Processes input which may be a single character or multiple. + /// Returns what should be passed on to any downstream input processing + /// (i.e., removes expected ANSI responses from the input stream). + /// + public string ProcessInput (string input) + { + var output = new StringBuilder (); // Holds characters that should pass through + var index = 0; // Tracks position in the input string + + while (index < input.Length) + { + var currentChar = input [index]; + + switch (State) + { + case ParserState.Normal: + if (currentChar == '\x1B') + { + // Escape character detected, move to ExpectingBracket state + State = ParserState.ExpectingBracket; + held.Append (currentChar); // Hold the escape character + index++; + } + else + { + // Normal character, append to output + output.Append (currentChar); + index++; + } + + break; + + case ParserState.ExpectingBracket: + if (currentChar == '[') + { + // Detected '[' , transition to InResponse state + State = ParserState.InResponse; + held.Append (currentChar); // Hold the '[' + index++; + } + else + { + // Invalid sequence, release held characters and reset to Normal + output.Append (held); + output.Append (currentChar); // Add current character + ResetState (); + index++; + } + + break; + + case ParserState.InResponse: + held.Append (currentChar); + + // Check if the held content should be released + if (ShouldReleaseHeldContent ()) + { + output.Append (held); + ResetState (); // Exit response mode and reset + } + + index++; + + break; + } + } + + return output.ToString(); // Return all characters that passed through + } + + /// + /// Resets the parser's state when a response is handled or finished. + /// + private void ResetState () + { + State = ParserState.Normal; + held.Clear (); + } + + /// + public override void ClearHeld () + { + held.Clear (); + } + + protected override string HeldToString () + { + return held.ToString (); + } +}