@gmod/cram
Version:
read CRAM files with pure Javascript
66 lines • 2.44 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const _base_ts_1 = __importDefault(require("./_base.js"));
const errors_ts_1 = require("../../errors.js");
class GammaCodec extends _base_ts_1.default {
constructor(parameters, dataType) {
super(parameters, dataType);
if (this.dataType !== 'int') {
throw new errors_ts_1.CramUnimplementedError(`${this.dataType} decoding not yet implemented by GAMMA codec`);
}
}
decode(_slice, coreDataBlock, _blocksByContentId, cursors) {
return decodeGammaInline(coreDataBlock.content, cursors.coreBlock, this.parameters.offset);
}
}
exports.default = GammaCodec;
/**
* Optimized gamma decoder with inlined bit reading.
* Avoids function call overhead by inlining the getBits logic.
*/
function decodeGammaInline(data, cursor, offset) {
let { bytePosition, bitPosition } = cursor;
let length = 1;
// Count leading zeros (each 0 bit increases length). A truncated core block
// reads as zeros forever, so guard against running off the end.
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
while (true) {
if (bytePosition >= data.length) {
throw new errors_ts_1.CramBufferOverrunError('read beyond end of core block; file seems truncated');
}
const bit = (data[bytePosition] >> bitPosition) & 1;
bitPosition -= 1;
if (bitPosition < 0) {
bytePosition += 1;
bitPosition = 7;
}
if (bit === 1) {
break;
}
length += 1;
}
// Now read (length - 1) more bits for the value
let readBits = 0;
const bitsToRead = length - 1;
if (bitsToRead > 0) {
// Optimized multi-bit read
for (let i = 0; i < bitsToRead; i++) {
readBits <<= 1;
readBits |= (data[bytePosition] >> bitPosition) & 1;
bitPosition -= 1;
if (bitPosition < 0) {
bytePosition += 1;
bitPosition = 7;
}
}
}
// Update cursor
cursor.bytePosition = bytePosition;
cursor.bitPosition = bitPosition;
const value = readBits | (1 << (length - 1));
return value - offset;
}
//# sourceMappingURL=gamma.js.map