mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 07:44:48 -05:00
feat(std/node): support hex / base64 encoding in Buffer (#6414)
This commit is contained in:
parent
40866d7cd5
commit
86448fd9aa
2 changed files with 203 additions and 5 deletions
|
@ -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;
|
||||
static from(string: string, encoding?: string): Buffer;
|
||||
static from(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static from(value: any, offset?: number, length?: number): Buffer {
|
||||
if (typeof value == "string")
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,6 +116,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() {
|
||||
|
|
Loading…
Reference in a new issue