package.internals.uint8-from-base64.js Maven / Gradle / Ivy
The newest version!
'use strict';
var globalThis = require('../internals/global-this');
var uncurryThis = require('../internals/function-uncurry-this');
var anObjectOrUndefined = require('../internals/an-object-or-undefined');
var aString = require('../internals/a-string');
var hasOwn = require('../internals/has-own-property');
var base64Map = require('../internals/base64-map');
var getAlphabetOption = require('../internals/get-alphabet-option');
var notDetached = require('../internals/array-buffer-not-detached');
var base64Alphabet = base64Map.c2i;
var base64UrlAlphabet = base64Map.c2iUrl;
var SyntaxError = globalThis.SyntaxError;
var TypeError = globalThis.TypeError;
var at = uncurryThis(''.charAt);
var skipAsciiWhitespace = function (string, index) {
var length = string.length;
for (;index < length; index++) {
var chr = at(string, index);
if (chr !== ' ' && chr !== '\t' && chr !== '\n' && chr !== '\f' && chr !== '\r') break;
} return index;
};
var decodeBase64Chunk = function (chunk, alphabet, throwOnExtraBits) {
var chunkLength = chunk.length;
if (chunkLength < 4) {
chunk += chunkLength === 2 ? 'AA' : 'A';
}
var triplet = (alphabet[at(chunk, 0)] << 18)
+ (alphabet[at(chunk, 1)] << 12)
+ (alphabet[at(chunk, 2)] << 6)
+ alphabet[at(chunk, 3)];
var chunkBytes = [
(triplet >> 16) & 255,
(triplet >> 8) & 255,
triplet & 255
];
if (chunkLength === 2) {
if (throwOnExtraBits && chunkBytes[1] !== 0) {
throw new SyntaxError('Extra bits');
}
return [chunkBytes[0]];
}
if (chunkLength === 3) {
if (throwOnExtraBits && chunkBytes[2] !== 0) {
throw new SyntaxError('Extra bits');
}
return [chunkBytes[0], chunkBytes[1]];
}
return chunkBytes;
};
var writeBytes = function (bytes, elements, written) {
var elementsLength = elements.length;
for (var index = 0; index < elementsLength; index++) {
bytes[written + index] = elements[index];
}
return written + elementsLength;
};
/* eslint-disable max-statements, max-depth -- TODO */
module.exports = function (string, options, into, maxLength) {
aString(string);
anObjectOrUndefined(options);
var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet;
var lastChunkHandling = options ? options.lastChunkHandling : undefined;
if (lastChunkHandling === undefined) lastChunkHandling = 'loose';
if (lastChunkHandling !== 'loose' && lastChunkHandling !== 'strict' && lastChunkHandling !== 'stop-before-partial') {
throw new TypeError('Incorrect `lastChunkHandling` option');
}
if (into) notDetached(into.buffer);
var bytes = into || [];
var written = 0;
var read = 0;
var chunk = '';
var index = 0;
if (maxLength) while (true) {
index = skipAsciiWhitespace(string, index);
if (index === string.length) {
if (chunk.length > 0) {
if (lastChunkHandling === 'stop-before-partial') {
break;
}
if (lastChunkHandling === 'loose') {
if (chunk.length === 1) {
throw new SyntaxError('Malformed padding: exactly one additional character');
}
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written);
} else {
throw new SyntaxError('Missing padding');
}
}
read = string.length;
break;
}
var chr = at(string, index);
++index;
if (chr === '=') {
if (chunk.length < 2) {
throw new SyntaxError('Padding is too early');
}
index = skipAsciiWhitespace(string, index);
if (chunk.length === 2) {
if (index === string.length) {
if (lastChunkHandling === 'stop-before-partial') {
break;
}
throw new SyntaxError('Malformed padding: only one =');
}
if (at(string, index) === '=') {
++index;
index = skipAsciiWhitespace(string, index);
}
}
if (index < string.length) {
throw new SyntaxError('Unexpected character after padding');
}
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written);
read = string.length;
break;
}
if (!hasOwn(alphabet, chr)) {
throw new SyntaxError('Unexpected character');
}
var remainingBytes = maxLength - written;
if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) {
// special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=`
break;
}
chunk += chr;
if (chunk.length === 4) {
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written);
chunk = '';
read = index;
if (written === maxLength) {
break;
}
}
}
return { bytes: bytes, read: read, written: written };
};
© 2015 - 2024 Weber Informatics LLC | Privacy Policy