| "use strict"; |
| |
| /** |
| * A minimal base64 implementation for number arrays. |
| * @memberof util |
| * @namespace |
| */ |
| var base64 = exports; |
| |
| /** |
| * Calculates the byte length of a base64 encoded string. |
| * @param {string} string Base64 encoded string |
| * @returns {number} Byte length |
| */ |
| base64.length = function length(string) { |
| var p = string.length; |
| if (!p) |
| return 0; |
| var n = 0; |
| while (--p % 4 > 1 && string.charAt(p) === "=") |
| ++n; |
| return Math.ceil(string.length * 3) / 4 - n; |
| }; |
| |
| // Base64 encoding table |
| var b64 = new Array(64); |
| |
| // Base64 decoding table |
| var s64 = new Array(123); |
| |
| // 65..90, 97..122, 48..57, 43, 47 |
| for (var i = 0; i < 64;) |
| s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; |
| |
| /** |
| * Encodes a buffer to a base64 encoded string. |
| * @param {Uint8Array} buffer Source buffer |
| * @param {number} start Source start |
| * @param {number} end Source end |
| * @returns {string} Base64 encoded string |
| */ |
| base64.encode = function encode(buffer, start, end) { |
| var parts = null, |
| chunk = []; |
| var i = 0, // output index |
| j = 0, // goto index |
| t; // temporary |
| while (start < end) { |
| var b = buffer[start++]; |
| switch (j) { |
| case 0: |
| chunk[i++] = b64[b >> 2]; |
| t = (b & 3) << 4; |
| j = 1; |
| break; |
| case 1: |
| chunk[i++] = b64[t | b >> 4]; |
| t = (b & 15) << 2; |
| j = 2; |
| break; |
| case 2: |
| chunk[i++] = b64[t | b >> 6]; |
| chunk[i++] = b64[b & 63]; |
| j = 0; |
| break; |
| } |
| if (i > 8191) { |
| (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); |
| i = 0; |
| } |
| } |
| if (j) { |
| chunk[i++] = b64[t]; |
| chunk[i++] = 61; |
| if (j === 1) |
| chunk[i++] = 61; |
| } |
| if (parts) { |
| if (i) |
| parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); |
| return parts.join(""); |
| } |
| return String.fromCharCode.apply(String, chunk.slice(0, i)); |
| }; |
| |
| var invalidEncoding = "invalid encoding"; |
| |
| /** |
| * Decodes a base64 encoded string to a buffer. |
| * @param {string} string Source string |
| * @param {Uint8Array} buffer Destination buffer |
| * @param {number} offset Destination offset |
| * @returns {number} Number of bytes written |
| * @throws {Error} If encoding is invalid |
| */ |
| base64.decode = function decode(string, buffer, offset) { |
| var start = offset; |
| var j = 0, // goto index |
| t; // temporary |
| for (var i = 0; i < string.length;) { |
| var c = string.charCodeAt(i++); |
| if (c === 61 && j > 1) |
| break; |
| if ((c = s64[c]) === undefined) |
| throw Error(invalidEncoding); |
| switch (j) { |
| case 0: |
| t = c; |
| j = 1; |
| break; |
| case 1: |
| buffer[offset++] = t << 2 | (c & 48) >> 4; |
| t = c; |
| j = 2; |
| break; |
| case 2: |
| buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2; |
| t = c; |
| j = 3; |
| break; |
| case 3: |
| buffer[offset++] = (t & 3) << 6 | c; |
| j = 0; |
| break; |
| } |
| } |
| if (j === 1) |
| throw Error(invalidEncoding); |
| return offset - start; |
| }; |
| |
| /** |
| * Tests if the specified string appears to be base64 encoded. |
| * @param {string} string String to test |
| * @returns {boolean} `true` if probably base64 encoded, otherwise false |
| */ |
| base64.test = function test(string) { |
| return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string); |
| }; |