| 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) | |
| } | |
| } | |