"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PacketLengthParser = void 0; const stream_1 = require("stream"); /** * A transform stream that decodes packets with a delimiter and length of payload * specified within the data stream. * @extends Transform * @summary Decodes packets of the general form: * [delimiter][len][payload0] ... [payload0 + len] * * The length field can be up to 4 bytes and can be at any offset within the packet * [delimiter][header0][header1][len0][len1[payload0] ... [payload0 + len] * * The offset and number of bytes of the length field need to be provided in options * if not 1 byte immediately following the delimiter. */ class PacketLengthParser extends stream_1.Transform { constructor(options = {}) { super(options); const { delimiter = 0xaa, packetOverhead = 2, lengthBytes = 1, lengthOffset = 1, maxLen = 0xff } = options; this.opts = { delimiter, packetOverhead, lengthBytes, lengthOffset, maxLen, }; this.buffer = Buffer.alloc(0); this.start = false; } _transform(chunk, encoding, cb) { for (let ndx = 0; ndx < chunk.length; ndx++) { const byte = chunk[ndx]; if (byte === this.opts.delimiter) { this.start = true; } if (true === this.start) { this.buffer = Buffer.concat([this.buffer, Buffer.from([byte])]); if (this.buffer.length >= this.opts.lengthOffset + this.opts.lengthBytes) { const len = this.buffer.readUIntLE(this.opts.lengthOffset, this.opts.lengthBytes); if (this.buffer.length == len + this.opts.packetOverhead || len > this.opts.maxLen) { this.push(this.buffer); this.buffer = Buffer.alloc(0); this.start = false; } } } } cb(); } _flush(cb) { this.push(this.buffer); this.buffer = Buffer.alloc(0); cb(); } } exports.PacketLengthParser = PacketLengthParser;