index.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. var duplexify = require('duplexify')
  2. var through = require('through2')
  3. var bufferFrom = require('buffer-from')
  4. var noop = function() {}
  5. var isObject = function(data) {
  6. return !Buffer.isBuffer(data) && typeof data !== 'string'
  7. }
  8. var peek = function(opts, onpeek) {
  9. if (typeof opts === 'number') opts = {maxBuffer:opts}
  10. if (typeof opts === 'function') return peek(null, opts)
  11. if (!opts) opts = {}
  12. var maxBuffer = typeof opts.maxBuffer === 'number' ? opts.maxBuffer : 65535
  13. var strict = opts.strict
  14. var newline = opts.newline !== false
  15. var buffer = []
  16. var bufferSize = 0
  17. var dup = duplexify.obj()
  18. var peeker = through.obj({highWaterMark:1}, function(data, enc, cb) {
  19. if (isObject(data)) return ready(data, null, cb)
  20. if (!Buffer.isBuffer(data)) data = bufferFrom(data)
  21. if (newline) {
  22. var nl = Array.prototype.indexOf.call(data, 10)
  23. if (nl > 0 && data[nl-1] === 13) nl--
  24. if (nl > -1) {
  25. buffer.push(data.slice(0, nl))
  26. return ready(Buffer.concat(buffer), data.slice(nl), cb)
  27. }
  28. }
  29. buffer.push(data)
  30. bufferSize += data.length
  31. if (bufferSize < maxBuffer) return cb()
  32. if (strict) return cb(new Error('No newline found'))
  33. ready(Buffer.concat(buffer), null, cb)
  34. })
  35. var onpreend = function() {
  36. if (strict) return dup.destroy(new Error('No newline found'))
  37. dup.cork()
  38. ready(Buffer.concat(buffer), null, function(err) {
  39. if (err) return dup.destroy(err)
  40. dup.uncork()
  41. })
  42. }
  43. var ready = function(data, overflow, cb) {
  44. dup.removeListener('preend', onpreend)
  45. onpeek(data, function(err, parser) {
  46. if (err) return cb(err)
  47. dup.setWritable(parser)
  48. dup.setReadable(parser)
  49. if (data) parser.write(data)
  50. if (overflow) parser.write(overflow)
  51. overflow = buffer = peeker = null // free the data
  52. cb()
  53. })
  54. }
  55. dup.on('preend', onpreend)
  56. dup.setWritable(peeker)
  57. return dup
  58. }
  59. module.exports = peek