"use strict";

var stream = require("stream");
var util = require("util");

var Transform = stream.Transform;

var NL = 10;

function WholeLineStream(prefix) {
    Transform.call(this);
    this.prefix = prefix ? Buffer(prefix) : null;
    this.queued = null;
}

util.inherits(WholeLineStream, Transform);

WholeLineStream.prototype._transform = function(chunk, encoding, done) {
    if (!Buffer.isBuffer(chunk)) throw new Error("Only accepting buffers");
    if (this.queued) {
        chunk = Buffer.concat([this.queued, chunk]);
        this.queued = null;
    }
    var bol = 0, eol = 0;
    while (eol < chunk.length) {
        if (chunk[eol++] === NL) {
            if (this.prefix)
                this.push(this.prefix);
            this.push(chunk.slice(bol, eol));
            bol = eol;
        }
    }
    if (bol !== eol)
        this.queued = chunk.slice(bol);
    done();
};

WholeLineStream.prototype._flush = function(done) {
    if(this.queued)
        this._transform(Buffer.concat([this.queued, new Buffer("\n")]),
                        null, done);
    else
        done();
}

module.exports = WholeLineStream;

"use strict";

var stream = require("stream");
var util = require("util");

var Transform = stream.Transform;

var NL = 10;
var CR = 13;

function WholeLineStream(prefix) {
    Transform.call(this);
    this.prefix = prefix ? Buffer(prefix) : null;
    this.queued = null;
}

util.inherits(WholeLineStream, Transform);

WholeLineStream.prototype._transform = function(chunk, encoding, done) {
    if (!Buffer.isBuffer(chunk)) throw new Error("Only accepting buffers");
    if (this.queued) {
        chunk = Buffer.concat([this.queued, chunk]);
        this.queued = null;
    }
    var bol = 0, eol = 0;
    while (eol < chunk.length) {
        var chr = chunk[eol++];
        if (chr === CR) { // \r erases the current line, mocha does that
            bol = eol;
        }
        if (chr === NL) {
            if (this.prefix)
                this.push(this.prefix);
            this.push(chunk.slice(bol, eol));
            bol = eol;
        }
    }
    if (bol !== eol)
        this.queued = chunk.slice(bol);
    done();
};

WholeLineStream.prototype._flush = function(done) {
    if(this.queued)
        this._transform(Buffer.concat([this.queued, new Buffer("\n")]),
                        null, done);
    else
        done();
}

module.exports = WholeLineStream;

Handle carriage return in build system
Handle carriage return in build system

Mocha uses carriage return to clear the current line. At least if its output
is not a TTY.  If we don't want that to interfere with what's already
written to the terminal, we have to handle it somewhere.
