esnext.uint8-array.from-base64.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. var base64Alphabet = base64Map.c2i;
  12. var base64UrlAlphabet = base64Map.c2iUrl;
  13. var Uint8Array = global.Uint8Array;
  14. var SyntaxError = global.SyntaxError;
  15. var charAt = uncurryThis(''.charAt);
  16. var replace = uncurryThis(''.replace);
  17. var stringSlice = uncurryThis(''.slice);
  18. var push = uncurryThis([].push);
  19. var SPACES = /[\t\n\f\r ]/g;
  20. var EXTRA_BITS = 'Extra bits';
  21. // `Uint8Array.fromBase64` method
  22. // https://github.com/tc39/proposal-arraybuffer-base64
  23. if (Uint8Array) $({ target: 'Uint8Array', stat: true, forced: true }, {
  24. fromBase64: function fromBase64(string /* , options */) {
  25. aString(string);
  26. var options = arguments.length > 1 ? anObjectOrUndefined(arguments[1]) : undefined;
  27. var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet;
  28. var strict = options ? !!options.strict : false;
  29. var input = strict ? string : replace(string, SPACES, '');
  30. if (input.length % 4 === 0) {
  31. if (stringSlice(input, -2) === '==') input = stringSlice(input, 0, -2);
  32. else if (stringSlice(input, -1) === '=') input = stringSlice(input, 0, -1);
  33. } else if (strict) throw new SyntaxError('Input is not correctly padded');
  34. var lastChunkSize = input.length % 4;
  35. switch (lastChunkSize) {
  36. case 1: throw new SyntaxError('Bad input length');
  37. case 2: input += 'AA'; break;
  38. case 3: input += 'A';
  39. }
  40. var bytes = [];
  41. var i = 0;
  42. var inputLength = input.length;
  43. var at = function (shift) {
  44. var chr = charAt(input, i + shift);
  45. if (!hasOwn(alphabet, chr)) throw new SyntaxError('Bad char in input: "' + chr + '"');
  46. return alphabet[chr] << (18 - 6 * shift);
  47. };
  48. for (; i < inputLength; i += 4) {
  49. var triplet = at(0) + at(1) + at(2) + at(3);
  50. push(bytes, (triplet >> 16) & 255, (triplet >> 8) & 255, triplet & 255);
  51. }
  52. var byteLength = bytes.length;
  53. if (lastChunkSize === 2) {
  54. if (strict && bytes[byteLength - 2] !== 0) throw new SyntaxError(EXTRA_BITS);
  55. byteLength -= 2;
  56. } else if (lastChunkSize === 3) {
  57. if (strict && bytes[byteLength - 1] !== 0) throw new SyntaxError(EXTRA_BITS);
  58. byteLength--;
  59. }
  60. return arrayFromConstructorAndList(Uint8Array, bytes, byteLength);
  61. }
  62. });