-
Notifications
You must be signed in to change notification settings - Fork 1
/
wasm.js
53 lines (42 loc) · 1.49 KB
/
wasm.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
import base64SimdWasm from './wat/base64-simd.wat';
import base64Wasm from './wat/base64.wat';
import {allocate, free, wrap} from './wasm-tools.js';
export {toBytes, toBase64};
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const wasmModule = wrap(base64SimdWasm, {fallback: base64Wasm});
async function toBytes(base64) {
base64 = base64.replace(/=/g, '');
let n = base64.length;
let rem = n % 4;
let k = rem && rem - 1;
let m = (n >> 2) * 3 + k;
let [memory, view] = allocate(n + 16);
const {base642bytes} = await wasmModule({imports: {memory}});
let bytes = new Uint8Array(memory.buffer, view.byteOffset, n);
encoder.encodeInto(base64, bytes);
base642bytes(bytes.byteOffset, bytes.byteOffset + n);
let decoded = bytes.slice(0, m);
free(memory, view);
return decoded;
}
async function toBase64(bytes) {
let m = bytes.length;
let k = m % 3;
let n = Math.floor(m / 3) * 4 + (k && k + 1);
let M = m + 2;
let N = Math.ceil(m / 3) * 4;
let [memory, view] = allocate(N + M);
const {bytes2base64} = await wasmModule({imports: {memory}});
let decoded = new Uint8Array(memory.buffer, view.byteOffset, M);
decoded.set(bytes);
decoded[m] = 0;
decoded[m + 1] = 0;
bytes2base64(view.byteOffset, view.byteOffset + m, view.byteOffset + M);
let encoded = new Uint8Array(memory.buffer, view.byteOffset + M, n);
let base64 = decoder.decode(encoded);
if (k === 1) base64 += '==';
if (k === 2) base64 += '=';
free(memory, view);
return base64;
}