diff --git a/archive.js b/archive.js index 5053e94..d2d3fad 100644 --- a/archive.js +++ b/archive.js @@ -100,6 +100,23 @@ bitjs.archive.UnarchiveInfoEvent = function(msg) { }; bitjs.inherits(bitjs.archive.UnarchiveInfoEvent, bitjs.archive.UnarchiveEvent); +/** + * An unrecoverable error has occured. + * + * @param {string} msg The error message. + */ +bitjs.archive.UnarchiveErrorEvent = function(msg) { + bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.ERROR); + + /** + * The information message. + * + * @type {string} + */ + this.msg = msg; +}; +bitjs.inherits(bitjs.archive.UnarchiveErrorEvent, bitjs.archive.UnarchiveEvent); + /** * Start event. * @@ -120,6 +137,27 @@ bitjs.archive.UnarchiveFinishEvent = function() { }; bitjs.inherits(bitjs.archive.UnarchiveFinishEvent, bitjs.archive.UnarchiveEvent); +/** + * Progress event. + */ +bitjs.archive.UnarchiveProgressEvent = function( + currentFilename, + currentFileNumber, + currentBytesUnarchivedInFile, + currentBytesUnarchived, + totalUncompressedBytesInArchive, + totalFilesInArchive) { + bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.PROGRESS); + + this.currentFilename = currentFilename; + this.currentFileNumber = currentFileNumber; + this.currentBytesUnarchivedInFile = currentBytesUnarchivedInFile; + this.totalFilesInArchive = totalFilesInArchive; + this.currentBytesUnarchived = currentBytesUnarchived; + this.totalUncompressedBytesInArchive = totalUncompressedBytesInArchive; +}; +bitjs.inherits(bitjs.archive.UnarchiveProgressEvent, bitjs.archive.UnarchiveEvent); + /** * All extracted files returned by an Unarchiver will implement * the following interface: @@ -131,6 +169,20 @@ bitjs.inherits(bitjs.archive.UnarchiveFinishEvent, bitjs.archive.UnarchiveEvent) * */ +/** + * Extract event. + */ +bitjs.archive.UnarchiveExtractEvent = function(unarchivedFile) { + bitjs.base(this, bitjs.archive.UnarchiveEvent.Type.EXTRACT); + + /** + * @type {UnarchivedFile} + */ + this.unarchivedFile = unarchivedFile; +}; +bitjs.inherits(bitjs.archive.UnarchiveExtractEvent, bitjs.archive.UnarchiveEvent); + + /** * Base class for all Unarchivers. * @@ -232,12 +284,14 @@ bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { }; this.worker_.onmessage = function(e) { - if (e instanceof bitjs.archive.UnarchiveEvent) { - me.handleWorkerEvent_(e.data); - } else if (typeof e.data == 'string') { + if (typeof e.data == 'string') { // Just log any strings the workers pump our way. console.log(e.data); - } + } else { + // Assume that it is an UnarchiveEvent. Some browsers preserve the 'type' + // so that instanceof UnarchiveEvent returns true, but others do not. + me.handleWorkerEvent_(e.data); + } }; this.worker_.postMessage({file: this.ab}); diff --git a/drive.html b/drive.html index 851e783..a60d400 100644 --- a/drive.html +++ b/drive.html @@ -60,7 +60,13 @@ fr.onload = function() { var ua = new bitjs.archive.Unzipper(fr.result); ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.INFO, function(e) { - console.log("handler: " + e.msg); + console.log("info: " + e.msg); + }) + ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.PROGRESS, function(e) { + console.log("progress: " + e.msg); + }) + ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.EXTRACT, function(e) { + console.log("extract: " + e.unarchiveFile.filename); }) ua.start(); }; diff --git a/unrar.js b/unrar.js index 0f82015..eec8c8f 100644 --- a/unrar.js +++ b/unrar.js @@ -13,10 +13,30 @@ importScripts('binary.js'); importScripts('archive.js'); -// Helper function. +// Progress variables. +var currentFilename = ""; +var currentFileNumber = 0; +var currentBytesUnarchivedInFile = 0; +var currentBytesUnarchived = 0; +var totalUncompressedBytesInArchive = 0; +var totalFilesInArchive = 0; + +// Helper functions. var info = function(str) { postMessage(new bitjs.archive.UnarchiveInfoEvent(str)); }; +var err = function(str) { + postMessage(new bitjs.archive.UnarchiveErrorEvent(str)); +}; +var postProgress = function() { + postMessage(new bitjs.archive.UnarchiveProgressEvent( + currentFilename, + currentBytesUnarchivedInFile, + currentBytesUnarchived, + totalUncompressedBytesInArchive, + totalFilesInArchive)); +}; + // Volume Types var MARK_HEAD = 0x72, @@ -31,31 +51,25 @@ var MARK_HEAD = 0x72, ENDARC_HEAD = 0x7b; // bstream is a bit stream -var RarVolumeHeader = function(bstream, bDebug) { - - this.debug = bDebug; +var RarVolumeHeader = function(bstream) { var headPos = bstream.bytePtr; // byte 1,2 info("Rar Volume Header @"+bstream.bytePtr); this.crc = bstream.readBits(16); - //console.log(this.crc); - if (bDebug) - info(" crc=" + this.crc); + info(" crc=" + this.crc); // byte 3 this.headType = bstream.readBits(8); - if (bDebug) - info(" headType=" + this.headType); + info(" headType=" + this.headType); // Get flags // bytes 4,5 this.flags = {}; this.flags.value = bstream.peekBits(16); - if (bDebug) - info(" flags=" + twoByteValueToHexString(this.flags.value)); + info(" flags=" + twoByteValueToHexString(this.flags.value)); switch (this.headType) { case MAIN_HEAD: this.flags.MHD_VOLUME = !!bstream.readBits(1); @@ -85,8 +99,7 @@ var RarVolumeHeader = function(bstream, bDebug) { this.flags.LHD_EXTTIME = !!bstream.readBits(1); // 0x1000 this.flags.LHD_EXTFLAGS = !!bstream.readBits(1); // 0x2000 bstream.readBits(2); // unused - if (bDebug) - info(" LHD_SPLIT_BEFORE = " + this.flags.LHD_SPLIT_BEFORE); + info(" LHD_SPLIT_BEFORE = " + this.flags.LHD_SPLIT_BEFORE); break; default: bstream.readBits(16); @@ -94,16 +107,15 @@ var RarVolumeHeader = function(bstream, bDebug) { // byte 6,7 this.headSize = bstream.readBits(16); - if (bDebug) - info(" headSize=" + this.headSize); + info(" headSize=" + this.headSize); switch (this.headType) { case MAIN_HEAD: this.highPosAv = bstream.readBits(16); this.posAv = bstream.readBits(32); - if (this.flags.MHD_ENCRYPTVER) + if (this.flags.MHD_ENCRYPTVER) { this.encryptVer = bstream.readBits(8); - if (this.debug) - info("Found MAIN_HEAD with highPosAv=" + this.highPosAv + ", posAv=" + this.posAv); + } + info("Found MAIN_HEAD with highPosAv=" + this.highPosAv + ", posAv=" + this.posAv); break; case FILE_HEAD: this.packSize = bstream.readBits(32); @@ -172,13 +184,11 @@ var RarVolumeHeader = function(bstream, bDebug) { while(headPos + this.headSize > bstream.bytePtr) bstream.readBits(1); - if (this.debug) - info("Found FILE_HEAD with packSize=" + this.packSize + ", unpackedSize= " + this.unpackedSize + ", hostOS=" + this.hostOS + ", unpVer=" + this.unpVer + ", method=" + this.method + ", filename=" + this.filename); + info("Found FILE_HEAD with packSize=" + this.packSize + ", unpackedSize= " + this.unpackedSize + ", hostOS=" + this.hostOS + ", unpVer=" + this.unpVer + ", method=" + this.method + ", filename=" + this.filename); break; default: - if (this.debug) - info("Found a header of type 0x" + byteValueToHexString(this.headType)); + info("Found a header of type 0x" + byteValueToHexString(this.headType)); // skip the rest of the header bytes (for now) bstream.readBytes( this.headSize - 7 ); break; @@ -751,9 +761,9 @@ function unpack(v) { } // bstream is a bit stream -var RarLocalFile = function(bstream, bDebug) { +var RarLocalFile = function(bstream) { - this.header = new RarVolumeHeader(bstream, bDebug); + this.header = new RarVolumeHeader(bstream); this.filename = this.header.filename; if (this.header.headType != FILE_HEAD && this.header.headType != ENDARC_HEAD) { @@ -792,19 +802,25 @@ RarLocalFile.prototype.unrar = function() { } } -var unrar = function(arrayBuffer, bDebug) { +var unrar = function(arrayBuffer) { + currentFilename = ""; + currentFileNumber = 0; + currentBytesUnarchivedInFile = 0; + currentBytesUnarchived = 0; + totalUncompressedBytesInArchive = 0; + totalFilesInArchive = 0; + postMessage(new bitjs.archive.UnarchiveStartEvent()); var bstream = new bitjs.io.BitStream(arrayBuffer, false /* rtl */); - var header = new RarVolumeHeader(bstream, bDebug); + var header = new RarVolumeHeader(bstream); if (header.crc == 0x6152 && header.headType == 0x72 && header.flags.value == 0x1A21 && header.headSize == 7) { - if (bDebug) - info("Found RAR signature"); + info("Found RAR signature"); - var mhead = new RarVolumeHeader(bstream, bDebug); + var mhead = new RarVolumeHeader(bstream); if (mhead.headType != MAIN_HEAD) { progress.isValid = false; info("Error! RAR did not include a MAIN_HEAD header"); @@ -814,9 +830,8 @@ var unrar = function(arrayBuffer, bDebug) { localFile = null; do { try { - localFile = new RarLocalFile(bstream, bDebug); - if (bDebug) - info("RAR localFile isValid=" + localFile.isValid + ", volume packSize=" + localFile.header.packSize); + localFile = new RarLocalFile(bstream); + info("RAR localFile isValid=" + localFile.isValid + ", volume packSize=" + localFile.header.packSize); if (localFile && localFile.isValid && localFile.header.packSize > 0) { progress.totalSizeInBytes += localFile.header.unpackedSize; progress.isValid = true; @@ -879,8 +894,9 @@ var unrar = function(arrayBuffer, bDebug) { } } else { - untar(arrayBuffer, bDebug); + err("Invalid RAR file"); } + postMessage(new bitjs.archive.UnarchiveFinishEvent()); }; // event.data.file has the ArrayBuffer. diff --git a/untar.js b/untar.js index 550a1bd..0e338fa 100644 --- a/untar.js +++ b/untar.js @@ -12,10 +12,29 @@ importScripts('binary.js'); importScripts('archive.js'); -// Helper function. +// Progress variables. +var currentFilename = ""; +var currentFileNumber = 0; +var currentBytesUnarchivedInFile = 0; +var currentBytesUnarchived = 0; +var totalUncompressedBytesInArchive = 0; +var totalFilesInArchive = 0; + +// Helper functions. var info = function(str) { postMessage(new bitjs.archive.UnarchiveInfoEvent(str)); }; +var err = function(str) { + postMessage(new bitjs.archive.UnarchiveErrorEvent(str)); +}; +var postProgress = function() { + postMessage(new bitjs.archive.UnarchiveProgressEvent( + currentFilename, + currentBytesUnarchivedInFile, + currentBytesUnarchived, + totalUncompressedBytesInArchive, + totalFilesInArchive)); +}; // Removes all characters from the first zero-byte in the string onwards. var readCleanString = function(bstr, numBytes) { @@ -25,8 +44,7 @@ var readCleanString = function(bstr, numBytes) { }; // takes a ByteStream and parses out the local file information -var TarLocalFile = function(bstream, bDebug) { - this.debug = bDebug || false; +var TarLocalFile = function(bstream) { this.isValid = false; // Read in the header block @@ -61,11 +79,9 @@ var TarLocalFile = function(bstream, bDebug) { this.filename = this.name; this.fileData = null; - if (this.debug) { - info("Untarring file '" + this.filename + "'"); - info(" size = " + this.size); - info(" typeflag = " + this.typeflag); - } + info("Untarring file '" + this.filename + "'"); + info(" size = " + this.size); + info(" typeflag = " + this.typeflag); // A regular file. if (this.typeflag == 0) { @@ -85,23 +101,28 @@ var TarLocalFile = function(bstream, bDebug) { bstream.readBytes(remaining); } } else if (this.typeflag == 5) { - if (this.debug) { - info(" This is a directory.") - } + info(" This is a directory.") } }; // Takes an ArrayBuffer of a tar file in // returns null on error // returns an array of DecompressedFile objects on success -var untar = function(arrayBuffer, bDebug) { +var untar = function(arrayBuffer) { + currentFilename = ""; + currentFileNumber = 0; + currentBytesUnarchivedInFile = 0; + currentBytesUnarchived = 0; + totalUncompressedBytesInArchive = 0; + totalFilesInArchive = 0; + postMessage(new bitjs.archive.UnarchiveStartEvent()); var bstream = new bitjs.io.ByteStream(arrayBuffer); var localFiles = []; // While we don't encounter an empty block, keep making TarLocalFiles. while (bstream.peekNumber(4) != 0) { - var oneLocalFile = new TarLocalFile(bstream, bDebug); + var oneLocalFile = new TarLocalFile(bstream); if (oneLocalFile && oneLocalFile.isValid) { localFiles.push(oneLocalFile); progress.totalNumFilesInZip++; @@ -158,11 +179,13 @@ var untar = function(arrayBuffer, bDebug) { progress.isDone = true; postMessage(progress); + postMessage(new bitjs.archive.UnarchiveFinishEvent()); + return progress; }; // event.data.file has the ArrayBuffer. onmessage = function(event) { var ab = event.data.file; - untar(ab, true); + untar(ab); }; diff --git a/unzip.js b/unzip.js index 8f02ba0..f3e3e80 100644 --- a/unzip.js +++ b/unzip.js @@ -14,10 +14,30 @@ importScripts('binary.js'); importScripts('archive.js'); -// Helper function. +// Progress variables. +var currentFilename = ""; +var currentFileNumber = 0; +var currentBytesUnarchivedInFile = 0; +var currentBytesUnarchived = 0; +var totalUncompressedBytesInArchive = 0; +var totalFilesInArchive = 0; + +// Helper functions. var info = function(str) { postMessage(new bitjs.archive.UnarchiveInfoEvent(str)); }; +var err = function(str) { + postMessage(new bitjs.archive.UnarchiveErrorEvent(str)); +}; +var postProgress = function() { + postMessage(new bitjs.archive.UnarchiveProgressEvent( + currentFilename, + currentFileNumber, + currentBytesUnarchivedInFile, + currentBytesUnarchived, + totalUncompressedBytesInArchive, + totalFilesInArchive)); +}; var zLocalFileHeaderSignature = 0x04034b50; var zArchiveExtraDataSignature = 0x08064b50; @@ -27,14 +47,12 @@ var zEndOfCentralDirSignature = 0x06064b50; var zEndOfCentralDirLocatorSignature = 0x07064b50; // takes a ByteStream and parses out the local file information -var ZipLocalFile = function(bstream, bDebug) { +var ZipLocalFile = function(bstream) { if (typeof bstream != typeof {} || !bstream.readNumber || typeof bstream.readNumber != typeof function(){}) { return null; } bstream.readNumber(4); // swallow signature - this.debug = bDebug||false; - this.isValid = false; this.version = bstream.readNumber(2); this.generalPurpose = bstream.readNumber(2); this.compressionMethod = bstream.readNumber(2); @@ -51,27 +69,23 @@ var ZipLocalFile = function(bstream, bDebug) { this.filename = bstream.readString(this.fileNameLength); } - if (this.debug) { - info(new bitjs.archive.UnarchiveInfoEvent("Zip Local File Header:")); - info(" version=" + this.version); - info(" general purpose=" + this.generalPurpose); - info(" compression method=" + this.compressionMethod); - info(" last mod file time=" + this.lastModFileTime); - info(" last mod file date=" + this.lastModFileDate); - info(" crc32=" + this.crc32); - info(" compressed size=" + this.compressedSize); - info(" uncompressed size=" + this.uncompressedSize); - info(" file name length=" + this.fileNameLength); - info(" extra field length=" + this.extraFieldLength); - info(" filename = '" + this.filename + "'"); - } + info("Zip Local File Header:"); + info(" version=" + this.version); + info(" general purpose=" + this.generalPurpose); + info(" compression method=" + this.compressionMethod); + info(" last mod file time=" + this.lastModFileTime); + info(" last mod file date=" + this.lastModFileDate); + info(" crc32=" + this.crc32); + info(" compressed size=" + this.compressedSize); + info(" uncompressed size=" + this.uncompressedSize); + info(" file name length=" + this.fileNameLength); + info(" extra field length=" + this.extraFieldLength); + info(" filename = '" + this.filename + "'"); this.extraField = null; if (this.extraFieldLength > 0) { this.extraField = bstream.readString(this.extraFieldLength); - if (this.debug) { - info(" extra field=" + this.extraField); - } + info(" extra field=" + this.extraField); } // read in the compressed data @@ -94,57 +108,53 @@ var ZipLocalFile = function(bstream, bDebug) { // determine what kind of compressed data we have and decompress ZipLocalFile.prototype.unzip = function() { - - // Zip Version 1.0, no compression (store only) - if (this.compressionMethod == 0 ) { - if (this.debug) - info("ZIP v"+this.version+", store only: " + this.filename + " (" + this.compressedSize + " bytes)"); - progress.currentFileBytesUnzipped = this.compressedSize; - progress.totalBytesUnzipped += this.compressedSize; - this.isValid = true; - } - // version == 20, compression method == 8 (DEFLATE) - else if (this.compressionMethod == 8) { - if (this.debug) - info("ZIP v2.0, DEFLATE: " + this.filename + " (" + this.compressedSize + " bytes)"); - this.fileData = inflate(this.fileData, this.uncompressedSize); - this.isValid = true; - } - else { - info("UNSUPPORTED VERSION/FORMAT: ZIP v" + this.version + ", compression method=" + this.compressionMethod + ": " + this.filename + " (" + this.compressedSize + " bytes)"); - this.isValid = false; - this.fileData = null; - } - - if (this.isValid) { - this.imageString = createURLFromArray(this.fileData); - this.fileData = null; - } + // Zip Version 1.0, no compression (store only) + if (this.compressionMethod == 0 ) { + info("ZIP v"+this.version+", store only: " + this.filename + " (" + this.compressedSize + " bytes)"); + currentBytesUnarchivedInFile = this.compressedSize; + currentBytesUnarchived += this.compressedSize; + } + // version == 20, compression method == 8 (DEFLATE) + else if (this.compressionMethod == 8) { + info("ZIP v2.0, DEFLATE: " + this.filename + " (" + this.compressedSize + " bytes)"); + this.fileData = inflate(this.fileData, this.uncompressedSize); + } + else { + err("UNSUPPORTED VERSION/FORMAT: ZIP v" + this.version + ", compression method=" + this.compressionMethod + ": " + this.filename + " (" + this.compressedSize + " bytes)"); + this.fileData = null; + } }; // Takes an ArrayBuffer of a zip file in // returns null on error // returns an array of DecompressedFile objects on success -var unzip = function(arrayBuffer, bDebug) { - postMessage(new bitjs.archive.UnarchiveStartEvent()); - - var bstream = new bitjs.io.ByteStream(arrayBuffer); - // detect local file header signature or return null - if (bstream.peekNumber(4) == zLocalFileHeaderSignature) { +var unzip = function(arrayBuffer) { + postMessage(new bitjs.archive.UnarchiveStartEvent()); + + currentFilename = ""; + currentFileNumber = 0; + currentBytesUnarchivedInFile = 0; + currentBytesUnarchived = 0; + totalUncompressedBytesInArchive = 0; + totalFilesInArchive = 0; + currentBytesUnarchived = 0; + + var bstream = new bitjs.io.ByteStream(arrayBuffer); + // detect local file header signature or return null + if (bstream.peekNumber(4) == zLocalFileHeaderSignature) { var localFiles = []; // loop until we don't see any more local files while (bstream.peekNumber(4) == zLocalFileHeaderSignature) { - var oneLocalFile = new ZipLocalFile(bstream, bDebug); + var oneLocalFile = new ZipLocalFile(bstream); // this should strip out directories/folders if (oneLocalFile && oneLocalFile.uncompressedSize > 0 && oneLocalFile.fileData) { localFiles.push(oneLocalFile); - progress.totalNumFilesInZip++; - progress.totalSizeInBytes += oneLocalFile.uncompressedSize; + totalUncompressedBytesInArchive += oneLocalFile.uncompressedSize; } } - progress.totalNumFilesInZip = localFiles.length; + totalFilesInArchive = localFiles.length; // got all local files, now sort them localFiles.sort(function(a,b) { @@ -169,9 +179,8 @@ var unzip = function(arrayBuffer, bDebug) { // archive extra data record if (bstream.peekNumber(4) == zArchiveExtraDataSignature) { - if (gDebug) { - info(" Found an Archive Extra Data Signature"); - } + info(" Found an Archive Extra Data Signature"); + // skipping this record for now bstream.readNumber(4); var archiveExtraFieldLength = bstream.readNumber(4); @@ -181,9 +190,8 @@ var unzip = function(arrayBuffer, bDebug) { // central directory structure // TODO: handle the rest of the structures (Zip64 stuff) if (bstream.peekNumber(4) == zCentralFileHeaderSignature) { - if (gDebug) { - info(" Found a Central File Header"); - } + info(" Found a Central File Header"); + // read all file headers while (bstream.peekNumber(4) == zCentralFileHeaderSignature) { bstream.readNumber(4); // signature @@ -212,19 +220,16 @@ var unzip = function(arrayBuffer, bDebug) { // digital signature if (bstream.peekNumber(4) == zDigitalSignatureSignature) { - if (gDebug) { - info(" Found a Digital Signature"); - } + info(" Found a Digital Signature"); + bstream.readNumber(4); var sizeOfSignature = bstream.readNumber(2); bstream.readString(sizeOfSignature); // digital signature data } - progress.isValid = true; - // report # files and total length if (localFiles.length > 0) { - postMessage(progress); + postProgress(); } // now do the unzipping of each file @@ -232,23 +237,21 @@ var unzip = function(arrayBuffer, bDebug) { var localfile = localFiles[i]; // update progress - progress.currentFilename = localfile.filename; - progress.currentFileBytesUnzipped = 0; + currentFilename = localfile.filename; + currentFileNumber = i; + currentBytesUnarchivedInFile = 0; // actually do the unzipping localfile.unzip(); - if (progress.isValid) { - progress.localFiles.push(localfile); - postMessage(progress); - // Wipe out old localFiles array now that has been copied out of the thread. - progress.localFiles = []; + if (localfile.fileData != null) { + postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile)); + postProgress(); } } - progress.isDone = true; - postMessage(progress); - } - return progress; + postProgress(); + postMessage(new bitjs.archive.UnarchiveFinishEvent()); + } } // returns a table of Huffman codes @@ -257,7 +260,7 @@ var unzip = function(arrayBuffer, bDebug) { function getHuffmanCodes(bitLengths) { // ensure bitLengths is an array containing at least one element if (typeof bitLengths != typeof [] || bitLengths.length < 1) { - throw "Error! getHuffmanCodes() called with an invalid array"; + err("Error! getHuffmanCodes() called with an invalid array"); return null; } @@ -271,7 +274,7 @@ function getHuffmanCodes(bitLengths) { var length = bitLengths[i]; // test to ensure each bit length is a positive, non-zero number if (typeof length != typeof 1 || length < 0) { - throw ("bitLengths contained an invalid number in getHuffmanCodes(): " + length + " of type " + (typeof length)); + err("bitLengths contained an invalid number in getHuffmanCodes(): " + length + " of type " + (typeof length)); return null; } // increment the appropriate bitlength count @@ -372,8 +375,8 @@ function decodeSymbol(bstream, hcTable) { break; } if (len > hcTable.maxLength) { - throw ("Bit stream out of sync, didn't find a Huffman Code, length was " + len + - " and table only max code length of " + hcTable.maxLength); + err("Bit stream out of sync, didn't find a Huffman Code, length was " + len + + " and table only max code length of " + hcTable.maxLength); break; } } @@ -488,13 +491,13 @@ function inflateBlockData(bstream, hcLiteralTable, hcDistanceTable, buffer) { // // loop for each character var ch = buffer.ptr - distance; - blockSize += length; - if(length > distance){ + blockSize += length; + if(length > distance) { var data = buffer.data; while (length--) { buffer.insertByte(data[ch++]); } - }else{ + } else { buffer.insertBytes(buffer.data.subarray(ch, ch + length)) } @@ -606,14 +609,14 @@ function inflate(compressedData, numDecompressedBytes) { } // error else { - throw "Error! Encountered deflate block of type 3"; + err("Error! Encountered deflate block of type 3"); return null; } // update progress - progress.currentFileBytesUnzipped += blockSize; - progress.totalBytesUnzipped += blockSize; - postMessage(progress); + currentBytesUnarchivedInFile += blockSize; + currentBytesUnarchived += blockSize; + postProgress(); } while (bFinal != 1); // we are done reading blocks if the bFinal bit was set for this block