Home | History | Annotate | Download | only in tracing_examples
      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 
     13 function 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 
     30 function 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 
     53 function 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 
     70 function 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 
     89 function 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 
    116 function 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