From 93fdd699db3ad4d9eabe6033d6f1e24bbc63c6ec Mon Sep 17 00:00:00 2001 From: fauxpark Date: Fri, 16 Feb 2024 18:46:36 +1100 Subject: [PATCH] [Windows] Update HidDeviceReportEvent() --- .../HidConsole/HidConsoleDevice.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/windows/QMK Toolbox/HidConsole/HidConsoleDevice.cs b/windows/QMK Toolbox/HidConsole/HidConsoleDevice.cs index b4b4a54eef..9b2bf1d4ca 100644 --- a/windows/QMK Toolbox/HidConsole/HidConsoleDevice.cs +++ b/windows/QMK Toolbox/HidConsole/HidConsoleDevice.cs @@ -1,4 +1,5 @@ using HidLibrary; +using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -54,29 +55,34 @@ private async Task ReadReportAsync() return await Task.Run(() => HidDevice.ReadReport()); } - private string currentLine = ""; + private List currentLine = new(); private void HidDeviceReportEvent(HidReport report) { if (HidDevice.IsConnected) { // Check if we have a completed line queued - int lineEnd = currentLine.IndexOf('\n'); + int lineEnd = currentLine.IndexOf((byte)'\n'); if (lineEnd == -1) { // Partial line or nothing - append incoming report to current line - string reportString = Encoding.UTF8.GetString(report.Data).Trim('\0'); - currentLine += reportString; + foreach (byte b in report.Data) + { + // Trim trailing null bytes + if (b == 0) break; + currentLine.Add(b); + } } // Check again for a completed line - lineEnd = currentLine.IndexOf('\n'); + lineEnd = currentLine.IndexOf((byte)'\n'); while (lineEnd >= 0) { // Fire delegate with completed lines until we have none left - string completedLine = currentLine[..lineEnd]; - currentLine = currentLine[(lineEnd + 1)..]; - lineEnd = currentLine.IndexOf('\n'); + // Only convert to string at the last possible moment in case there is a UTF-8 sequence split across reports + string completedLine = Encoding.UTF8.GetString(currentLine.GetRange(0, lineEnd).ToArray()); + currentLine = currentLine.Skip(lineEnd + 1).ToList(); + lineEnd = currentLine.IndexOf((byte)'\n'); consoleReportReceived?.Invoke(this, completedLine); }