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.

63 lines
2.1 KiB
JavaScript

5 months ago
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SlipEncoder = void 0;
const stream_1 = require("stream");
/**
* A transform stream that emits SLIP-encoded data for each incoming packet.
*
* Runs in O(n) time, adding a 0xC0 character at the end of each
* received packet and escaping characters, according to RFC 1055.
*/
class SlipEncoder extends stream_1.Transform {
constructor(options = {}) {
super(options);
const { START, ESC = 0xdb, END = 0xc0, ESC_START, ESC_END = 0xdc, ESC_ESC = 0xdd, bluetoothQuirk = false } = options;
this.opts = {
START,
ESC,
END,
ESC_START,
ESC_END,
ESC_ESC,
bluetoothQuirk,
};
}
_transform(chunk, encoding, cb) {
const chunkLength = chunk.length;
if (this.opts.bluetoothQuirk && chunkLength === 0) {
// Edge case: push no data. Bluetooth-quirky SLIP parsers don't like
// lots of 0xC0s together.
return cb();
}
// Allocate memory for the worst-case scenario: all bytes are escaped,
// plus start and end separators.
const encoded = Buffer.alloc(chunkLength * 2 + 2);
let j = 0;
if (this.opts.bluetoothQuirk == true) {
encoded[j++] = this.opts.END;
}
if (this.opts.START !== undefined) {
encoded[j++] = this.opts.START;
}
for (let i = 0; i < chunkLength; i++) {
let byte = chunk[i];
if (byte === this.opts.START && this.opts.ESC_START) {
encoded[j++] = this.opts.ESC;
byte = this.opts.ESC_START;
}
else if (byte === this.opts.END) {
encoded[j++] = this.opts.ESC;
byte = this.opts.ESC_END;
}
else if (byte === this.opts.ESC) {
encoded[j++] = this.opts.ESC;
byte = this.opts.ESC_ESC;
}
encoded[j++] = byte;
}
encoded[j++] = this.opts.END;
cb(null, encoded.slice(0, j));
}
}
exports.SlipEncoder = SlipEncoder;