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
63 lines
2.1 KiB
JavaScript
8 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;
|