diff --git a/doc/api/stream.md b/doc/api/stream.md index 9e86955b9792..4cbe9404bced 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -915,9 +915,14 @@ getReadableStreamSomehow() ##### readable.setEncoding(encoding) -* `encoding` {string} The encoding to use. +* `encoding` {string|null} The encoding to use. * Returns: `this` The `readable.setEncoding()` method sets the default character encoding for @@ -934,9 +939,8 @@ The Readable stream will properly handle multi-byte characters delivered through the stream that would otherwise become improperly decoded if simply pulled from the stream as `Buffer` objects. -Encoding can be disabled by calling `readable.setEncoding(null)`. This approach -is useful when working with binary data or with large multi-byte strings spread -out over multiple chunks. +Decoding can be disabled by calling `readable.setEncoding(null)` or +`readable.setEncoding('buffer')`. ```js const readable = getReadableStreamSomehow(); diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 879e5ddb53fe..c59207b3ab3f 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -231,8 +231,16 @@ function needMoreData(state) { state.length === 0); } -// backwards compatibility. Readable.prototype.setEncoding = function(enc) { + if (enc === null || enc === 'buffer') { + if (this._readableState.decoder) { + this.push(this._readableState.decoder.end()); + } + this._readableState.decoder = null; + this._readableState.encoding = null; + return; + } + if (!StringDecoder) StringDecoder = require('string_decoder').StringDecoder; this._readableState.decoder = new StringDecoder(enc); diff --git a/test/parallel/test-stream-set-encoding-null.js b/test/parallel/test-stream-set-encoding-null.js new file mode 100644 index 000000000000..5b3411095e59 --- /dev/null +++ b/test/parallel/test-stream-set-encoding-null.js @@ -0,0 +1,32 @@ +'use strict'; +require('../common'); +const { PassThrough } = require('stream'); +const assert = require('assert'); + +{ + const stream = new PassThrough(); + stream.setEncoding('utf8'); + stream.write('foobar'); + assert.strictEqual(stream.read(), 'foobar'); + stream.setEncoding(null); + stream.write('foobar'); + assert.deepStrictEqual(stream.read(), Buffer.from('foobar')); +} + +{ + const stream = new PassThrough(); + stream.setEncoding('utf8'); + stream.write('foobar'); + assert.strictEqual(stream.read(), 'foobar'); + stream.setEncoding('buffer'); + stream.write('foobar'); + assert.deepStrictEqual(stream.read(), Buffer.from('foobar')); +} + +{ + const stream = new PassThrough(); + stream.setEncoding('utf8'); + stream.write(Buffer.from([0xc3])); + stream.setEncoding('buffer'); + assert.strictEqual(stream.read(), '\ufffd'); +}