1 /** 2 * This file is part of the Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) Copyright 2011 - 2013 Warren Willmey. It is covered by the GNU General Public License version 3 as published by the Free Software Foundation, you should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. 3 */ 4 5 if( undefined == window.weasel ) window.weasel = {}; 6 7 // --------------------------------------------------------------------------- 8 /** Object to stream encode bytes/ints into a Base64 string. 9 * 10 * @constructor 11 * 12 * @author Warren Willmey 2012 13 */ 14 weasel.Base64Stream = function( ) 15 { 16 this.sBase64Stream = ''; 17 18 this.iBitCount = 0; 19 this.iBitStream= 0; 20 this.iBytesIn = 0; 21 22 this.sBase64StreamSaved = ''; 23 this.iBitCountSaved = 0; 24 this.iBitStreamSaved= 0; 25 this.iBytesInSaved = 0; 26 }; 27 28 //--------------------------------------------------------------------------- 29 /** Lookup table of Base64 tokens for easy conversion of byte array to Base64, 30 * might be improved by using a 12bit to Base64 pair of chars as opposed to 6bit to single Base64 char. 31 * 32 * @const 33 * @type {array} 34 */ 35 weasel.Base64Stream.prototype.aBase64Tokens = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split( '' ); 36 37 // --------------------------------------------------------------------------- 38 /** 39 * Convert, if there are enough, bits in the stream into Base64 characters. 40 * 41 * @private 42 */ 43 weasel.Base64Stream.prototype.__convertBitStream = function( ) 44 { 45 while( this.iBitCount >= 6 ) 46 { 47 var iTokenNumber = (this.iBitStream >>> ( this.iBitCount - 6 )) & 63; 48 this.sBase64Stream += this.aBase64Tokens[ iTokenNumber ]; 49 50 this.iBitCount -= 6; 51 this.iBitStream &= 0x7fffffff >>> (31 - this.iBitCount); 52 } 53 }; 54 55 // --------------------------------------------------------------------------- 56 /** 57 * Append a byte to the Base64 stream. 58 * 59 * @param {int} iByte = Byte of data to append to the stream. 60 */ 61 weasel.Base64Stream.prototype.appendByte = function( iByte ) 62 { 63 this.iBitCount += 8; 64 this.iBitStream = ( this.iBitStream << 8) | iByte; 65 this.iBytesIn++; 66 67 this.__convertBitStream(); 68 }; 69 70 // --------------------------------------------------------------------------- 71 /** Append 2 bytes at once to the stream, this is to reduce the overheads of calling 72 * appendByte() 2 times. 73 * 74 * @param {int} iWord = The 2 bytes you want to append to the stream in format 0x1122. 75 */ 76 weasel.Base64Stream.prototype.appendWord = function( iWord ) 77 { 78 this.iBitCount += 16; 79 this.iBitStream = ( this.iBitStream << 16) | iWord; 80 this.iBytesIn += 2; 81 82 this.__convertBitStream(); 83 }; 84 85 // --------------------------------------------------------------------------- 86 /** Append 3 bytes at once to the stream, this is to reduce the overheads of calling 87 * appendByte() 3 times. 88 * 89 * @param {int} i3Bytes = The 3 bytes you want to append to the stream in format 0x112233. 90 */ 91 weasel.Base64Stream.prototype.appendTriple = function( i3Bytes ) 92 { 93 this.iBitCount += 24; 94 this.iBitStream = ( this.iBitStream << 24) | i3Bytes; 95 this.iBytesIn += 3; 96 97 this.__convertBitStream(); 98 }; 99 100 // --------------------------------------------------------------------------- 101 /** 102 * Complete the Base64 stream (flush all remaining bits and append terminators). 103 * 104 */ 105 weasel.Base64Stream.prototype.flush = function() 106 { 107 this.__convertBitStream(); 108 109 if( 0 != this.iBitCount ) 110 { 111 var iBitPadding = 6 - this.iBitCount; 112 this.iBitCount += iBitPadding; 113 this.iBitStream <<= iBitPadding; 114 115 this.__convertBitStream(); 116 } 117 118 // Append terminators. 119 // 120 if( 1 == this.iBytesIn % 3 ) 121 { 122 this.sBase64Stream += '=='; 123 } 124 else if( 2 == this.iBytesIn % 3 ) 125 { 126 this.sBase64Stream += '='; 127 } 128 }; 129 130 // --------------------------------------------------------------------------- 131 /** 132 * Get the generated base encoded string, you should have called flush() before using this. 133 * 134 * @return {string} = The base64 encoded byte stream. 135 */ 136 weasel.Base64Stream.prototype.getBase64EncodedString = function() 137 { 138 return this.sBase64Stream; 139 }; 140 141 // --------------------------------------------------------------------------- 142 /** 143 * Add a non-encoded string to the beginning of the Base64 encoded string, such as the dataURI header. 144 * 145 * @param {string} sString = The string to prepend. 146 * 147 */ 148 weasel.Base64Stream.prototype.prepend = function( sString ) 149 { 150 this.sBase64Stream = sString.concat( this.sBase64Stream ); 151 }; 152 153 // --------------------------------------------------------------------------- 154 /** 155 * Save the current state of the base 64 encoding, if you have already saved the state it will be overwritten. 156 * 157 */ 158 weasel.Base64Stream.prototype.save = function() 159 { 160 this.sBase64StreamSaved = this.sBase64Stream; 161 this.iBitCountSaved = this.iBitCount; 162 this.iBitStreamSaved= this.iBitStream; 163 this.iBytesInSaved = this.iBytesIn; 164 165 }; 166 167 // --------------------------------------------------------------------------- 168 /** 169 * Load the previously saved state of the base 64 encoding. 170 * 171 */ 172 weasel.Base64Stream.prototype.load = function() 173 { 174 this.sBase64Stream = this.sBase64StreamSaved; 175 this.iBitCount = this.iBitCountSaved; 176 this.iBitStream= this.iBitStreamSaved; 177 this.iBytesIn = this.iBytesInSaved; 178 179 }; 180