1/* 2 * Copyright (c) 2010 Nick Galbreath 3 * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript 4 * 5 * Permission is hereby granted, free of charge, to any person 6 * obtaining a copy of this software and associated documentation 7 * files (the "Software"), to deal in the Software without 8 * restriction, including without limitation the rights to use, 9 * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following 12 * conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27/* base64 encode/decode compatible with window.btoa/atob 28 * 29 * window.atob/btoa is a Firefox extension to convert binary data (the "b") 30 * to base64 (ascii, the "a"). 31 * 32 * It is also found in Safari and Chrome. It is not available in IE. 33 * 34 * if (!window.btoa) window.btoa = base64.encode 35 * if (!window.atob) window.atob = base64.decode 36 * 37 * The original spec's for atob/btoa are a bit lacking 38 * https://developer.mozilla.org/en/DOM/window.atob 39 * https://developer.mozilla.org/en/DOM/window.btoa 40 * 41 * window.btoa and base64.encode takes a string where charCodeAt is [0,255] 42 * If any character is not [0,255], then an DOMException(5) is thrown. 43 * 44 * window.atob and base64.decode take a base64-encoded string 45 * If the input length is not a multiple of 4, or contains invalid characters 46 * then an DOMException(5) is thrown. 47 */ 48var base64 = {}; 49base64.PADCHAR = '='; 50base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 51 52base64.makeDOMException = function() { 53 // sadly in FF,Safari,Chrome you can't make a DOMException 54 var e, tmp; 55 56 try { 57 return new DOMException(DOMException.INVALID_CHARACTER_ERR); 58 } catch (tmp) { 59 // not available, just passback a duck-typed equiv 60 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error 61 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype 62 var ex = new Error("DOM Exception 5"); 63 64 // ex.number and ex.description is IE-specific. 65 ex.code = ex.number = 5; 66 ex.name = ex.description = "INVALID_CHARACTER_ERR"; 67 68 // Safari/Chrome output format 69 ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; }; 70 return ex; 71 } 72} 73 74base64.getbyte64 = function(s,i) { 75 // This is oddly fast, except on Chrome/V8. 76 // Minimal or no improvement in performance by using a 77 // object with properties mapping chars to value (eg. 'A': 0) 78 var idx = base64.ALPHA.indexOf(s.charAt(i)); 79 if (idx === -1) { 80 throw base64.makeDOMException(); 81 } 82 return idx; 83} 84 85base64.decode = function(s) { 86 // convert to string 87 s = '' + s; 88 var getbyte64 = base64.getbyte64; 89 var pads, i, b10; 90 var imax = s.length 91 if (imax === 0) { 92 return s; 93 } 94 95 if (imax % 4 !== 0) { 96 throw base64.makeDOMException(); 97 } 98 99 pads = 0 100 if (s.charAt(imax - 1) === base64.PADCHAR) { 101 pads = 1; 102 if (s.charAt(imax - 2) === base64.PADCHAR) { 103 pads = 2; 104 } 105 // either way, we want to ignore this last block 106 imax -= 4; 107 } 108 109 var x = []; 110 for (i = 0; i < imax; i += 4) { 111 b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | 112 (getbyte64(s,i+2) << 6) | getbyte64(s,i+3); 113 x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff)); 114 } 115 116 switch (pads) { 117 case 1: 118 b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6); 119 x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff)); 120 break; 121 case 2: 122 b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12); 123 x.push(String.fromCharCode(b10 >> 16)); 124 break; 125 } 126 return x.join(''); 127} 128 129base64.getbyte = function(s,i) {
130 var x = s.charCodeAt(i); 131 if (x > 255) { 132 throw base64.makeDOMException(); 133 } 134 return x; 135} 136 137base64.encode = function(s) { 138 if (arguments.length !== 1) { 139 throw new SyntaxError("Not enough arguments"); 140 } 141 var padchar = base64.PADCHAR; 142 var alpha = base64.ALPHA; 143 var getbyte = base64.getbyte; 144 145 var i, b10; 146 var x = []; 147 148 // convert to string 149 s = '' + s; 150 151 var imax = s.length - s.length % 3; 152 153 if (s.length === 0) { 154 return s; 155 } 156 for (i = 0; i < imax; i += 3) { 157 b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2); 158 x.push(alpha.charAt(b10 >> 18)); 159 x.push(alpha.charAt((b10 >> 12) & 0x3F)); 160 x.push(alpha.charAt((b10 >> 6) & 0x3f)); 161 x.push(alpha.charAt(b10 & 0x3f)); 162 } 163 switch (s.length - imax) { 164 case 1: 165 b10 = getbyte(s,i) << 16; 166 x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + 167 padchar + padchar); 168 break; 169 case 2: 170 b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8); 171 x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + 172 alpha.charAt((b10 >> 6) & 0x3f) + padchar); 173 break; 174 } 175 return x.join(''); 176} 177 178 179if (!window.atob) { 180 window.atob = base64.encode; 181} 182 183if (!window.btoa) { 184 window.atob = base64.decode; 185} 186
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.