1
0
Fork 0
mirror of https://github.com/codedread/bitjs synced 2025-10-04 10:09:16 +02:00

Transition unrar and untar over to using UnarchiveEvents. Update Unarchiver to accept an optional path to the location of the BitJS files

This commit is contained in:
codedread 2011-09-18 15:03:21 -05:00
parent 4925062e3d
commit b2d58e9f49
3 changed files with 71 additions and 53 deletions

View file

@ -164,7 +164,7 @@ bitjs.inherits(bitjs.archive.UnarchiveProgressEvent, bitjs.archive.UnarchiveEven
* *
* interface UnarchivedFile { * interface UnarchivedFile {
* string filename * string filename
* TypedArray filedata * TypedArray fileData
* } * }
* *
*/ */
@ -187,9 +187,10 @@ bitjs.inherits(bitjs.archive.UnarchiveExtractEvent, bitjs.archive.UnarchiveEvent
* Base class for all Unarchivers. * Base class for all Unarchivers.
* *
* @param {ArrayBuffer} arrayBuffer The Array Buffer. * @param {ArrayBuffer} arrayBuffer The Array Buffer.
* @param {string} opt_pathToBitJS Optional string for where the BitJS files are located.
* @constructor * @constructor
*/ */
bitjs.archive.Unarchiver = function(arrayBuffer) { bitjs.archive.Unarchiver = function(arrayBuffer, opt_pathToBitJS) {
/** /**
* The ArrayBuffer object. * The ArrayBuffer object.
* @type {ArrayBuffer} * @type {ArrayBuffer}
@ -197,6 +198,13 @@ bitjs.archive.Unarchiver = function(arrayBuffer) {
*/ */
this.ab = 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. * A map from event type to an array of listeners.
* @type {Map.<string, Array>} * @type {Map.<string, Array>}
@ -259,11 +267,9 @@ bitjs.archive.Unarchiver.prototype.removeEventListener = function(type, listener
* @private * @private
*/ */
bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) { bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) {
if (e instanceof bitjs.archive.UnarchiveEvent) { if ((e instanceof bitjs.archive.UnarchiveEvent || e.type) &&
var listeners = this.listeners_[e.type]; this.listeners_[e.type] instanceof Array) {
if (listeners instanceof Array) { this.listeners_[e.type].forEach(function (listener) { listener(e) });
listeners.forEach(function (listener) { listener(e) });
}
} else { } else {
console.log(e); console.log(e);
} }
@ -274,7 +280,7 @@ bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) {
*/ */
bitjs.archive.Unarchiver.prototype.start = function() { bitjs.archive.Unarchiver.prototype.start = function() {
var me = this; var me = this;
var scriptFileName = this.getScriptFileName(); var scriptFileName = this.pathToBitJS_ + this.getScriptFileName();
if (scriptFileName) { if (scriptFileName) {
this.worker_ = new Worker(scriptFileName); this.worker_ = new Worker(scriptFileName);
@ -303,11 +309,32 @@ bitjs.archive.Unarchiver.prototype.handleWorkerEvent_ = function(e) {
* @extends {bitjs.archive.Unarchiver} * @extends {bitjs.archive.Unarchiver}
* @constructor * @constructor
*/ */
bitjs.archive.Unzipper = function(arrayBuffer) { bitjs.archive.Unzipper = function(arrayBuffer, opt_pathToBitJS) {
bitjs.base(this, arrayBuffer); bitjs.base(this, arrayBuffer, opt_pathToBitJS);
}; };
bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver); bitjs.inherits(bitjs.archive.Unzipper, bitjs.archive.Unarchiver);
bitjs.archive.Unzipper.prototype.getScriptFileName = function() { return 'unzip.js' }; 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' };
})(); })();

View file

@ -31,12 +31,22 @@ var err = function(str) {
var postProgress = function() { var postProgress = function() {
postMessage(new bitjs.archive.UnarchiveProgressEvent( postMessage(new bitjs.archive.UnarchiveProgressEvent(
currentFilename, currentFilename,
currentFileNumber,
currentBytesUnarchivedInFile, currentBytesUnarchivedInFile,
currentBytesUnarchived, currentBytesUnarchived,
totalUncompressedBytesInArchive, totalUncompressedBytesInArchive,
totalFilesInArchive)); 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 // Volume Types
var MARK_HEAD = 0x72, var MARK_HEAD = 0x72,
@ -469,10 +479,10 @@ function Unpack20(bstream, Solid) {
} }
function RarUpdateProgress() { function RarUpdateProgress() {
var change = rBuffer.ptr - progress.currentFileBytesUnzipped; var change = rBuffer.ptr - currentBytesUnarchivedInFile;
progress.currentFileBytesUnzipped = rBuffer.ptr; currentBytesUnarchivedInFile = rBuffer.ptr;
progress.totalBytesUnzipped += change; currentBytesUnarchived += change;
postMessage(progress); postProgress();
} }
@ -768,7 +778,6 @@ var RarLocalFile = function(bstream) {
if (this.header.headType != FILE_HEAD && this.header.headType != ENDARC_HEAD) { if (this.header.headType != FILE_HEAD && this.header.headType != ENDARC_HEAD) {
this.isValid = false; this.isValid = false;
//progress.isValid = false;
info("Error! RAR Volume did not include a FILE_HEAD header "); info("Error! RAR Volume did not include a FILE_HEAD header ");
} }
else { else {
@ -789,16 +798,12 @@ RarLocalFile.prototype.unrar = function() {
info("Unstore "+this.filename); info("Unstore "+this.filename);
this.isValid = true; this.isValid = true;
progress.currentFileBytesUnzipped += this.fileData.length; currentBytesUnarchivedInFile += this.fileData.length;
progress.totalBytesUnzipped += this.fileData.length; currentBytesUnarchived += this.fileData.length;
} else { } else {
this.isValid = true; this.isValid = true;
this.fileData = unpack(this); 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); var mhead = new RarVolumeHeader(bstream);
if (mhead.headType != MAIN_HEAD) { if (mhead.headType != MAIN_HEAD) {
progress.isValid = false;
info("Error! RAR did not include a MAIN_HEAD header"); info("Error! RAR did not include a MAIN_HEAD header");
} }
else { else {
@ -833,19 +837,17 @@ var unrar = function(arrayBuffer) {
localFile = new RarLocalFile(bstream); localFile = new RarLocalFile(bstream);
info("RAR localFile isValid=" + localFile.isValid + ", volume packSize=" + localFile.header.packSize); info("RAR localFile isValid=" + localFile.isValid + ", volume packSize=" + localFile.header.packSize);
if (localFile && localFile.isValid && localFile.header.packSize > 0) { if (localFile && localFile.isValid && localFile.header.packSize > 0) {
progress.totalSizeInBytes += localFile.header.unpackedSize; totalUncompressedBytesInArchive += localFile.header.unpackedSize;
progress.isValid = true;
localFiles.push(localFile); localFiles.push(localFile);
} else if (localFile.header.packSize == 0 && localFile.header.unpackedSize == 0) { } else if (localFile.header.packSize == 0 && localFile.header.unpackedSize == 0) {
localFile.isValid = true; localFile.isValid = true;
progress.isValid = true;
} }
} catch(err) { } catch(err) {
break; break;
} }
//info("bstream" + bstream.bytePtr+"/"+bstream.bytes.length); //info("bstream" + bstream.bytePtr+"/"+bstream.bytes.length);
} while( localFile.isValid ); } while( localFile.isValid );
progress.totalNumFilesInZip = localFiles.length; totalFilesInArchive = localFiles.length;
// now we have all information but things are unpacked // now we have all information but things are unpacked
// TODO: unpack // TODO: unpack
@ -876,21 +878,19 @@ var unrar = function(arrayBuffer) {
var localfile = localFiles[i]; var localfile = localFiles[i];
// update progress // update progress
progress.currentFilename = localfile.header.filename; currentFilename = localfile.header.filename;
progress.currentFileBytesUnzipped = 0; currentBytesUnarchivedInFile = 0;
// actually do the unzipping // actually do the unzipping
localfile.unrar(); localfile.unrar();
if (localfile.isValid) { if (localfile.isValid) {
progress.localFiles.push(localfile); postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile));
postMessage(progress); postProgress();
progress.localFiles = [];
} }
} }
progress.isDone = true; postProgress();
postMessage(progress);
} }
} }
else { else {

View file

@ -30,6 +30,7 @@ var err = function(str) {
var postProgress = function() { var postProgress = function() {
postMessage(new bitjs.archive.UnarchiveProgressEvent( postMessage(new bitjs.archive.UnarchiveProgressEvent(
currentFilename, currentFilename,
currentFileNumber,
currentBytesUnarchivedInFile, currentBytesUnarchivedInFile,
currentBytesUnarchived, currentBytesUnarchived,
totalUncompressedBytesInArchive, totalUncompressedBytesInArchive,
@ -90,7 +91,6 @@ var TarLocalFile = function(bstream) {
this.fileData = new Uint8Array(bstream.bytes.buffer, bstream.ptr, this.size); this.fileData = new Uint8Array(bstream.bytes.buffer, bstream.ptr, this.size);
if (this.name.length > 0 && this.size > 0 && this.fileData && this.fileData.buffer) { if (this.name.length > 0 && this.size > 0 && this.fileData && this.fileData.buffer) {
this.isValid = true; this.isValid = true;
this.imageString = createURLFromArray(this.fileData);
} }
bstream.readBytes(this.size); bstream.readBytes(this.size);
@ -125,11 +125,10 @@ var untar = function(arrayBuffer) {
var oneLocalFile = new TarLocalFile(bstream); var oneLocalFile = new TarLocalFile(bstream);
if (oneLocalFile && oneLocalFile.isValid) { if (oneLocalFile && oneLocalFile.isValid) {
localFiles.push(oneLocalFile); localFiles.push(oneLocalFile);
progress.totalNumFilesInZip++; totalUncompressedBytesInArchive += oneLocalFile.size;
progress.totalSizeInBytes += oneLocalFile.size;
} }
} }
progress.totalNumFilesInZip = localFiles.length; totalFilesInArchive = localFiles.length;
// got all local files, now sort them // got all local files, now sort them
localFiles.sort(function(a,b) { localFiles.sort(function(a,b) {
@ -152,11 +151,9 @@ var untar = function(arrayBuffer) {
return anum - bnum; return anum - bnum;
}); });
progress.isValid = true;
// report # files and total length // report # files and total length
if (localFiles.length > 0) { if (localFiles.length > 0) {
postMessage(progress); postProgress();
} }
// now do the shipping of each file // now do the shipping of each file
@ -165,23 +162,17 @@ var untar = function(arrayBuffer) {
info("Sending file '" + localfile.filename + "' up"); info("Sending file '" + localfile.filename + "' up");
// update progress // update progress
progress.currentFilename = localfile.filename; currentFilename = localfile.filename;
progress.currentFileBytesUnzipped = localfile.size; currentFileNumber = i;
progress.totalBytesUnzipped += localfile.size; currentBytesUnarchivedInFile = localfile.size;
progress.isValid = true; currentBytesUnarchived += localfile.size;
progress.localFiles.push(localfile); postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile));
postMessage(progress); postProgress();
// Wipe out old localFiles array now that has been copied out of the thread.
progress.localFiles = [];
} }
progress.isDone = true; postProgress();
postMessage(progress);
postMessage(new bitjs.archive.UnarchiveFinishEvent()); postMessage(new bitjs.archive.UnarchiveFinishEvent());
return progress;
}; };
// event.data.file has the ArrayBuffer. // event.data.file has the ArrayBuffer.