From 43db7aa05dc4a4265d0f98cc7cdf577e77927bf1 Mon Sep 17 00:00:00 2001 From: Marcos Casagrande Date: Mon, 6 Jul 2020 00:02:09 +0200 Subject: fix(std/node): add encoding argument to Buffer.byteLength (#6639) --- std/node/buffer.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'std/node/buffer.ts') diff --git a/std/node/buffer.ts b/std/node/buffer.ts index 0fc8be6f1..dae04a66e 100644 --- a/std/node/buffer.ts +++ b/std/node/buffer.ts @@ -28,6 +28,46 @@ function checkEncoding(encoding = "utf8", strict = true): string { return normalized; } +interface EncodingOp { + byteLength(string: string): number; +} + +// https://github.com/nodejs/node/blob/56dbe466fdbc598baea3bfce289bf52b97b8b8f7/lib/buffer.js#L598 +const encodingOps: { [key: string]: EncodingOp } = { + utf8: { + byteLength: (string: string): number => + new TextEncoder().encode(string).byteLength, + }, + ucs2: { + byteLength: (string: string): number => string.length * 2, + }, + utf16le: { + byteLength: (string: string): number => string.length * 2, + }, + latin1: { + byteLength: (string: string): number => string.length, + }, + ascii: { + byteLength: (string: string): number => string.length, + }, + base64: { + byteLength: (string: string): number => + base64ByteLength(string, string.length), + }, + hex: { + byteLength: (string: string): number => string.length >>> 1, + }, +}; + +function base64ByteLength(str: string, bytes: number): number { + // Handle padding + if (str.charCodeAt(bytes - 1) === 0x3d) bytes--; + if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3d) bytes--; + + // Base64 ratio: 3/4 + return (bytes * 3) >>> 2; +} + /** * See also https://nodejs.org/api/buffer.html */ @@ -95,10 +135,13 @@ export default class Buffer extends Uint8Array { * used to convert the string into bytes. */ static byteLength( - string: string | Buffer | ArrayBufferView | ArrayBuffer | SharedArrayBuffer + string: string | Buffer | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, + encoding = "utf8" ): number { if (typeof string != "string") return string.byteLength; - return new TextEncoder().encode(string).length; + + encoding = normalizeEncoding(encoding) || "utf8"; + return encodingOps[encoding].byteLength(string); } /** -- cgit v1.2.3