* @param {BufferEncoding} encoding * @returns {this}
(encoding)
| 325 | * @returns {this} |
| 326 | */ |
| 327 | setEncoding (encoding) { |
| 328 | if (Buffer.isEncoding(encoding)) { |
| 329 | // Preserve raw Buffer chunks for the consume path (body.text(), |
| 330 | // body.json(), etc.) before super.setEncoding() replaces them |
| 331 | // with decoded strings. Without this, the consume path would |
| 332 | // lose access to the original bytes — some of which may be held |
| 333 | // by the decoder for incomplete multi-byte sequences, and the |
| 334 | // rest converted to strings that can't be safely concatenated |
| 335 | // byte-wise. |
| 336 | const state = this._readableState |
| 337 | const buffer = state.buffer |
| 338 | if (buffer && state.length > 0) { |
| 339 | const bufferIndex = state.bufferIndex ?? 0 |
| 340 | const preserved = [] |
| 341 | const source = typeof buffer.slice === 'function' |
| 342 | ? buffer.slice(bufferIndex) |
| 343 | : buffer |
| 344 | for (const data of source) { |
| 345 | if (Buffer.isBuffer(data)) { |
| 346 | preserved.push(data) |
| 347 | } |
| 348 | } |
| 349 | if (preserved.length > 0) { |
| 350 | this[kPreservedBuffer] = (this[kPreservedBuffer] || []).concat(preserved) |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | // Delegate to Node.js Readable.setEncoding() which initializes a |
| 355 | // StringDecoder and re-encodes already-buffered chunks. This properly |
| 356 | // handles multi-byte sequences split at chunk boundaries for the |
| 357 | // for-await / on('data') paths. Without this, Node.js uses |
| 358 | // buf.toString(encoding) on each chunk, producing U+FFFD for split chars. |
| 359 | super.setEncoding(encoding) |
| 360 | } |
| 361 | return this |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | /** |
no test coverage detected