index.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. var Writable = require('readable-stream').Writable
  2. var inherits = require('inherits')
  3. if (typeof Uint8Array === 'undefined') {
  4. var U8 = require('typedarray').Uint8Array
  5. } else {
  6. var U8 = Uint8Array
  7. }
  8. function ConcatStream(opts, cb) {
  9. if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb)
  10. if (typeof opts === 'function') {
  11. cb = opts
  12. opts = {}
  13. }
  14. if (!opts) opts = {}
  15. var encoding = opts.encoding
  16. var shouldInferEncoding = false
  17. if (!encoding) {
  18. shouldInferEncoding = true
  19. } else {
  20. encoding = String(encoding).toLowerCase()
  21. if (encoding === 'u8' || encoding === 'uint8') {
  22. encoding = 'uint8array'
  23. }
  24. }
  25. Writable.call(this, { objectMode: true })
  26. this.encoding = encoding
  27. this.shouldInferEncoding = shouldInferEncoding
  28. if (cb) this.on('finish', function () { cb(this.getBody()) })
  29. this.body = []
  30. }
  31. module.exports = ConcatStream
  32. inherits(ConcatStream, Writable)
  33. ConcatStream.prototype._write = function(chunk, enc, next) {
  34. this.body.push(chunk)
  35. next()
  36. }
  37. ConcatStream.prototype.inferEncoding = function (buff) {
  38. var firstBuffer = buff === undefined ? this.body[0] : buff;
  39. if (Buffer.isBuffer(firstBuffer)) return 'buffer'
  40. if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array'
  41. if (Array.isArray(firstBuffer)) return 'array'
  42. if (typeof firstBuffer === 'string') return 'string'
  43. if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object'
  44. return 'buffer'
  45. }
  46. ConcatStream.prototype.getBody = function () {
  47. if (!this.encoding && this.body.length === 0) return []
  48. if (this.shouldInferEncoding) this.encoding = this.inferEncoding()
  49. if (this.encoding === 'array') return arrayConcat(this.body)
  50. if (this.encoding === 'string') return stringConcat(this.body)
  51. if (this.encoding === 'buffer') return bufferConcat(this.body)
  52. if (this.encoding === 'uint8array') return u8Concat(this.body)
  53. return this.body
  54. }
  55. var isArray = Array.isArray || function (arr) {
  56. return Object.prototype.toString.call(arr) == '[object Array]'
  57. }
  58. function isArrayish (arr) {
  59. return /Array\]$/.test(Object.prototype.toString.call(arr))
  60. }
  61. function stringConcat (parts) {
  62. var strings = []
  63. var needsToString = false
  64. for (var i = 0; i < parts.length; i++) {
  65. var p = parts[i]
  66. if (typeof p === 'string') {
  67. strings.push(p)
  68. } else if (Buffer.isBuffer(p)) {
  69. strings.push(p)
  70. } else {
  71. strings.push(Buffer(p))
  72. }
  73. }
  74. if (Buffer.isBuffer(parts[0])) {
  75. strings = Buffer.concat(strings)
  76. strings = strings.toString('utf8')
  77. } else {
  78. strings = strings.join('')
  79. }
  80. return strings
  81. }
  82. function bufferConcat (parts) {
  83. var bufs = []
  84. for (var i = 0; i < parts.length; i++) {
  85. var p = parts[i]
  86. if (Buffer.isBuffer(p)) {
  87. bufs.push(p)
  88. } else if (typeof p === 'string' || isArrayish(p)
  89. || (p && typeof p.subarray === 'function')) {
  90. bufs.push(Buffer(p))
  91. } else bufs.push(Buffer(String(p)))
  92. }
  93. return Buffer.concat(bufs)
  94. }
  95. function arrayConcat (parts) {
  96. var res = []
  97. for (var i = 0; i < parts.length; i++) {
  98. res.push.apply(res, parts[i])
  99. }
  100. return res
  101. }
  102. function u8Concat (parts) {
  103. var len = 0
  104. for (var i = 0; i < parts.length; i++) {
  105. if (typeof parts[i] === 'string') {
  106. parts[i] = Buffer(parts[i])
  107. }
  108. len += parts[i].length
  109. }
  110. var u8 = new U8(len)
  111. for (var i = 0, offset = 0; i < parts.length; i++) {
  112. var part = parts[i]
  113. for (var j = 0; j < part.length; j++) {
  114. u8[offset++] = part[j]
  115. }
  116. }
  117. return u8
  118. }