line-buffer.js 1.35 KB
Newer Older
bovornsiriampairat committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
const {EventEmitter} = require('events');

class LineBuffer extends EventEmitter {
  constructor(options) {
    super();

    this.encoding = options.encoding;

    this.buffer = null;

    // part of cork/uncork
    this.corked = false;
    this.queue = [];
  }

  // Events:
  //  line: here is a line
  //  done: all lines emitted

  write(chunk) {
    // find line or lines in chunk and emit them if not corked
    // or queue them if corked
    const data = this.buffer ? this.buffer + chunk : chunk;
    const lines = data.split(/\r?\n/g);

    // save the last line
    this.buffer = lines.pop();

    lines.forEach(function(line) {
      if (this.corked) {
        this.queue.push(line);
      } else {
        this.emit('line', line);
      }
    });

    return !this.corked;
  }

  cork() {
    this.corked = true;
  }

  uncork() {
    this.corked = false;
    this._flush();

    // tell the source I'm ready again
    this.emit('drain');
  }

  setDefaultEncoding() {
    // ?
  }

  end() {
    if (this.buffer) {
      this.emit('line', this.buffer);
      this.buffer = null;
    }
    this.emit('done');
  }

  _flush() {
    if (!this.corked) {
      this.queue.forEach(line => {
        this.emit('line', line);
      });
      this.queue = [];
    }
  }
}

module.exports = LineBuffer;