128 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright Joyent, Inc. and other Node contributors.
 | |
| //
 | |
| // Permission is hereby granted, free of charge, to any person obtaining a
 | |
| // copy of this software and associated documentation files (the
 | |
| // "Software"), to deal in the Software without restriction, including
 | |
| // without limitation the rights to use, copy, modify, merge, publish,
 | |
| // distribute, sublicense, and/or sell copies of the Software, and to permit
 | |
| // persons to whom the Software is furnished to do so, subject to the
 | |
| // following conditions:
 | |
| //
 | |
| // The above copyright notice and this permission notice shall be included
 | |
| // in all copies or substantial portions of the Software.
 | |
| //
 | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | |
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 | |
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 | |
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 | |
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 | |
| // USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| 
 | |
| module.exports = Stream;
 | |
| 
 | |
| var EE = require('events').EventEmitter;
 | |
| var inherits = require('inherits');
 | |
| 
 | |
| inherits(Stream, EE);
 | |
| Stream.Readable = require('readable-stream/readable.js');
 | |
| Stream.Writable = require('readable-stream/writable.js');
 | |
| Stream.Duplex = require('readable-stream/duplex.js');
 | |
| Stream.Transform = require('readable-stream/transform.js');
 | |
| Stream.PassThrough = require('readable-stream/passthrough.js');
 | |
| 
 | |
| // Backwards-compat with node 0.4.x
 | |
| Stream.Stream = Stream;
 | |
| 
 | |
| 
 | |
| 
 | |
| // old-style streams.  Note that the pipe method (the only relevant
 | |
| // part of this class) is overridden in the Readable class.
 | |
| 
 | |
| function Stream() {
 | |
|   EE.call(this);
 | |
| }
 | |
| 
 | |
| Stream.prototype.pipe = function(dest, options) {
 | |
|   var source = this;
 | |
| 
 | |
|   function ondata(chunk) {
 | |
|     if (dest.writable) {
 | |
|       if (false === dest.write(chunk) && source.pause) {
 | |
|         source.pause();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   source.on('data', ondata);
 | |
| 
 | |
|   function ondrain() {
 | |
|     if (source.readable && source.resume) {
 | |
|       source.resume();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   dest.on('drain', ondrain);
 | |
| 
 | |
|   // If the 'end' option is not supplied, dest.end() will be called when
 | |
|   // source gets the 'end' or 'close' events.  Only dest.end() once.
 | |
|   if (!dest._isStdio && (!options || options.end !== false)) {
 | |
|     source.on('end', onend);
 | |
|     source.on('close', onclose);
 | |
|   }
 | |
| 
 | |
|   var didOnEnd = false;
 | |
|   function onend() {
 | |
|     if (didOnEnd) return;
 | |
|     didOnEnd = true;
 | |
| 
 | |
|     dest.end();
 | |
|   }
 | |
| 
 | |
| 
 | |
|   function onclose() {
 | |
|     if (didOnEnd) return;
 | |
|     didOnEnd = true;
 | |
| 
 | |
|     if (typeof dest.destroy === 'function') dest.destroy();
 | |
|   }
 | |
| 
 | |
|   // don't leave dangling pipes when there are errors.
 | |
|   function onerror(er) {
 | |
|     cleanup();
 | |
|     if (EE.listenerCount(this, 'error') === 0) {
 | |
|       throw er; // Unhandled stream error in pipe.
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   source.on('error', onerror);
 | |
|   dest.on('error', onerror);
 | |
| 
 | |
|   // remove all the event listeners that were added.
 | |
|   function cleanup() {
 | |
|     source.removeListener('data', ondata);
 | |
|     dest.removeListener('drain', ondrain);
 | |
| 
 | |
|     source.removeListener('end', onend);
 | |
|     source.removeListener('close', onclose);
 | |
| 
 | |
|     source.removeListener('error', onerror);
 | |
|     dest.removeListener('error', onerror);
 | |
| 
 | |
|     source.removeListener('end', cleanup);
 | |
|     source.removeListener('close', cleanup);
 | |
| 
 | |
|     dest.removeListener('close', cleanup);
 | |
|   }
 | |
| 
 | |
|   source.on('end', cleanup);
 | |
|   source.on('close', cleanup);
 | |
| 
 | |
|   dest.on('close', cleanup);
 | |
| 
 | |
|   dest.emit('pipe', source);
 | |
| 
 | |
|   // Allow for unix-like usage: A.pipe(B).pipe(C)
 | |
|   return dest;
 | |
| };
 |