+++ /dev/null
-/**
- * Copyright (c) 2019 The xterm.js authors. All rights reserved.
- * @license MIT
- */
-
-import { IDisposable } from 'common/Types';
-import { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType } from 'common/parser/Types';
-import { utf32ToString } from 'common/input/TextDecoder';
-import { Params } from 'common/parser/Params';
-import { PAYLOAD_LIMIT } from 'common/parser/Constants';
-
-const EMPTY_HANDLERS: IDcsHandler[] = [];
-
-export class DcsParser implements IDcsParser {
- private _handlers: IHandlerCollection<IDcsHandler> = Object.create(null);
- private _active: IDcsHandler[] = EMPTY_HANDLERS;
- private _ident: number = 0;
- private _handlerFb: DcsFallbackHandlerType = () => {};
-
- public dispose(): void {
- this._handlers = Object.create(null);
- this._handlerFb = () => {};
- }
-
- public addHandler(ident: number, handler: IDcsHandler): IDisposable {
- if (this._handlers[ident] === undefined) {
- this._handlers[ident] = [];
- }
- const handlerList = this._handlers[ident];
- handlerList.push(handler);
- return {
- dispose: () => {
- const handlerIndex = handlerList.indexOf(handler);
- if (handlerIndex !== -1) {
- handlerList.splice(handlerIndex, 1);
- }
- }
- };
- }
-
- public setHandler(ident: number, handler: IDcsHandler): void {
- this._handlers[ident] = [handler];
- }
-
- public clearHandler(ident: number): void {
- if (this._handlers[ident]) delete this._handlers[ident];
- }
-
- public setHandlerFallback(handler: DcsFallbackHandlerType): void {
- this._handlerFb = handler;
- }
-
- public reset(): void {
- if (this._active.length) {
- this.unhook(false);
- }
- this._active = EMPTY_HANDLERS;
- this._ident = 0;
- }
-
- public hook(ident: number, params: IParams): void {
- // always reset leftover handlers
- this.reset();
- this._ident = ident;
- this._active = this._handlers[ident] || EMPTY_HANDLERS;
- if (!this._active.length) {
- this._handlerFb(this._ident, 'HOOK', params);
- } else {
- for (let j = this._active.length - 1; j >= 0; j--) {
- this._active[j].hook(params);
- }
- }
- }
-
- public put(data: Uint32Array, start: number, end: number): void {
- if (!this._active.length) {
- this._handlerFb(this._ident, 'PUT', utf32ToString(data, start, end));
- } else {
- for (let j = this._active.length - 1; j >= 0; j--) {
- this._active[j].put(data, start, end);
- }
- }
- }
-
- public unhook(success: boolean): void {
- if (!this._active.length) {
- this._handlerFb(this._ident, 'UNHOOK', success);
- } else {
- let j = this._active.length - 1;
- for (; j >= 0; j--) {
- if (this._active[j].unhook(success) !== false) {
- break;
- }
- }
- j--;
- // cleanup left over handlers
- for (; j >= 0; j--) {
- this._active[j].unhook(false);
- }
- }
- this._active = EMPTY_HANDLERS;
- this._ident = 0;
- }
-}
-
-/**
- * Convenient class to create a DCS handler from a single callback function.
- * Note: The payload is currently limited to 50 MB (hardcoded).
- */
-export class DcsHandler implements IDcsHandler {
- private _data = '';
- private _params: IParams | undefined;
- private _hitLimit: boolean = false;
-
- constructor(private _handler: (data: string, params: IParams) => any) {}
-
- public hook(params: IParams): void {
- this._params = params.clone();
- this._data = '';
- this._hitLimit = false;
- }
-
- public put(data: Uint32Array, start: number, end: number): void {
- if (this._hitLimit) {
- return;
- }
- this._data += utf32ToString(data, start, end);
- if (this._data.length > PAYLOAD_LIMIT) {
- this._data = '';
- this._hitLimit = true;
- }
- }
-
- public unhook(success: boolean): any {
- let ret;
- if (this._hitLimit) {
- ret = false;
- } else if (success) {
- ret = this._handler(this._data, this._params ? this._params : new Params());
- }
- this._params = undefined;
- this._data = '';
- this._hitLimit = false;
- return ret;
- }
-}