2025-11-25 12:32:13 +00:00
|
|
|
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) {
|
2025-08-18 01:29:06 +00:00
|
|
|
// align to byte boundary
|
|
|
|
|
bit = 0;
|
|
|
|
|
byte++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-11-25 12:32:13 +00:00
|
|
|
|
|
|
|
|
let result = 0;
|
|
|
|
|
let remaining = n as number;
|
|
|
|
|
|
|
|
|
|
while (remaining > 0) {
|
2025-08-18 01:29:06 +00:00
|
|
|
if (byte >= bytes.length) {
|
|
|
|
|
byte = 0;
|
|
|
|
|
bytes = nextBuffer();
|
|
|
|
|
}
|
2025-11-25 12:32:13 +00:00
|
|
|
|
|
|
|
|
const left = 8 - bit;
|
|
|
|
|
|
|
|
|
|
if (bit === 0 && remaining > 0) {
|
|
|
|
|
_bytesRead++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (remaining >= left) {
|
2025-08-18 01:29:06 +00:00
|
|
|
result <<= left;
|
|
|
|
|
result |= BITMASK[left] & bytes[byte++];
|
|
|
|
|
bit = 0;
|
2025-11-25 12:32:13 +00:00
|
|
|
remaining -= left;
|
2025-08-18 01:29:06 +00:00
|
|
|
} else {
|
2025-11-25 12:32:13 +00:00
|
|
|
result <<= remaining;
|
|
|
|
|
result |= (bytes[byte] & (BITMASK[remaining] << (8 - remaining - bit))) >> (8 - remaining - bit);
|
|
|
|
|
bit += remaining;
|
|
|
|
|
remaining = 0;
|
2025-08-18 01:29:06 +00:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-25 12:32:13 +00:00
|
|
|
|
2025-08-18 01:29:06 +00:00
|
|
|
return result;
|
2025-11-25 12:32:13 +00:00
|
|
|
} as IBitReader;
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(reader, 'bytesRead', {
|
|
|
|
|
get: () => _bytesRead,
|
|
|
|
|
enumerable: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return reader;
|
2025-08-18 01:29:06 +00:00
|
|
|
}
|