• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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