123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /* jshint worker:true */
- (function main(global) {
- "use strict";
- if (global.zWorkerInitialized)
- throw new Error('z-worker.js should be run only once');
- global.zWorkerInitialized = true;
- addEventListener("message", function(event) {
- var message = event.data, type = message.type, sn = message.sn;
- var handler = handlers[type];
- if (handler) {
- try {
- handler(message);
- } catch (e) {
- onError(type, sn, e);
- }
- }
- //for debug
- //postMessage({type: 'echo', originalType: type, sn: sn});
- });
- var handlers = {
- importScripts: doImportScripts,
- newTask: newTask,
- append: processData,
- flush: processData,
- };
- // deflater/inflater tasks indexed by serial numbers
- var tasks = {};
- function doImportScripts(msg) {
- if (msg.scripts && msg.scripts.length > 0)
- importScripts.apply(undefined, msg.scripts);
- postMessage({type: 'importScripts'});
- }
- function newTask(msg) {
- var CodecClass = global[msg.codecClass];
- var sn = msg.sn;
- if (tasks[sn])
- throw Error('duplicated sn');
- tasks[sn] = {
- codec: new CodecClass(msg.options),
- crcInput: msg.crcType === 'input',
- crcOutput: msg.crcType === 'output',
- crc: new Crc32(),
- };
- postMessage({type: 'newTask', sn: sn});
- }
- // performance may not be supported
- var now = global.performance ? global.performance.now.bind(global.performance) : Date.now;
- function processData(msg) {
- var sn = msg.sn, type = msg.type, input = msg.data;
- var task = tasks[sn];
- // allow creating codec on first append
- if (!task && msg.codecClass) {
- newTask(msg);
- task = tasks[sn];
- }
- var isAppend = type === 'append';
- var start = now();
- var output;
- if (isAppend) {
- try {
- output = task.codec.append(input, function onprogress(loaded) {
- postMessage({type: 'progress', sn: sn, loaded: loaded});
- });
- } catch (e) {
- delete tasks[sn];
- throw e;
- }
- } else {
- delete tasks[sn];
- output = task.codec.flush();
- }
- var codecTime = now() - start;
- start = now();
- if (input && task.crcInput)
- task.crc.append(input);
- if (output && task.crcOutput)
- task.crc.append(output);
- var crcTime = now() - start;
- var rmsg = {type: type, sn: sn, codecTime: codecTime, crcTime: crcTime};
- var transferables = [];
- if (output) {
- rmsg.data = output;
- transferables.push(output.buffer);
- }
- if (!isAppend && (task.crcInput || task.crcOutput))
- rmsg.crc = task.crc.get();
- postMessage(rmsg, transferables);
- }
- function onError(type, sn, e) {
- var msg = {
- type: type,
- sn: sn,
- error: formatError(e)
- };
- postMessage(msg);
- }
- function formatError(e) {
- return { message: e.message, stack: e.stack };
- }
- // Crc32 code copied from file zip.js
- function Crc32() {
- this.crc = -1;
- }
- Crc32.prototype.append = function append(data) {
- var crc = this.crc | 0, table = this.table;
- for (var offset = 0, len = data.length | 0; offset < len; offset++)
- crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
- this.crc = crc;
- };
- Crc32.prototype.get = function get() {
- return ~this.crc;
- };
- Crc32.prototype.table = (function() {
- var i, j, t, table = []; // Uint32Array is actually slower than []
- for (i = 0; i < 256; i++) {
- t = i;
- for (j = 0; j < 8; j++)
- if (t & 1)
- t = (t >>> 1) ^ 0xEDB88320;
- else
- t = t >>> 1;
- table[i] = t;
- }
- return table;
- })();
- // "no-op" codec
- function NOOP() {}
- global.NOOP = NOOP;
- NOOP.prototype.append = function append(bytes, onprogress) {
- return bytes;
- };
- NOOP.prototype.flush = function flush() {};
- })(this);
|