summaryrefslogtreecommitdiff
path: root/std/node
diff options
context:
space:
mode:
Diffstat (limited to 'std/node')
-rw-r--r--std/node/_utils.ts64
-rw-r--r--std/node/buffer.ts26
-rw-r--r--std/node/buffer_test.ts47
3 files changed, 126 insertions, 11 deletions
diff --git a/std/node/_utils.ts b/std/node/_utils.ts
index 463d4e67c..66b7b10d9 100644
--- a/std/node/_utils.ts
+++ b/std/node/_utils.ts
@@ -44,3 +44,67 @@ export function spliceOne(list: string[], index: number): void {
for (; index + 1 < list.length; index++) list[index] = list[index + 1];
list.pop();
}
+
+// Taken from: https://github.com/nodejs/node/blob/ba684805b6c0eded76e5cd89ee00328ac7a59365/lib/internal/util.js#L125
+// Return undefined if there is no match.
+// Move the "slow cases" to a separate function to make sure this function gets
+// inlined properly. That prioritizes the common case.
+export function normalizeEncoding(enc: string | null): string | undefined {
+ if (enc == null || enc === "utf8" || enc === "utf-8") return "utf8";
+ return slowCases(enc);
+}
+
+// https://github.com/nodejs/node/blob/ba684805b6c0eded76e5cd89ee00328ac7a59365/lib/internal/util.js#L130
+function slowCases(enc: string): string | undefined {
+ switch (enc.length) {
+ case 4:
+ if (enc === "UTF8") return "utf8";
+ if (enc === "ucs2" || enc === "UCS2") return "utf16le";
+ enc = `${enc}`.toLowerCase();
+ if (enc === "utf8") return "utf8";
+ if (enc === "ucs2") return "utf16le";
+ break;
+ case 3:
+ if (enc === "hex" || enc === "HEX" || `${enc}`.toLowerCase() === "hex")
+ return "hex";
+ break;
+ case 5:
+ if (enc === "ascii") return "ascii";
+ if (enc === "ucs-2") return "utf16le";
+ if (enc === "UTF-8") return "utf8";
+ if (enc === "ASCII") return "ascii";
+ if (enc === "UCS-2") return "utf16le";
+ enc = `${enc}`.toLowerCase();
+ if (enc === "utf-8") return "utf8";
+ if (enc === "ascii") return "ascii";
+ if (enc === "ucs-2") return "utf16le";
+ break;
+ case 6:
+ if (enc === "base64") return "base64";
+ if (enc === "latin1" || enc === "binary") return "latin1";
+ if (enc === "BASE64") return "base64";
+ if (enc === "LATIN1" || enc === "BINARY") return "latin1";
+ enc = `${enc}`.toLowerCase();
+ if (enc === "base64") return "base64";
+ if (enc === "latin1" || enc === "binary") return "latin1";
+ break;
+ case 7:
+ if (
+ enc === "utf16le" ||
+ enc === "UTF16LE" ||
+ `${enc}`.toLowerCase() === "utf16le"
+ )
+ return "utf16le";
+ break;
+ case 8:
+ if (
+ enc === "utf-16le" ||
+ enc === "UTF-16LE" ||
+ `${enc}`.toLowerCase() === "utf-16le"
+ )
+ return "utf16le";
+ break;
+ default:
+ if (enc === "") return "utf8";
+ }
+}
diff --git a/std/node/buffer.ts b/std/node/buffer.ts
index b878092dc..9ec7c04ff 100644
--- a/std/node/buffer.ts
+++ b/std/node/buffer.ts
@@ -1,8 +1,7 @@
import * as hex from "../encoding/hex.ts";
import * as base64 from "../encoding/base64.ts";
-import { notImplemented } from "./_utils.ts";
+import { notImplemented, normalizeEncoding } from "./_utils.ts";
-const validEncodings = ["utf8", "hex", "base64"];
const notImplementedEncodings = [
"utf16le",
"latin1",
@@ -17,20 +16,16 @@ function checkEncoding(encoding = "utf8", strict = true): string {
throw new TypeError(`Unkown encoding: ${encoding}`);
}
- encoding = encoding.toLowerCase();
- if (encoding === "utf-8" || encoding === "") {
- return "utf8";
- }
+ const normalized = normalizeEncoding(encoding);
+
+ if (normalized === undefined)
+ throw new TypeError(`Unkown encoding: ${encoding}`);
if (notImplementedEncodings.includes(encoding)) {
notImplemented(`"${encoding}" encoding`);
}
- if (!validEncodings.includes(encoding)) {
- throw new TypeError(`Unkown encoding: ${encoding}`);
- }
-
- return encoding;
+ return normalized;
}
/**
@@ -181,6 +176,15 @@ export default class Buffer extends Uint8Array {
return obj instanceof Buffer;
}
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ static isEncoding(encoding: any): boolean {
+ return (
+ typeof encoding === "string" &&
+ encoding.length !== 0 &&
+ normalizeEncoding(encoding) !== undefined
+ );
+ }
+
/**
* Copies data from a region of buf to a region in target, even if the target
* memory region overlaps with buf.
diff --git a/std/node/buffer_test.ts b/std/node/buffer_test.ts
index 105bc284e..4e6dc9afc 100644
--- a/std/node/buffer_test.ts
+++ b/std/node/buffer_test.ts
@@ -471,3 +471,50 @@ Deno.test({
assertEquals(slice.toString(), "deno");
},
});
+
+Deno.test({
+ name: "isEncoding returns true for valid encodings",
+ fn() {
+ [
+ "hex",
+ "HEX",
+ "HeX",
+ "utf8",
+ "utf-8",
+ "ascii",
+ "latin1",
+ "binary",
+ "base64",
+ "BASE64",
+ "BASe64",
+ "ucs2",
+ "ucs-2",
+ "utf16le",
+ "utf-16le",
+ ].forEach((enc) => {
+ assertEquals(Buffer.isEncoding(enc), true);
+ });
+ },
+});
+
+Deno.test({
+ name: "isEncoding returns false for invalid encodings",
+ fn() {
+ [
+ "utf9",
+ "utf-7",
+ "Unicode-FTW",
+ "new gnu gun",
+ false,
+ NaN,
+ {},
+ Infinity,
+ [],
+ 1,
+ 0,
+ -1,
+ ].forEach((enc) => {
+ assertEquals(Buffer.isEncoding(enc), false);
+ });
+ },
+});