1 /**
  2  *  Base64 encoding / decoding
  3  *  @see http://www.webtoolkit.info/
  4  */
  5 
  6 
  7 /*global JXG: true, define: true*/
  8 /*jslint nomen: true, plusplus: true, bitwise: true*/
  9 
 10 /* depends:
 11  jxg
 12  utils/encoding
 13  */
 14 
 15 define(['jxg', 'utils/encoding'], function (JXG, Encoding) {
 16 
 17     "use strict";
 18 
 19     var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
 20 
 21     // Util namespace
 22     JXG.Util = JXG.Util || {};
 23 
 24     /**
 25      * Base64 routines
 26      * @namespace
 27      */
 28     JXG.Util.Base64 = {
 29         encode : function (input) {
 30             var chr1, chr2, chr3, enc1, enc2, enc3, enc4,
 31                 output = [],
 32                 i = 0;
 33 
 34             input = Encoding.encode(input);
 35 
 36             while (i < input.length) {
 37                 chr1 = input.charCodeAt(i++);
 38                 chr2 = input.charCodeAt(i++);
 39                 chr3 = input.charCodeAt(i++);
 40 
 41                 enc1 = chr1 >> 2;
 42                 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
 43                 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
 44                 enc4 = chr3 & 63;
 45 
 46                 if (isNaN(chr2)) {
 47                     enc3 = enc4 = 64;
 48                 } else if (isNaN(chr3)) {
 49                     enc4 = 64;
 50                 }
 51 
 52                 output.push([keyStr.charAt(enc1),
 53                     keyStr.charAt(enc2),
 54                     keyStr.charAt(enc3),
 55                     keyStr.charAt(enc4)].join(''));
 56             }
 57 
 58             return output.join('');
 59         },
 60 
 61         // public method for decoding
 62         decode : function (input, utf8) {
 63             var chr1, chr2, chr3,
 64                 enc1, enc2, enc3, enc4,
 65                 output = [],
 66                 i = 0,
 67                 len = input.length;
 68 
 69             // deactivate regexp linting. Our regex is secure, because we're replacing everything with ''
 70             /*jslint regexp:true*/
 71             input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
 72             /*jslint regexp:false*/
 73 
 74             while (i < len) {
 75                 enc1 = keyStr.indexOf(input.charAt(i++));
 76                 enc2 = keyStr.indexOf(input.charAt(i++));
 77                 enc3 = keyStr.indexOf(input.charAt(i++));
 78                 enc4 = keyStr.indexOf(input.charAt(i++));
 79 
 80                 chr1 = (enc1 << 2) | (enc2 >> 4);
 81                 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
 82                 chr3 = ((enc3 & 3) << 6) | enc4;
 83 
 84                 output.push(String.fromCharCode(chr1));
 85 
 86                 if (enc3 !== 64) {
 87                     output.push(String.fromCharCode(chr2));
 88                 }
 89 
 90                 if (enc4 !== 64) {
 91                     output.push(String.fromCharCode(chr3));
 92                 }
 93             }
 94 
 95             output = output.join('');
 96 
 97             if (utf8) {
 98                 output = Encoding.decode(output);
 99             }
100 
101             return output;
102 
103         },
104 
105         /**
106          * Disas
107          * @param {string} input
108          * @return {Array}
109          */
110         decodeAsArray: function (input) {
111             var i,
112                 dec = this.decode(input),
113                 ar = [],
114                 len = dec.length;
115 
116             for (i = 0; i < len; i++) {
117                 ar[i] = dec.charCodeAt(i);
118             }
119 
120             return ar;
121         }
122     };
123 
124     return JXG.Util.Base64;
125 });