Skip to content

Instantly share code, notes, and snippets.

@yomotsu
Created March 1, 2017 13:22
Show Gist options
  • Save yomotsu/150243247f9a113fc2311a561613f65e to your computer and use it in GitHub Desktop.
Save yomotsu/150243247f9a113fc2311a561613f65e to your computer and use it in GitHub Desktop.
import pako from 'pako/lib/inflate.js';
console.log( pako );
// TODO
// Webワーカー
// https://github.com/yomotsu/xmas2016/blob/master/src/js/utils/zipFileManager.js
const LITTLE_ENDIAN = true;
const DataReader = class {
constructor ( buffer ) {
this.littleEndian = true;
this.dataView = new DataView( buffer );
this.position = 0;
}
_read ( type, length ) {
const start = this.position;
this.position += length;
return this.dataView[ type ]( start, LITTLE_ENDIAN );
}
readUint32 () {
return this._read( 'getUint32', 4 );
}
readUint16 () {
return this._read( 'getUint16', 2 );
}
readUint8 () {
return this._read( 'getUint8', 1 );
}
};
// https://nodeca.github.io/pako/#Inflate
// https://github.com/yomotsu/xmas2016/blob/master/src/js/utils/zipFileManager.js
// https://pxgrid.esa.io/posts/1372
const ZipLoader = class ZipLoader {
constructor ( url ) {
this.url = url;
// console.log( url );
}
load ( callback ) {
const xhr = new XMLHttpRequest();
xhr.open( 'GET', this.url, true );
xhr.responseType = 'arraybuffer';
xhr.onprogress = ( e ) => {
// console.log( e.loaded );
// this.$emit( 'loadProgress', e.loaded, e.total );
};
xhr.onload = ( e ) => {
ZipLoader.parse( xhr.response );
// const buffer = new Int8Array( xhr.response );
};
xhr.send();
}
}
// # Local file header
// http://www.onicos.com/staff/iz/formats/zip.html
//
// | Offset | Length | Contents |
// | ------ | -------- | ---------------------------------------- |
// | 0 | 4 bytes | Local file header signature (0x04034b50) |
// | 4 | 2 bytes | Version needed to extract |
// | 6 | 2 bytes | General purpose bit flag |
// | 8 | 2 bytes | Compression method |
// | 10 | 2 bytes | Last mod file time |
// | 12 | 2 bytes | Last mod file date |
// | 14 | 4 bytes | CRC-32 |
// | 18 | 4 bytes | Compressed size (n) |
// | 22 | 4 bytes | Uncompressed size |
// | 26 | 2 bytes | Filename length (f) |
// | 28 | 2 bytes | Extra field length (e) |
// | | (f)bytes | Filename |
// | | (e)bytes | Extra field |
// | | (n)bytes | Compressed data |
ZipLoader.parse = ( buffer ) => {
const reader = new DataReader( buffer );
// console.log( reader.position );
const entrySignature = reader.readUint32();
const version = reader.readUint16();
const bitFlag = reader.readUint16();
const compression = reader.readUint16();
const lastModTime = reader.readUint16();
const lastModDate = reader.readUint16();
const CRC32 = reader.readUint32();
const compressedSize = reader.readUint32();
const uncompressedSize = reader.readUint32();
const filenameLength = reader.readUint16();
const extraFieldLength = reader.readUint16();
const filename = [];
const extraField = [];
const compressedData = [];
for ( let i = 0; i < filenameLength; i ++ ) {
filename.push( String.fromCharCode( reader.readUint8() ) );
}
for ( let i = 0; i < extraFieldLength; i ++ ) {
extraField.push( reader.readUint8() );
}
for ( let i = 0; i < compressedSize; i ++ ) {
compressedData.push( reader.readUint8() );
}
const data = pako.inflate( new Uint8Array( compressedData ), { raw: true } );
data.forEach( ( x ) => {
console.log( String.fromCharCode( x ) );
} );
// const blob = new Blob( [ data ], { type: 'application/json' } );
// console.log( blob );
}
// export default
export default ZipLoader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment