29 lines
1.1 KiB
OCaml
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)
|