| var stream = require("stream"),
	constants = require("./constants"),
	util = require("util");
 
var ReadableStreamBuffer = module.exports = function(opts) {
	var that = this;
 
	stream.Stream.call(this);
 
	opts = opts || {};
	var frequency = opts.hasOwnProperty("frequency") ? opts.frequency : constants.DEFAULT_FREQUENCY;
	var chunkSize = opts.chunkSize || constants.DEFAULT_CHUNK_SIZE;
	var initialSize = opts.initialSize || constants.DEFAULT_INITIAL_SIZE;
	var incrementAmount = opts.incrementAmount || constants.DEFAULT_INCREMENT_AMOUNT;
 
	var size = 0;
	var buffer = new Buffer(initialSize);
	var encoding = null;
 
	this.readable = true;
	this.writable = false;
 
	var sendData = function() {
		var amount = Math.min(chunkSize, size);
 
		if (amount > 0) {
			var chunk = null;
			if(encoding) {
				chunk = buffer.toString(encoding, 0, amount);
			}
			else {
				chunk = new Buffer(amount);
				buffer.copy(chunk, 0, 0, amount);
			}
 
			that.emit("data", chunk);
 
			Eif(amount < buffer.length)
				buffer.copy(buffer, 0, amount, size);
			size -= amount;
		}
 
		if(size === 0 && !that.readable) {
			that.emit("end");
			that.emit("close");
			if (sendData && sendData.interval) {
				clearInterval(sendData.interval);
				sendData.interval = null;
			}
		}
	};
 
	this.size = function() {
		return size;
	};
 
	this.maxSize = function() {
		return buffer.length;
	};
 
	var increaseBufferIfNecessary = function(incomingDataSize) {
		if((buffer.length - size) < incomingDataSize) {
			var factor = Math.ceil((incomingDataSize - (buffer.length - size)) / incrementAmount);
 
			var newBuffer = new Buffer(buffer.length + (incrementAmount * factor));
			buffer.copy(newBuffer, 0, 0, size);
			buffer = newBuffer;
		}
	};
 
	this.put = function(data, encoding) {
		Iif(!that.readable) return;
 
		var wasEmpty = size === 0;
		if(Buffer.isBuffer(data)) {
			increaseBufferIfNecessary(data.length);
			data.copy(buffer, size, 0);
			size += data.length;
		}
		else {
			data = data + "";
			var dataSizeInBytes = Buffer.byteLength(data);
			increaseBufferIfNecessary(dataSizeInBytes);
			buffer.write(data, size, encoding || "utf8");
			size += dataSizeInBytes;
		}
 
		if (wasEmpty && size > 0) {
			this.emit('readable')
		}
 
		if (!this.isPaused && !frequency) {
			while (size > 0) {
				sendData();
			}
		}
	};
 
	this.pause = function() {
		this.isPaused = true;
		Eif(sendData && sendData.interval) {
			clearInterval(sendData.interval);
			delete sendData.interval;
		}
	};
 
	this.resume = function() {
		this.isPaused = false;
		if(sendData && !sendData.interval && frequency > 0) {
			sendData.interval = setInterval(sendData, frequency);
		}
	};
 
	this.destroy = function() {
		that.emit("end");
		if(sendData.interval) clearInterval(sendData.interval);
		sendData = null;
		that.readable = false;
		that.emit("close");
	};
 
	this.destroySoon = function() {
		that.readable = false;
		if (!sendData.interval) {
			that.emit("end");
			that.emit("close");
		}
	};
 
	this.setEncoding = function(_encoding) {
		encoding = _encoding;
	};
 
	this.resume();
};
util.inherits(ReadableStreamBuffer, stream.Stream);
  |