├── main.js ├── package.json └── tests.js /main.js: -------------------------------------------------------------------------------- 1 | var stream = require('stream') 2 | , fs = require('fs') 3 | , util = require('util') 4 | ; 5 | 6 | var BufferedStream = function (limit) { 7 | if (typeof limit === 'undefined') { 8 | limit = Infinity; 9 | } 10 | this.limit = limit; 11 | this.size = 0; 12 | this.chunks = []; 13 | this.writable = true; 14 | this.readable = true; 15 | } 16 | util.inherits(BufferedStream, stream.Stream); 17 | BufferedStream.prototype.pipe = function (dest, options) { 18 | var self = this 19 | if (self.resume) self.resume(); 20 | stream.Stream.prototype.pipe.call(self, dest, options) 21 | //just incase you are piping to two streams, do not emit data twice. 22 | //note: you can pipe twice, but you need to pipe both streams in the same tick. 23 | //(this is normal for streams) 24 | if(this.piped) 25 | return dest 26 | 27 | process.nextTick(function () { 28 | self.chunks.forEach(function (c) {self.emit('data', c)}) 29 | self.size = 0; 30 | delete self.chunks; 31 | if(self.ended){ 32 | self.emit('end') 33 | } 34 | }) 35 | this.piped = true 36 | 37 | return dest 38 | } 39 | BufferedStream.prototype.write = function (chunk) { 40 | if (!this.chunks) { 41 | this.emit('data', chunk); 42 | return; 43 | } 44 | this.chunks.push(chunk); 45 | this.size += chunk.length; 46 | if (this.limit < this.size) { 47 | this.pause(); 48 | } 49 | } 50 | BufferedStream.prototype.end = function () { 51 | if(!this.chunks) 52 | this.emit('end'); 53 | else 54 | this.ended = true 55 | } 56 | 57 | if (!stream.Stream.prototype.pause) { 58 | BufferedStream.prototype.pause = function() { 59 | this.emit('pause'); 60 | }; 61 | } 62 | if (!stream.Stream.prototype.resume) { 63 | BufferedStream.prototype.resume = function() { 64 | this.emit('resume'); 65 | }; 66 | } 67 | 68 | exports.BufferedStream = BufferedStream; 69 | 70 | var UpgradableStream = function () { 71 | var self = this; 72 | self.upgradable = false; 73 | self.on('pipe', function (source) { 74 | self.source = source; 75 | self.upgradable = (source instanceof fs.ReadStream); 76 | }) 77 | }; 78 | util.inherits(UpgradableStream, stream.Stream); 79 | UpgradableStream.prototype.pipe = function () { 80 | var dest = this.dest = arguments[0] 81 | , destfd 82 | ; 83 | if (dest.socket) destfd = dest.socket.fd; 84 | else if (dest.fd) destfd = dest.fd; 85 | 86 | if (this.upgradable && destfd) { 87 | console.log('sendfile') 88 | console.log(this.source.bufferSize) 89 | console.error(this.source) 90 | // this.source.end(); 91 | var p = this.source.path; 92 | var m = this.source.mode; 93 | dest.socket.flush(); 94 | fs.stat(p, function (e, stat) { 95 | fs.open(p, m, 0, function(err, fd) { 96 | console.dir(fd) 97 | fs.sendfile(fd, destfd, 0, stat.size, function () { 98 | dest.end(); 99 | }); 100 | 101 | }) 102 | }) 103 | 104 | delete this.source 105 | return dest 106 | } else { 107 | console.log('pipeing') 108 | return this.source.pipe.apply(this.source, arguments); 109 | } 110 | } 111 | UpgradableStream.prototype.write = function () {} 112 | UpgradableStream.prototype.end = function () {} 113 | UpgradableStream.prototype.resume = function () {} 114 | 115 | 116 | exports.UpgradableStream = UpgradableStream 117 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "morestreams", 3 | "description": "Collection of useful stream objects.", 4 | "version": "0.1.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "git@github.com:mikeal/morestreams.git" 8 | }, 9 | "author": "Mikeal Rogers (http://www.mikealrogers.com)", 10 | "main": "main.js", 11 | "directories": { 12 | "lib": "." 13 | }, 14 | "engines": { 15 | "node": "*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests.js: -------------------------------------------------------------------------------- 1 | var streams = require('./main') 2 | , assert = require('assert') 3 | , stream = require('stream') 4 | ; 5 | 6 | var source = new stream.Stream() 7 | , dest = new stream.Stream() 8 | , buffered = new streams.BufferedStream() 9 | ; 10 | 11 | source.readable = true 12 | dest.writable = true 13 | 14 | source.pause = function () { 15 | throw new Error("Pause should not be called") 16 | } 17 | source.pipe(buffered) 18 | var i = 0; 19 | 20 | while (i !== 100) { 21 | source.emit("data", "asdf") 22 | i++ 23 | } 24 | 25 | setTimeout(function () { 26 | assert.ok(buffered.chunks.length === 100); 27 | 28 | i = 0; 29 | dest.write = function () { 30 | i++ 31 | } 32 | 33 | assert.deepEqual(buffered.pipe(dest), dest) 34 | 35 | setTimeout(function () { 36 | assert.ok(i === 100); 37 | }, 0) 38 | 39 | 40 | 41 | }, 0) 42 | 43 | 44 | --------------------------------------------------------------------------------