@ -16,12 +16,13 @@ declare var has_buf:boolean;
declare var new _buf : any ;
declare var new _raw _buf : any ;
declare var new _unsafe _buf : any ;
declare var Buffer _from : any ;
* /
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*jshint eqnull:true */
/*exported CFB */
/*global Uint8Array:false, Uint16Array:false */
/*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */
/ * : :
declare var DO _NOT _EXPORT _CFB : ? boolean ;
@ -71,70 +72,68 @@ function signed_crc_table()/*:any*/ {
return typeof Int32Array !== 'undefined' ? new Int32Array ( table ) : table ;
}
var T = signed _crc _table ( ) ;
function crc32 _bstr ( bstr /*:string*/ , seed /*:number*/ ) /*:number*/ {
var C = seed ^ - 1 , L = bstr . length - 1 ;
for ( var i = 0 ; i < L ; ) {
C = ( C >>> 8 ) ^ T [ ( C ^ bstr . charCodeAt ( i ++ ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ bstr . charCodeAt ( i ++ ) ) & 0xFF ] ;
}
if ( i === L ) C = ( C >>> 8 ) ^ T [ ( C ^ bstr . charCodeAt ( i ) ) & 0xFF ] ;
return C ^ - 1 ;
}
function crc32 _buf ( buf /*:Uint8Array|Array<number>*/ , seed /*:number*/ ) /*:number*/ {
if ( buf . length > 10000 ) return crc32 _buf _8 ( buf , seed ) ;
var C = seed ^ - 1 , L = buf . length - 3 ;
for ( var i = 0 ; i < L ; ) {
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
}
while ( i < L + 3 ) C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
return C ^ - 1 ;
}
function crc32 _buf _8 ( buf /*:Uint8Array|Array<number>*/ , seed /*:number*/ ) /*:number*/ {
var C = seed ^ - 1 , L = buf . length - 7 ;
for ( var i = 0 ; i < L ; ) {
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
var T0 = signed _crc _table ( ) ;
function slice _by _16 _tables ( T ) {
var c = 0 , v = 0 , n = 0 , table /*:Array<number>*/ = typeof Int32Array !== 'undefined' ? new Int32Array ( 4096 ) : new Array ( 4096 ) ;
for ( n = 0 ; n != 256 ; ++ n ) table [ n ] = T [ n ] ;
for ( n = 0 ; n != 256 ; ++ n ) {
v = T [ n ] ;
for ( c = 256 + n ; c < 4096 ; c += 256 ) v = table [ c ] = ( v >>> 8 ) ^ T [ v & 0xFF ] ;
}
while ( i < L + 7 ) C = ( C >>> 8 ) ^ T [ ( C ^ buf [ i ++ ] ) & 0xFF ] ;
return C ^ - 1 ;
var out = [ ] ;
for ( n = 1 ; n != 16 ; ++ n ) out [ n - 1 ] = typeof Int32Array !== 'undefined' ? table . subarray ( n * 256 , n * 256 + 256 ) : table . slice ( n * 256 , n * 256 + 256 ) ;
return out ;
}
var TT = slice _by _16 _tables ( T0 ) ;
var T1 = TT [ 0 ] , T2 = TT [ 1 ] , T3 = TT [ 2 ] , T4 = TT [ 3 ] , T5 = TT [ 4 ] ;
var T6 = TT [ 5 ] , T7 = TT [ 6 ] , T8 = TT [ 7 ] , T9 = TT [ 8 ] , Ta = TT [ 9 ] ;
var Tb = TT [ 10 ] , Tc = TT [ 11 ] , Td = TT [ 12 ] , Te = TT [ 13 ] , Tf = TT [ 14 ] ;
function crc32 _bstr ( bstr /*:string*/ , seed /*:number*/ ) /*:number*/ {
var C = seed /*:: ? 0 : 0 */ ^ - 1 ;
for ( var i = 0 , L = bstr . length ; i < L ; ) C = ( C >>> 8 ) ^ T0 [ ( C ^ bstr . charCodeAt ( i ++ ) ) & 0xFF ] ;
return ~ C ;
}
function crc32 _buf ( B /*:Uint8Array|Array<number>*/ , seed /*:number*/ ) /*:number*/ {
var C = seed /*:: ? 0 : 0 */ ^ - 1 , L = B . length - 15 , i = 0 ;
for ( ; i < L ; ) C =
Tf [ B [ i ++ ] ^ ( C & 255 ) ] ^
Te [ B [ i ++ ] ^ ( ( C >> 8 ) & 255 ) ] ^
Td [ B [ i ++ ] ^ ( ( C >> 16 ) & 255 ) ] ^
Tc [ B [ i ++ ] ^ ( C >>> 24 ) ] ^
Tb [ B [ i ++ ] ] ^ Ta [ B [ i ++ ] ] ^ T9 [ B [ i ++ ] ] ^ T8 [ B [ i ++ ] ] ^
T7 [ B [ i ++ ] ] ^ T6 [ B [ i ++ ] ] ^ T5 [ B [ i ++ ] ] ^ T4 [ B [ i ++ ] ] ^
T3 [ B [ i ++ ] ] ^ T2 [ B [ i ++ ] ] ^ T1 [ B [ i ++ ] ] ^ T0 [ B [ i ++ ] ] ;
L += 15 ;
while ( i < L ) C = ( C >>> 8 ) ^ T0 [ ( C ^ B [ i ++ ] ) & 0xFF ] ;
return ~ C ;
}
function crc32 _str ( str /*:string*/ , seed /*:number*/ ) /*:number*/ {
var C = seed ^ - 1 ;
for ( var i = 0 , L = str . length , c , d ; i < L ; ) {
for ( var i = 0 , L = str . length , c = 0 , d = 0 ; i < L ; ) {
c = str . charCodeAt ( i ++ ) ;
if ( c < 0x80 ) {
C = ( C >>> 8 ) ^ T [ ( C ^ c ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ c ) & 0xFF ] ;
} else if ( c < 0x800 ) {
C = ( C >>> 8 ) ^ T [ ( C ^ ( 192 | ( ( c >> 6 ) & 31 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 128 | ( c & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 192 | ( ( c >> 6 ) & 31 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 128 | ( c & 63 ) ) ) & 0xFF ] ;
} else if ( c >= 0xD800 && c < 0xE000 ) {
c = ( c & 1023 ) + 64 ; d = str . charCodeAt ( i ++ ) & 1023 ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 240 | ( ( c >> 8 ) & 7 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 128 | ( ( c >> 2 ) & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 128 | ( ( d >> 6 ) & 15 ) | ( ( c & 3 ) << 4 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 128 | ( d & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 240 | ( ( c >> 8 ) & 7 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 128 | ( ( c >> 2 ) & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 128 | ( ( d >> 6 ) & 15 ) | ( ( c & 3 ) << 4 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 128 | ( d & 63 ) ) ) & 0xFF ] ;
} else {
C = ( C >>> 8 ) ^ T [ ( C ^ ( 224 | ( ( c >> 12 ) & 15 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 128 | ( ( c >> 6 ) & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T [ ( C ^ ( 128 | ( c & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 224 | ( ( c >> 12 ) & 15 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 128 | ( ( c >> 6 ) & 63 ) ) ) & 0xFF ] ;
C = ( C >>> 8 ) ^ T 0 [ ( C ^ ( 128 | ( c & 63 ) ) ) & 0xFF ] ;
}
}
return C ^ - 1 ;
return ~ C ;
}
CRC32 . table = T ;
CRC32 . table = T 0 ;
CRC32 . bstr = crc32 _bstr ;
CRC32 . buf = crc32 _buf ;
CRC32 . str = crc32 _str ;
@ -142,7 +141,7 @@ CRC32.str = crc32_str;
/* [MS-CFB] v20171201 */
var CFB = ( function _CFB ( ) {
var exports /*:CFBModule*/ = /*::(*/ { } /*:: :any)*/ ;
exports . version = '1. 1.4 ';
exports . version = '1. 2.1 ';
/* [MS-CFB] 2.6.4 */
function namecmp ( l /*:string*/ , r /*:string*/ ) /*:number*/ {
var L = l . split ( "/" ) , R = r . split ( "/" ) ;
@ -232,6 +231,7 @@ var fs/*:: = require('fs'); */;
function get _fs ( ) { return fs || ( fs = require ( 'fs' ) ) ; }
function parse ( file /*:RawBytes*/ , options /*:CFBReadOpts*/ ) /*:CFBContainer*/ {
if ( file [ 0 ] == 0x50 && file [ 1 ] == 0x4b ) return parse _zip ( file , options ) ;
if ( ( file [ 0 ] | 0x20 ) == 0x6d && ( file [ 1 ] | 0x20 ) == 0x69 ) return parse _mad ( file , options ) ;
if ( file . length < 512 ) throw new Error ( "CFB file size " + file . length + " < 512" ) ;
var mver = 3 ;
var ssz = 512 ;
@ -441,7 +441,7 @@ function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/,
if ( ( q = _ _readInt32LE ( sector , i * 4 ) ) === ENDOFCHAIN ) break ;
fat _addrs . push ( q ) ;
}
if ( cnt >= 1 ) sleuth _fat ( _ _readInt32LE ( sector , ssz - 4 ) , cnt - 1 , sectors , ssz , fat _addrs ) ;
sleuth _fat ( _ _readInt32LE ( sector , ssz - 4 ) , cnt - 1 , sectors , ssz , fat _addrs ) ;
}
}
@ -553,7 +553,11 @@ function read_file(filename/*:string*/, options/*:CFBReadOpts*/) {
}
function read ( blob /*:RawBytes|string*/ , options /*:CFBReadOpts*/ ) {
switch ( options && options . type || "base64" ) {
var type = options && options . type ;
if ( ! type ) {
if ( has _buf && Buffer . isBuffer ( blob ) ) type = "buffer" ;
}
switch ( type || "base64" ) {
case "file" : /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */ return read _file ( blob , options ) ;
case "base64" : /*:: if(typeof blob !== 'string') throw "Must pass a base64-encoded binary string when type='file'"; */ return parse ( s2a ( Base64 . decode ( blob ) ) , options ) ;
case "binary" : /*:: if(typeof blob !== 'string') throw "Must pass a binary string when type='file'"; */ return parse ( s2a ( blob ) , options ) ;
@ -602,22 +606,28 @@ function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
if ( ! gc && ! f ) return ;
var now = new Date ( 1987 , 1 , 19 ) , j = 0 ;
// Track which names exist
var fullPaths = Object . create ? Object . create ( null ) : { } ;
var data /*:Array<[string, CFBEntry]>*/ = [ ] ;
for ( i = 0 ; i < cfb . FullPaths . length ; ++ i ) {
fullPaths [ cfb . FullPaths [ i ] ] = true ;
if ( cfb . FileIndex [ i ] . type === 0 ) continue ;
data . push ( [ cfb . FullPaths [ i ] , cfb . FileIndex [ i ] ] ) ;
}
for ( i = 0 ; i < data . length ; ++ i ) {
var dad = dirname ( data [ i ] [ 0 ] ) ;
s = false ;
for ( j = 0 ; j < data . length ; ++ j ) if ( data [ j ] [ 0 ] === dad ) s = true ;
if ( ! s ) data . push ( [ dad , ( {
name : filename ( dad ) . replace ( "/" , "" ) ,
type : 1 ,
clsid : HEADER _CLSID ,
ct : now , mt : now ,
content : null
} /*:any*/ ) ] ) ;
s = fullPaths [ dad ] ;
if ( ! s ) {
data . push ( [ dad , ( {
name : filename ( dad ) . replace ( "/" , "" ) ,
type : 1 ,
clsid : HEADER _CLSID ,
ct : now , mt : now ,
content : null
} /*:any*/ ) ] ) ;
// Add name to set
fullPaths [ dad ] = true ;
}
}
data . sort ( function ( x , y ) { return namecmp ( x [ 0 ] , y [ 0 ] ) ; } ) ;
@ -650,10 +660,15 @@ function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
}
function _write ( cfb /*:CFBContainer*/ , options /*:CFBWriteOpts*/ ) /*:RawBytes */ {
function _write ( cfb /*:CFBContainer*/ , options /*:CFBWriteOpts*/ ) /*:RawBytes |string */ {
var _opts = options || { } ;
/* MAD is order-sensitive, skip rebuild and sort */
if ( _opts . fileType == 'mad' ) return write _mad ( cfb , _opts ) ;
rebuild _cfb ( cfb ) ;
if ( _opts . fileType == 'zip' ) return write _zip ( cfb , _opts ) ;
switch ( _opts . fileType ) {
case 'zip' : return write _zip ( cfb , _opts ) ;
//case 'mad': return write_mad(cfb, _opts);
}
var L = ( function ( cfb /*:CFBContainer*/ ) /*:Array<number>*/ {
var mini _size = 0 , fat _size = 0 ;
for ( var i = 0 ; i < cfb . FileIndex . length ; ++ i ) {
@ -771,19 +786,36 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ {
/*:: if(!file.content) throw new Error("unreachable"); */
if ( file . size >= 0x1000 ) {
o . l = ( file . start + 1 ) << 9 ;
for ( j = 0 ; j < file . size ; ++ j ) o . write _shift ( 1 , file . content [ j ] ) ;
for ( ; j & 0x1FF ; ++ j ) o . write _shift ( 1 , 0 ) ;
if ( has _buf && Buffer . isBuffer ( file . content ) ) {
file . content . copy ( o , o . l , 0 , file . size ) ;
// o is a 0-filled Buffer so just set next offset
o . l += ( file . size + 511 ) & - 512 ;
} else {
for ( j = 0 ; j < file . size ; ++ j ) o . write _shift ( 1 , file . content [ j ] ) ;
for ( ; j & 0x1FF ; ++ j ) o . write _shift ( 1 , 0 ) ;
}
}
}
for ( i = 1 ; i < cfb . FileIndex . length ; ++ i ) {
file = cfb . FileIndex [ i ] ;
/*:: if(!file.content) throw new Error("unreachable"); */
if ( file . size > 0 && file . size < 0x1000 ) {
for ( j = 0 ; j < file . size ; ++ j ) o . write _shift ( 1 , file . content [ j ] ) ;
for ( ; j & 0x3F ; ++ j ) o . write _shift ( 1 , 0 ) ;
if ( has _buf && Buffer . isBuffer ( file . content ) ) {
file . content . copy ( o , o . l , 0 , file . size ) ;
// o is a 0-filled Buffer so just set next offset
o . l += ( file . size + 63 ) & - 64 ;
} else {
for ( j = 0 ; j < file . size ; ++ j ) o . write _shift ( 1 , file . content [ j ] ) ;
for ( ; j & 0x3F ; ++ j ) o . write _shift ( 1 , 0 ) ;
}
}
}
while ( o . l < o . length ) o . write _shift ( 1 , 0 ) ;
if ( has _buf ) {
o . l = o . length ;
} else {
// When using Buffer, already 0-filled
while ( o . l < o . length ) o . write _shift ( 1 , 0 ) ;
}
return o ;
}
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
@ -847,10 +879,13 @@ function a2s(o/*:RawBytes*/)/*:string*/ {
function write ( cfb /*:CFBContainer*/ , options /*:CFBWriteOpts*/ ) /*:RawBytes|string*/ {
var o = _write ( cfb , options ) ;
switch ( options && options . type ) {
switch ( options && options . type || "buffer" ) {
case "file" : get _fs ( ) ; fs . writeFileSync ( options . filename , ( o /*:any*/ ) ) ; return o ;
case "binary" : return a2s ( o ) ;
case "base64" : return Base64 . encode ( a2s ( o ) ) ;
case "binary" : return typeof o == "string" ? o : a2s ( o ) ;
case "base64" : return Base64 . encode ( typeof o == "string" ? o : a2s ( o ) ) ;
case "buffer" : if ( has _buf ) return Buffer . isBuffer ( o ) ? o : Buffer _from ( o ) ;
/* falls through */
case "array" : return typeof o == "string" ? s2a ( o ) : o ;
}
return o ;
}
@ -920,6 +955,38 @@ function read_bits_n(buf, bl, n) {
return v & f ;
}
/* helpers for unaligned bit writes */
function write _bits _3 ( buf , bl , v ) { var w = bl & 7 , h = bl >>> 3 ;
if ( w <= 5 ) buf [ h ] |= ( v & 7 ) << w ;
else {
buf [ h ] |= ( v << w ) & 0xFF ;
buf [ h + 1 ] = ( v & 7 ) >> ( 8 - w ) ;
}
return bl + 3 ;
}
function write _bits _1 ( buf , bl , v ) {
var w = bl & 7 , h = bl >>> 3 ;
v = ( v & 1 ) << w ;
buf [ h ] |= v ;
return bl + 1 ;
}
function write _bits _8 ( buf , bl , v ) {
var w = bl & 7 , h = bl >>> 3 ;
v <<= w ;
buf [ h ] |= v & 0xFF ; v >>>= 8 ;
buf [ h + 1 ] = v ;
return bl + 8 ;
}
function write _bits _16 ( buf , bl , v ) {
var w = bl & 7 , h = bl >>> 3 ;
v <<= w ;
buf [ h ] |= v & 0xFF ; v >>>= 8 ;
buf [ h + 1 ] = v & 0xFF ;
buf [ h + 2 ] = v >>> 8 ;
return bl + 16 ;
}
/* until ArrayBuffer#realloc is a thing, fake a realloc */
function realloc ( b , sz /*:number*/ ) {
var L = b . length , M = 2 * L > sz ? 2 * L : sz + 5 , i = 0 ;
@ -933,7 +1000,7 @@ function realloc(b, sz/*:number*/) {
} else if ( use _typed _arrays ) {
var a = new Uint8Array ( M ) ;
if ( a . set ) a . set ( b ) ;
else for ( ; i < b. length ; ++ i ) a [ i ] = b [ i ] ;
else for ( ; i < L ; ++ i ) a [ i ] = b [ i ] ;
return a ;
}
b . length = M ;
@ -945,30 +1012,7 @@ function zero_fill_array(n) {
var o = new Array ( n ) ;
for ( var i = 0 ; i < n ; ++ i ) o [ i ] = 0 ;
return o ;
} var _deflate = ( function ( ) {
var _deflateRaw = ( function ( ) {
return function deflateRaw ( data , out ) {
var boff = 0 ;
while ( boff < data . length ) {
var L = Math . min ( 0xFFFF , data . length - boff ) ;
var h = boff + L == data . length ;
/* TODO: this is only type 0 stored */
out . write _shift ( 1 , + h ) ;
out . write _shift ( 2 , L ) ;
out . write _shift ( 2 , ( ~ L ) & 0xFFFF ) ;
while ( L -- > 0 ) out [ out . l ++ ] = data [ boff ++ ] ;
}
return out . l ;
} ;
} ) ( ) ;
return function ( data ) {
var buf = new _buf ( 50 + Math . floor ( data . length * 1.1 ) ) ;
var off = _deflateRaw ( data , buf ) ;
return buf . slice ( 0 , off ) ;
} ;
} ) ( ) ;
/* modified inflate function also moves original read head */
}
/* build tree (used for literals and lengths) */
function build _tree ( clens , cmap , MAX /*:number*/ ) /*:number*/ {
@ -1008,6 +1052,7 @@ function build_tree(clens, cmap, MAX/*:number*/)/*:number*/ {
return maxlen ;
}
/* Fixed Huffman */
var fix _lmap = use _typed _arrays ? new Uint16Array ( 512 ) : zero _fill _array ( 512 ) ;
var fix _dmap = use _typed _arrays ? new Uint16Array ( 32 ) : zero _fill _array ( 32 ) ;
if ( ! use _typed _arrays ) {
@ -1027,8 +1072,125 @@ if(!use_typed_arrays) {
for ( ; i <= 279 ; i ++ ) clens . push ( 7 ) ;
for ( ; i <= 287 ; i ++ ) clens . push ( 8 ) ;
build _tree ( clens , fix _lmap , 288 ) ;
} ) ( ) ; var _deflateRaw = ( function _deflateRawIIFE ( ) {
var DST _LN _RE = use _typed _arrays ? new Uint8Array ( 0x8000 ) : [ ] ;
var j = 0 , k = 0 ;
for ( ; j < DST _LN . length - 1 ; ++ j ) {
for ( ; k < DST _LN [ j + 1 ] ; ++ k ) DST _LN _RE [ k ] = j ;
}
for ( ; k < 32768 ; ++ k ) DST _LN _RE [ k ] = 29 ;
var LEN _LN _RE = use _typed _arrays ? new Uint8Array ( 0x103 ) : [ ] ;
for ( j = 0 , k = 0 ; j < LEN _LN . length - 1 ; ++ j ) {
for ( ; k < LEN _LN [ j + 1 ] ; ++ k ) LEN _LN _RE [ k ] = j ;
}
function write _stored ( data , out ) {
var boff = 0 ;
while ( boff < data . length ) {
var L = Math . min ( 0xFFFF , data . length - boff ) ;
var h = boff + L == data . length ;
out . write _shift ( 1 , + h ) ;
out . write _shift ( 2 , L ) ;
out . write _shift ( 2 , ( ~ L ) & 0xFFFF ) ;
while ( L -- > 0 ) out [ out . l ++ ] = data [ boff ++ ] ;
}
return out . l ;
}
/* Fixed Huffman */
function write _huff _fixed ( data , out ) {
var bl = 0 ;
var boff = 0 ;
var addrs = use _typed _arrays ? new Uint16Array ( 0x8000 ) : [ ] ;
while ( boff < data . length ) {
var L = /* data.length - boff; */ Math . min ( 0xFFFF , data . length - boff ) ;
/* write a stored block for short data */
if ( L < 10 ) {
bl = write _bits _3 ( out , bl , + ! ! ( boff + L == data . length ) ) ; // jshint ignore:line
if ( bl & 7 ) bl += 8 - ( bl & 7 ) ;
out . l = ( bl / 8 ) | 0 ;
out . write _shift ( 2 , L ) ;
out . write _shift ( 2 , ( ~ L ) & 0xFFFF ) ;
while ( L -- > 0 ) out [ out . l ++ ] = data [ boff ++ ] ;
bl = out . l * 8 ;
continue ;
}
bl = write _bits _3 ( out , bl , + ! ! ( boff + L == data . length ) + 2 ) ; // jshint ignore:line
var hash = 0 ;
while ( L -- > 0 ) {
var d = data [ boff ] ;
hash = ( ( hash << 5 ) ^ d ) & 0x7FFF ;
var match = - 1 , mlen = 0 ;
if ( ( match = addrs [ hash ] ) ) {
match |= boff & ~ 0x7FFF ;
if ( match > boff ) match -= 0x8000 ;
if ( match < boff ) while ( data [ match + mlen ] == data [ boff + mlen ] && mlen < 250 ) ++ mlen ;
}
if ( mlen > 2 ) {
/* Copy Token */
d = LEN _LN _RE [ mlen ] ;
if ( d <= 22 ) bl = write _bits _8 ( out , bl , bitswap8 [ d + 1 ] >> 1 ) - 1 ;
else {
write _bits _8 ( out , bl , 3 ) ;
bl += 5 ;
write _bits _8 ( out , bl , bitswap8 [ d - 23 ] >> 5 ) ;
bl += 3 ;
}
var len _eb = ( d < 8 ) ? 0 : ( ( d - 4 ) >> 2 ) ;
if ( len _eb > 0 ) {
write _bits _16 ( out , bl , mlen - LEN _LN [ d ] ) ;
bl += len _eb ;
}
d = DST _LN _RE [ boff - match ] ;
bl = write _bits _8 ( out , bl , bitswap8 [ d ] >> 3 ) ;
bl -= 3 ;
var dst _eb = d < 4 ? 0 : ( d - 2 ) >> 1 ;
if ( dst _eb > 0 ) {
write _bits _16 ( out , bl , boff - match - DST _LN [ d ] ) ;
bl += dst _eb ;
}
for ( var q = 0 ; q < mlen ; ++ q ) {
addrs [ hash ] = boff & 0x7FFF ;
hash = ( ( hash << 5 ) ^ data [ boff ] ) & 0x7FFF ;
++ boff ;
}
L -= mlen - 1 ;
} else {
/* Literal Token */
if ( d <= 143 ) d = d + 48 ;
else bl = write _bits _1 ( out , bl , 1 ) ;
bl = write _bits _8 ( out , bl , bitswap8 [ d ] ) ;
addrs [ hash ] = boff & 0x7FFF ;
++ boff ;
}
}
bl = write _bits _8 ( out , bl , 0 ) - 1 ;
}
out . l = ( ( bl + 7 ) / 8 ) | 0 ;
return out . l ;
}
return function _deflateRaw ( data , out ) {
if ( data . length < 8 ) return write _stored ( data , out ) ;
return write _huff _fixed ( data , out ) ;
} ;
} ) ( ) ;
function _deflate ( data ) {
var buf = new _buf ( 50 + Math . floor ( data . length * 1.1 ) ) ;
var off = _deflateRaw ( data , buf ) ;
return buf . slice ( 0 , off ) ;
}
/* modified inflate function also moves original read head */
var dyn _lmap = use _typed _arrays ? new Uint16Array ( 32768 ) : zero _fill _array ( 32768 ) ;
var dyn _dmap = use _typed _arrays ? new Uint16Array ( 32768 ) : zero _fill _array ( 32768 ) ;
var dyn _cmap = use _typed _arrays ? new Uint16Array ( 128 ) : zero _fill _array ( 128 ) ;
@ -1132,14 +1294,12 @@ function inflate(data, usz/*:number*/) {
var sz = data [ boff >>> 3 ] | data [ ( boff >>> 3 ) + 1 ] << 8 ;
boff += 32 ;
/* push sz bytes */
if ( ! usz && OL < woff + sz ) { outbuf = realloc ( outbuf , woff + sz ) ; OL = outbuf . length ; }
if ( typeof data . copy === 'function' ) {
// $FlowIgnore
data . copy ( outbuf , woff , boff >>> 3 , ( boff >>> 3 ) + sz ) ;
woff += sz ; boff += 8 * sz ;
} else while ( sz -- > 0 ) { outbuf [ woff ++ ] = data [ boff >>> 3 ] ; boff += 8 ; }
if ( sz > 0 ) {
if ( ! usz && OL < woff + sz ) { outbuf = realloc ( outbuf , woff + sz ) ; OL = outbuf . length ; }
while ( sz -- > 0 ) { outbuf [ woff ++ ] = data [ boff >>> 3 ] ; boff += 8 ; }
}
continue ;
} else if ( ( header >> > 1 ) == 1 ) {
} else if ( ( header >> 1 ) == 1 ) {
/* Fixed Huffman */
max _len _1 = 9 ; max _len _2 = 5 ;
} else {
@ -1147,8 +1307,8 @@ function inflate(data, usz/*:number*/) {
boff = dyn ( data , boff ) ;
max _len _1 = dyn _len _1 ; max _len _2 = dyn _len _2 ;
}
if ( ! usz && ( OL < woff + 32767 ) ) { outbuf = realloc ( outbuf , woff + 32767 ) ; OL = outbuf . length ; }
for ( ; ; ) { // while(true) is apparently out of vogue in modern JS circles
if ( ! usz && ( OL < woff + 32767 ) ) { outbuf = realloc ( outbuf , woff + 32767 ) ; OL = outbuf . length ; }
/* ingest code and move read head */
var bits = read _bits _n ( data , boff , max _len _1 ) ;
var code = ( header >>> 1 ) == 1 ? fix _lmap [ bits ] : dyn _lmap [ bits ] ;
@ -1179,12 +1339,13 @@ function inflate(data, usz/*:number*/) {
}
/* in the common case, manual byte copy is faster than TA set / Buffer copy */
if ( ! usz && OL < tgt ) { outbuf = realloc ( outbuf , tgt ) ; OL = outbuf . length ; }
if ( ! usz && OL < tgt ) { outbuf = realloc ( outbuf , tgt + 100 ) ; OL = outbuf . length ; }
while ( woff < tgt ) { outbuf [ woff ] = outbuf [ woff - dst ] ; ++ woff ; }
}
}
}
return [ usz ? outbuf : outbuf . slice ( 0 , woff ) , ( boff + 7 ) >>> 3 ] ;
if ( usz ) return [ outbuf , ( boff + 7 ) >>> 3 ] ;
return [ outbuf . slice ( 0 , woff ) , ( boff + 7 ) >>> 3 ] ;
}
function _inflate ( payload , usz ) {
@ -1242,7 +1403,6 @@ function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/
parse _local _file ( blob , csz , usz , o , EF ) ;
blob . l = L ;
}
return o ;
}
@ -1278,7 +1438,7 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
var data = blob . slice ( blob . l , blob . l + _csz ) ;
switch ( meth ) {
case 8 : data = _inflateRawSync ( blob , _usz ) ; break ;
case 0 : break ;
case 0 : break ; // TODO: scan for magic number
default : throw new Error ( "Unsupported ZIP Compression method " + meth ) ;
}
@ -1293,8 +1453,8 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
if ( _csz != csz ) warn _or _throw ( wrn , "Bad compressed size: " + csz + " != " + _csz ) ;
if ( _usz != usz ) warn _or _throw ( wrn , "Bad uncompressed size: " + usz + " != " + _usz ) ;
var _crc32 = CRC32 . buf ( data , 0 ) ;
if ( ( crc32 >> 0 ) != ( _crc32 >> 0 ) ) warn _or _throw ( wrn , "Bad CRC32 checksum: " + crc32 + " != " + _crc32 ) ;
//var _crc32 = CRC32.buf(data, 0);
//if((crc32>>0) != (_crc32>>0)) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32);
cfb _add ( o , name , data , { unsafe : true , mt : date } ) ;
}
function write _zip ( cfb /*:CFBContainer*/ , options /*:CFBWriteOpts*/ ) /*:RawBytes*/ {
@ -1345,7 +1505,10 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
start _cd += namebuf . length ;
out . push ( namebuf ) ;
/* TODO: extra fields? */
/* TODO: encryption header ? */
start _cd += outbuf . length ;
out . push ( outbuf ) ;
@ -1399,6 +1562,212 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
return bconcat ( ( [ bconcat ( ( out /*:any*/ ) ) , bconcat ( cdirs ) , o ] /*:any*/ ) ) ;
}
var ContentTypeMap = ( {
"htm" : "text/html" ,
"xml" : "text/xml" ,
"gif" : "image/gif" ,
"jpg" : "image/jpeg" ,
"png" : "image/png" ,
"mso" : "application/x-mso" ,
"thmx" : "application/vnd.ms-officetheme" ,
"sh33tj5" : "application/octet-stream"
} /*:any*/ ) ;
function get _content _type ( fi /*:CFBEntry*/ , fp /*:string*/ ) /*:string*/ {
if ( fi . ctype ) return fi . ctype ;
var ext = fi . name || "" , m = ext . match ( /\.([^\.]+)$/ ) ;
if ( m && ContentTypeMap [ m [ 1 ] ] ) return ContentTypeMap [ m [ 1 ] ] ;
if ( fp ) {
m = ( ext = fp ) . match ( /[\.\\]([^\.\\])+$/ ) ;
if ( m && ContentTypeMap [ m [ 1 ] ] ) return ContentTypeMap [ m [ 1 ] ] ;
}
return "application/octet-stream" ;
}
/* 76 character chunks TODO: intertwine encoding */
function write _base64 _76 ( bstr /*:string*/ ) /*:string*/ {
var data = Base64 . encode ( bstr ) ;
var o = [ ] ;
for ( var i = 0 ; i < data . length ; i += 76 ) o . push ( data . slice ( i , i + 76 ) ) ;
return o . join ( "\r\n" ) + "\r\n" ;
}
/ *
Rules for QP :
- escape = # # applies for all non - display characters and literal "="
- space or tab at end of line must be encoded
- \ r \ n newlines can be preserved , but bare \ r and \ n must be escaped
- lines must not exceed 76 characters , use soft breaks = \ r \ n
TODO : Some files from word appear to write line extensions with bare equals :
` ` `
< table class = 3 DMsoTableGrid border = 3 D1 cellspacing = 3 D0 cellpadding = 3 D0 width =
= "70%"
` ` `
* /
function write _quoted _printable ( text /*:string*/ ) /*:string*/ {
var encoded = text . replace ( /[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF=]/g , function ( c ) {
var w = c . charCodeAt ( 0 ) . toString ( 16 ) . toUpperCase ( ) ;
return "=" + ( w . length == 1 ? "0" + w : w ) ;
} ) ;
encoded = encoded . replace ( / $/mg , "=20" ) . replace ( /\t$/mg , "=09" ) ;
if ( encoded . charAt ( 0 ) == "\n" ) encoded = "=0D" + encoded . slice ( 1 ) ;
encoded = encoded . replace ( /\r(?!\n)/mg , "=0D" ) . replace ( /\n\n/mg , "\n=0A" ) . replace ( /([^\r\n])\n/mg , "$1=0A" ) ;
var o /*:Array<string>*/ = [ ] , split = encoded . split ( "\r\n" ) ;
for ( var si = 0 ; si < split . length ; ++ si ) {
var str = split [ si ] ;
if ( str . length == 0 ) { o . push ( "" ) ; continue ; }
for ( var i = 0 ; i < str . length ; ) {
var end = 76 ;
var tmp = str . slice ( i , i + end ) ;
if ( tmp . charAt ( end - 1 ) == "=" ) end -- ;
else if ( tmp . charAt ( end - 2 ) == "=" ) end -= 2 ;
else if ( tmp . charAt ( end - 3 ) == "=" ) end -= 3 ;
tmp = str . slice ( i , i + end ) ;
i += end ;
if ( i < str . length ) tmp += "=" ;
o . push ( tmp ) ;
}
}
return o . join ( "\r\n" ) ;
}
function parse _quoted _printable ( data /*:Array<string>*/ ) /*:RawBytes*/ {
var o = [ ] ;
/* unify long lines */
for ( var di = 0 ; di < data . length ; ++ di ) {
var line = data [ di ] ;
while ( di <= data . length && line . charAt ( line . length - 1 ) == "=" ) line = line . slice ( 0 , line . length - 1 ) + data [ ++ di ] ;
o . push ( line ) ;
}
/* decode */
for ( var oi = 0 ; oi < o . length ; ++ oi ) o [ oi ] = o [ oi ] . replace ( /[=][0-9A-Fa-f]{2}/g , function ( $$ ) { return String . fromCharCode ( parseInt ( $$ . slice ( 1 ) , 16 ) ) ; } ) ;
return s2a ( o . join ( "\r\n" ) ) ;
}
function parse _mime ( cfb /*:CFBContainer*/ , data /*:Array<string>*/ , root /*:string*/ ) /*:void*/ {
var fname = "" , cte = "" , ctype = "" , fdata ;
var di = 0 ;
for ( ; di < 10 ; ++ di ) {
var line = data [ di ] ;
if ( ! line || line . match ( /^\s*$/ ) ) break ;
var m = line . match ( /^(.*?):\s*([^\s].*)$/ ) ;
if ( m ) switch ( m [ 1 ] . toLowerCase ( ) ) {
case "content-location" : fname = m [ 2 ] . trim ( ) ; break ;
case "content-type" : ctype = m [ 2 ] . trim ( ) ; break ;
case "content-transfer-encoding" : cte = m [ 2 ] . trim ( ) ; break ;
}
}
++ di ;
switch ( cte . toLowerCase ( ) ) {
case 'base64' : fdata = s2a ( Base64 . decode ( data . slice ( di ) . join ( "" ) ) ) ; break ;
case 'quoted-printable' : fdata = parse _quoted _printable ( data . slice ( di ) ) ; break ;
default : throw new Error ( "Unsupported Content-Transfer-Encoding " + cte ) ;
}
var file = cfb _add ( cfb , fname . slice ( root . length ) , fdata , { unsafe : true } ) ;
if ( ctype ) file . ctype = ctype ;
}
function parse _mad ( file /*:RawBytes*/ , options /*:CFBReadOpts*/ ) /*:CFBContainer*/ {
if ( a2s ( file . slice ( 0 , 13 ) ) . toLowerCase ( ) != "mime-version:" ) throw new Error ( "Unsupported MAD header" ) ;
var root = ( options && options . root || "" ) ;
// $FlowIgnore
var data = ( has _buf && Buffer . isBuffer ( file ) ? file . toString ( "binary" ) : a2s ( file ) ) . split ( "\r\n" ) ;
var di = 0 , row = "" ;
/* if root is not specified, scan for the common prefix */
for ( di = 0 ; di < data . length ; ++ di ) {
row = data [ di ] ;
if ( ! /^Content-Location:/i . test ( row ) ) continue ;
row = row . slice ( row . indexOf ( "file" ) ) ;
if ( ! root ) root = row . slice ( 0 , row . lastIndexOf ( "/" ) + 1 ) ;
if ( row . slice ( 0 , root . length ) == root ) continue ;
while ( root . length > 0 ) {
root = root . slice ( 0 , root . length - 1 ) ;
root = root . slice ( 0 , root . lastIndexOf ( "/" ) + 1 ) ;
if ( row . slice ( 0 , root . length ) == root ) break ;
}
}
var mboundary = ( data [ 1 ] || "" ) . match ( /boundary="(.*?)"/ ) ;
if ( ! mboundary ) throw new Error ( "MAD cannot find boundary" ) ;
var boundary = "--" + ( mboundary [ 1 ] || "" ) ;
var FileIndex /*:CFBFileIndex*/ = [ ] , FullPaths /*:Array<string>*/ = [ ] ;
var o = {
FileIndex : FileIndex ,
FullPaths : FullPaths
} ;
init _cfb ( o ) ;
var start _di , fcnt = 0 ;
for ( di = 0 ; di < data . length ; ++ di ) {
var line = data [ di ] ;
if ( line !== boundary && line !== boundary + "--" ) continue ;
if ( fcnt ++ ) parse _mime ( o , data . slice ( start _di , di ) , root ) ;
start _di = di ;
}
return o ;
}
function write _mad ( cfb /*:CFBContainer*/ , options /*:CFBWriteOpts*/ ) /*:string*/ {
var opts = options || { } ;
var boundary = opts . boundary || "SheetJS" ;
boundary = '------=' + boundary ;
var out = [
'MIME-Version: 1.0' ,
'Content-Type: multipart/related; boundary="' + boundary . slice ( 2 ) + '"' ,
'' ,
'' ,
''
] ;
var root = cfb . FullPaths [ 0 ] , fp = root , fi = cfb . FileIndex [ 0 ] ;
for ( var i = 1 ; i < cfb . FullPaths . length ; ++ i ) {
fp = cfb . FullPaths [ i ] . slice ( root . length ) ;
fi = cfb . FileIndex [ i ] ;
if ( ! fi . size || ! fi . content || fp == "\u0001Sh33tJ5" ) continue ;
/* Normalize filename */
fp = fp . replace ( /[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF]/g , function ( c ) {
return "_x" + c . charCodeAt ( 0 ) . toString ( 16 ) + "_" ;
} ) . replace ( /[\u0080-\uFFFF]/g , function ( u ) {
return "_u" + u . charCodeAt ( 0 ) . toString ( 16 ) + "_" ;
} ) ;
/* Extract content as binary string */
var ca = fi . content ;
// $FlowIgnore
var cstr = has _buf && Buffer . isBuffer ( ca ) ? ca . toString ( "binary" ) : a2s ( ca ) ;
/* 4/5 of first 1024 chars ascii -> quoted printable, else base64 */
var dispcnt = 0 , L = Math . min ( 1024 , cstr . length ) , cc = 0 ;
for ( var csl = 0 ; csl <= L ; ++ csl ) if ( ( cc = cstr . charCodeAt ( csl ) ) >= 0x20 && cc < 0x80 ) ++ dispcnt ;
var qp = dispcnt >= L * 4 / 5 ;
out . push ( boundary ) ;
out . push ( 'Content-Location: ' + ( opts . root || 'file:///C:/SheetJS/' ) + fp ) ;
out . push ( 'Content-Transfer-Encoding: ' + ( qp ? 'quoted-printable' : 'base64' ) ) ;
out . push ( 'Content-Type: ' + get _content _type ( fi , fp ) ) ;
out . push ( '' ) ;
out . push ( qp ? write _quoted _printable ( cstr ) : write _base64 _76 ( cstr ) ) ;
}
out . push ( boundary + '--\r\n' ) ;
return out . join ( "\r\n" ) ;
}
function cfb _new ( opts /*:?any*/ ) /*:CFBContainer*/ {
var o /*:CFBContainer*/ = ( { } /*:any*/ ) ;
init _cfb ( o , opts ) ;