@@ -24,7 +24,9 @@ var _ie = /MSIE/.test(navigator.userAgent),
2424 _num2b64 = ( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
2525 "abcdefghijklmnopqrstuvwxyz0123456789+/" ) . split ( "" ) ,
2626 _sign = { 8 : 0x80 , 16 : 0x8000 , 32 : 0x80000000 } ,
27- _8bits = / [ 0 1 ] { 8 } / g;
27+ _pooledArray = [ ] ,
28+ _IEEE754positive = / ^ .( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) $ / ,
29+ _IEEE754negative = / ^ ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) ( .{ 8 } ) $ / ;
2830
2931// for WebWorkers Code Block
3032self . importScripts && ( onmessage = function ( event ) {
@@ -42,21 +44,10 @@ function msgpackpack(data, // @param Mix:
4244 // [1][mix to String] msgpack.pack({}, true) -> "..."
4345 // [2][mix to ByteArray] msgpack.pack({}) -> [...]
4446
45- var byteArray = encode ( [ ] , data ) , rv , i , iz , num2bin = _num2bin ;
47+ var byteArray = encode ( [ ] , data ) ;
4648
47- if ( toString ) {
48- // http://d.hatena.ne.jp/uupaa/20101128
49- try {
50- return String . fromCharCode . apply ( this , byteArray ) ; // toString
51- } catch ( err ) {
52- ; // avoid "Maximum call stack size exceeded"
53- }
54- for ( rv = [ ] , i = 0 , iz = byteArray . length ; i < iz ; ++ i ) {
55- rv [ i ] = num2bin [ byteArray [ i ] ] ;
56- }
57- return rv . join ( "" ) ;
58- }
59- return byteArray ;
49+ return toString ? byteArrayToByteString ( byteArray )
50+ : byteArray ;
6051}
6152
6253// msgpack.unpack
@@ -73,7 +64,7 @@ function msgpackunpack(data) { // @param BinaryString/ByteArray:
7364// inner - encoder
7465function encode ( rv , // @param ByteArray: result
7566 mix ) { // @param Mix: source data
76- var size = 0 , i = 0 , iz , c , hash , pos ,
67+ var size = 0 , i = 0 , iz , c , ary , hash , pos ,
7768 high , low , i64 = 0 , sign , exp , frac ;
7869
7970 if ( mix == null ) { // null or undefined
@@ -135,7 +126,8 @@ function encode(rv, // @param ByteArray: result
135126 sign && ( mix *= - 1 ) ;
136127
137128 // add offset 1023 to ensure positive
138- exp = Math . log ( mix ) / Math . LN2 + 1023 | 0 ;
129+ // 0.6931471805599453 = Math.LN2;
130+ exp = ( ( Math . log ( mix ) / 0.6931471805599453 ) + 1023 ) | 0 ;
139131
140132 // shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
141133 // then throw away trash less than decimal point
@@ -144,15 +136,13 @@ function encode(rv, // @param ByteArray: result
144136
145137 // exp is between 1 and 2047. make it 11 bits
146138 // http://d.hatena.ne.jp/uupaa/20101128
147- if ( ! sign ) {
148- ary = ( ( exp + 4096 ) . toString ( 2 ) . slice ( 1 ) + frac ) . match ( _8bits ) ;
149- } else {
150- ary = ( ( exp + 2048 ) . toString ( 2 ) + frac ) . match ( _8bits ) ;
151- }
152- rv . push ( 0xcb , hash [ ary [ 0 ] ] , hash [ ary [ 1 ] ] ,
153- hash [ ary [ 2 ] ] , hash [ ary [ 3 ] ] ,
154- hash [ ary [ 4 ] ] , hash [ ary [ 5 ] ] ,
155- hash [ ary [ 6 ] ] , hash [ ary [ 7 ] ] ) ;
139+ _pooledArray = ! sign ? _IEEE754positive . exec ( ( exp + 4096 ) . toString ( 2 ) + frac )
140+ : _IEEE754negative . exec ( ( exp + 2048 ) . toString ( 2 ) + frac ) ;
141+ ary = _pooledArray ; // alias
142+ rv . push ( 0xcb , hash [ ary [ 1 ] ] , hash [ ary [ 2 ] ] ,
143+ hash [ ary [ 3 ] ] , hash [ ary [ 4 ] ] ,
144+ hash [ ary [ 5 ] ] , hash [ ary [ 6 ] ] ,
145+ hash [ ary [ 7 ] ] , hash [ ary [ 8 ] ] ) ;
156146 }
157147 break ;
158148 case "string" :
@@ -218,7 +208,7 @@ function encode(rv, // @param ByteArray: result
218208
219209// inner - decoder
220210function decode ( ) { // @return Mix:
221- var rv , undef , size , i = 0 , iz , msb = 0 , c , sign , exp , frac , key ,
211+ var rv , undef , size , i = 0 , iz , msb = 0 , c , sign , exp , frac , key , ary ,
222212 that = this ,
223213 data = that . data ,
224214 type = data [ ++ that . index ] ;
@@ -284,18 +274,21 @@ function decode() { // @return Mix:
284274 case 0xa0 : i = that . index + 1 ; // raw
285275 that . index += size ;
286276 // utf8.decode
287- for ( rv = [ ] , ri = - 1 , iz = i + size ; i < iz ; ++ i ) {
277+ _pooledArray = [ ] ;
278+ ary = _pooledArray ; // alias
279+ for ( iz = i + size ; i < iz ; ++ i ) {
288280 c = data [ i ] ; // first byte
289281 if ( c < 0x80 ) { // ASCII(0x00 ~ 0x7f)
290- rv [ ++ ri ] = c ;
282+ ary . push ( c ) ;
291283 } else if ( c < 0xe0 ) {
292- rv [ ++ ri ] = ( c & 0x1f ) << 6 | ( data [ ++ i ] & 0x3f ) ;
284+ ary . push ( ( c & 0x1f ) << 6 | ( data [ ++ i ] & 0x3f ) ) ;
293285 } else if ( c < 0xf0 ) {
294- rv [ ++ ri ] = ( c & 0x0f ) << 12 | ( data [ ++ i ] & 0x3f ) << 6
295- | ( data [ ++ i ] & 0x3f ) ;
286+ ary . push ( ( c & 0x0f ) << 12 | ( data [ ++ i ] & 0x3f ) << 6
287+ | ( data [ ++ i ] & 0x3f ) ) ;
296288 }
297289 }
298- return String . fromCharCode . apply ( null , rv ) ;
290+ return ary . length < 1024000 ? String . fromCharCode . apply ( null , ary )
291+ : byteArrayToByteString ( ary ) ;
299292 case 0xdf : size = readByte ( that , 4 ) ; // map 32
300293 case 0xde : size === undef && ( size = readByte ( that , 2 ) ) ; // map 16
301294 case 0x80 : for ( rv = { } ; i < size ; ++ i ) { // map
@@ -374,6 +367,23 @@ function setType(rv, // @param ByteArray: result
374367 }
375368}
376369
370+ // inner - byteArray To ByteString
371+ function byteArrayToByteString ( byteArray ) { // @param ByteArray
372+ // @return String
373+ // http://d.hatena.ne.jp/uupaa/20101128
374+ try {
375+ return String . fromCharCode . apply ( this , byteArray ) ; // toString
376+ } catch ( err ) {
377+ ; // avoid "Maximum call stack size exceeded"
378+ }
379+ var rv = [ ] , i = 0 , iz = byteArray . length , num2bin = _num2bin ;
380+
381+ for ( ; i < iz ; ++ i ) {
382+ rv [ i ] = num2bin [ byteArray [ i ] ] ;
383+ }
384+ return rv . join ( "" ) ;
385+ }
386+
377387// msgpack.download - load from server
378388function msgpackdownload ( url , // @param String:
379389 option , // @param Hash: { worker, timeout, before, after }
0 commit comments