1 | 'use strict';
|
2 | var $ = require('../internals/export');
|
3 | var global = require('../internals/global');
|
4 | var uncurryThis = require('../internals/function-uncurry-this');
|
5 | var anObjectOrUndefined = require('../internals/an-object-or-undefined');
|
6 | var aString = require('../internals/a-string');
|
7 | var hasOwn = require('../internals/has-own-property');
|
8 | var arrayFromConstructorAndList = require('../internals/array-from-constructor-and-list');
|
9 | var base64Map = require('../internals/base64-map');
|
10 | var getAlphabetOption = require('../internals/get-alphabet-option');
|
11 |
|
12 | var base64Alphabet = base64Map.c2i;
|
13 | var base64UrlAlphabet = base64Map.c2iUrl;
|
14 |
|
15 | var Uint8Array = global.Uint8Array;
|
16 | var SyntaxError = global.SyntaxError;
|
17 | var charAt = uncurryThis(''.charAt);
|
18 | var replace = uncurryThis(''.replace);
|
19 | var stringSlice = uncurryThis(''.slice);
|
20 | var push = uncurryThis([].push);
|
21 | var SPACES = /[\t\n\f\r ]/g;
|
22 | var EXTRA_BITS = 'Extra bits';
|
23 |
|
24 |
|
25 |
|
26 | if (Uint8Array) $({ target: 'Uint8Array', stat: true, forced: true }, {
|
27 | fromBase64: function fromBase64(string /* , options */) {
|
28 | aString(string);
|
29 | var options = arguments.length > 1 ? anObjectOrUndefined(arguments[1]) : undefined;
|
30 | var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet;
|
31 | var strict = options ? !!options.strict : false;
|
32 |
|
33 | var input = strict ? string : replace(string, SPACES, '');
|
34 |
|
35 | if (input.length % 4 === 0) {
|
36 | if (stringSlice(input, -2) === '==') input = stringSlice(input, 0, -2);
|
37 | else if (stringSlice(input, -1) === '=') input = stringSlice(input, 0, -1);
|
38 | } else if (strict) throw new SyntaxError('Input is not correctly padded');
|
39 |
|
40 | var lastChunkSize = input.length % 4;
|
41 |
|
42 | switch (lastChunkSize) {
|
43 | case 1: throw new SyntaxError('Bad input length');
|
44 | case 2: input += 'AA'; break;
|
45 | case 3: input += 'A';
|
46 | }
|
47 |
|
48 | var bytes = [];
|
49 | var i = 0;
|
50 | var inputLength = input.length;
|
51 |
|
52 | var at = function (shift) {
|
53 | var chr = charAt(input, i + shift);
|
54 | if (!hasOwn(alphabet, chr)) throw new SyntaxError('Bad char in input: "' + chr + '"');
|
55 | return alphabet[chr] << (18 - 6 * shift);
|
56 | };
|
57 |
|
58 | for (; i < inputLength; i += 4) {
|
59 | var triplet = at(0) + at(1) + at(2) + at(3);
|
60 | push(bytes, (triplet >> 16) & 255, (triplet >> 8) & 255, triplet & 255);
|
61 | }
|
62 |
|
63 | var byteLength = bytes.length;
|
64 |
|
65 | if (lastChunkSize === 2) {
|
66 | if (strict && bytes[byteLength - 2] !== 0) throw new SyntaxError(EXTRA_BITS);
|
67 | byteLength -= 2;
|
68 | } else if (lastChunkSize === 3) {
|
69 | if (strict && bytes[byteLength - 1] !== 0) throw new SyntaxError(EXTRA_BITS);
|
70 | byteLength--;
|
71 | }
|
72 |
|
73 | return arrayFromConstructorAndList(Uint8Array, bytes, byteLength);
|
74 | }
|
75 | });
|