import type { IBitReader } from '../interfaces.js'; const BITMASK = [0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff] as const; /** * Creates a bit reader function for BZIP2 decompression. * Takes a buffer iterator as input and returns a function that reads bits. */ export function bitIterator(nextBuffer: () => Buffer): IBitReader { let bit = 0; let byte = 0; let bytes = nextBuffer(); let _bytesRead = 0; const reader = function (n: number | null): number | void { if (n === null && bit !== 0) { // align to byte boundary bit = 0; byte++; return; } let result = 0; let remaining = n as number; while (remaining > 0) { if (byte >= bytes.length) { byte = 0; bytes = nextBuffer(); } const left = 8 - bit; if (bit === 0 && remaining > 0) { _bytesRead++; } if (remaining >= left) { result <<= left; result |= BITMASK[left] & bytes[byte++]; bit = 0; remaining -= left; } else { result <<= remaining; result |= (bytes[byte] & (BITMASK[remaining] << (8 - remaining - bit))) >> (8 - remaining - bit); bit += remaining; remaining = 0; } } return result; } as IBitReader; Object.defineProperty(reader, 'bytesRead', { get: () => _bytesRead, enumerable: true, }); return reader; }