package decompress
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=aa2e842dc009bcddcbb5c0791f5dbeee2bda5a104ecc7681aa37ac42537e3121
sha512=58e2529fa93f4f671ffd0a69c3542e835868f8c72db9c62b48d207c31f3585101d4d314f7e5922b273c86609b00c87343987b03b568d3e69749d2c7f7fa4089b
doc/README.html
Decompress - Pure OCaml implementation of decompression algorithms
decompress is a library which implements:
The library
The library is available with:
$ opam install decompressIt provides three sub-packages:
decompress.deto handle RFC1951 streamdecompress.zlto handle Zlib streamdecompress.gzto handle Gzip streamdecompress.lzoto handle LZO contents
Each sub-package provide 3 sub-modules:
Infto inflate/decompress a streamDefto deflate/compress a streamHigheras a easy entry point to use the stream
How to use it
The binary
The distribution provides a simple binary which is able to compress/uncompress anything:
$ decompress -fgzip --deflate < my_document.txt > my_document.gzip
$ decompress -fgzip < my_document.gzip > my_document.out
$ diff my_document.txt my_document.outIt does the GZip compression, the Zlib one and the DEFLATE one. It can do an LZO compression too.
Link issue
decompress uses checkseum to compute CRC of streams. checkseum provides 2 implementations:
- a C implementation to be fast
- an OCaml implementation to be usable with
js_of_ocaml(or, at least, require only the caml runtime)
When the user wants to make an OCaml executable, it must choose which implementation of checkseum he wants. A compilation of an executable with decompress.zl is:
$ ocamlfind opt -linkpkg -package checkseum.c,decompress.zl main.mlOtherwise, the end-user should have a linking error (see #47).
With dune
checkseum uses a mechanism integrated into dune which solves the link issue. It provides a way to silently choose the default implementation of checkseum: checkseum.c.
By this way (and only with dune), an executable with decompress.zl is:
(executable
(name main)
(libraries decompress.zl))Of course, the user still is able to choose which implementation he wants:
(executable
(name main)
(libraries checkseum.ocaml decompress.zl))The API
decompress proposes to the user a full control of:
- the input/output loop
- the allocation
Input / Output
The process of the inflation/deflation is non-blocking and it does not require any syscalls (as an usual MirageOS project). The user can decide how to get the input and how to store the output.
An usual loop (which can fit into lwt or async) of decompress.zl is:
let rec go decoder = match Zl.Inf.decode decoder with
| `Await decoder ->
let len = input itmp 0 (Bstr.length tmp) in
go (Zl.Inf.src decoder itmp 0 len)
| `Flush decoder ->
let len = Bstr.length otmp - Zl.Inf.dst_rem decoder in
output stdout otmp 0 len ;
go (Zl.Inf.flush decoder)
| `Malformed err -> invalid_arg err
| `End decoder ->
let len = Bstr.length otmp - Zl.Inf.dst_rem decoder in
output stdout otmp 0 len in
go decoderAllocation
Then, the process does not allocate large objects but it requires at the initialisation these objects. Such objects can be re-used by another inflation/deflation process - of course, these processes can not use same objects at the same time.
val decompress : window:De.window -> in_channel -> out_channel -> unit
let w0 = De.make_windows ~bits:15
(* Safe use of decompress *)
let () =
decompress ~window:w0 stdin stdout ;
decompress ~window:w0 (open_in "file.z") (open_out "file")
(* Unsafe use of decompress,
the second process must use an other pre-allocated window. *)
let () =
Lwt_main.run @@
Lwt.join [ (decompress ~window:w0 stdin stdout |> Lwt.return)
; (decompress ~window:w0 (open_in "file.z") (open_out "file")
|> Lwt.return) ]This ability can be used on:
- the input buffer given to the encoder/decoder with
src - the output buffer given to the encoder/decoder
- the window given to the encoder/decoder
- the shared-queue used by the compression algorithm and the encoder
Example
An example exists into bin/decompress.ml where you can see how to use decompress.zl and decompress.de.
Higher interface
However, decompress provides a higher interface close to what camlzip provides to help newcomers to use decompress:
val compress :
refill:(bigstring -> int)
-> flush:(bigstring -> int -> unit)
-> unit
val uncompress :
refill:(bigstring -> int)
-> flush:(bigstring -> int -> unit)
-> unitBenchmark
You can run a simple benchmark which compares decompress with camlzip and bytesrw.zlib (both use zlib). These libraries must be installed and you can launch the benchmark with:
$ git clone https://github.com/mirage/decompress
$ cd decompress
$ opam pin add -yn .
$ opam install --deps-only -t decompress
$ dune build @runbenchBuild Requirements
- OCaml >= 4.07.0
duneto build the projectbase-bytesmeta-packagecheckseumoptint