diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index d20877e921e445..b34226d8a090b5 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -69,45 +69,42 @@ function Duplex(options) { } Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, get() { return this._writableState.highWaterMark; } }); Object.defineProperty(Duplex.prototype, 'writableBuffer', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function() { - return this._writableState && this._writableState.getBuffer(); + get() { + return this._writableState.getBuffer(); } }); Object.defineProperty(Duplex.prototype, 'writableLength', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, get() { return this._writableState.length; } }); Object.defineProperty(Duplex.prototype, 'writableFinished', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, get() { return this._writableState.finished; } }); +Object.defineProperty(Duplex.prototype, 'destroyed', { + get() { + return this._readableState.destroyed && this._writableState.destroyed; + }, + set(value) { + // Backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } +}); + + // The no-half-open enforcer function onend() { // If the writable side ended, then we're ok. @@ -122,30 +119,3 @@ function onend() { function onEndNT(self) { self.end(); } - -Object.defineProperty(Duplex.prototype, 'destroyed', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get() { - if (this._readableState === undefined || - this._writableState === undefined) { - return false; - } - return this._readableState.destroyed && this._writableState.destroyed; - }, - set(value) { - // We ignore the value if the stream - // has not been initialized yet - if (this._readableState === undefined || - this._writableState === undefined) { - return; - } - - // Backward compatibility, the user is explicitly - // managing destroyed - this._readableState.destroyed = value; - this._writableState.destroyed = value; - } -}); diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 754e45da645dbc..9881061edc113d 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -178,30 +178,59 @@ function Readable(options) { Stream.call(this); } +// Exposed for testing purposes only. +Readable._fromList = fromList; + Object.defineProperty(Readable.prototype, 'destroyed', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, get() { - if (this._readableState === undefined) { - return false; - } return this._readableState.destroyed; }, set(value) { - // We ignore the value if the stream - // has not been initialized yet - if (!this._readableState) { - return; - } - // Backward compatibility, the user is explicitly // managing destroyed this._readableState.destroyed = value; } }); +Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { + get() { + return this._readableState.highWaterMark; + } +}); + +Object.defineProperty(Readable.prototype, 'readableBuffer', { + get() { + return this._readableState.buffer; + } +}); + +Object.defineProperty(Readable.prototype, 'readableFlowing', { + get() { + return this._readableState.flowing; + }, + set(state) { + this._readableState.flowing = state; + } +}); + +Object.defineProperty(Readable.prototype, 'readableLength', { + get() { + return this._readableState.length; + } +}); + +Object.defineProperty(Readable.prototype, 'readableObjectMode', { + get() { + return this._readableState.objectMode; + } +}); + +Object.defineProperty(Readable.prototype, 'readableEncoding', { + get() { + return this._readableState.encoding; + } +}); + Readable.prototype.destroy = destroyImpl.destroy; Readable.prototype._undestroy = destroyImpl.undestroy; Readable.prototype._destroy = function(err, cb) { @@ -1027,68 +1056,6 @@ Readable.prototype[Symbol.asyncIterator] = function() { return createReadableStreamAsyncIterator(this); }; -Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function() { - return this._readableState.highWaterMark; - } -}); - -Object.defineProperty(Readable.prototype, 'readableBuffer', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function() { - return this._readableState && this._readableState.buffer; - } -}); - -Object.defineProperty(Readable.prototype, 'readableFlowing', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function() { - return this._readableState.flowing; - }, - set: function(state) { - if (this._readableState) { - this._readableState.flowing = state; - } - } -}); - -// Exposed for testing purposes only. -Readable._fromList = fromList; - -Object.defineProperty(Readable.prototype, 'readableLength', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get() { - return this._readableState.length; - } -}); - -Object.defineProperty(Readable.prototype, 'readableObjectMode', { - enumerable: false, - get() { - return this._readableState ? this._readableState.objectMode : false; - } -}); - -Object.defineProperty(Readable.prototype, 'readableEncoding', { - enumerable: false, - get() { - return this._readableState ? this._readableState.encoding : null; - } -}); - // Pluck off n bytes from an array of buffers. // Length is the combined lengths of all the buffers in the list. // This function is designed to be inlinable, so please take care when making diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index bf9abeeed81d45..a92f854eee9ac5 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -164,6 +164,13 @@ function WritableState(options, stream, isDuplex) { this.corkedRequestsFree = corkReq; } +Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function writableStateBufferGetter() { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + + 'instead.', 'DEP0003') +}); + WritableState.prototype.getBuffer = function getBuffer() { var current = this.bufferedRequest; const out = []; @@ -174,13 +181,6 @@ WritableState.prototype.getBuffer = function getBuffer() { return out; }; -Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function writableStateBufferGetter() { - return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + - 'instead.', 'DEP0003') -}); - // Test _writableState for inheritance to account for Duplex streams, // whose prototype chain only points to Readable. var realHasInstance; @@ -240,6 +240,41 @@ function Writable(options) { Stream.call(this); } +Object.defineProperty(Writable.prototype, 'destroyed', { + get() { + return this._writableState.destroyed; + }, + set(value) { + // Backward compatibility, the user is explicitly + // managing destroyed + this._writableState.destroyed = value; + } +}); + +Object.defineProperty(Writable.prototype, 'writableObjectMode', { + get() { + return this._writableState.objectMode; + } +}); + +Object.defineProperty(Writable.prototype, 'writableFinished', { + get() { + return this._writableState.finished; + } +}); + +Object.defineProperty(Writable.prototype, 'writableBuffer', { + get() { + return this._writableState.getBuffer(); + } +}); + +Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { + get() { + return this._writableState.highWaterMark; + } +}); + // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function() { errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); @@ -333,16 +368,6 @@ Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { return this; }; -Object.defineProperty(Writable.prototype, 'writableBuffer', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function() { - return this._writableState && this._writableState.getBuffer(); - } -}); - function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && @@ -352,16 +377,6 @@ function decodeChunk(state, chunk, encoding) { return chunk; } -Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function() { - return this._writableState.highWaterMark; - } -}); - // If we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. @@ -599,7 +614,6 @@ Object.defineProperty(Writable.prototype, 'writableLength', { // Making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail - enumerable: false, get() { return this._writableState.length; } @@ -684,47 +698,6 @@ function onCorkedFinish(corkReq, state, err) { state.corkedRequestsFree.next = corkReq; } -Object.defineProperty(Writable.prototype, 'destroyed', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get() { - if (this._writableState === undefined) { - return false; - } - return this._writableState.destroyed; - }, - set(value) { - // We ignore the value if the stream - // has not been initialized yet - if (!this._writableState) { - return; - } - - // Backward compatibility, the user is explicitly - // managing destroyed - this._writableState.destroyed = value; - } -}); - -Object.defineProperty(Writable.prototype, 'writableObjectMode', { - enumerable: false, - get() { - return this._writableState ? this._writableState.objectMode : false; - } -}); - -Object.defineProperty(Writable.prototype, 'writableFinished', { - // Making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get() { - return this._writableState.finished; - } -}); - Writable.prototype.destroy = destroyImpl.destroy; Writable.prototype._undestroy = destroyImpl.undestroy; Writable.prototype._destroy = function(err, cb) { diff --git a/test/parallel/test-stream-duplex-destroy.js b/test/parallel/test-stream-duplex-destroy.js index 3c38d2c364051c..5247006dab7959 100644 --- a/test/parallel/test-stream-duplex-destroy.js +++ b/test/parallel/test-stream-duplex-destroy.js @@ -184,9 +184,10 @@ const assert = require('assert'); { function MyDuplex() { - assert.strictEqual(this.destroyed, false); - this.destroyed = false; Duplex.call(this); + assert.strictEqual(this.destroyed, false); + this.destroyed = true; + assert.strictEqual(this.destroyed, true); } Object.setPrototypeOf(MyDuplex.prototype, Duplex.prototype); diff --git a/test/parallel/test-stream-readable-destroy.js b/test/parallel/test-stream-readable-destroy.js index 05e7dd464ddca0..95305a6f5bce2b 100644 --- a/test/parallel/test-stream-readable-destroy.js +++ b/test/parallel/test-stream-readable-destroy.js @@ -154,9 +154,10 @@ const assert = require('assert'); { function MyReadable() { - assert.strictEqual(this.destroyed, false); - this.destroyed = false; Readable.call(this); + assert.strictEqual(this.destroyed, false); + this.destroyed = true; + assert.strictEqual(this.destroyed, true); } Object.setPrototypeOf(MyReadable.prototype, Readable.prototype); diff --git a/test/parallel/test-stream-writable-destroy.js b/test/parallel/test-stream-writable-destroy.js index a431d6d48d1c8e..68160a47e702d1 100644 --- a/test/parallel/test-stream-writable-destroy.js +++ b/test/parallel/test-stream-writable-destroy.js @@ -193,9 +193,10 @@ const assert = require('assert'); { function MyWritable() { - assert.strictEqual(this.destroyed, false); - this.destroyed = false; Writable.call(this); + assert.strictEqual(this.destroyed, false); + this.destroyed = true; + assert.strictEqual(this.destroyed, true); } Object.setPrototypeOf(MyWritable.prototype, Writable.prototype);