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
9 var objectKeys = Object.keys || function (obj) {
11 for (var key in obj) keys.push(key);
17 module.exports = Duplex;
20 var processNextTick = require('process-nextick-args');
26 var util = require('core-util-is');
27 util.inherits = require('inherits');
30 var Readable = require('./_stream_readable');
31 var Writable = require('./_stream_writable');
33 util.inherits(Duplex, Readable);
35 var keys = objectKeys(Writable.prototype);
36 for (var v = 0; v < keys.length; v++) {
38 if (!Duplex.prototype[method])
39 Duplex.prototype[method] = Writable.prototype[method];
42 function Duplex(options) {
43 if (!(this instanceof Duplex))
44 return new Duplex(options);
46 Readable.call(this, options);
47 Writable.call(this, options);
49 if (options && options.readable === false)
50 this.readable = false;
52 if (options && options.writable === false)
53 this.writable = false;
55 this.allowHalfOpen = true;
56 if (options && options.allowHalfOpen === false)
57 this.allowHalfOpen = false;
59 this.once('end', onend);
62 // the no-half-open enforcer
64 // if we allow half-open state, or if the writable side ended,
66 if (this.allowHalfOpen || this._writableState.ended)
69 // no more data can be written.
70 // But allow more writes to happen in this tick.
71 processNextTick(onEndNT, this);
74 function onEndNT(self) {
78 function forEach (xs, f) {
79 for (var i = 0, l = xs.length; i < l; i++) {