@xterm/xterm 6.1.0-beta.24 → 6.1.0-beta.240
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -38
- package/css/xterm.css +29 -22
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +8 -34
- package/lib/xterm.mjs.map +4 -4
- package/package.json +25 -22
- package/src/browser/AccessibilityManager.ts +11 -6
- package/src/browser/Clipboard.ts +6 -3
- package/src/browser/CoreBrowserTerminal.ts +149 -319
- package/src/browser/Dom.ts +178 -0
- package/src/browser/Linkifier.ts +11 -11
- package/src/browser/OscLinkProvider.ts +82 -14
- package/src/browser/RenderDebouncer.ts +2 -2
- package/src/browser/TimeBasedDebouncer.ts +2 -2
- package/src/browser/Types.ts +12 -11
- package/src/browser/Viewport.ts +55 -20
- package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
- package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
- package/src/browser/input/CompositionHelper.ts +44 -8
- package/src/browser/public/Terminal.ts +25 -28
- package/src/browser/renderer/dom/DomRenderer.ts +242 -76
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
- package/src/browser/renderer/dom/WidthCache.ts +54 -52
- package/src/browser/renderer/shared/Constants.ts +7 -0
- package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
- package/src/browser/renderer/shared/Types.ts +8 -2
- package/src/browser/scrollable/abstractScrollbar.ts +300 -0
- package/src/browser/scrollable/fastDomNode.ts +126 -0
- package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
- package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
- package/src/browser/scrollable/mouseEvent.ts +292 -0
- package/src/browser/scrollable/scrollable.ts +486 -0
- package/src/browser/scrollable/scrollableElement.ts +581 -0
- package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
- package/src/browser/scrollable/scrollbarArrow.ts +110 -0
- package/src/browser/scrollable/scrollbarState.ts +246 -0
- package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
- package/src/browser/scrollable/touch.ts +485 -0
- package/src/browser/scrollable/verticalScrollbar.ts +143 -0
- package/src/browser/scrollable/widget.ts +23 -0
- package/src/browser/services/CharSizeService.ts +2 -2
- package/src/browser/services/CoreBrowserService.ts +7 -5
- package/src/browser/services/KeyboardService.ts +67 -0
- package/src/browser/services/LinkProviderService.ts +1 -1
- package/src/browser/services/MouseCoordsService.ts +47 -0
- package/src/browser/services/MouseService.ts +518 -25
- package/src/browser/services/RenderService.ts +28 -16
- package/src/browser/services/SelectionService.ts +45 -39
- package/src/browser/services/Services.ts +40 -17
- package/src/browser/services/ThemeService.ts +2 -2
- package/src/common/Async.ts +141 -0
- package/src/common/CircularList.ts +2 -2
- package/src/common/Color.ts +8 -0
- package/src/common/CoreTerminal.ts +31 -21
- package/src/common/Event.ts +118 -0
- package/src/common/InputHandler.ts +283 -85
- package/src/common/Lifecycle.ts +113 -0
- package/src/common/Platform.ts +13 -3
- package/src/common/SortedList.ts +7 -3
- package/src/common/StringBuilder.ts +67 -0
- package/src/common/TaskQueue.ts +14 -5
- package/src/common/Types.ts +51 -31
- package/src/common/Version.ts +9 -0
- package/src/common/buffer/Buffer.ts +34 -19
- package/src/common/buffer/BufferLine.ts +133 -65
- package/src/common/buffer/BufferLineStringCache.ts +69 -0
- package/src/common/buffer/BufferSet.ts +11 -6
- package/src/common/buffer/CellData.ts +57 -0
- package/src/common/buffer/Marker.ts +2 -2
- package/src/common/buffer/Types.ts +6 -2
- package/src/common/data/EscapeSequences.ts +71 -70
- package/src/common/input/Keyboard.ts +14 -7
- package/src/common/input/KittyKeyboard.ts +526 -0
- package/src/common/input/Win32InputMode.ts +297 -0
- package/src/common/input/WriteBuffer.ts +69 -32
- package/src/common/input/XParseColor.ts +2 -2
- package/src/common/parser/ApcParser.ts +196 -0
- package/src/common/parser/Constants.ts +14 -4
- package/src/common/parser/DcsParser.ts +11 -12
- package/src/common/parser/EscapeSequenceParser.ts +205 -63
- package/src/common/parser/OscParser.ts +11 -12
- package/src/common/parser/Params.ts +27 -8
- package/src/common/parser/Types.ts +36 -2
- package/src/common/public/BufferLineApiView.ts +2 -2
- package/src/common/public/BufferNamespaceApi.ts +3 -3
- package/src/common/public/ParserApi.ts +3 -0
- package/src/common/services/BufferService.ts +14 -9
- package/src/common/services/CharsetService.ts +4 -0
- package/src/common/services/CoreService.ts +22 -9
- package/src/common/services/DecorationService.ts +258 -8
- package/src/common/services/LogService.ts +1 -31
- package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
- package/src/common/services/OptionsService.ts +13 -4
- package/src/common/services/ServiceRegistry.ts +9 -7
- package/src/common/services/Services.ts +49 -40
- package/src/common/services/UnicodeService.ts +1 -1
- package/typings/xterm.d.ts +318 -34
- package/src/common/Clone.ts +0 -23
- package/src/common/TypedArrayUtils.ts +0 -17
- package/src/vs/base/browser/browser.ts +0 -141
- package/src/vs/base/browser/canIUse.ts +0 -49
- package/src/vs/base/browser/dom.ts +0 -2369
- package/src/vs/base/browser/fastDomNode.ts +0 -316
- package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
- package/src/vs/base/browser/iframe.ts +0 -135
- package/src/vs/base/browser/keyboardEvent.ts +0 -213
- package/src/vs/base/browser/mouseEvent.ts +0 -229
- package/src/vs/base/browser/touch.ts +0 -372
- package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
- package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
- package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
- package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
- package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
- package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
- package/src/vs/base/browser/ui/widget.ts +0 -57
- package/src/vs/base/browser/window.ts +0 -14
- package/src/vs/base/common/arrays.ts +0 -887
- package/src/vs/base/common/arraysFind.ts +0 -202
- package/src/vs/base/common/assert.ts +0 -71
- package/src/vs/base/common/async.ts +0 -1992
- package/src/vs/base/common/cancellation.ts +0 -148
- package/src/vs/base/common/charCode.ts +0 -450
- package/src/vs/base/common/collections.ts +0 -140
- package/src/vs/base/common/decorators.ts +0 -130
- package/src/vs/base/common/equals.ts +0 -146
- package/src/vs/base/common/errors.ts +0 -303
- package/src/vs/base/common/event.ts +0 -1778
- package/src/vs/base/common/functional.ts +0 -32
- package/src/vs/base/common/hash.ts +0 -316
- package/src/vs/base/common/iterator.ts +0 -159
- package/src/vs/base/common/keyCodes.ts +0 -526
- package/src/vs/base/common/keybindings.ts +0 -284
- package/src/vs/base/common/lazy.ts +0 -47
- package/src/vs/base/common/lifecycle.ts +0 -801
- package/src/vs/base/common/linkedList.ts +0 -142
- package/src/vs/base/common/map.ts +0 -202
- package/src/vs/base/common/numbers.ts +0 -98
- package/src/vs/base/common/observable.ts +0 -76
- package/src/vs/base/common/observableInternal/api.ts +0 -31
- package/src/vs/base/common/observableInternal/autorun.ts +0 -281
- package/src/vs/base/common/observableInternal/base.ts +0 -489
- package/src/vs/base/common/observableInternal/debugName.ts +0 -145
- package/src/vs/base/common/observableInternal/derived.ts +0 -428
- package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
- package/src/vs/base/common/observableInternal/logging.ts +0 -328
- package/src/vs/base/common/observableInternal/promise.ts +0 -209
- package/src/vs/base/common/observableInternal/utils.ts +0 -610
- package/src/vs/base/common/platform.ts +0 -281
- package/src/vs/base/common/scrollable.ts +0 -522
- package/src/vs/base/common/sequence.ts +0 -34
- package/src/vs/base/common/stopwatch.ts +0 -43
- package/src/vs/base/common/strings.ts +0 -557
- package/src/vs/base/common/symbols.ts +0 -9
- package/src/vs/base/common/uint.ts +0 -59
- package/src/vs/patches/nls.ts +0 -90
- package/src/vs/typings/base-common.d.ts +0 -20
- package/src/vs/typings/require.d.ts +0 -42
- package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
- package/src/vs/typings/vscode-globals-product.d.ts +0 -33
|
@@ -14,13 +14,18 @@ export const enum ParserState {
|
|
|
14
14
|
CSI_PARAM = 4,
|
|
15
15
|
CSI_INTERMEDIATE = 5,
|
|
16
16
|
CSI_IGNORE = 6,
|
|
17
|
-
|
|
17
|
+
SOS_PM_STRING = 7,
|
|
18
18
|
OSC_STRING = 8,
|
|
19
19
|
DCS_ENTRY = 9,
|
|
20
20
|
DCS_PARAM = 10,
|
|
21
21
|
DCS_IGNORE = 11,
|
|
22
22
|
DCS_INTERMEDIATE = 12,
|
|
23
|
-
DCS_PASSTHROUGH = 13
|
|
23
|
+
DCS_PASSTHROUGH = 13,
|
|
24
|
+
APC_ENTRY = 14,
|
|
25
|
+
APC_INTERMEDIATE = 15,
|
|
26
|
+
APC_PASSTHROUGH = 16,
|
|
27
|
+
// Number of states, meaning LAST_STATE + 1.
|
|
28
|
+
STATE_LENGTH = 17
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
/**
|
|
@@ -41,7 +46,10 @@ export const enum ParserAction {
|
|
|
41
46
|
CLEAR = 11,
|
|
42
47
|
DCS_HOOK = 12,
|
|
43
48
|
DCS_PUT = 13,
|
|
44
|
-
DCS_UNHOOK = 14
|
|
49
|
+
DCS_UNHOOK = 14,
|
|
50
|
+
APC_START = 15,
|
|
51
|
+
APC_PUT = 16,
|
|
52
|
+
APC_END = 17
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
/**
|
|
@@ -55,4 +63,6 @@ export const enum OscState {
|
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
// payload limit for OSC and DCS
|
|
58
|
-
export const
|
|
66
|
+
export const enum ParserConstants {
|
|
67
|
+
PAYLOAD_LIMIT = 10000000
|
|
68
|
+
}
|
|
@@ -7,7 +7,8 @@ import { IDisposable } from 'common/Types';
|
|
|
7
7
|
import { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from 'common/parser/Types';
|
|
8
8
|
import { utf32ToString } from 'common/input/TextDecoder';
|
|
9
9
|
import { Params } from 'common/parser/Params';
|
|
10
|
-
import {
|
|
10
|
+
import { ParserConstants } from 'common/parser/Constants';
|
|
11
|
+
import { LimitedStringBuilder } from 'common/StringBuilder';
|
|
11
12
|
|
|
12
13
|
const EMPTY_HANDLERS: IDcsHandler[] = [];
|
|
13
14
|
|
|
@@ -29,9 +30,7 @@ export class DcsParser implements IDcsParser {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
public registerHandler(ident: number, handler: IDcsHandler): IDisposable {
|
|
32
|
-
|
|
33
|
-
this._handlers[ident] = [];
|
|
34
|
-
}
|
|
33
|
+
this._handlers[ident] ??= [];
|
|
35
34
|
const handlerList = this._handlers[ident];
|
|
36
35
|
handlerList.push(handler);
|
|
37
36
|
return {
|
|
@@ -140,7 +139,9 @@ EMPTY_PARAMS.addParam(0);
|
|
|
140
139
|
* Note: The payload is currently limited to 50 MB (hardcoded).
|
|
141
140
|
*/
|
|
142
141
|
export class DcsHandler implements IDcsHandler {
|
|
143
|
-
private
|
|
142
|
+
private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
|
|
143
|
+
|
|
144
|
+
private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);
|
|
144
145
|
private _params: IParams = EMPTY_PARAMS;
|
|
145
146
|
private _hitLimit: boolean = false;
|
|
146
147
|
|
|
@@ -152,7 +153,7 @@ export class DcsHandler implements IDcsHandler {
|
|
|
152
153
|
// perf optimization:
|
|
153
154
|
// clone only, if we have non empty params, otherwise stick with default
|
|
154
155
|
this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;
|
|
155
|
-
this._data
|
|
156
|
+
this._data.reset();
|
|
156
157
|
this._hitLimit = false;
|
|
157
158
|
}
|
|
158
159
|
|
|
@@ -160,9 +161,7 @@ export class DcsHandler implements IDcsHandler {
|
|
|
160
161
|
if (this._hitLimit) {
|
|
161
162
|
return;
|
|
162
163
|
}
|
|
163
|
-
this._data
|
|
164
|
-
if (this._data.length > PAYLOAD_LIMIT) {
|
|
165
|
-
this._data = '';
|
|
164
|
+
if (this._data.append(utf32ToString(data, start, end))) {
|
|
166
165
|
this._hitLimit = true;
|
|
167
166
|
}
|
|
168
167
|
}
|
|
@@ -172,20 +171,20 @@ export class DcsHandler implements IDcsHandler {
|
|
|
172
171
|
if (this._hitLimit) {
|
|
173
172
|
ret = false;
|
|
174
173
|
} else if (success) {
|
|
175
|
-
ret = this._handler(this._data, this._params);
|
|
174
|
+
ret = this._handler(this._data.toString(), this._params);
|
|
176
175
|
if (ret instanceof Promise) {
|
|
177
176
|
// need to hold data and params until `ret` got resolved
|
|
178
177
|
// dont care for errors, data will be freed anyway on next start
|
|
179
178
|
return ret.then(res => {
|
|
180
179
|
this._params = EMPTY_PARAMS;
|
|
181
|
-
this._data
|
|
180
|
+
this._data.reset();
|
|
182
181
|
this._hitLimit = false;
|
|
183
182
|
return res;
|
|
184
183
|
});
|
|
185
184
|
}
|
|
186
185
|
}
|
|
187
186
|
this._params = EMPTY_PARAMS;
|
|
188
|
-
this._data
|
|
187
|
+
this._data.reset();
|
|
189
188
|
this._hitLimit = false;
|
|
190
189
|
return ret;
|
|
191
190
|
}
|
|
@@ -3,13 +3,32 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType } from 'common/parser/Types';
|
|
6
|
+
import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from 'common/parser/Types';
|
|
7
7
|
import { ParserState, ParserAction } from 'common/parser/Constants';
|
|
8
|
-
import { Disposable, toDisposable } from '
|
|
8
|
+
import { Disposable, toDisposable } from 'common/Lifecycle';
|
|
9
9
|
import { IDisposable } from 'common/Types';
|
|
10
10
|
import { Params } from 'common/parser/Params';
|
|
11
11
|
import { OscParser } from 'common/parser/OscParser';
|
|
12
12
|
import { DcsParser } from 'common/parser/DcsParser';
|
|
13
|
+
import { ApcParser } from 'common/parser/ApcParser';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* VT commands done by the parser
|
|
17
|
+
*/
|
|
18
|
+
// @vt: #Y ESC CSI "Control Sequence Introducer" "ESC [" "Start of a CSI sequence."
|
|
19
|
+
// @vt: #Y ESC OSC "Operating System Command" "ESC ]" "Start of an OSC sequence."
|
|
20
|
+
// @vt: #Y ESC DCS "Device Control String" "ESC P" "Start of a DCS sequence."
|
|
21
|
+
// @vt: #Y ESC ST "String Terminator" "ESC \" "Terminator used for string type sequences."
|
|
22
|
+
// @vt: #Y ESC PM "Privacy Message" "ESC ^" "Start of a privacy message."
|
|
23
|
+
// @vt: #Y ESC APC "Application Program Command" "ESC _" "Start of an APC sequence."
|
|
24
|
+
// @vt: #Y C1 CSI "Control Sequence Introducer" "\x9B" "Start of a CSI sequence."
|
|
25
|
+
// @vt: #Y C1 OSC "Operating System Command" "\x9D" "Start of an OSC sequence."
|
|
26
|
+
// @vt: #Y C1 DCS "Device Control String" "\x90" "Start of a DCS sequence."
|
|
27
|
+
// @vt: #Y C1 ST "String Terminator" "\x9C" "Terminator used for string type sequences."
|
|
28
|
+
// @vt: #Y C1 PM "Privacy Message" "\x9E" "Start of a privacy message."
|
|
29
|
+
// @vt: #Y C1 APC "Application Program Command" "\x9F" "Start of an APC sequence."
|
|
30
|
+
// @vt: #Y C0 NUL "Null" "\0, \x00" "NUL is ignored."
|
|
31
|
+
// @vt: #Y C0 ESC "Escape" "\e, \x1B" "Start of a sequence. Cancels any other sequence."
|
|
13
32
|
|
|
14
33
|
/**
|
|
15
34
|
* Table values are generated like this:
|
|
@@ -17,8 +36,8 @@ import { DcsParser } from 'common/parser/DcsParser';
|
|
|
17
36
|
* value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState
|
|
18
37
|
*/
|
|
19
38
|
const enum TableAccess {
|
|
20
|
-
TRANSITION_ACTION_SHIFT =
|
|
21
|
-
TRANSITION_STATE_MASK =
|
|
39
|
+
TRANSITION_ACTION_SHIFT = 8,
|
|
40
|
+
TRANSITION_STATE_MASK = 255,
|
|
22
41
|
INDEX_STATE_SHIFT = 8
|
|
23
42
|
}
|
|
24
43
|
|
|
@@ -26,10 +45,10 @@ const enum TableAccess {
|
|
|
26
45
|
* Transition table for EscapeSequenceParser.
|
|
27
46
|
*/
|
|
28
47
|
export class TransitionTable {
|
|
29
|
-
public table:
|
|
48
|
+
public table: Uint16Array;
|
|
30
49
|
|
|
31
50
|
constructor(length: number) {
|
|
32
|
-
this.table = new
|
|
51
|
+
this.table = new Uint16Array(length);
|
|
33
52
|
}
|
|
34
53
|
|
|
35
54
|
/**
|
|
@@ -76,7 +95,9 @@ const NON_ASCII_PRINTABLE = 0xA0;
|
|
|
76
95
|
* Taken from https://vt100.net/emu/dec_ansi_parser.
|
|
77
96
|
*/
|
|
78
97
|
export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
79
|
-
|
|
98
|
+
// table size:
|
|
99
|
+
// (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1
|
|
100
|
+
const table: TransitionTable = new TransitionTable(4257);
|
|
80
101
|
|
|
81
102
|
// range macro for byte
|
|
82
103
|
const BYTE_VALUES = 256;
|
|
@@ -89,22 +110,22 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
89
110
|
EXECUTABLES.push(0x19);
|
|
90
111
|
EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
|
|
91
112
|
|
|
92
|
-
const states: number[] = r(ParserState.GROUND, ParserState.
|
|
93
|
-
let state: any;
|
|
113
|
+
const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);
|
|
94
114
|
|
|
95
115
|
// set default transition
|
|
96
116
|
table.setDefault(ParserAction.ERROR, ParserState.GROUND);
|
|
97
117
|
// printables
|
|
98
118
|
table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
|
|
99
119
|
// global anywhere rules
|
|
100
|
-
for (state
|
|
120
|
+
for (const state of states) {
|
|
101
121
|
table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);
|
|
102
122
|
table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);
|
|
103
123
|
table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);
|
|
104
124
|
table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator
|
|
105
125
|
table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC
|
|
106
126
|
table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC
|
|
107
|
-
table.addMany([0x98, 0x9e
|
|
127
|
+
table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM
|
|
128
|
+
table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC
|
|
108
129
|
table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
|
|
109
130
|
table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
|
|
110
131
|
}
|
|
@@ -128,12 +149,27 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
128
149
|
table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
|
|
129
150
|
table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);
|
|
130
151
|
table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);
|
|
131
|
-
// sos/pm
|
|
132
|
-
table.addMany([0x58, 0x5e
|
|
133
|
-
table.addMany(PRINTABLES, ParserState.
|
|
134
|
-
table.addMany(EXECUTABLES, ParserState.
|
|
135
|
-
table.add(0x9c, ParserState.
|
|
136
|
-
table.add(0x7f, ParserState.
|
|
152
|
+
// sos/pm
|
|
153
|
+
table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
|
|
154
|
+
table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
|
|
155
|
+
table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
|
|
156
|
+
table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);
|
|
157
|
+
table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
|
|
158
|
+
// apc
|
|
159
|
+
table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);
|
|
160
|
+
table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);
|
|
161
|
+
table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);
|
|
162
|
+
table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);
|
|
163
|
+
table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);
|
|
164
|
+
table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);
|
|
165
|
+
table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);
|
|
166
|
+
table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);
|
|
167
|
+
table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);
|
|
168
|
+
table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
|
|
169
|
+
table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);
|
|
170
|
+
table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
|
|
171
|
+
table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);
|
|
172
|
+
table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);
|
|
137
173
|
// csi entries
|
|
138
174
|
table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);
|
|
139
175
|
table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);
|
|
@@ -162,22 +198,18 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
162
198
|
table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);
|
|
163
199
|
table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
|
|
164
200
|
table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
|
|
165
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
|
|
166
201
|
table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
|
|
167
202
|
table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);
|
|
168
203
|
table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);
|
|
169
204
|
table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
170
205
|
table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
171
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
172
206
|
table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
|
|
173
207
|
table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
|
|
174
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
|
|
175
208
|
table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);
|
|
176
209
|
table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
177
210
|
table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
|
|
178
211
|
table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
|
|
179
212
|
table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
|
|
180
|
-
table.addMany(r(0x1c, 0x20), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
|
|
181
213
|
table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
|
|
182
214
|
table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
183
215
|
table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
|
|
@@ -193,6 +225,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
|
|
193
225
|
table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
|
|
194
226
|
table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
|
195
227
|
table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
|
|
228
|
+
table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
|
|
196
229
|
return table;
|
|
197
230
|
})();
|
|
198
231
|
|
|
@@ -239,10 +272,13 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
239
272
|
// handler lookup containers
|
|
240
273
|
protected _printHandler: PrintHandlerType;
|
|
241
274
|
protected _executeHandlers: { [flag: number]: ExecuteHandlerType };
|
|
275
|
+
// fast path for EXE bytes < 0x18
|
|
276
|
+
protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];
|
|
242
277
|
protected _csiHandlers: IHandlerCollection<CsiHandlerType>;
|
|
243
278
|
protected _escHandlers: IHandlerCollection<EscHandlerType>;
|
|
244
279
|
protected readonly _oscParser: IOscParser;
|
|
245
280
|
protected readonly _dcsParser: IDcsParser;
|
|
281
|
+
protected readonly _apcParser: IApcParser;
|
|
246
282
|
protected _errorHandler: (state: IParsingState) => IParsingState;
|
|
247
283
|
|
|
248
284
|
// fallback handlers
|
|
@@ -281,15 +317,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
281
317
|
this._errorHandlerFb = (state: IParsingState): IParsingState => state;
|
|
282
318
|
this._printHandler = this._printHandlerFb;
|
|
283
319
|
this._executeHandlers = Object.create(null);
|
|
320
|
+
this._executeHandlersArr = new Array(0x18).fill(undefined);
|
|
284
321
|
this._csiHandlers = Object.create(null);
|
|
285
322
|
this._escHandlers = Object.create(null);
|
|
286
323
|
this._register(toDisposable(() => {
|
|
287
324
|
this._csiHandlers = Object.create(null);
|
|
288
325
|
this._executeHandlers = Object.create(null);
|
|
326
|
+
this._executeHandlersArr = new Array(0x18).fill(undefined);
|
|
289
327
|
this._escHandlers = Object.create(null);
|
|
290
328
|
}));
|
|
291
329
|
this._oscParser = this._register(new OscParser());
|
|
292
330
|
this._dcsParser = this._register(new DcsParser());
|
|
331
|
+
this._apcParser = this._register(new ApcParser());
|
|
293
332
|
this._errorHandler = this._errorHandlerFb;
|
|
294
333
|
|
|
295
334
|
// swallow 7bit ST (ESC+\)
|
|
@@ -351,9 +390,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
351
390
|
|
|
352
391
|
public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {
|
|
353
392
|
const ident = this._identifier(id, [0x30, 0x7e]);
|
|
354
|
-
|
|
355
|
-
this._escHandlers[ident] = [];
|
|
356
|
-
}
|
|
393
|
+
this._escHandlers[ident] ??= [];
|
|
357
394
|
const handlerList = this._escHandlers[ident];
|
|
358
395
|
handlerList.push(handler);
|
|
359
396
|
return {
|
|
@@ -373,10 +410,14 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
373
410
|
}
|
|
374
411
|
|
|
375
412
|
public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {
|
|
376
|
-
|
|
413
|
+
const code = flag.charCodeAt(0);
|
|
414
|
+
this._executeHandlers[code] = handler;
|
|
415
|
+
if (code < 0x18) this._executeHandlersArr[code] = handler;
|
|
377
416
|
}
|
|
378
417
|
public clearExecuteHandler(flag: string): void {
|
|
379
|
-
|
|
418
|
+
const code = flag.charCodeAt(0);
|
|
419
|
+
if (this._executeHandlers[code]) delete this._executeHandlers[code];
|
|
420
|
+
if (code < 0x18) this._executeHandlersArr[code] = undefined;
|
|
380
421
|
}
|
|
381
422
|
public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {
|
|
382
423
|
this._executeHandlerFb = handler;
|
|
@@ -384,9 +425,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
384
425
|
|
|
385
426
|
public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {
|
|
386
427
|
const ident = this._identifier(id);
|
|
387
|
-
|
|
388
|
-
this._csiHandlers[ident] = [];
|
|
389
|
-
}
|
|
428
|
+
this._csiHandlers[ident] ??= [];
|
|
390
429
|
const handlerList = this._csiHandlers[ident];
|
|
391
430
|
handlerList.push(handler);
|
|
392
431
|
return {
|
|
@@ -425,6 +464,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
425
464
|
this._oscParser.setHandlerFallback(handler);
|
|
426
465
|
}
|
|
427
466
|
|
|
467
|
+
public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {
|
|
468
|
+
id.prefix = undefined; // APC does not support prefix byte
|
|
469
|
+
return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);
|
|
470
|
+
}
|
|
471
|
+
public clearApcHandler(id: IFunctionIdentifier): void {
|
|
472
|
+
id.prefix = undefined; // APC does not support prefix byte
|
|
473
|
+
this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));
|
|
474
|
+
}
|
|
475
|
+
public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {
|
|
476
|
+
this._apcParser.setHandlerFallback(handler);
|
|
477
|
+
}
|
|
478
|
+
|
|
428
479
|
public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
|
|
429
480
|
this._errorHandler = callback;
|
|
430
481
|
}
|
|
@@ -445,8 +496,8 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
445
496
|
this.currentState = this.initialState;
|
|
446
497
|
this._oscParser.reset();
|
|
447
498
|
this._dcsParser.reset();
|
|
448
|
-
this.
|
|
449
|
-
this._params.
|
|
499
|
+
this._apcParser.reset();
|
|
500
|
+
this._params.resetZdm();
|
|
450
501
|
this._collect = 0;
|
|
451
502
|
this.precedingJoinState = 0;
|
|
452
503
|
// abort pending continuation from async handler
|
|
@@ -489,6 +540,10 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
489
540
|
* - OSC_STRING:OSC_PUT
|
|
490
541
|
* - DCS_PASSTHROUGH:DCS_PUT
|
|
491
542
|
*
|
|
543
|
+
* Additionally the following fast paths exist before the table lookup:
|
|
544
|
+
* - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)
|
|
545
|
+
* - 7-bit CSI sequences without intermediates (ESC [ params final)
|
|
546
|
+
*
|
|
492
547
|
* Note on asynchronous handler support:
|
|
493
548
|
* Any handler returning a promise will be treated as asynchronous.
|
|
494
549
|
* To keep the in-band blocking working for async handlers, `parse` pauses execution,
|
|
@@ -591,8 +646,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
591
646
|
return handlerResult;
|
|
592
647
|
}
|
|
593
648
|
if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
|
|
594
|
-
this._params.
|
|
595
|
-
this._params.addParam(0); // ZDM
|
|
649
|
+
this._params.resetZdm();
|
|
596
650
|
this._collect = 0;
|
|
597
651
|
break;
|
|
598
652
|
case ParserStackType.OSC:
|
|
@@ -602,8 +656,17 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
602
656
|
return handlerResult;
|
|
603
657
|
}
|
|
604
658
|
if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
|
|
605
|
-
this._params.
|
|
606
|
-
this.
|
|
659
|
+
this._params.resetZdm();
|
|
660
|
+
this._collect = 0;
|
|
661
|
+
break;
|
|
662
|
+
case ParserStackType.APC:
|
|
663
|
+
code = data[this._parseStack.chunkPos];
|
|
664
|
+
handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);
|
|
665
|
+
if (handlerResult) {
|
|
666
|
+
return handlerResult;
|
|
667
|
+
}
|
|
668
|
+
if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
|
|
669
|
+
this._params.resetZdm();
|
|
607
670
|
this._collect = 0;
|
|
608
671
|
break;
|
|
609
672
|
}
|
|
@@ -621,34 +684,90 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
621
684
|
for (let i = start; i < length; ++i) {
|
|
622
685
|
code = data[i];
|
|
623
686
|
|
|
687
|
+
// EXE fast-path: common control bytes (0x00-0x17) in non-payload states
|
|
688
|
+
if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {
|
|
689
|
+
(this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);
|
|
690
|
+
this.precedingJoinState = 0;
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop
|
|
695
|
+
if (code === 0x1b
|
|
696
|
+
&& this.currentState < ParserState.OSC_STRING
|
|
697
|
+
&& i + 2 < length && data[i + 1] === 0x5b
|
|
698
|
+
) {
|
|
699
|
+
this._params.resetZdm();
|
|
700
|
+
this._collect = 0;
|
|
701
|
+
let k = i + 2;
|
|
702
|
+
let ch = data[k];
|
|
703
|
+
if (ch >= 0x3c && ch <= 0x3f) {
|
|
704
|
+
this._collect = ch;
|
|
705
|
+
k++;
|
|
706
|
+
}
|
|
707
|
+
let csiDone = false;
|
|
708
|
+
for (; k < length; k++) {
|
|
709
|
+
ch = data[k];
|
|
710
|
+
if (ch >= 0x30 && ch <= 0x39) {
|
|
711
|
+
this._params.addDigit(ch - 48);
|
|
712
|
+
} else if (ch === 0x3b) {
|
|
713
|
+
this._params.addParam(0);
|
|
714
|
+
} else if (ch === 0x3a) {
|
|
715
|
+
this._params.addSubParam(-1);
|
|
716
|
+
} else if (ch >= 0x40 && ch <= 0x7e) {
|
|
717
|
+
const handlers = this._csiHandlers[this._collect << 8 | ch];
|
|
718
|
+
let j = handlers ? handlers.length - 1 : -1;
|
|
719
|
+
for (; j >= 0; j--) {
|
|
720
|
+
handlerResult = handlers[j](this._params);
|
|
721
|
+
if (handlerResult === true) {
|
|
722
|
+
break;
|
|
723
|
+
} else if (handlerResult instanceof Promise) {
|
|
724
|
+
transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;
|
|
725
|
+
this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);
|
|
726
|
+
return handlerResult;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
if (j < 0) {
|
|
730
|
+
this._csiHandlerFb(this._collect << 8 | ch, this._params);
|
|
731
|
+
}
|
|
732
|
+
this.precedingJoinState = 0;
|
|
733
|
+
i = k;
|
|
734
|
+
this.currentState = ParserState.GROUND;
|
|
735
|
+
csiDone = true;
|
|
736
|
+
break;
|
|
737
|
+
} else {
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
if (!csiDone) {
|
|
742
|
+
i = k - 1;
|
|
743
|
+
this.currentState = ParserState.CSI_PARAM;
|
|
744
|
+
}
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
747
|
+
|
|
624
748
|
// normal transition & action lookup
|
|
625
|
-
transition = this._transitions.table[
|
|
749
|
+
transition = this._transitions.table[
|
|
750
|
+
this.currentState << TableAccess.INDEX_STATE_SHIFT |
|
|
751
|
+
(code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)
|
|
752
|
+
];
|
|
626
753
|
switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {
|
|
627
754
|
case ParserAction.PRINT:
|
|
628
|
-
// read ahead with loop unrolling
|
|
629
755
|
// Note: 0x20 (SP) is included, 0x7F (DEL) is excluded
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
|
|
642
|
-
this._printHandler(data, i, j);
|
|
643
|
-
i = j - 1;
|
|
644
|
-
break;
|
|
645
|
-
}
|
|
646
|
-
if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
|
|
647
|
-
this._printHandler(data, i, j);
|
|
648
|
-
i = j - 1;
|
|
649
|
-
break;
|
|
756
|
+
let c = i;
|
|
757
|
+
const l4 = length - 4;
|
|
758
|
+
while (c < l4
|
|
759
|
+
&& data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
|
|
760
|
+
&& data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
|
|
761
|
+
&& data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
|
|
762
|
+
&& data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
|
|
763
|
+
) {}
|
|
764
|
+
if (c >= l4) {
|
|
765
|
+
while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {
|
|
766
|
+
c++;
|
|
650
767
|
}
|
|
651
768
|
}
|
|
769
|
+
this._printHandler(data, i, c);
|
|
770
|
+
i = c - 1;
|
|
652
771
|
break;
|
|
653
772
|
case ParserAction.EXECUTE:
|
|
654
773
|
if (this._executeHandlers[code]) this._executeHandlers[code]();
|
|
@@ -730,8 +849,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
730
849
|
this.precedingJoinState = 0;
|
|
731
850
|
break;
|
|
732
851
|
case ParserAction.CLEAR:
|
|
733
|
-
this._params.
|
|
734
|
-
this._params.addParam(0); // ZDM
|
|
852
|
+
this._params.resetZdm();
|
|
735
853
|
this._collect = 0;
|
|
736
854
|
break;
|
|
737
855
|
case ParserAction.DCS_HOOK:
|
|
@@ -755,8 +873,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
755
873
|
return handlerResult;
|
|
756
874
|
}
|
|
757
875
|
if (code === 0x1b) transition |= ParserState.ESCAPE;
|
|
758
|
-
this._params.
|
|
759
|
-
this._params.addParam(0); // ZDM
|
|
876
|
+
this._params.resetZdm();
|
|
760
877
|
this._collect = 0;
|
|
761
878
|
this.precedingJoinState = 0;
|
|
762
879
|
break;
|
|
@@ -780,8 +897,33 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
|
|
780
897
|
return handlerResult;
|
|
781
898
|
}
|
|
782
899
|
if (code === 0x1b) transition |= ParserState.ESCAPE;
|
|
783
|
-
this._params.
|
|
784
|
-
this.
|
|
900
|
+
this._params.resetZdm();
|
|
901
|
+
this._collect = 0;
|
|
902
|
+
this.precedingJoinState = 0;
|
|
903
|
+
break;
|
|
904
|
+
case ParserAction.APC_START:
|
|
905
|
+
this._apcParser.start(this._collect << 8 | code);
|
|
906
|
+
break;
|
|
907
|
+
case ParserAction.APC_PUT:
|
|
908
|
+
// inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c
|
|
909
|
+
// allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE
|
|
910
|
+
for (let j = i + 1; ; ++j) {
|
|
911
|
+
if (j < length && (
|
|
912
|
+
(data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE
|
|
913
|
+
)) continue;
|
|
914
|
+
this._apcParser.put(data, i, j);
|
|
915
|
+
i = j - 1;
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
break;
|
|
919
|
+
case ParserAction.APC_END:
|
|
920
|
+
handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);
|
|
921
|
+
if (handlerResult) {
|
|
922
|
+
this._preserveStack(ParserStackType.APC, [], 0, transition, i);
|
|
923
|
+
return handlerResult;
|
|
924
|
+
}
|
|
925
|
+
if (code === 0x1b) transition |= ParserState.ESCAPE;
|
|
926
|
+
this._params.resetZdm();
|
|
785
927
|
this._collect = 0;
|
|
786
928
|
this.precedingJoinState = 0;
|
|
787
929
|
break;
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from 'common/parser/Types';
|
|
7
|
-
import { OscState,
|
|
7
|
+
import { OscState, ParserConstants } from 'common/parser/Constants';
|
|
8
8
|
import { utf32ToString } from 'common/input/TextDecoder';
|
|
9
9
|
import { IDisposable } from 'common/Types';
|
|
10
|
+
import { LimitedStringBuilder } from 'common/StringBuilder';
|
|
10
11
|
|
|
11
12
|
const EMPTY_HANDLERS: IOscHandler[] = [];
|
|
12
13
|
|
|
@@ -23,9 +24,7 @@ export class OscParser implements IOscParser {
|
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
public registerHandler(ident: number, handler: IOscHandler): IDisposable {
|
|
26
|
-
|
|
27
|
-
this._handlers[ident] = [];
|
|
28
|
-
}
|
|
27
|
+
this._handlers[ident] ??= [];
|
|
29
28
|
const handlerList = this._handlers[ident];
|
|
30
29
|
handlerList.push(handler);
|
|
31
30
|
return {
|
|
@@ -194,13 +193,15 @@ export class OscParser implements IOscParser {
|
|
|
194
193
|
* as OSC handlers.
|
|
195
194
|
*/
|
|
196
195
|
export class OscHandler implements IOscHandler {
|
|
197
|
-
private
|
|
196
|
+
private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
|
|
197
|
+
|
|
198
|
+
private _data = new LimitedStringBuilder(OscHandler._payloadLimit);
|
|
198
199
|
private _hitLimit: boolean = false;
|
|
199
200
|
|
|
200
201
|
constructor(private _handler: (data: string) => boolean | Promise<boolean>) { }
|
|
201
202
|
|
|
202
203
|
public start(): void {
|
|
203
|
-
this._data
|
|
204
|
+
this._data.reset();
|
|
204
205
|
this._hitLimit = false;
|
|
205
206
|
}
|
|
206
207
|
|
|
@@ -208,9 +209,7 @@ export class OscHandler implements IOscHandler {
|
|
|
208
209
|
if (this._hitLimit) {
|
|
209
210
|
return;
|
|
210
211
|
}
|
|
211
|
-
this._data
|
|
212
|
-
if (this._data.length > PAYLOAD_LIMIT) {
|
|
213
|
-
this._data = '';
|
|
212
|
+
if (this._data.append(utf32ToString(data, start, end))) {
|
|
214
213
|
this._hitLimit = true;
|
|
215
214
|
}
|
|
216
215
|
}
|
|
@@ -220,18 +219,18 @@ export class OscHandler implements IOscHandler {
|
|
|
220
219
|
if (this._hitLimit) {
|
|
221
220
|
ret = false;
|
|
222
221
|
} else if (success) {
|
|
223
|
-
ret = this._handler(this._data);
|
|
222
|
+
ret = this._handler(this._data.toString());
|
|
224
223
|
if (ret instanceof Promise) {
|
|
225
224
|
// need to hold data until `ret` got resolved
|
|
226
225
|
// dont care for errors, data will be freed anyway on next start
|
|
227
226
|
return ret.then(res => {
|
|
228
|
-
this._data
|
|
227
|
+
this._data.reset();
|
|
229
228
|
this._hitLimit = false;
|
|
230
229
|
return res;
|
|
231
230
|
});
|
|
232
231
|
}
|
|
233
232
|
}
|
|
234
|
-
this._data
|
|
233
|
+
this._data.reset();
|
|
235
234
|
this._hitLimit = false;
|
|
236
235
|
return ret;
|
|
237
236
|
}
|