123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- 'use strict';
- const stream = require('stream');
- const Transform = stream.Transform;
- /**
- * Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
- * Also makes sure that only <CR><LF> sequences are used for linebreaks
- *
- * @param {Object} options Stream options
- */
- class DataStream extends Transform {
- constructor(options) {
- super(options);
- // init Transform
- this.options = options || {};
- this._curLine = '';
- this.inByteCount = 0;
- this.outByteCount = 0;
- this.lastByte = false;
- }
- /**
- * Escapes dots
- */
- _transform(chunk, encoding, done) {
- let chunks = [];
- let chunklen = 0;
- let i,
- len,
- lastPos = 0;
- let buf;
- if (!chunk || !chunk.length) {
- return done();
- }
- if (typeof chunk === 'string') {
- chunk = Buffer.from(chunk);
- }
- this.inByteCount += chunk.length;
- for (i = 0, len = chunk.length; i < len; i++) {
- if (chunk[i] === 0x2e) {
- // .
- if ((i && chunk[i - 1] === 0x0a) || (!i && (!this.lastByte || this.lastByte === 0x0a))) {
- buf = chunk.slice(lastPos, i + 1);
- chunks.push(buf);
- chunks.push(Buffer.from('.'));
- chunklen += buf.length + 1;
- lastPos = i + 1;
- }
- } else if (chunk[i] === 0x0a) {
- // .
- if ((i && chunk[i - 1] !== 0x0d) || (!i && this.lastByte !== 0x0d)) {
- if (i > lastPos) {
- buf = chunk.slice(lastPos, i);
- chunks.push(buf);
- chunklen += buf.length + 2;
- } else {
- chunklen += 2;
- }
- chunks.push(Buffer.from('\r\n'));
- lastPos = i + 1;
- }
- }
- }
- if (chunklen) {
- // add last piece
- if (lastPos < chunk.length) {
- buf = chunk.slice(lastPos);
- chunks.push(buf);
- chunklen += buf.length;
- }
- this.outByteCount += chunklen;
- this.push(Buffer.concat(chunks, chunklen));
- } else {
- this.outByteCount += chunk.length;
- this.push(chunk);
- }
- this.lastByte = chunk[chunk.length - 1];
- done();
- }
- /**
- * Finalizes the stream with a dot on a single line
- */
- _flush(done) {
- let buf;
- if (this.lastByte === 0x0a) {
- buf = Buffer.from('.\r\n');
- } else if (this.lastByte === 0x0d) {
- buf = Buffer.from('\n.\r\n');
- } else {
- buf = Buffer.from('\r\n.\r\n');
- }
- this.outByteCount += buf.length;
- this.push(buf);
- done();
- }
- }
- module.exports = DataStream;
|