88 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| var Stream = require("stream")
 | |
| var writeMethods = ["write", "end", "destroy"]
 | |
| var readMethods = ["resume", "pause"]
 | |
| var readEvents = ["data", "close"]
 | |
| var slice = Array.prototype.slice
 | |
| 
 | |
| module.exports = duplex
 | |
| 
 | |
| function forEach (arr, fn) {
 | |
|     if (arr.forEach) {
 | |
|         return arr.forEach(fn)
 | |
|     }
 | |
| 
 | |
|     for (var i = 0; i < arr.length; i++) {
 | |
|         fn(arr[i], i)
 | |
|     }
 | |
| }
 | |
| 
 | |
| function duplex(writer, reader) {
 | |
|     var stream = new Stream()
 | |
|     var ended = false
 | |
| 
 | |
|     forEach(writeMethods, proxyWriter)
 | |
| 
 | |
|     forEach(readMethods, proxyReader)
 | |
| 
 | |
|     forEach(readEvents, proxyStream)
 | |
| 
 | |
|     reader.on("end", handleEnd)
 | |
| 
 | |
|     writer.on("drain", function() {
 | |
|       stream.emit("drain")
 | |
|     })
 | |
| 
 | |
|     writer.on("error", reemit)
 | |
|     reader.on("error", reemit)
 | |
| 
 | |
|     stream.writable = writer.writable
 | |
|     stream.readable = reader.readable
 | |
| 
 | |
|     return stream
 | |
| 
 | |
|     function proxyWriter(methodName) {
 | |
|         stream[methodName] = method
 | |
| 
 | |
|         function method() {
 | |
|             return writer[methodName].apply(writer, arguments)
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function proxyReader(methodName) {
 | |
|         stream[methodName] = method
 | |
| 
 | |
|         function method() {
 | |
|             stream.emit(methodName)
 | |
|             var func = reader[methodName]
 | |
|             if (func) {
 | |
|                 return func.apply(reader, arguments)
 | |
|             }
 | |
|             reader.emit(methodName)
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function proxyStream(methodName) {
 | |
|         reader.on(methodName, reemit)
 | |
| 
 | |
|         function reemit() {
 | |
|             var args = slice.call(arguments)
 | |
|             args.unshift(methodName)
 | |
|             stream.emit.apply(stream, args)
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function handleEnd() {
 | |
|         if (ended) {
 | |
|             return
 | |
|         }
 | |
|         ended = true
 | |
|         var args = slice.call(arguments)
 | |
|         args.unshift("end")
 | |
|         stream.emit.apply(stream, args)
 | |
|     }
 | |
| 
 | |
|     function reemit(err) {
 | |
|         stream.emit("error", err)
 | |
|     }
 | |
| }
 |