blob: b690daae617eeeb516b93428b19942dc4a7a56ec [file] [log] [blame]
'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 = new Buffer(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(new Buffer('.'));
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(new Buffer('\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 = new Buffer('.\r\n');
} else if (this.lastByte === 0x0D) {
buf = new Buffer('\n.\r\n');
} else {
buf = new Buffer('\r\n.\r\n');
}
this.outByteCount += buf.length;
this.push(buf);
done();
}
}
module.exports = DataStream;