1"use strict"; 2 3/*\ 4|*| 5|*| Base64 / binary data / UTF-8 strings utilities 6|*| 7|*| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding 8|*| 9\*/ 10 11/* Array of bytes to base64 string decoding */ 12 13function b64ToUint6 (nChr) { 14 15 return nChr > 64 && nChr < 91 ? 16 nChr - 65 17 : nChr > 96 && nChr < 123 ? 18 nChr - 71 19 : nChr > 47 && nChr < 58 ? 20 nChr + 4 21 : nChr === 43 ? 22 62 23 : nChr === 47 ? 24 63 25 : 26 0; 27 28} 29 30function base64DecToArr (sBase64, nBlocksSize) { 31 32 var 33 sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, 34 nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen); 35 36 for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { 37 nMod4 = nInIdx & 3; 38 nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; 39 if (nMod4 === 3 || nInLen - nInIdx === 1) { 40 for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { 41 taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; 42 } 43 nUint24 = 0; 44 45 } 46 } 47 48 return taBytes; 49} 50 51/* Base64 string to array encoding */ 52 53function uint6ToB64 (nUint6) { 54 55 return nUint6 < 26 ? 56 nUint6 + 65 57 : nUint6 < 52 ? 58 nUint6 + 71 59 : nUint6 < 62 ? 60 nUint6 - 4 61 : nUint6 === 62 ? 62 43 63 : nUint6 === 63 ? 64 47 65 : 66 65; 67 68} 69 70function base64EncArr (aBytes) { 71 72 var nMod3, sB64Enc = ""; 73 74 for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { 75 nMod3 = nIdx % 3; 76 nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24); 77 if (nMod3 === 2 || aBytes.length - nIdx === 1) { 78 sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63)); 79 nUint24 = 0; 80 } 81 } 82 83 return sB64Enc.replace(/A(?=A$|$)/g, "="); 84 85} 86 87/* UTF-8 array to DOMString and vice versa */ 88 89function UTF8ArrToStr (aBytes) { 90 91 var sView = ""; 92 93 for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) { 94 nPart = aBytes[nIdx]; 95 sView += String.fromCharCode( 96 nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */ 97 /* (nPart - 252 << 32) is not possible in ECMAScript! So...: */ 98 (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 99 : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */ 100 (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 101 : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */ 102 (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 103 : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */ 104 (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 105 : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */ 106 (nPart - 192 << 6) + aBytes[++nIdx] - 128 107 : /* nPart < 127 ? */ /* one byte */ 108 nPart 109 ); 110 } 111 112 return sView; 113 114} 115 116function strToUTF8Arr (sDOMStr) { 117 118 var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0; 119 120 /* mapping... */ 121 122 for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) { 123 nChr = sDOMStr.charCodeAt(nMapIdx); 124 nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6; 125 } 126 127 aBytes = new Uint8Array(nArrLen); 128 129 /* transcription... */ 130 131 for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) { 132 nChr = sDOMStr.charCodeAt(nChrIdx); 133 if (nChr < 128) { 134 /* one byte */ 135 aBytes[nIdx++] = nChr; 136 } else if (nChr < 0x800) { 137 /* two bytes */ 138 aBytes[nIdx++] = 192 + (nChr >>> 6); 139 aBytes[nIdx++] = 128 + (nChr & 63); 140 } else if (nChr < 0x10000) { 141 /* three bytes */ 142 aBytes[nIdx++] = 224 + (nChr >>> 12); 143 aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); 144 aBytes[nIdx++] = 128 + (nChr & 63); 145 } else if (nChr < 0x200000) { 146 /* four bytes */ 147 aBytes[nIdx++] = 240 + (nChr >>> 18); 148 aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); 149 aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); 150 aBytes[nIdx++] = 128 + (nChr & 63); 151 } else if (nChr < 0x4000000) { 152 /* five bytes */ 153 aBytes[nIdx++] = 248 + (nChr >>> 24); 154 aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); 155 aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); 156 aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); 157 aBytes[nIdx++] = 128 + (nChr & 63); 158 } else /* if (nChr <= 0x7fffffff) */ { 159 /* six bytes */ 160 aBytes[nIdx++] = 252 + /* (nChr >>> 32) is not possible in ECMAScript! So...: */ (nChr / 1073741824); 161 aBytes[nIdx++] = 128 + (nChr >>> 24 & 63); 162 aBytes[nIdx++] = 128 + (nChr >>> 18 & 63); 163 aBytes[nIdx++] = 128 + (nChr >>> 12 & 63); 164 aBytes[nIdx++] = 128 + (nChr >>> 6 & 63); 165 aBytes[nIdx++] = 128 + (nChr & 63); 166 } 167 } 168 169 return aBytes; 170 171} 172