|
|
/* * buffered-stream.js: A simple(r) Stream which is partially buffered into memory. * * (C) 2010, Mikeal Rogers * * Adapted for Flatiron * (C) 2011, Charlie Robbins & the Contributors * MIT LICENSE * */
var events = require('events'), fs = require('fs'), stream = require('stream'), util = require('util');
//
// ### function BufferedStream (limit)
// #### @limit {number} **Optional** Size of the buffer to limit
// Constructor function for the BufferedStream object responsible for
// maintaining a stream interface which can also persist to memory
// temporarily.
//
var BufferedStream = module.exports = function (limit) { events.EventEmitter.call(this);
if (typeof limit === 'undefined') { limit = Infinity; }
this.limit = limit; this.size = 0; this.chunks = []; this.writable = true; this.readable = true; this._buffer = true; };
util.inherits(BufferedStream, stream.Stream);
Object.defineProperty(BufferedStream.prototype, 'buffer', { get: function () { return this._buffer; }, set: function (value) { if (!value && this.chunks) { var self = this; this.chunks.forEach(function (c) { self.emit('data', c) }); if (this.ended) this.emit('end'); this.size = 0; delete this.chunks; }
this._buffer = value; } });
BufferedStream.prototype.pipe = function () { var self = this, dest;
if (self.resume) { self.resume(); }
dest = stream.Stream.prototype.pipe.apply(self, arguments);
//
// just incase you are piping to two streams, do not emit data twice.
// note: you can pipe twice, but you need to pipe both streams in the same tick.
// (this is normal for streams)
//
if (this.piped) { return dest; }
process.nextTick(function () { if (self.chunks) { self.chunks.forEach(function (c) { self.emit('data', c) }); self.size = 0; delete self.chunks; }
if (!self.readable) { if (self.ended) { self.emit('end'); } else if (self.closed) { self.emit('close'); } } });
this.piped = true;
return dest; };
BufferedStream.prototype.write = function (chunk) { if (!this.chunks || this.piped) { this.emit('data', chunk); return; }
this.chunks.push(chunk); this.size += chunk.length; if (this.limit < this.size) { this.pause(); } };
BufferedStream.prototype.end = function () { this.readable = false; this.ended = true; this.emit('end'); };
BufferedStream.prototype.destroy = function () { this.readable = false; this.writable = false; delete this.chunks; };
BufferedStream.prototype.close = function () { this.readable = false; this.closed = true; };
if (!stream.Stream.prototype.pause) { BufferedStream.prototype.pause = function () { this.emit('pause'); }; }
if (!stream.Stream.prototype.resume) { BufferedStream.prototype.resume = function () { this.emit('resume'); }; }
|