Home | History | Annotate | Download | only in include
      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2  * License, v. 2.0. If a copy of the MPL was not distributed with this
      3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
      6 
      7 /*jslint white: false */
      8 /*global console */
      9 
     10 var Base64 = {
     11     /* Convert data (an array of integers) to a Base64 string. */
     12     toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
     13     base64Pad     : '=',
     14 
     15     encode: function (data) {
     16         "use strict";
     17         var result = '';
     18         var toBase64Table = Base64.toBase64Table;
     19         var length = data.length;
     20         var lengthpad = (length % 3);
     21         // Convert every three bytes to 4 ascii characters.
     22 
     23         for (var i = 0; i < (length - 2); i += 3) {
     24             result += toBase64Table[data[i] >> 2];
     25             result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
     26             result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
     27             result += toBase64Table[data[i + 2] & 0x3f];
     28         }
     29 
     30         // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
     31         var j = 0;
     32         if (lengthpad === 2) {
     33             j = length - lengthpad;
     34             result += toBase64Table[data[j] >> 2];
     35             result += toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
     36             result += toBase64Table[(data[j + 1] & 0x0f) << 2];
     37             result += toBase64Table[64];
     38         } else if (lengthpad === 1) {
     39             j = length - lengthpad;
     40             result += toBase64Table[data[j] >> 2];
     41             result += toBase64Table[(data[j] & 0x03) << 4];
     42             result += toBase64Table[64];
     43             result += toBase64Table[64];
     44         }
     45 
     46         return result;
     47     },
     48 
     49     /* Convert Base64 data to a string */
     50     /* jshint -W013 */
     51     toBinaryTable : [
     52         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
     53         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
     54         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
     55         52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
     56         -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
     57         15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
     58         -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
     59         41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
     60     ],
     61     /* jshint +W013 */
     62 
     63     decode: function (data, offset) {
     64         "use strict";
     65         offset = typeof(offset) !== 'undefined' ? offset : 0;
     66         var toBinaryTable = Base64.toBinaryTable;
     67         var base64Pad = Base64.base64Pad;
     68         var result, result_length;
     69         var leftbits = 0; // number of bits decoded, but yet to be appended
     70         var leftdata = 0; // bits decoded, but yet to be appended
     71         var data_length = data.indexOf('=') - offset;
     72 
     73         if (data_length < 0) { data_length = data.length - offset; }
     74 
     75         /* Every four characters is 3 resulting numbers */
     76         result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
     77         result = new Array(result_length);
     78 
     79         // Convert one by one.
     80         for (var idx = 0, i = offset; i < data.length; i++) {
     81             var c = toBinaryTable[data.charCodeAt(i) & 0x7f];
     82             var padding = (data.charAt(i) === base64Pad);
     83             // Skip illegal characters and whitespace
     84             if (c === -1) {
     85                 console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
     86                 continue;
     87             }
     88 
     89             // Collect data into leftdata, update bitcount
     90             leftdata = (leftdata << 6) | c;
     91             leftbits += 6;
     92 
     93             // If we have 8 or more bits, append 8 bits to the result
     94             if (leftbits >= 8) {
     95                 leftbits -= 8;
     96                 // Append if not padding.
     97                 if (!padding) {
     98                     result[idx++] = (leftdata >> leftbits) & 0xff;
     99                 }
    100                 leftdata &= (1 << leftbits) - 1;
    101             }
    102         }
    103 
    104         // If there are any bits left, the base64 string was corrupted
    105         if (leftbits) {
    106             err = new Error('Corrupted base64 string');
    107             err.name = 'Base64-Error';
    108             throw err;
    109         }
    110 
    111         return result;
    112     }
    113 }; /* End of Base64 namespace */
    114