|
| 1 | +/** |
| 2 | + * @license |
| 3 | + * Copyright 2020 The Emscripten Authors |
| 4 | + * SPDX-License-Identifier: MIT |
| 5 | + */ |
| 6 | + |
| 7 | +addToLibrary({ |
| 8 | + // Decodes a _known valid_ base64 string (without validation) and returns it as a new Uint8Array. |
| 9 | + // Benchmarked to be around 5x faster compared to a simple |
| 10 | + // "Uint8Array.from(atob(b64), c => c.charCodeAt(0))" (TODO: perhaps use this form in -Oz builds?) |
| 11 | + $base64Decode__postset: ` |
| 12 | + // Precreate a reverse lookup table from chars |
| 13 | + // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" back to |
| 14 | + // bytes to make decoding fast. |
| 15 | + for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) { |
| 16 | + base64ReverseLookup[48+i] = 52+i; // '0-9' |
| 17 | + base64ReverseLookup[65+i] = i; // 'A-Z' |
| 18 | + base64ReverseLookup[97+i] = 26+i; // 'a-z' |
| 19 | + } |
| 20 | + base64ReverseLookup[43] = 62; // '+' |
| 21 | + base64ReverseLookup[47] = 63; // '/' |
| 22 | +`, |
| 23 | + $base64Decode__docs: '/** @noinline */', |
| 24 | + $base64Decode: (b64) => { |
| 25 | +#if ENVIRONMENT_MAY_BE_NODE |
| 26 | + if (ENVIRONMENT_IS_NODE) { |
| 27 | + var buf = Buffer.from(b64, 'base64'); |
| 28 | + return new Uint8Array(buf.buffer, buf.byteOffset, buf.length); |
| 29 | + } |
| 30 | +#endif |
| 31 | + |
| 32 | +#if ASSERTIONS |
| 33 | + assert(b64.length % 4 == 0); |
| 34 | +#endif |
| 35 | + var b1, b2, i = 0, j = 0, bLength = b64.length; |
| 36 | + var output = new Uint8Array((bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=')); |
| 37 | + for (; i < bLength; i += 4, j += 3) { |
| 38 | + b1 = base64ReverseLookup[b64.charCodeAt(i+1)]; |
| 39 | + b2 = base64ReverseLookup[b64.charCodeAt(i+2)]; |
| 40 | + output[j] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4; |
| 41 | + output[j+1] = b1 << 4 | b2 >> 2; |
| 42 | + output[j+2] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; |
| 43 | + } |
| 44 | + return output; |
| 45 | + }, |
| 46 | + |
| 47 | + // Prefix of data URIs emitted by SINGLE_FILE and related options. |
| 48 | + // Double quotes here needed, othersise jsifier will not include any in the |
| 49 | + // output. |
| 50 | + $dataURIPrefix: "'data:application/octet-stream;base64,'", |
| 51 | + |
| 52 | + /** |
| 53 | + * Indicates whether filename is a base64 data URI. |
| 54 | + */ |
| 55 | + $isDataURI: (filename) => filename.startsWith(dataURIPrefix), |
| 56 | + |
| 57 | + // If filename is a base64 data URI, parses and returns data (Buffer on node, |
| 58 | + // Uint8Array otherwise). If filename is not a base64 data URI, returns |
| 59 | + // undefined. |
| 60 | + $tryParseAsDataURI__deps: ['$base64Decode', '$isDataURI', '$dataURIPrefix'], |
| 61 | + $tryParseAsDataURI: (filename) => { |
| 62 | + if (isDataURI(filename)) { |
| 63 | + return base64Decode(filename.slice(dataURIPrefix.length)); |
| 64 | + } |
| 65 | + }, |
| 66 | +}); |
0 commit comments