1const Minipass = require('minipass') 2 3class SizeError extends Error { 4 constructor (found, expect) { 5 super(`Bad data size: expected ${expect} bytes, but got ${found}`) 6 this.expect = expect 7 this.found = found 8 this.code = 'EBADSIZE' 9 Error.captureStackTrace(this, this.constructor) 10 } 11 get name () { 12 return 'SizeError' 13 } 14} 15 16class MinipassSized extends Minipass { 17 constructor (options = {}) { 18 super(options) 19 20 if (options.objectMode) 21 throw new TypeError(`${ 22 this.constructor.name 23 } streams only work with string and buffer data`) 24 25 this.found = 0 26 this.expect = options.size 27 if (typeof this.expect !== 'number' || 28 this.expect > Number.MAX_SAFE_INTEGER || 29 isNaN(this.expect) || 30 this.expect < 0 || 31 !isFinite(this.expect) || 32 this.expect !== Math.floor(this.expect)) 33 throw new Error('invalid expected size: ' + this.expect) 34 } 35 36 write (chunk, encoding, cb) { 37 const buffer = Buffer.isBuffer(chunk) ? chunk 38 : typeof chunk === 'string' ? 39 Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8') 40 : chunk 41 42 if (!Buffer.isBuffer(buffer)) { 43 this.emit('error', new TypeError(`${ 44 this.constructor.name 45 } streams only work with string and buffer data`)) 46 return false 47 } 48 49 this.found += buffer.length 50 if (this.found > this.expect) 51 this.emit('error', new SizeError(this.found, this.expect)) 52 53 return super.write(chunk, encoding, cb) 54 } 55 56 emit (ev, ...data) { 57 if (ev === 'end') { 58 if (this.found !== this.expect) 59 this.emit('error', new SizeError(this.found, this.expect)) 60 } 61 return super.emit(ev, ...data) 62 } 63} 64 65MinipassSized.SizeError = SizeError 66 67module.exports = MinipassSized 68