You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.6 KiB
JavaScript

class PacketBufferScanFirst {
#callback;
#timeout;
#buf;
#tout;
constructor(callback, timeout = 600) {
this.#callback = callback;
this.#timeout = timeout;
this.#buf = [];
}
push(data) {
if (this.#tout) clearTimeout(this.#tout);
this.#tout = setTimeout(() => this.#buf.length = 0, this.#timeout);
if (!this.#buf && !(data.startsWith('\n{') || data.startsWith('#{')))
return;
this.#buf.push(data);
if ((data.endsWith('}\n') || data.endsWith('}#')) && this.#buf[0][0] === data[data.length - 1]) {
this.#callback(this.#buf.join(''));
this.#buf.length = 0;
if (this.#tout) clearTimeout(this._tout);
this.#tout = null;
}
}
clear() {
if (this.#tout) clearTimeout(this.#tout);
this.#tout = undefined;
this.#buf.length = 0;
}
};
class PacketBufferScanAll {
#callback;
#timeout;
/** @type {Uint8Array} */ #buf;
#tout = null;
constructor(callback, timeout = 600) {
this.#callback = callback;
this.#timeout = timeout;
this.#buf = null;
}
/**
*
* @param {Uint8Array} data
*/
push(data) {
if (this.#tout) clearTimeout(this.#tout);
this.#tout = setTimeout(() => this.#buf = null, this.#timeout);
if (this.#buf) {
const merged = new Uint8Array(this.#buf.length + data.length);
merged.set(this.#buf);
merged.set(data, this.#buf.length);
this.#buf = merged;
data = null;
} else {
this.#buf = data;
}
this.#pump();
}
#pump() {
let index = 0;
const decoder = new TextDecoder();
while (true) {
const startIndex1 = this.#indexOfSeq('\n{', index);
const startIndex2 = this.#indexOfSeq('#{', index);
let startIndex;
let endIndex;
if (startIndex1 < startIndex2) {
startIndex = startIndex1;
endIndex = this.#indexOfSeq('}\n', startIndex1);
} else {
startIndex = startIndex2;
endIndex = this.#indexOfSeq('}#', startIndex2);
}
if (startIndex === this.#buf.length || endIndex === this.#buf.length)
break;
const text = decoder.decode(this.#buf.subarray(startIndex, endIndex + 2));
this.#callback(text);
index = endIndex + 2;
}
if (index) {
this.#buf = this.#buf.slice(index);
}
}
#indexOfSeq(seq, fromIndex = 0) {
while (true) {
const i = this.#buf.indexOf(seq.charCodeAt(0), fromIndex);
if (i === -1 || i > this.#buf.length - 2)
return this.#buf.length;
if (this.#buf[i + 1] === seq.charCodeAt(1)) {
return i;
}
fromIndex = i + 1;
}
}
};