UNPKG

@gmod/bgzf-filehandle

Version:

read from a compressed bgzip file (with .gzi) as if it were uncompressed

37 lines 1.79 kB
import GziIndex from "./gziIndex.js"; import { unzip } from "./unzip.js"; import { concatUint8Array } from "./util.js"; export default class BgzFilehandle { constructor({ filehandle, gziFilehandle, }) { this.filehandle = filehandle; this.gzi = new GziIndex({ 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 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 concatUint8Array(blocks); } } //# sourceMappingURL=bgzFilehandle.js.map