14b6202eec
Fixes func in helper,web Fixes for pdf reader fixes for calling from another folder renamed to calibreweb for importing in python caller script
170 lines
5.3 KiB
JavaScript
170 lines
5.3 KiB
JavaScript
/**
|
|
* untar.js
|
|
*
|
|
* Licensed under the MIT License
|
|
*
|
|
* Copyright(c) 2011 Google Inc.
|
|
*
|
|
* Reference Documentation:
|
|
*
|
|
* TAR format: http://www.gnu.org/software/automake/manual/tar/Standard.html
|
|
*/
|
|
|
|
/* global bitjs, importScripts, Uint8Array */
|
|
|
|
// This file expects to be invoked as a Worker (see onmessage below).
|
|
importScripts("../io/bytestream.js");
|
|
importScripts("archive.js");
|
|
|
|
// Progress variables.
|
|
var currentFilename = "";
|
|
var currentFileNumber = 0;
|
|
var currentBytesUnarchivedInFile = 0;
|
|
var currentBytesUnarchived = 0;
|
|
var totalUncompressedBytesInArchive = 0;
|
|
var totalFilesInArchive = 0;
|
|
var allLocalFiles = [];
|
|
|
|
// Helper functions.
|
|
var info = function(str) {
|
|
postMessage(new bitjs.archive.UnarchiveInfoEvent(str));
|
|
};
|
|
var err = function(str) {
|
|
postMessage(new bitjs.archive.UnarchiveErrorEvent(str));
|
|
};
|
|
|
|
// Removes all characters from the first zero-byte in the string onwards.
|
|
var readCleanString = function(bstr, numBytes) {
|
|
var str = bstr.readString(numBytes);
|
|
var zIndex = str.indexOf(String.fromCharCode(0));
|
|
return zIndex != -1 ? str.substr(0, zIndex) : str;
|
|
};
|
|
|
|
var postProgress = function() {
|
|
postMessage(new bitjs.archive.UnarchiveProgressEvent(
|
|
currentFilename,
|
|
currentFileNumber,
|
|
currentBytesUnarchivedInFile,
|
|
currentBytesUnarchived,
|
|
totalUncompressedBytesInArchive,
|
|
totalFilesInArchive
|
|
));
|
|
};
|
|
|
|
// takes a ByteStream and parses out the local file information
|
|
var TarLocalFile = function(bstream) {
|
|
this.isValid = false;
|
|
|
|
var bytesRead = 0;
|
|
|
|
// Read in the header block
|
|
this.name = readCleanString(bstream, 100);
|
|
this.mode = readCleanString(bstream, 8);
|
|
this.uid = readCleanString(bstream, 8);
|
|
this.gid = readCleanString(bstream, 8);
|
|
this.size = parseInt(readCleanString(bstream, 12), 8);
|
|
this.mtime = readCleanString(bstream, 12);
|
|
this.chksum = readCleanString(bstream, 8);
|
|
this.typeflag = readCleanString(bstream, 1);
|
|
this.linkname = readCleanString(bstream, 100);
|
|
this.maybeMagic = readCleanString(bstream, 6);
|
|
|
|
if (this.maybeMagic === "ustar") {
|
|
this.version = readCleanString(bstream, 2);
|
|
this.uname = readCleanString(bstream, 32);
|
|
this.gname = readCleanString(bstream, 32);
|
|
this.devmajor = readCleanString(bstream, 8);
|
|
this.devminor = readCleanString(bstream, 8);
|
|
this.prefix = readCleanString(bstream, 155);
|
|
|
|
if (this.prefix.length) {
|
|
this.name = this.prefix + this.name;
|
|
}
|
|
bstream.readBytes(12); // 512 - 500
|
|
} else {
|
|
bstream.readBytes(255); // 512 - 257
|
|
}
|
|
|
|
bytesRead += 512;
|
|
|
|
// Done header, now rest of blocks are the file contents.
|
|
this.filename = this.name;
|
|
this.fileData = null;
|
|
|
|
info("Untarring file '" + this.filename + "'");
|
|
info(" size = " + this.size);
|
|
info(" typeflag = " + this.typeflag);
|
|
|
|
// A regular file.
|
|
if (this.typeflag == 0) {
|
|
info(" This is a regular file.");
|
|
var sizeInBytes = parseInt(this.size);
|
|
this.fileData = new Uint8Array(bstream.readBytes(sizeInBytes));
|
|
bytesRead += sizeInBytes;
|
|
if (this.name.length > 0 && this.size > 0 && this.fileData && this.fileData.buffer) {
|
|
this.isValid = true;
|
|
}
|
|
|
|
// Round up to 512-byte blocks.
|
|
var remaining = 512 - (bytesRead % 512);
|
|
if (remaining > 0 && remaining < 512) {
|
|
bstream.readBytes(remaining);
|
|
}
|
|
} else if (this.typeflag == 5) {
|
|
info(" This is a directory.");
|
|
}
|
|
};
|
|
|
|
var untar = function(arrayBuffer) {
|
|
postMessage(new bitjs.archive.UnarchiveStartEvent());
|
|
currentFilename = "";
|
|
currentFileNumber = 0;
|
|
currentBytesUnarchivedInFile = 0;
|
|
currentBytesUnarchived = 0;
|
|
totalUncompressedBytesInArchive = 0;
|
|
totalFilesInArchive = 0;
|
|
allLocalFiles = [];
|
|
|
|
var bstream = new bitjs.io.ByteStream(arrayBuffer);
|
|
postProgress();
|
|
// While we don't encounter an empty block, keep making TarLocalFiles.
|
|
while (bstream.peekNumber(4) !== 0) {
|
|
var oneLocalFile = new TarLocalFile(bstream);
|
|
if (oneLocalFile && oneLocalFile.isValid) {
|
|
// If we make it to this point and haven't thrown an error, we have successfully
|
|
// read in the data for a local file, so we can update the actual bytestream.
|
|
|
|
allLocalFiles.push(oneLocalFile);
|
|
totalUncompressedBytesInArchive += oneLocalFile.size;
|
|
|
|
// update progress
|
|
currentFilename = oneLocalFile.filename;
|
|
currentFileNumber = totalFilesInArchive++;
|
|
currentBytesUnarchivedInFile = oneLocalFile.size;
|
|
currentBytesUnarchived += oneLocalFile.size;
|
|
postMessage(new bitjs.archive.UnarchiveExtractEvent(oneLocalFile));
|
|
postProgress();
|
|
}
|
|
}
|
|
totalFilesInArchive = allLocalFiles.length;
|
|
|
|
postProgress();
|
|
postMessage(new bitjs.archive.UnarchiveFinishEvent());
|
|
};
|
|
|
|
// event.data.file has the first ArrayBuffer.
|
|
// event.data.bytes has all subsequent ArrayBuffers.
|
|
onmessage = function(event) {
|
|
try {
|
|
untar(event.data.file, true);
|
|
} catch (e) {
|
|
if (typeof e === "string" && e.startsWith("Error! Overflowed")) {
|
|
// Overrun the buffer.
|
|
// unarchiveState = UnarchiveState.WAITING;
|
|
} else {
|
|
err("Found an error while untarring");
|
|
err(e);
|
|
throw e;
|
|
}
|
|
}
|
|
};
|