1
0
mirror of synced 2026-09-01 00:04:45 +00:00
Files

60 lines
1.3 KiB
TypeScript
Raw Permalink Normal View History

import type { ITokenizer } from 'strtok3';
2018-11-10 15:50:39 +01:00
import * as Token from 'token-types';
export class BitReader {
2024-08-08 10:19:14 +02:00
public pos = 0;
private dword: number | null = null;
private tokenizer: ITokenizer;
2018-11-10 15:50:39 +01:00
public constructor(tokenizer: ITokenizer) {
this.tokenizer = tokenizer;
2018-11-10 15:50:39 +01:00
}
/**
*
* @param bits 1..30 bits
*/
2018-11-24 15:23:57 +01:00
public async read(bits: number): Promise<number> {
2018-11-10 15:50:39 +01:00
while (this.dword === null) {
2018-11-24 15:23:57 +01:00
this.dword = await this.tokenizer.readToken(Token.UINT32_LE);
2018-11-10 15:50:39 +01:00
}
let out = this.dword;
this.pos += bits;
if (this.pos < 32) {
out >>>= (32 - this.pos);
2018-11-24 15:23:57 +01:00
return out & ((1 << bits) - 1);
2024-08-08 10:19:14 +02:00
}
2018-11-10 15:50:39 +01:00
this.pos -= 32;
if (this.pos === 0) {
this.dword = null;
2018-11-24 15:23:57 +01:00
return out & ((1 << bits) - 1);
2024-08-08 10:19:14 +02:00
}
2018-11-24 15:23:57 +01:00
this.dword = await this.tokenizer.readToken(Token.UINT32_LE);
if (this.pos) {
out <<= this.pos;
out |= this.dword >>> (32 - this.pos);
}
return out & ((1 << bits) - 1);
2018-11-10 15:50:39 +01:00
}
2018-11-24 15:23:57 +01:00
public async ignore(bits: number): Promise<number> {
2018-11-10 15:50:39 +01:00
if (this.pos > 0) {
const remaining = 32 - this.pos;
this.dword = null;
2018-11-10 15:50:39 +01:00
bits -= remaining;
this.pos = 0;
}
const remainder = bits % 32;
const numOfWords = (bits - remainder) / 32;
2018-11-24 15:23:57 +01:00
await this.tokenizer.ignore(numOfWords * 4);
return this.read(remainder);
2018-11-10 15:50:39 +01:00
}
}