From 8e12e69e4efc677f2f541f8963c5b9857db70d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 24 Apr 2026 16:49:06 +0200 Subject: [PATCH] basic read ahead optimization --- .../parser/EscapeSequenceParser.test.ts | 54 +++---------------- src/common/parser/EscapeSequenceParser.ts | 18 +++---- 2 files changed, 16 insertions(+), 56 deletions(-) diff --git a/src/common/parser/EscapeSequenceParser.test.ts b/src/common/parser/EscapeSequenceParser.test.ts index ef91d190e..6e5efd637 100644 --- a/src/common/parser/EscapeSequenceParser.test.ts +++ b/src/common/parser/EscapeSequenceParser.test.ts @@ -1240,38 +1240,18 @@ describe('EscapeSequenceParser', () => { it('single APC', () => { test('\x1b_X3+$aäbc;däe\x9c', [ ['apc start'], - //['apc put', '3+$aäbc;däe'], - ['apc put', '3'], - ['apc put', '+'], - ['apc put', '$'], - ['apc put', 'a'], - ['apc put', 'ä'], - ['apc put', 'b'], - ['apc put', 'c'], - ['apc put', ';'], - ['apc put', 'd'], - ['apc put', 'ä'], - ['apc put', 'e'], + ['apc put', '3+$aäbc;däe'], ['apc end', true] ], null); }); it('multi APC', () => { test('\x1b_Xabc;de', [ ['apc start'], - //['dcs put', 'abc;de'] - ['apc put', 'a'], - ['apc put', 'b'], - ['apc put', 'c'], - ['apc put', ';'], - ['apc put', 'd'], - ['apc put', 'e'], + ['apc put', 'abc;de'] ], null); testTerminal.clear(); test('abc\x9c', [ - //['apc put', 'abc'], - ['apc put', 'a'], - ['apc put', 'b'], - ['apc put', 'c'], + ['apc put', 'abc'], ['apc end', true] ], true); }); @@ -1279,12 +1259,7 @@ describe('EscapeSequenceParser', () => { test('abc\x9fAbc;de\x9cxyz', [ ['print', 'abc'], ['apc start'], - //['apc put', 'bc;de'], - ['apc put', 'b'], - ['apc put', 'c'], - ['apc put', ';'], - ['apc put', 'd'], - ['apc put', 'e'], + ['apc put', 'bc;de'], ['apc end', true], ['print', 'xyz'] ], null); @@ -1293,12 +1268,7 @@ describe('EscapeSequenceParser', () => { test('abc\x1b_Abc;de\x1b\\xyz', [ ['print', 'abc'], ['apc start'], - //['apc put', 'bc;de'], - ['apc put', 'b'], - ['apc put', 'c'], - ['apc put', ';'], - ['apc put', 'd'], - ['apc put', 'e'], + ['apc put', 'bc;de'], ['apc end', true], ['print', 'xyz'] ], null); @@ -1353,12 +1323,7 @@ describe('EscapeSequenceParser', () => { test('abc\x9fXbc;de\x18', [ ['print', 'abc'], ['apc start'], - //['apc put', 'bc;de'], - ['apc put', 'b'], - ['apc put', 'c'], - ['apc put', ';'], - ['apc put', 'd'], - ['apc put', 'e'], + ['apc put', 'bc;de'], ['apc end', false] // false for abort ], null); }); @@ -1366,12 +1331,7 @@ describe('EscapeSequenceParser', () => { test('abc\x9fXbc;de\x1a', [ ['print', 'abc'], ['apc start'], - //['apc put', 'bc;de'], - ['apc put', 'b'], - ['apc put', 'c'], - ['apc put', ';'], - ['apc put', 'd'], - ['apc put', 'e'], + ['apc put', 'bc;de'], ['apc end', false] // false for abort ], null); }); diff --git a/src/common/parser/EscapeSequenceParser.ts b/src/common/parser/EscapeSequenceParser.ts index 6046e2325..57f39c7eb 100644 --- a/src/common/parser/EscapeSequenceParser.ts +++ b/src/common/parser/EscapeSequenceParser.ts @@ -886,16 +886,16 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP this._apcParser.start(this._collect << 8 | code); break; case ParserAction.APC_PUT: - // FIXME: this is wrong, must be 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c - // for (let j = i + 1; ; ++j) { - // if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || code === 0x9c || (code > 0x7f && code < NON_ASCII_PRINTABLE)) { - // this._apcParser.put(data, i, j); - // i = j - 1; - // break; - // } - // } - this._apcParser.put(data, i, i+1); + // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE + // FIXME: 00/08 .. 00/13 currently handled by second APC_PUT invocation + for (let j = i + 1; ; ++j) { + if (j >= length || data[j] < 0x20 || (data[j] >= 0x7f && data[j] < NON_ASCII_PRINTABLE)) { + this._apcParser.put(data, i, j); + i = j - 1; + break; + } + } break; case ParserAction.APC_END: handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);