summaryrefslogtreecommitdiff
path: root/std/node
diff options
context:
space:
mode:
Diffstat (limited to 'std/node')
-rw-r--r--std/node/buffer.ts64
-rw-r--r--std/node/buffer_test.ts144
2 files changed, 203 insertions, 5 deletions
diff --git a/std/node/buffer.ts b/std/node/buffer.ts
index fa911ee6f..b9b33be99 100644
--- a/std/node/buffer.ts
+++ b/std/node/buffer.ts
@@ -1,3 +1,38 @@
+import * as hex from "../encoding/hex.ts";
+import * as base64 from "../encoding/base64.ts";
+import { notImplemented } from "./_utils.ts";
+
+const validEncodings = ["utf8", "hex", "base64"];
+const notImplementedEncodings = [
+ "utf16le",
+ "latin1",
+ "ascii",
+ "binary",
+ "ucs2",
+];
+
+function checkEncoding(encoding = "utf8", strict = true): string {
+ if (typeof encoding !== "string" || (strict && encoding === "")) {
+ if (!strict) return "utf8";
+ throw new TypeError(`Unkown encoding: ${encoding}`);
+ }
+
+ encoding = encoding.toLowerCase();
+ if (encoding === "utf-8" || encoding === "") {
+ return "utf8";
+ }
+
+ if (notImplementedEncodings.includes(encoding)) {
+ notImplemented(`"${encoding}" encoding`);
+ }
+
+ if (!validEncodings.includes(encoding)) {
+ throw new TypeError(`Unkown encoding: ${encoding}`);
+ }
+
+ return encoding;
+}
+
/**
* See also https://nodejs.org/api/buffer.html
*/
@@ -66,11 +101,24 @@ export default class Buffer extends Uint8Array {
/**
* Creates a new Buffer containing string.
*/
- static from(string: string): Buffer;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- static from(value: any, offset?: number, length?: number): Buffer {
- if (typeof value == "string")
+ static from(string: string, encoding?: string): Buffer;
+ static from(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ value: any,
+ offsetOrEncoding?: number | string,
+ length?: number
+ ): Buffer {
+ const offset =
+ typeof offsetOrEncoding === "string" ? undefined : offsetOrEncoding;
+ let encoding =
+ typeof offsetOrEncoding === "string" ? offsetOrEncoding : undefined;
+
+ if (typeof value == "string") {
+ encoding = checkEncoding(encoding, false);
+ if (encoding === "hex") return new Buffer(hex.decodeString(value).buffer);
+ if (encoding === "base64") return new Buffer(base64.decode(value));
return new Buffer(new TextEncoder().encode(value).buffer);
+ }
// workaround for https://github.com/microsoft/TypeScript/issues/38446
return new Buffer(value, offset!, length);
@@ -246,7 +294,13 @@ export default class Buffer extends Uint8Array {
* encoding. start and end may be passed to decode only a subset of buf.
*/
toString(encoding = "utf8", start = 0, end = this.length): string {
- return new TextDecoder(encoding).decode(this.subarray(start, end));
+ encoding = checkEncoding(encoding);
+
+ const b = this.subarray(start, end);
+ if (encoding === "hex") return hex.encodeToString(b);
+ if (encoding === "base64") return base64.encode(b.buffer);
+
+ return new TextDecoder(encoding).decode(b);
}
/**
diff --git a/std/node/buffer_test.ts b/std/node/buffer_test.ts
index d2b41fa1b..adbc79751 100644
--- a/std/node/buffer_test.ts
+++ b/std/node/buffer_test.ts
@@ -117,6 +117,150 @@ Deno.test({
});
Deno.test({
+ name: "Buffer from string hex",
+ fn() {
+ for (const encoding of ["hex", "HEX"]) {
+ const buffer: Buffer = Buffer.from(
+ "7468697320697320612074c3a97374",
+ encoding
+ );
+ assertEquals(buffer.length, 15, "Buffer length should be 15");
+ assertEquals(
+ buffer.toString(),
+ "this is a tést",
+ "Buffer to string should recover the string"
+ );
+ }
+ },
+});
+
+Deno.test({
+ name: "Buffer from string base64",
+ fn() {
+ for (const encoding of ["base64", "BASE64"]) {
+ const buffer: Buffer = Buffer.from("dGhpcyBpcyBhIHTDqXN0", encoding);
+ assertEquals(buffer.length, 15, "Buffer length should be 15");
+ assertEquals(
+ buffer.toString(),
+ "this is a tést",
+ "Buffer to string should recover the string"
+ );
+ }
+ },
+});
+
+Deno.test({
+ name: "Buffer to string base64",
+ fn() {
+ for (const encoding of ["base64", "BASE64"]) {
+ const buffer: Buffer = Buffer.from("deno land");
+ assertEquals(
+ buffer.toString(encoding),
+ "ZGVubyBsYW5k",
+ "Buffer to string should recover the string in base64"
+ );
+ }
+ const b64 = "dGhpcyBpcyBhIHTDqXN0";
+ assertEquals(Buffer.from(b64, "base64").toString("base64"), b64);
+ },
+});
+
+Deno.test({
+ name: "Buffer to string hex",
+ fn() {
+ for (const encoding of ["hex", "HEX"]) {
+ const buffer: Buffer = Buffer.from("deno land");
+ assertEquals(
+ buffer.toString(encoding),
+ "64656e6f206c616e64",
+ "Buffer to string should recover the string"
+ );
+ }
+ const hex = "64656e6f206c616e64";
+ assertEquals(Buffer.from(hex, "hex").toString("hex"), hex);
+ },
+});
+
+Deno.test({
+ name: "Buffer to string invalid encoding",
+ fn() {
+ const buffer: Buffer = Buffer.from("deno land");
+ const invalidEncodings = [null, 5, {}, true, false, "foo", ""];
+
+ for (const encoding of invalidEncodings) {
+ assertThrows(
+ () => {
+ // deno-lint-ignore ban-ts-comment
+ // @ts-ignore
+ buffer.toString(encoding);
+ },
+ TypeError,
+ `Unkown encoding: ${encoding}`,
+ "Should throw on invalid encoding"
+ );
+ }
+ },
+});
+
+Deno.test({
+ name: "Buffer from string invalid encoding",
+ fn() {
+ const defaultToUtf8Encodings = [null, 5, {}, true, false, ""];
+ const invalidEncodings = ["deno", "base645"];
+
+ for (const encoding of defaultToUtf8Encodings) {
+ // deno-lint-ignore ban-ts-comment
+ // @ts-ignore
+ assertEquals(Buffer.from("yes", encoding).toString(), "yes");
+ }
+
+ for (const encoding of invalidEncodings) {
+ assertThrows(
+ () => {
+ // deno-lint-ignore ban-ts-comment
+ // @ts-ignore
+ Buffer.from("yes", encoding);
+ },
+ TypeError,
+ `Unkown encoding: ${encoding}`
+ );
+ }
+ },
+});
+
+Deno.test({
+ name: "Buffer to/from string not implemented encodings",
+ fn() {
+ const buffer: Buffer = Buffer.from("deno land");
+ const notImplemented = ["ascii", "binary"];
+
+ for (const encoding of notImplemented) {
+ assertThrows(
+ () => {
+ // deno-lint-ignore ban-ts-comment
+ // @ts-ignore
+ buffer.toString(encoding);
+ },
+ Error,
+ `"${encoding}" encoding`,
+ "Should throw on invalid encoding"
+ );
+
+ assertThrows(
+ () => {
+ // deno-lint-ignore ban-ts-comment
+ // @ts-ignore
+ Buffer.from("", encoding);
+ },
+ Error,
+ `"${encoding}" encoding`,
+ "Should throw on invalid encoding"
+ );
+ }
+ },
+});
+
+Deno.test({
name: "Buffer from another buffer creates a Buffer",
fn() {
const buffer: Buffer = Buffer.from(Buffer.from("test"));