UNPKG

@gmod/cram

Version:

read CRAM files with pure Javascript

52 lines 1.8 kB
import CramCodec from "./_base.js"; import { CramUnimplementedError } from "../../errors.js"; export default class SubexpCodec extends CramCodec { constructor(parameters, dataType) { super(parameters, dataType); if (this.dataType !== 'int') { throw new CramUnimplementedError(`${this.dataType} decoding not yet implemented by SUBEXP codec`); } } decode(_slice, coreDataBlock, _blocksByContentId, cursors) { return decodeSubexpInline(coreDataBlock.content, cursors.coreBlock, this.parameters.K, this.parameters.offset); } } /** * Optimized subexp decoder with inlined bit reading. */ function decodeSubexpInline(data, cursor, K, offset) { let { bytePosition, bitPosition } = cursor; // Count leading ones (inline single-bit reads) let numLeadingOnes = 0; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition while (true) { const bit = (data[bytePosition] >> bitPosition) & 1; bitPosition -= 1; if (bitPosition < 0) { bytePosition += 1; bitPosition = 7; } if (bit === 0) { break; } numLeadingOnes += 1; } // Determine how many bits to read for the value const b = numLeadingOnes === 0 ? K : numLeadingOnes + K - 1; // Read b bits let bits = 0; for (let i = 0; i < b; i++) { bits <<= 1; bits |= (data[bytePosition] >> bitPosition) & 1; bitPosition -= 1; if (bitPosition < 0) { bytePosition += 1; bitPosition = 7; } } cursor.bytePosition = bytePosition; cursor.bitPosition = bitPosition; const n = numLeadingOnes === 0 ? bits : (1 << b) | bits; return n - offset; } //# sourceMappingURL=subexp.js.map