mirror of
https://github.com/denoland/deno.git
synced 2025-03-04 01:44:26 -05:00
Add atob() and btoa() (#776)
This commit is contained in:
parent
52d415537b
commit
4d16d54ff8
4 changed files with 74 additions and 0 deletions
|
@ -25,6 +25,8 @@ declare global {
|
||||||
|
|
||||||
TextEncoder: typeof TextEncoder;
|
TextEncoder: typeof TextEncoder;
|
||||||
TextDecoder: typeof TextDecoder;
|
TextDecoder: typeof TextDecoder;
|
||||||
|
atob: typeof atob;
|
||||||
|
btoa: typeof btoa;
|
||||||
|
|
||||||
Headers: typeof Headers;
|
Headers: typeof Headers;
|
||||||
Blob: typeof Blob;
|
Blob: typeof Blob;
|
||||||
|
@ -43,6 +45,8 @@ declare global {
|
||||||
// tslint:disable:variable-name
|
// tslint:disable:variable-name
|
||||||
const TextEncoder: typeof textEncoding.TextEncoder;
|
const TextEncoder: typeof textEncoding.TextEncoder;
|
||||||
const TextDecoder: typeof textEncoding.TextDecoder;
|
const TextDecoder: typeof textEncoding.TextDecoder;
|
||||||
|
const atob: typeof textEncoding.atob;
|
||||||
|
const btoa: typeof textEncoding.btoa;
|
||||||
const Headers: typeof DenoHeaders;
|
const Headers: typeof DenoHeaders;
|
||||||
const Blob: typeof DenoBlob;
|
const Blob: typeof DenoBlob;
|
||||||
// tslint:enable:variable-name
|
// tslint:enable:variable-name
|
||||||
|
@ -62,6 +66,8 @@ window.clearInterval = timers.clearTimer;
|
||||||
window.console = new Console(libdeno.print);
|
window.console = new Console(libdeno.print);
|
||||||
window.TextEncoder = textEncoding.TextEncoder;
|
window.TextEncoder = textEncoding.TextEncoder;
|
||||||
window.TextDecoder = textEncoding.TextDecoder;
|
window.TextDecoder = textEncoding.TextDecoder;
|
||||||
|
window.atob = textEncoding.atob;
|
||||||
|
window.btoa = textEncoding.btoa;
|
||||||
|
|
||||||
window.fetch = fetch_.fetch;
|
window.fetch = fetch_.fetch;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,45 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import * as base64 from "base64-js";
|
||||||
|
import { DenoError, ErrorKind } from "./errors";
|
||||||
|
|
||||||
|
export function atob(s: string): string {
|
||||||
|
const rem = s.length % 4;
|
||||||
|
// base64-js requires length exactly times of 4
|
||||||
|
if (rem > 0) {
|
||||||
|
s = s.padEnd(s.length + (4 - rem), "=");
|
||||||
|
}
|
||||||
|
let byteArray;
|
||||||
|
try {
|
||||||
|
byteArray = base64.toByteArray(s);
|
||||||
|
} catch (_) {
|
||||||
|
throw new DenoError(
|
||||||
|
ErrorKind.InvalidInput,
|
||||||
|
"The string to be decoded is not correctly encoded"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let result = "";
|
||||||
|
for (let i = 0; i < byteArray.length; i++) {
|
||||||
|
result += String.fromCharCode(byteArray[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function btoa(s: string): string {
|
||||||
|
const byteArray = [];
|
||||||
|
for (let i = 0; i < s.length; i++) {
|
||||||
|
const charCode = s[i].charCodeAt(0);
|
||||||
|
if (charCode > 0xff) {
|
||||||
|
throw new DenoError(
|
||||||
|
ErrorKind.InvalidInput,
|
||||||
|
"The string to be encoded contains characters " +
|
||||||
|
"outside of the Latin1 range."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
byteArray.push(charCode);
|
||||||
|
}
|
||||||
|
const result = base64.fromByteArray(Uint8Array.from(byteArray));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// @types/text-encoding relies on lib.dom.d.ts for some interfaces. We do not
|
// @types/text-encoding relies on lib.dom.d.ts for some interfaces. We do not
|
||||||
// want to include lib.dom.d.ts (due to size) into deno's global type scope.
|
// want to include lib.dom.d.ts (due to size) into deno's global type scope.
|
||||||
|
|
26
js/text_encoding_test.ts
Normal file
26
js/text_encoding_test.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { test, assert, assertEqual } from "./test_util.ts";
|
||||||
|
|
||||||
|
test(function atobSuccess() {
|
||||||
|
const text = "hello world";
|
||||||
|
const encoded = btoa(text);
|
||||||
|
assertEqual(encoded, "aGVsbG8gd29ybGQ=");
|
||||||
|
});
|
||||||
|
|
||||||
|
test(function btoaSuccess() {
|
||||||
|
const encoded = "aGVsbG8gd29ybGQ=";
|
||||||
|
const decoded = atob(encoded);
|
||||||
|
assertEqual(decoded, "hello world");
|
||||||
|
});
|
||||||
|
|
||||||
|
test(function btoaFailed() {
|
||||||
|
const text = "你好";
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
btoa(text);
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
assert(!!err);
|
||||||
|
assertEqual(err.name, "InvalidInput");
|
||||||
|
});
|
|
@ -15,3 +15,4 @@ import "./blob_test.ts";
|
||||||
import "./timers_test.ts";
|
import "./timers_test.ts";
|
||||||
import "./symlink_test.ts";
|
import "./symlink_test.ts";
|
||||||
import "./platform_test.ts";
|
import "./platform_test.ts";
|
||||||
|
import "./text_encoding_test.ts";
|
||||||
|
|
Loading…
Add table
Reference in a new issue