lz77/lib/reader.ml

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