lz77/lib/writer.ml

37 lines
1.2 KiB
OCaml

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