From b2d58e9f49d3d5afdae2943be1fcb18d63d0ce64 Mon Sep 17 00:00:00 2001 From: codedread Date: Sun, 18 Sep 2011 15:03:21 -0500 Subject: [PATCH] Transition unrar and untar over to using UnarchiveEvents. Update Unarchiver to accept an optional path to the location of the BitJS files --- archive.js | 47 +++++++++++++++++++++++++++++++++++++---------- unrar.js | 46 +++++++++++++++++++++++----------------------- untar.js | 31 +++++++++++-------------------- 3 files changed, 71 insertions(+), 53 deletions(-) diff --git a/archive.js b/archive.js index d2d3fad..ae6f1e5 100644 --- a/archive.js +++ b/archive.js @@ -164,7 +164,7 @@ bitjs.inherits(bitjs.archive.UnarchiveProgressEvent, bitjs.archive.UnarchiveEven * * interface UnarchivedFile { * string filename - * TypedArray filedata + * TypedArray fileData * } * */ @@ -187,9 +187,10 @@ bitjs.inherits(bitjs.archive.UnarchiveExtractEvent, bitjs.archive.UnarchiveEvent * Base class for all Unarchivers. * * @param {ArrayBuffer} arrayBuffer The Array Buffer. + * @param {string} opt_pathToBitJS Optional string for where the BitJS files are located. * @constructor */ -bitjs.archive.Unarchiver = function(arrayBuffer) { +bitjs.archive.Unarchiver = function(arrayBuffer, opt_pathToBitJS) { /** * The ArrayBuffer object. * @type {ArrayBuffer} @@ -197,6 +198,13 @@ bitjs.archive.Unarchiver = function(arrayBuffer) { */ this.ab = arrayBuffer; + /** + * The path to the BitJS files. + * @type {string} + * @private + */ + this.pathToBitJS_ = opt_pathToBitJS || ''; + /** * A map from event type to an array of listeners. * @type {Map.} @@ -259,11 +267,9 @@ bitjs.archive.Unarchiver.prototype.removeEventListener = function(type, listener * @private */ bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { - if (e instanceof bitjs.archive.UnarchiveEvent) { - var listeners = this.listeners_[e.type]; - if (listeners instanceof Array) { - listeners.forEach(function (listener) { listener(e) }); - } + if ((e instanceof bitjs.archive.UnarchiveEvent || e.type) && + this.listeners_[e.type] instanceof Array) { + this.listeners_[e.type].forEach(function (listener) { listener(e) }); } else { console.log(e); } @@ -274,7 +280,7 @@ bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { */ bitjs.archive.Unarchiver.prototype.start = function() { var me = this; - var scriptFileName = this.getScriptFileName(); + var scriptFileName = this.pathToBitJS_ + this.getScriptFileName(); if (scriptFileName) { this.worker_ = new Worker(scriptFileName); @@ -303,11 +309,32 @@ bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { * @extends {bitjs.archive.Unarchiver} * @constructor */ -bitjs.archive.Unzipper = function(arrayBuffer) { - bitjs.base(this, arrayBuffer); +bitjs.archive.Unzipper = function(arrayBuffer, opt_pathToBitJS) { + bitjs.base(this, arrayBuffer, opt_pathToBitJS); }; bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver); bitjs.archive.Unzipper.prototype.getScriptFileName = function() { return 'unzip.js' }; +/** + * Unrarrer + * @extends {bitjs.archive.Unarchiver} + * @constructor + */ +bitjs.archive.Unrarrer = function(arrayBuffer, opt_pathToBitJS) { + bitjs.base(this, arrayBuffer, opt_pathToBitJS); +}; +bitjs.inherits(bitjs.archive.Unrarrer, bitjs.archive.Unarchiver); +bitjs.archive.Unrarrer.prototype.getScriptFileName = function() { return 'unrar.js' }; + +/** + * Untarrer + * @extends {bitjs.archive.Unarchiver} + * @constructor + */ +bitjs.archive.Untarrer = function(arrayBuffer, opt_pathToBitJS) { + bitjs.base(this, arrayBuffer, opt_pathToBitJS); +}; +bitjs.inherits(bitjs.archive.Untarrer, bitjs.archive.Unarchiver); +bitjs.archive.Untarrer.prototype.getScriptFileName = function() { return 'untar.js' }; })(); \ No newline at end of file diff --git a/unrar.js b/unrar.js index eec8c8f..110d296 100644 --- a/unrar.js +++ b/unrar.js @@ -31,12 +31,22 @@ var err = function(str) { var postProgress = function() { postMessage(new bitjs.archive.UnarchiveProgressEvent( currentFilename, + currentFileNumber, currentBytesUnarchivedInFile, currentBytesUnarchived, totalUncompressedBytesInArchive, totalFilesInArchive)); }; +// shows a byte value as its hex representation +var nibble = "0123456789ABCDEF"; +var byteValueToHexString = function(num) { + return nibble[num>>4] + nibble[num&0xF]; +}; +var twoByteValueToHexString = function(num) { + return nibble[(num>>12)&0xF] + nibble[(num>>8)&0xF] + nibble[(num>>4)&0xF] + nibble[num&0xF]; +}; + // Volume Types var MARK_HEAD = 0x72, @@ -469,10 +479,10 @@ function Unpack20(bstream, Solid) { } function RarUpdateProgress() { - var change = rBuffer.ptr - progress.currentFileBytesUnzipped; - progress.currentFileBytesUnzipped = rBuffer.ptr; - progress.totalBytesUnzipped += change; - postMessage(progress); + var change = rBuffer.ptr - currentBytesUnarchivedInFile; + currentBytesUnarchivedInFile = rBuffer.ptr; + currentBytesUnarchived += change; + postProgress(); } @@ -768,7 +778,6 @@ var RarLocalFile = function(bstream) { if (this.header.headType != FILE_HEAD && this.header.headType != ENDARC_HEAD) { this.isValid = false; - //progress.isValid = false; info("Error! RAR Volume did not include a FILE_HEAD header "); } else { @@ -789,16 +798,12 @@ RarLocalFile.prototype.unrar = function() { info("Unstore "+this.filename); this.isValid = true; - progress.currentFileBytesUnzipped += this.fileData.length; - progress.totalBytesUnzipped += this.fileData.length; + currentBytesUnarchivedInFile += this.fileData.length; + currentBytesUnarchived += this.fileData.length; } else { this.isValid = true; this.fileData = unpack(this); } - } - if (this.isValid && this.fileData && this.fileData.buffer) { - this.imageString = createURLFromArray(this.fileData); - this.fileData = null; } } @@ -822,7 +827,6 @@ var unrar = function(arrayBuffer) { var mhead = new RarVolumeHeader(bstream); if (mhead.headType != MAIN_HEAD) { - progress.isValid = false; info("Error! RAR did not include a MAIN_HEAD header"); } else { @@ -833,19 +837,17 @@ var unrar = function(arrayBuffer) { 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; + totalUncompressedBytesInArchive += localFile.header.unpackedSize; localFiles.push(localFile); } else if (localFile.header.packSize == 0 && localFile.header.unpackedSize == 0) { localFile.isValid = true; - progress.isValid = true; } } catch(err) { break; } //info("bstream" + bstream.bytePtr+"/"+bstream.bytes.length); } while( localFile.isValid ); - progress.totalNumFilesInZip = localFiles.length; + totalFilesInArchive = localFiles.length; // now we have all information but things are unpacked // TODO: unpack @@ -876,21 +878,19 @@ var unrar = function(arrayBuffer) { var localfile = localFiles[i]; // update progress - progress.currentFilename = localfile.header.filename; - progress.currentFileBytesUnzipped = 0; + currentFilename = localfile.header.filename; + currentBytesUnarchivedInFile = 0; // actually do the unzipping localfile.unrar(); if (localfile.isValid) { - progress.localFiles.push(localfile); - postMessage(progress); - progress.localFiles = []; + postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile)); + postProgress(); } } - progress.isDone = true; - postMessage(progress); + postProgress(); } } else { diff --git a/untar.js b/untar.js index 0e338fa..4707de3 100644 --- a/untar.js +++ b/untar.js @@ -30,6 +30,7 @@ var err = function(str) { var postProgress = function() { postMessage(new bitjs.archive.UnarchiveProgressEvent( currentFilename, + currentFileNumber, currentBytesUnarchivedInFile, currentBytesUnarchived, totalUncompressedBytesInArchive, @@ -90,7 +91,6 @@ var TarLocalFile = function(bstream) { this.fileData = new Uint8Array(bstream.bytes.buffer, bstream.ptr, this.size); if (this.name.length > 0 && this.size > 0 && this.fileData && this.fileData.buffer) { this.isValid = true; - this.imageString = createURLFromArray(this.fileData); } bstream.readBytes(this.size); @@ -125,11 +125,10 @@ var untar = function(arrayBuffer) { var oneLocalFile = new TarLocalFile(bstream); if (oneLocalFile && oneLocalFile.isValid) { localFiles.push(oneLocalFile); - progress.totalNumFilesInZip++; - progress.totalSizeInBytes += oneLocalFile.size; + totalUncompressedBytesInArchive += oneLocalFile.size; } } - progress.totalNumFilesInZip = localFiles.length; + totalFilesInArchive = localFiles.length; // got all local files, now sort them localFiles.sort(function(a,b) { @@ -152,11 +151,9 @@ var untar = function(arrayBuffer) { return anum - bnum; }); - progress.isValid = true; - // report # files and total length if (localFiles.length > 0) { - postMessage(progress); + postProgress(); } // now do the shipping of each file @@ -165,23 +162,17 @@ var untar = function(arrayBuffer) { info("Sending file '" + localfile.filename + "' up"); // update progress - progress.currentFilename = localfile.filename; - progress.currentFileBytesUnzipped = localfile.size; - progress.totalBytesUnzipped += localfile.size; - progress.isValid = true; - progress.localFiles.push(localfile); - postMessage(progress); - - // Wipe out old localFiles array now that has been copied out of the thread. - progress.localFiles = []; + currentFilename = localfile.filename; + currentFileNumber = i; + currentBytesUnarchivedInFile = localfile.size; + currentBytesUnarchived += localfile.size; + postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile)); + postProgress(); } - progress.isDone = true; - postMessage(progress); + postProgress(); postMessage(new bitjs.archive.UnarchiveFinishEvent()); - - return progress; }; // event.data.file has the ArrayBuffer.