diff options
author | andy finch <andyfinch7@gmail.com> | 2019-06-21 18:32:14 -0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-06-21 15:32:14 -0700 |
commit | eb93dc58a11d9e9a295eff31f9c2c6a3a4c5170b (patch) | |
tree | 1143049825f1adad073988a65799a76be6f1090b /js | |
parent | 20f41e719d2cb5add8e9168d00f239843fd56d31 (diff) |
add encodeInto to TextEncoder (#2558)
Diffstat (limited to 'js')
-rw-r--r-- | js/text_encoding.ts | 35 | ||||
-rw-r--r-- | js/text_encoding_test.ts | 31 |
2 files changed, 65 insertions, 1 deletions
diff --git a/js/text_encoding.ts b/js/text_encoding.ts index 03cc966b1..025a17f4f 100644 --- a/js/text_encoding.ts +++ b/js/text_encoding.ts @@ -461,6 +461,11 @@ export class TextDecoder { } } +interface TextEncoderEncodeIntoResult { + read: number; + written: number; +} + export class TextEncoder { /** Returns "utf-8". */ readonly encoding = "utf-8"; @@ -484,6 +489,36 @@ export class TextEncoder { return new Uint8Array(output); } + encodeInto(input: string, dest: Uint8Array): TextEncoderEncodeIntoResult { + const encoder = new UTF8Encoder(); + const inputStream = new Stream(stringToCodePoints(input)); + + let written = 0; + let read = 0; + while (true) { + const result = encoder.handler(inputStream.read()); + if (result === FINISHED) { + break; + } + read++; + if (Array.isArray(result)) { + dest.set(result, written); + written += result.length; + if (result.length > 3) { + // increment read a second time if greater than U+FFFF + read++; + } + } else { + dest[written] = result; + written++; + } + } + + return { + read, + written + }; + } get [Symbol.toStringTag](): string { return "TextEncoder"; } diff --git a/js/text_encoding_test.ts b/js/text_encoding_test.ts index b5ce78a8f..7633e105a 100644 --- a/js/text_encoding_test.ts +++ b/js/text_encoding_test.ts @@ -91,7 +91,7 @@ test(function textDecoderErrorEncoding(): void { assert(didThrow); }); -test(function textEncoder2(): void { +test(function textEncoder(): void { const fixture = "𝓽𝓮𝔁𝓽"; const encoder = new TextEncoder(); // prettier-ignore @@ -103,6 +103,35 @@ test(function textEncoder2(): void { ]); }); +test(function textEncodeInto(): void { + const fixture = "text"; + const encoder = new TextEncoder(); + const bytes = new Uint8Array(5); + const result = encoder.encodeInto(fixture, bytes); + assertEquals(result.read, 4); + assertEquals(result.written, 4); + // prettier-ignore + assertEquals(Array.from(bytes), [ + 0x74, 0x65, 0x78, 0x74, 0x00, + ]); +}); + +test(function textEncodeInto2(): void { + const fixture = "𝓽𝓮𝔁𝓽"; + const encoder = new TextEncoder(); + const bytes = new Uint8Array(17); + const result = encoder.encodeInto(fixture, bytes); + assertEquals(result.read, 8); + assertEquals(result.written, 16); + // prettier-ignore + assertEquals(Array.from(bytes), [ + 0xf0, 0x9d, 0x93, 0xbd, + 0xf0, 0x9d, 0x93, 0xae, + 0xf0, 0x9d, 0x94, 0x81, + 0xf0, 0x9d, 0x93, 0xbd, 0x00, + ]); +}); + test(function textDecoderSharedUint8Array(): void { const ab = new SharedArrayBuffer(6); const dataView = new DataView(ab); |