39 lines
1.3 KiB
OCaml
39 lines
1.3 KiB
OCaml
let min_match_len = 3
|
|
let max_match_len = 255
|
|
let lookahead_size = 256
|
|
let window_size = 32768
|
|
|
|
let compress input =
|
|
let len = Bytes.length input in
|
|
let window = Window.create () in
|
|
let finder = Finder.create () in
|
|
let writer = Writer.create () in
|
|
let rec loop pos =
|
|
if pos >= len then () else
|
|
let la_len = min (len - pos) lookahead_size in
|
|
if la_len < min_match_len then (
|
|
for i = pos to len - 1 do
|
|
let byte = Char.code (Bytes.get input i) in
|
|
Writer.write_literal writer byte;
|
|
Window.add_byte window byte;
|
|
Finder.add_bytes finder window input i 1
|
|
done
|
|
) else (
|
|
match Finder.find_longest finder window input pos la_len with
|
|
| Some (distance, match_len) ->
|
|
let match_len = min match_len max_match_len in
|
|
Writer.write_match writer distance match_len;
|
|
Window.add_bytes window input pos match_len;
|
|
Finder.add_bytes finder window input pos match_len;
|
|
loop (pos + match_len)
|
|
| None ->
|
|
let byte = Char.code (Bytes.get input pos) in
|
|
Writer.write_literal writer byte;
|
|
Window.add_byte window byte;
|
|
Finder.add_bytes finder window input pos 1;
|
|
loop (pos + 1)
|
|
)
|
|
in
|
|
loop 0;
|
|
Writer.to_bytes writer
|