streams.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. "use strict"
  2. var Buffer = require("safer-buffer").Buffer
  3. // NOTE: Due to 'stream' module being pretty large (~100Kb, significant in browser environments),
  4. // we opt to dependency-inject it instead of creating a hard dependency.
  5. module.exports = function (streamModule) {
  6. var Transform = streamModule.Transform
  7. // == Encoder stream =======================================================
  8. function IconvLiteEncoderStream (conv, options) {
  9. this.conv = conv
  10. options = options || {}
  11. options.decodeStrings = false // We accept only strings, so we don't need to decode them.
  12. Transform.call(this, options)
  13. }
  14. IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, {
  15. constructor: { value: IconvLiteEncoderStream }
  16. })
  17. IconvLiteEncoderStream.prototype._transform = function (chunk, encoding, done) {
  18. if (typeof chunk !== "string") {
  19. return done(new Error("Iconv encoding stream needs strings as its input."))
  20. }
  21. try {
  22. var res = this.conv.write(chunk)
  23. if (res && res.length) this.push(res)
  24. done()
  25. } catch (e) {
  26. done(e)
  27. }
  28. }
  29. IconvLiteEncoderStream.prototype._flush = function (done) {
  30. try {
  31. var res = this.conv.end()
  32. if (res && res.length) this.push(res)
  33. done()
  34. } catch (e) {
  35. done(e)
  36. }
  37. }
  38. IconvLiteEncoderStream.prototype.collect = function (cb) {
  39. var chunks = []
  40. this.on("error", cb)
  41. this.on("data", function (chunk) { chunks.push(chunk) })
  42. this.on("end", function () {
  43. cb(null, Buffer.concat(chunks))
  44. })
  45. return this
  46. }
  47. // == Decoder stream =======================================================
  48. function IconvLiteDecoderStream (conv, options) {
  49. this.conv = conv
  50. options = options || {}
  51. options.encoding = this.encoding = "utf8" // We output strings.
  52. Transform.call(this, options)
  53. }
  54. IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, {
  55. constructor: { value: IconvLiteDecoderStream }
  56. })
  57. IconvLiteDecoderStream.prototype._transform = function (chunk, encoding, done) {
  58. if (!Buffer.isBuffer(chunk) && !(chunk instanceof Uint8Array)) { return done(new Error("Iconv decoding stream needs buffers as its input.")) }
  59. try {
  60. var res = this.conv.write(chunk)
  61. if (res && res.length) this.push(res, this.encoding)
  62. done()
  63. } catch (e) {
  64. done(e)
  65. }
  66. }
  67. IconvLiteDecoderStream.prototype._flush = function (done) {
  68. try {
  69. var res = this.conv.end()
  70. if (res && res.length) this.push(res, this.encoding)
  71. done()
  72. } catch (e) {
  73. done(e)
  74. }
  75. }
  76. IconvLiteDecoderStream.prototype.collect = function (cb) {
  77. var res = ""
  78. this.on("error", cb)
  79. this.on("data", function (chunk) { res += chunk })
  80. this.on("end", function () {
  81. cb(null, res)
  82. })
  83. return this
  84. }
  85. return {
  86. IconvLiteEncoderStream: IconvLiteEncoderStream,
  87. IconvLiteDecoderStream: IconvLiteDecoderStream
  88. }
  89. }