stream-converter.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. "use strict";
  2. // =======================================================================================================
  3. // StreamConverter
  4. //
  5. // convert between encoding schemes in a stream
  6. // Work in Progress - Will complete this at some point
  7. let jconv;
  8. class StreamConverter {
  9. constructor(inner, options) {
  10. this.inner = inner;
  11. options = options || {};
  12. this.innerEncoding = (options.innerEncoding || 'UTF8').toUpperCase();
  13. this.outerEncoding = (options.outerEncoding || 'UTF8').toUpperCase();
  14. this.innerBOM = options.innerBOM || null;
  15. this.outerBOM = options.outerBOM || null;
  16. this.writeStarted = false;
  17. }
  18. convertInwards(data) {
  19. if (data) {
  20. if (typeof data === 'string') {
  21. data = Buffer.from(data, this.outerEncoding);
  22. }
  23. if (this.innerEncoding !== this.outerEncoding) {
  24. data = jconv.convert(data, this.outerEncoding, this.innerEncoding);
  25. }
  26. }
  27. return data;
  28. }
  29. convertOutwards(data) {
  30. if (typeof data === 'string') {
  31. data = Buffer.from(data, this.innerEncoding);
  32. }
  33. if (this.innerEncoding !== this.outerEncoding) {
  34. data = jconv.convert(data, this.innerEncoding, this.outerEncoding);
  35. }
  36. return data;
  37. }
  38. addListener(event, handler) {
  39. this.inner.addListener(event, handler);
  40. }
  41. removeListener(event, handler) {
  42. this.inner.removeListener(event, handler);
  43. }
  44. write(data, encoding, callback) {
  45. if (encoding instanceof Function) {
  46. callback = encoding;
  47. encoding = undefined;
  48. }
  49. if (!this.writeStarted) {
  50. // if inner encoding has BOM, write it now
  51. if (this.innerBOM) {
  52. this.inner.write(this.innerBOM);
  53. }
  54. // if outer encoding has BOM, delete it now
  55. if (this.outerBOM) {
  56. if (data.length <= this.outerBOM.length) {
  57. if (callback) {
  58. callback();
  59. }
  60. return;
  61. }
  62. const bomless = Buffer.alloc(data.length - this.outerBOM.length);
  63. data.copy(bomless, 0, this.outerBOM.length, data.length);
  64. data = bomless;
  65. }
  66. this.writeStarted = true;
  67. }
  68. this.inner.write(this.convertInwards(data), encoding ? this.innerEncoding : undefined, callback);
  69. }
  70. read() {
  71. // TBD
  72. }
  73. pipe(destination, options) {
  74. const reverseConverter = new StreamConverter(destination, {
  75. innerEncoding: this.outerEncoding,
  76. outerEncoding: this.innerEncoding,
  77. innerBOM: this.outerBOM,
  78. outerBOM: this.innerBOM
  79. });
  80. this.inner.pipe(reverseConverter, options);
  81. }
  82. close() {
  83. this.inner.close();
  84. }
  85. on(type, callback) {
  86. switch (type) {
  87. case 'data':
  88. this.inner.on('data', chunk => {
  89. callback(this.convertOutwards(chunk));
  90. });
  91. return this;
  92. default:
  93. this.inner.on(type, callback);
  94. return this;
  95. }
  96. }
  97. once(type, callback) {
  98. this.inner.once(type, callback);
  99. }
  100. end(chunk, encoding, callback) {
  101. this.inner.end(this.convertInwards(chunk), this.innerEncoding, callback);
  102. }
  103. emit(type, value) {
  104. this.inner.emit(type, value);
  105. }
  106. }
  107. module.exports = StreamConverter;
  108. //# sourceMappingURL=stream-converter.js.map