@gmod/bgzf-filehandle
Version:
read from a compressed bgzip file (with .gzi) as if it were uncompressed
43 lines • 2.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const gziIndex_ts_1 = __importDefault(require("./gziIndex.js"));
const unzip_ts_1 = require("./unzip.js");
const util_ts_1 = require("./util.js");
class BgzFilehandle {
constructor({ filehandle, gziFilehandle, }) {
this.filehandle = filehandle;
this.gzi = new gziIndex_ts_1.default({
filehandle: gziFilehandle,
});
}
async _readAndUncompressBlock(compressedPosition, nextCompressedPosition) {
let next = nextCompressedPosition;
if (!next) {
next = (await this.filehandle.stat()).size;
}
// read the compressed data into the block buffer
const blockCompressedLength = next - compressedPosition;
const blockBuffer = await this.filehandle.read(blockCompressedLength, compressedPosition);
// uncompress it
return (0, unzip_ts_1.unzip)(blockBuffer);
}
async read(length, position) {
const blockPositions = await this.gzi.getRelevantBlocksForRead(length, position);
const blocks = [];
for (let blockNum = 0; blockNum < blockPositions.length - 1; blockNum += 1) {
const uncompressedBuffer = await this._readAndUncompressBlock(blockPositions[blockNum][0], blockPositions[blockNum + 1][0]);
const [, uncompressedPosition] = blockPositions[blockNum];
const sourceOffset = uncompressedPosition >= position ? 0 : position - uncompressedPosition;
const sourceEnd = Math.min(position + length, uncompressedPosition + uncompressedBuffer.length) - uncompressedPosition;
if (sourceOffset >= 0 && sourceOffset < uncompressedBuffer.length) {
blocks.push(uncompressedBuffer.subarray(sourceOffset, sourceEnd));
}
}
return (0, util_ts_1.concatUint8Array)(blocks);
}
}
exports.default = BgzFilehandle;
//# sourceMappingURL=bgzFilehandle.js.map