-
Notifications
You must be signed in to change notification settings - Fork 3.4k
/
Copy pathbase64Decode.js
67 lines (58 loc) · 2.28 KB
/
base64Decode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* @license
* Copyright 2020 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
#if WASM2JS && 0 // TODO: Figure out a way to enable this kind of sharing.
// Binaryen defines the following function if Wasm2JS is being used:
// function base64DecodeToExistingUint8Array(uint8Array, offset, b64);
// so should reuse that when available. However that lives inside the asm module
// for the time being, so cannot access it directly from here. Hence this block
// is disabled atm.
function base64Decode(b64) {
#if ASSERTIONS
assert(b64.length % 4 == 0);
#endif
return base64DecodeToExistingUint8Array(new Uint8Array(b64.length*3>>2), 0, b64);
}
#else
// Precreate a reverse lookup table from chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" back to bytes to make decoding fast.
for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {
base64ReverseLookup[48+i] = 52+i; // '0-9'
base64ReverseLookup[65+i] = i; // 'A-Z'
base64ReverseLookup[97+i] = 26+i; // 'a-z'
}
base64ReverseLookup[43] = 62; // '+'
base64ReverseLookup[47] = 63; // '/'
// Decodes a _known valid_ base64 string (without validation) and returns it as a new Uint8Array.
// Benchmarked to be around 5x faster compared to a simple
// "Uint8Array.from(atob(b64), c => c.charCodeAt(0))" (TODO: perhaps use this form in -Oz builds?)
/** @noinline */
function base64Decode(b64) {
#if ENVIRONMENT_MAY_BE_NODE
if (typeof ENVIRONMENT_IS_NODE !== 'undefined' && ENVIRONMENT_IS_NODE) {
try {
var buf = Buffer.from(b64, 'base64');
} catch (_) {
var buf = new Buffer(b64, 'base64');
}
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
}
#endif
#if ASSERTIONS
assert(b64.length % 4 == 0);
#endif
var output, b1, b2, i = 0, j = 0, bLength = b64.length, length = bLength*3>>2;
if (b64[bLength-2] == '=') --length;
if (b64[bLength-1] == '=') --length;
output = new Uint8Array(length);
for (; i < bLength; i += 4, j += 3) {
b1 = base64ReverseLookup[b64.charCodeAt(i+1)];
b2 = base64ReverseLookup[b64.charCodeAt(i+2)];
output[j] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;
output[j+1] = b1 << 4 | b2 >> 2;
output[j+2] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];
}
return output;
}
#endif // ~WASM2JS