@gmod/bgzf-filehandle
Version:
read from a compressed bgzip file (with .gzi) as if it were uncompressed
105 lines • 3.91 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.unzip = unzip;
exports.unzipChunkSlice = unzipChunkSlice;
const pako_1 = __importDefault(require("pako"));
const util_ts_1 = require("./util.js");
//@ts-ignore
const { Z_SYNC_FLUSH, Inflate } = pako_1.default;
// browserify-zlib, which is the zlib shim used by default in webpacked code,
// does not properly uncompress bgzf chunks that contain more than one bgzf
// block, so export an unzip function that uses pako directly if we are running
// in a browser.
async function unzip(inputData) {
try {
let strm;
let pos = 0;
let inflator;
const blocks = [];
do {
const remainingInput = inputData.subarray(pos);
inflator = new Inflate();
({ strm } = inflator);
inflator.push(remainingInput, Z_SYNC_FLUSH);
if (inflator.err) {
throw new Error(inflator.msg);
}
pos += strm.next_in;
blocks.push(inflator.result);
} while (strm.avail_in);
return (0, util_ts_1.concatUint8Array)(blocks);
}
catch (e) {
// return a slightly more informative error message
if (/incorrect header check/.exec(`${e}`)) {
throw new Error('problem decompressing block: incorrect gzip header check');
}
throw e;
}
}
// keeps track of the position of compressed blocks in terms of file offsets,
// and a decompressed equivalent
//
// also slices (0,minv.dataPosition) and (maxv.dataPosition,end) off
async function unzipChunkSlice(inputData, chunk) {
try {
let strm;
const { minv, maxv } = chunk;
let cpos = minv.blockPosition;
let dpos = minv.dataPosition;
const chunks = [];
const cpositions = [];
const dpositions = [];
let i = 0;
do {
const remainingInput = inputData.subarray(cpos - minv.blockPosition);
const inflator = new Inflate();
({ strm } = inflator);
inflator.push(remainingInput, Z_SYNC_FLUSH);
if (inflator.err) {
throw new Error(inflator.msg);
}
const buffer = inflator.result;
chunks.push(buffer);
let len = buffer.length;
cpositions.push(cpos);
dpositions.push(dpos);
if (chunks.length === 1 && minv.dataPosition) {
// this is the first chunk, trim it
chunks[0] = chunks[0].subarray(minv.dataPosition);
len = chunks[0].length;
}
const origCpos = cpos;
cpos += strm.next_in;
dpos += len;
if (origCpos >= maxv.blockPosition) {
// this is the last chunk, trim it and stop decompressing. note if it is
// the same block is minv it subtracts that already trimmed part of the
// slice length
chunks[i] = chunks[i].subarray(0, maxv.blockPosition === minv.blockPosition
? maxv.dataPosition - minv.dataPosition + 1
: maxv.dataPosition + 1);
cpositions.push(cpos);
dpositions.push(dpos);
break;
}
i++;
} while (strm.avail_in);
return {
buffer: (0, util_ts_1.concatUint8Array)(chunks),
cpositions,
dpositions,
};
}
catch (e) {
// return a slightly more informative error message
if (/incorrect header check/.exec(`${e}`)) {
throw new Error('problem decompressing block: incorrect gzip header check');
}
throw e;
}
}
//# sourceMappingURL=unzip.js.map