'use strict'
const stream = require('stream')
const NoFilter = require('nofilter')
class BinaryParseStream extends stream.Transform {
constructor(options) {
super(options)
this['_writableState'].objectMode = false
this['_readableState'].objectMode = true
this.bs = new NoFilter()
this.__restart()
}
_transform(fresh, encoding, cb) {
this.bs.write(fresh)
while (this.bs.length >= this.__needed) {
let ret = null
const chunk = (this.__needed === null) ?
undefined :
this.bs.read(this.__needed)
try {
ret = this.__parser.next(chunk)
} catch (e) {
return cb(e)
}
if (this.__needed) {
this.__fresh = false
}
if (ret.done) {
this.push(ret.value)
this.__restart()
} else {
this.__needed = ret.value || Infinity
}
}
return cb()
}
*_parse() { throw new Error('Must be implemented in subclass')
}
__restart() {
this.__needed = null
this.__parser = this._parse()
this.__fresh = true
}
_flush(cb) {
cb(this.__fresh ? null : new Error('unexpected end of input'))
}
}
module.exports = BinaryParseStream