diff --git a/lib/internal/encoding.js b/lib/internal/encoding.js index 11003db8bc5..2ad74d54536 100644 --- a/lib/internal/encoding.js +++ b/lib/internal/encoding.js @@ -13,6 +13,7 @@ const { StringPrototypeSlice, Symbol, SymbolToStringTag, + Uint8Array, } = primordials; const { FastBuffer } = require('internal/buffer'); @@ -338,11 +339,26 @@ function getEncodingFromLabel(label) { let lazyInspect; +const kSmallEncodeLength = 32; +let smallEncodeScratch; + class TextEncoder { #encoding = 'utf-8'; #encode(input) { - return encodeUtf8String(`${input}`); + input = `${input}`; + if (input.length > kSmallEncodeLength) { + return encodeUtf8String(input); + } + + smallEncodeScratch ??= new Uint8Array(kSmallEncodeLength * 3); + encodeInto(input, smallEncodeScratch); + const written = encodeIntoResults[1]; + const result = new Uint8Array(written); + for (let i = 0; i < written; i++) { + result[i] = smallEncodeScratch[i]; + } + return result; } #encodeInto(input, dest) { diff --git a/test/parallel/test-whatwg-encoding-custom-textencoder-short.js b/test/parallel/test-whatwg-encoding-custom-textencoder-short.js new file mode 100644 index 00000000000..3f8ad64b567 --- /dev/null +++ b/test/parallel/test-whatwg-encoding-custom-textencoder-short.js @@ -0,0 +1,33 @@ +'use strict'; + +// Tests TextEncoder.prototype.encode() around the short string path. + +require('../common'); + +const assert = require('assert'); + +const encoder = new TextEncoder(); + +const inputs = [ + '', + 'a', + 'a'.repeat(32), + 'a'.repeat(33), + '\xff'.repeat(32), + 'ğ'.repeat(32), + 'ࠀ'.repeat(32), + '\u{1F44B}'.repeat(16), + '\u{1F44B}'.repeat(17), + '\ud800', + 'a\udc00b', + 'abc\ud83d', +]; + +for (const input of inputs) { + const result = encoder.encode(input); + const expected = Buffer.from(input, 'utf8'); + assert.strictEqual(Object.getPrototypeOf(result), Uint8Array.prototype); + assert.strictEqual(result.byteOffset, 0); + assert.strictEqual(result.buffer.byteLength, expected.length); + assert.deepStrictEqual(Buffer.from(result), expected); +}