Files
smartarchive/ts/bzip2/bititerator.ts

61 lines
1.4 KiB
TypeScript
Raw Normal View History

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;
}