michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // From: http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956 michael@0: michael@0: /* Convert data (an array of integers) to a Base64 string. */ michael@0: var toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; michael@0: var base64Pad = '='; michael@0: michael@0: function toBase64(data) { michael@0: var result = ''; michael@0: var length = data.length; michael@0: var i; michael@0: // Convert every three bytes to 4 ascii characters. michael@0: /* BEGIN LOOP */ michael@0: for (i = 0; i < (length - 2); i += 3) { michael@0: result += toBase64Table[data[i] >> 2]; michael@0: result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; michael@0: result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)]; michael@0: result += toBase64Table[data[i+2] & 0x3f]; michael@0: } michael@0: /* END LOOP */ michael@0: michael@0: // Convert the remaining 1 or 2 bytes, pad out to 4 characters. michael@0: if (length%3) { michael@0: i = length - (length%3); michael@0: result += toBase64Table[data[i] >> 2]; michael@0: if ((length%3) == 2) { michael@0: result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; michael@0: result += toBase64Table[(data[i+1] & 0x0f) << 2]; michael@0: result += base64Pad; michael@0: } else { michael@0: result += toBase64Table[(data[i] & 0x03) << 4]; michael@0: result += base64Pad + base64Pad; michael@0: } michael@0: } michael@0: michael@0: return result; michael@0: } michael@0: michael@0: /* Convert Base64 data to a string */ michael@0: var toBinaryTable = [ michael@0: -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, michael@0: -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, michael@0: -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, michael@0: 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, michael@0: -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, michael@0: 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, michael@0: -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, michael@0: 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 michael@0: ]; michael@0: michael@0: function base64ToString(data) { michael@0: var result = ''; michael@0: var leftbits = 0; // number of bits decoded, but yet to be appended michael@0: var leftdata = 0; // bits decoded, but yet to be appended michael@0: michael@0: // Convert one by one. michael@0: /* BEGIN LOOP */ michael@0: for (var i = 0; i < data.length; i++) { michael@0: var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; michael@0: var padding = (data[i] == base64Pad); michael@0: // Skip illegal characters and whitespace michael@0: if (c == -1) continue; michael@0: michael@0: // Collect data into leftdata, update bitcount michael@0: leftdata = (leftdata << 6) | c; michael@0: leftbits += 6; michael@0: michael@0: // If we have 8 or more bits, append 8 bits to the result michael@0: if (leftbits >= 8) { michael@0: leftbits -= 8; michael@0: // Append if not padding. michael@0: if (!padding) michael@0: result += String.fromCharCode((leftdata >> leftbits) & 0xff); michael@0: leftdata &= (1 << leftbits) - 1; michael@0: } michael@0: } michael@0: /* END LOOP */ michael@0: michael@0: // If there are any bits left, the base64 string was corrupted michael@0: if (leftbits) michael@0: throw Components.Exception('Corrupted base64 string'); michael@0: michael@0: return result; michael@0: } michael@0: michael@0: var str = ""; michael@0: michael@0: /* BEGIN LOOP */ michael@0: for ( var i = 0; i < 8192; i++ ) michael@0: str += String.fromCharCode( (25 * Math.random()) + 97 ); michael@0: /* END LOOP */ michael@0: michael@0: /* BEGIN LOOP */ michael@0: for ( var i = 8192; i <= 16384; i *= 2 ) { michael@0: michael@0: var base64; michael@0: michael@0: base64 = toBase64(str); michael@0: base64ToString(base64); michael@0: michael@0: // Double the string michael@0: str += str; michael@0: } michael@0: /* END LOOP */ michael@0: michael@0: toBinaryTable = null;