1 // a duplex stream is just a stream that is both readable and writable.
2 // Since JS doesn't have multiple prototypal inheritance, this class
3 // prototypally inherits from Readable, and then parasitically from
10 var objectKeys = Object.keys || function (obj) {
12 for (var key in obj) {
18 module.exports = Duplex;
21 var processNextTick = require('process-nextick-args');
25 var util = require('core-util-is');
26 util.inherits = require('inherits');
29 var Readable = require('./_stream_readable');
30 var Writable = require('./_stream_writable');
32 util.inherits(Duplex, Readable);
34 var keys = objectKeys(Writable.prototype);
35 for (var v = 0; v < keys.length; v++) {
37 if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
40 function Duplex(options) {
41 if (!(this instanceof Duplex)) return new Duplex(options);
43 Readable.call(this, options);
44 Writable.call(this, options);
46 if (options && options.readable === false) this.readable = false;
48 if (options && options.writable === false) this.writable = false;
50 this.allowHalfOpen = true;
51 if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
53 this.once('end', onend);
56 // the no-half-open enforcer
58 // if we allow half-open state, or if the writable side ended,
60 if (this.allowHalfOpen || this._writableState.ended) return;
62 // no more data can be written.
63 // But allow more writes to happen in this tick.
64 processNextTick(onEndNT, this);
67 function onEndNT(self) {
71 function forEach(xs, f) {
72 for (var i = 0, l = xs.length; i < l; i++) {