package decompress
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=f91e6978beff3fcb61440d32f7c99c99f1e8654b4fb18408741d36035373ac60
sha512=c3f402404f76075e6f692ea36e701134a5d833824d5d1166365c6c81fb18b309270bf288ce4c118ac44fd0366d9b6eea0a6309255678d8e1bd2bbfa7ba843461
doc/decompress.gz/Gz/Higher/index.html
Module Gz.HigherSource
Type of the Operating-System configuration.
configuration ?ascii ?hcrc os mtime makes an Operating-System configuration to be able to compress any inputs.
val compress :
?level:int ->
?filename:string ->
?comment:string ->
w:De.Lz77.window ->
q:De.Queue.t ->
refill:(bigstring -> int) ->
flush:(bigstring -> int -> unit) ->
't ->
't configuration ->
bigstring ->
bigstring ->
unitcompress ?level ?filename ?comment ~w ~q ~refill ~flush time cfg i o compresses an input given by refill and outputs it via flush. It requires:
- a queue
qwhich is shared between the compression algorithm and the encoder. The length of it can be a bottleneck on the throughput - a window to be able to lookup repeated patterns
- a witness required by the given
cfg - a
configurationvalue iis the input bufferois the output buffer
When compress wants more input, it calls refill with i. The client returns how many bytes he wrotes into i. If he returns 0, he signals end of input.
When compress has written output buffer, it calls flush with o and how many bytes it wrote. Bytes into o must be copied and they will be lost at the next call to flush.
A simple example of how to use such interface (with unix) is:
let time () = Int32.of_float (Unix.gettimeofday ())
let deflate_string ?(level= 4) str =
let i = De.bigstring_create De.io_buffer_size in
let o = De.bigstring_create De.io_buffer_size in
let w = De.Lz77.make_window ~bits:15 in
let q = De.Queue.create 0x1000 in
let r = Buffer.create 0x1000 in
let p = ref 0 in
let cfg = Gz.Higher.configuration Gz.Unix time in
let refill buf =
let len = min (String.length str - !p) De.io_buffer_size in
Bigstringaf.blit_from_string str ~src_off:!p buf ~dst_off:0 ~len ;
p := !p + len ; len in
let flush buf len =
let str = Bigstringaf.substring buf ~off:0 ~len in
Buffer.add_string r str in
Gz.Higher.compress ~w ~q ~level ~refill ~flush () cfg i o ; Buffer.contents rAs De.Higher.compress or Zl.Higher.compress, decompress don't want to take the responsability of such function. It's why this function exists only as an example. Especially since a GZip compression requires an Unix syscall (see Unix.gettimeofday) which does not exists on some contexts such as MirageOS.
The speed and the compression ratio depends on the length of the given window and the given De.Queue.t. They can be a serious bottleneck on the throughput. Due to all of these choices, we show this function as an example - but it should not be copied as is!
type metadata = {filename : string option;comment : string option;os : os;extra : key:string -> string option;
}Type of metadata available into a GZIP flow.
val uncompress :
refill:(bigstring -> int) ->
flush:(bigstring -> int -> unit) ->
bigstring ->
bigstring ->
(metadata, [> `Msg of string ]) resultuncompress ~refill ~flush i o uncompresses an input given by refill and outputs it via flush. It requires:
ias the input bufferoas the output buffer
It returns then extracted metadata from the given GZip flow.
When uncompress wants more input, it calls refill with i. The client returns how many bytes he wrote into i. If he returns 0, he signals end of input.
When uncompress has written output buffer, it calls flush with o and how many bytes it wrote. Bytes into o must be copied and tjey will be lost at the next call to flush.
A simple example of how to use such interface is:
let inflate_string str =
let i = De.bigstring_create De.io_buffer_size in
let o = De.bigstring_create De.io_buffer_size in
let r = Buffer.create 0x1000 in
let p = ref 0 in
let refill buf =
let len = min (String.length str - !p) De.io_buffer_size in
Bigstringaf.blit_from_string str ~src_off:!p buf ~dst_off:0 ~len ;
p := !p + len ; len in
let flush buf len =
let str = Bigstringaf.substring buf ~off:0 ~len in
Buffer.add_string r str in
match Gz.Higher.uncompress ~refill ~flush i o with
| Ok m -> Ok (m, Buffer.contents r)
| Error _ as err -> errAs De.Higher.uncompress or Zl.Higher.uncompress, decompress does not want to take the responsability of such implementation when several choices was made depending on the context. Indeed, i and o can be a serious bottleneck on the throughput. The choice of Buffer can be replaced by something else such as a queue or a ropes. All of these choices should be made by the client. It's why we provide such function only as an example.