You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

141 lines
2.9 KiB

/*
* 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');
};
}