lz77/lib/decoder.ml

29 lines
1.1 KiB
OCaml

let decompress input =
let reader = Reader.of_bytes input in
let out = Buffer.create 4096 in
let window = Window.create () in
let rec loop () =
if Reader.available_bits reader <= 0 then () else
let flag = Reader.read_bits reader 1 in
if flag = 1 then (
if Reader.available_bits reader < 8 then invalid_arg "decompress: truncated literal";
let byte = Reader.read_bits reader 8 in
Buffer.add_char out (Char.chr byte);
Window.add_byte window byte;
loop ()
) else (
if Reader.available_bits reader < 23 then invalid_arg "decompress: truncated match";
let distance = Reader.read_bits reader 15 in
let length = Reader.read_bits reader 8 in
if distance <= 0 || distance > Window.window_size then invalid_arg "decompress: invalid distance";
for _ = 1 to length do
let b = Window.get_byte_at_distance window distance in
Buffer.add_char out (Char.chr b);
Window.add_byte window b
done;
loop ()
)
in
loop ();
Bytes.of_string (Buffer.contents out)