33 lines
1.1 KiB
OCaml
33 lines
1.1 KiB
OCaml
type t = { data : bytes; len : int; mutable byte_idx : int; mutable bit_idx : int }
|
|
|
|
let of_bytes b = { data = b; len = Bytes.length b; byte_idx = 0; bit_idx = 0 }
|
|
|
|
let byte_pos t = t.byte_idx
|
|
let bit_pos t = t.bit_idx
|
|
|
|
let has_more t = t.byte_idx < t.len || (t.byte_idx = t.len && t.bit_idx <> 0)
|
|
|
|
let available_bits t = (t.len - t.byte_idx) * 8 - t.bit_idx
|
|
|
|
let read_bits t n =
|
|
if n <= 0 then 0 else begin
|
|
if n > 31 then invalid_arg "read_bits: n too large";
|
|
if available_bits t < n then invalid_arg "read_bits: not enough bits";
|
|
let acc = ref 0 in
|
|
for _ = 1 to n do
|
|
if t.byte_idx >= t.len then invalid_arg "read_bits: out of data";
|
|
let byte = Char.code (Bytes.get t.data t.byte_idx) in
|
|
let bit_pos = 7 - t.bit_idx in
|
|
let bit = (byte lsr bit_pos) land 1 in
|
|
acc := (!acc lsl 1) lor bit;
|
|
if t.bit_idx = 7 then (t.byte_idx <- t.byte_idx + 1; t.bit_idx <- 0) else t.bit_idx <- t.bit_idx + 1
|
|
done;
|
|
!acc
|
|
end
|
|
|
|
let peek_bits t n =
|
|
let saved_b = t.byte_idx in
|
|
let saved_bit = t.bit_idx in
|
|
let v = read_bits t n in
|
|
t.byte_idx <- saved_b; t.bit_idx <- saved_bit; v
|