Airbreaks-Low-Power/Programming/Javascript/node_modules/@serialport/parser-ready/lib/index.js
2023-12-19 18:30:36 -06:00

64 lines
1.9 KiB
JavaScript

const { Transform } = require('stream')
/**
* A transform stream that waits for a sequence of "ready" bytes before emitting a ready event and emitting data events
* @summary To use the `Ready` parser provide a byte start sequence. After the bytes have been received a ready event is fired and data events are passed through.
* @extends Transform
* @example
const SerialPort = require('serialport')
const Ready = require('@serialport/parser-ready')
const port = new SerialPort('/dev/tty-usbserial1')
const parser = port.pipe(new Ready({ delimiter: 'READY' }))
parser.on('ready', () => console.log('the ready byte sequence has been received'))
parser.on('data', console.log) // all data after READY is received
*/
class ReadyParser extends Transform {
/**
*
* @param {object} options options for the parser
* @param {string|Buffer|array} options.delimiter data to look for before emitted "ready"
*/
constructor(options = {}) {
if (options.delimiter === undefined) {
throw new TypeError('"delimiter" is not a bufferable object')
}
if (options.delimiter.length === 0) {
throw new TypeError('"delimiter" has a 0 or undefined length')
}
super(options)
this.delimiter = Buffer.from(options.delimiter)
this.readOffset = 0
this.ready = false
}
_transform(chunk, encoding, cb) {
if (this.ready) {
this.push(chunk)
return cb()
}
const delimiter = this.delimiter
let chunkOffset = 0
while (this.readOffset < delimiter.length && chunkOffset < chunk.length) {
if (delimiter[this.readOffset] === chunk[chunkOffset]) {
this.readOffset++
} else {
this.readOffset = 0
}
chunkOffset++
}
if (this.readOffset === delimiter.length) {
this.ready = true
this.emit('ready')
const chunkRest = chunk.slice(chunkOffset)
if (chunkRest.length > 0) {
this.push(chunkRest)
}
}
cb()
}
}
module.exports = ReadyParser