type t = { buf : Buffer.t; mutable cur : int; mutable filled : int } let create () = { buf = Buffer.create 1024; cur = 0; filled = 0 } let push_byte t = Buffer.add_char t.buf (Char.chr t.cur); t.cur <- 0; t.filled <- 0 let write_bit t bit = let bit = if bit <> 0 then 1 else 0 in let pos = 7 - t.filled in t.cur <- t.cur lor (bit lsl pos); t.filled <- t.filled + 1; if t.filled = 8 then push_byte t let write_bits t value nbits = if nbits <= 0 then invalid_arg "write_bits: nbits must be > 0"; if nbits > 31 then invalid_arg "write_bits: nbits too large"; for i = nbits - 1 downto 0 do let bit = (value lsr i) land 1 in write_bit t bit done let write_literal t byte = if byte < 0 || byte > 255 then invalid_arg "write_literal: byte out of range"; write_bit t 1; write_bits t byte 8 let write_match t distance length = if distance <= 0 || distance >= (1 lsl 15) then invalid_arg "write_match: invalid distance"; if length <= 0 || length > 255 then invalid_arg "write_match: invalid length"; write_bit t 0; write_bits t distance 15; write_bits t length 8 let flush t = if t.filled > 0 then push_byte t let to_bytes t = flush t; Buffer.contents t.buf |> Bytes.of_string