155 lines
4.6 KiB
JavaScript
155 lines
4.6 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Copyright (c) 2023 The xterm.js authors. All rights reserved.
|
|
* @license MIT
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.HeaderParser = void 0;
|
|
// field value decoders
|
|
// ASCII bytes to string
|
|
function toStr(data) {
|
|
let s = '';
|
|
for (let i = 0; i < data.length; ++i) {
|
|
s += String.fromCharCode(data[i]);
|
|
}
|
|
return s;
|
|
}
|
|
// digits to integer
|
|
function toInt(data) {
|
|
let v = 0;
|
|
for (let i = 0; i < data.length; ++i) {
|
|
if (data[i] < 48 || data[i] > 57) {
|
|
throw new Error('illegal char');
|
|
}
|
|
v = v * 10 + data[i] - 48;
|
|
}
|
|
return v;
|
|
}
|
|
// check for correct size entry
|
|
function toSize(data) {
|
|
const v = toStr(data);
|
|
if (!v.match(/^((auto)|(\d+?((px)|(%)){0,1}))$/)) {
|
|
throw new Error('illegal size');
|
|
}
|
|
return v;
|
|
}
|
|
// name is base64 encoded utf-8
|
|
function toName(data) {
|
|
if (typeof Buffer !== 'undefined') {
|
|
return Buffer.from(toStr(data), 'base64').toString();
|
|
}
|
|
const bs = atob(toStr(data));
|
|
const b = new Uint8Array(bs.length);
|
|
for (let i = 0; i < b.length; ++i) {
|
|
b[i] = bs.charCodeAt(i);
|
|
}
|
|
return new TextDecoder().decode(b);
|
|
}
|
|
const DECODERS = {
|
|
inline: toInt,
|
|
size: toInt,
|
|
name: toName,
|
|
width: toSize,
|
|
height: toSize,
|
|
preserveAspectRatio: toInt
|
|
};
|
|
const FILE_MARKER = [70, 105, 108, 101];
|
|
const MAX_FIELDCHARS = 1024;
|
|
class HeaderParser {
|
|
constructor() {
|
|
this.state = 0 /* HeaderState.START */;
|
|
this._buffer = new Uint32Array(MAX_FIELDCHARS);
|
|
this._position = 0;
|
|
this._key = '';
|
|
this.fields = {};
|
|
}
|
|
reset() {
|
|
this._buffer.fill(0);
|
|
this.state = 0 /* HeaderState.START */;
|
|
this._position = 0;
|
|
this.fields = {};
|
|
this._key = '';
|
|
}
|
|
parse(data, start, end) {
|
|
let state = this.state;
|
|
let pos = this._position;
|
|
const buffer = this._buffer;
|
|
if (state === 1 /* HeaderState.ABORT */ || state === 4 /* HeaderState.END */)
|
|
return -1;
|
|
if (state === 0 /* HeaderState.START */ && pos > 6)
|
|
return -1;
|
|
for (let i = start; i < end; ++i) {
|
|
const c = data[i];
|
|
switch (c) {
|
|
case 59: // ;
|
|
if (!this._storeValue(pos))
|
|
return this._a();
|
|
state = 2 /* HeaderState.KEY */;
|
|
pos = 0;
|
|
break;
|
|
case 61: // =
|
|
if (state === 0 /* HeaderState.START */) {
|
|
for (let k = 0; k < FILE_MARKER.length; ++k) {
|
|
if (buffer[k] !== FILE_MARKER[k])
|
|
return this._a();
|
|
}
|
|
state = 2 /* HeaderState.KEY */;
|
|
pos = 0;
|
|
}
|
|
else if (state === 2 /* HeaderState.KEY */) {
|
|
if (!this._storeKey(pos))
|
|
return this._a();
|
|
state = 3 /* HeaderState.VALUE */;
|
|
pos = 0;
|
|
}
|
|
else if (state === 3 /* HeaderState.VALUE */) {
|
|
if (pos >= MAX_FIELDCHARS)
|
|
return this._a();
|
|
buffer[pos++] = c;
|
|
}
|
|
break;
|
|
case 58: // :
|
|
if (state === 3 /* HeaderState.VALUE */) {
|
|
if (!this._storeValue(pos))
|
|
return this._a();
|
|
}
|
|
this.state = 4 /* HeaderState.END */;
|
|
return i + 1;
|
|
default:
|
|
if (pos >= MAX_FIELDCHARS)
|
|
return this._a();
|
|
buffer[pos++] = c;
|
|
}
|
|
}
|
|
this.state = state;
|
|
this._position = pos;
|
|
return -2;
|
|
}
|
|
_a() {
|
|
this.state = 1 /* HeaderState.ABORT */;
|
|
return -1;
|
|
}
|
|
_storeKey(pos) {
|
|
const k = toStr(this._buffer.subarray(0, pos));
|
|
if (k) {
|
|
this._key = k;
|
|
this.fields[k] = null;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
_storeValue(pos) {
|
|
if (this._key) {
|
|
try {
|
|
const v = this._buffer.slice(0, pos);
|
|
this.fields[this._key] = DECODERS[this._key] ? DECODERS[this._key](v) : v;
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
exports.HeaderParser = HeaderParser; |