Crate libz_rs_sys

Source
Expand description

This crate is a C API for zlib-rs. The API is broadly equivalent to zlib-sys and zlib-ng-sys, but does not currently provide the gz* family of functions.

From a rust perspective, this API is not very ergonomic. Use the flate2 crate for a more ergonomic rust interface to zlib.

§Features

custom-prefix

Add a custom prefix to all exported symbols.

The value of the LIBZ_RS_SYS_PREFIX is used as a prefix for all exported symbols. For example:

> LIBZ_RS_SYS_PREFIX="MY_CUSTOM_PREFIX" cargo build -p libz-rs-sys --features=custom-prefix
   Compiling libz-rs-sys v0.2.1 (/home/folkertdev/rust/zlib-rs/libz-rs-sys)
    Finished `dev` profile [optimized + debuginfo] target(s) in 0.21s
> objdump -tT target/debug/liblibz_rs_sys.so | grep "uncompress"
0000000000081028 l     O .got	0000000000000000              _ZN7zlib_rs7inflate10uncompress17he7d985e55c58a189E$got
000000000002c570 l     F .text	00000000000001ef              _ZN7zlib_rs7inflate10uncompress17he7d985e55c58a189E
0000000000024330 g     F .text	000000000000008e              MY_CUSTOM_PREFIXuncompress
0000000000024330 g    DF .text	000000000000008e  Base        MY_CUSTOM_PREFIXuncompress

c-allocator, rust-allocator

Pick the default allocator implementation that is used if no zalloc and zfree are configured in the input z_stream.

  • c-allocator: use malloc/free for the implementation of zalloc and zfree
  • rust-allocator: the rust global allocator for the implementation of zalloc and zfree

The rust-allocator is the default when this crate is used as a rust dependency, and slightly more efficient because alignment is handled by the allocator. When building a dynamic library, it may make sense to use c-allocator instead.

std

Assume that std is available. When this feature is turned off, this crate is compatible with #![no_std].

§Example

This example compresses (“deflates”) the string "Hello, World!" and then decompresses (“inflates”) it again.

let mut strm = libz_rs_sys::z_stream::default();

let version = libz_rs_sys::zlibVersion();
let stream_size = core::mem::size_of_val(&strm) as i32;

let level = 6; // the default compression level
let err = unsafe { libz_rs_sys::deflateInit_(&mut strm, level, version, stream_size) };
assert_eq!(err, libz_rs_sys::Z_OK);

let input = "Hello, World!";
strm.avail_in = input.len() as _;
strm.next_in = input.as_ptr();

let mut output = [0u8; 32];
strm.avail_out = output.len() as _;
strm.next_out = output.as_mut_ptr();

let err = unsafe { libz_rs_sys::deflate(&mut strm, libz_rs_sys::Z_FINISH) };
assert_eq!(err, libz_rs_sys::Z_STREAM_END);

let err = unsafe { libz_rs_sys::deflateEnd(&mut strm) };
assert_eq!(err, libz_rs_sys::Z_OK);

let deflated = &mut output[..strm.total_out as usize];

let mut strm = libz_rs_sys::z_stream::default();
let err = unsafe { libz_rs_sys::inflateInit_(&mut strm, version, stream_size) };
assert_eq!(err, libz_rs_sys::Z_OK);

strm.avail_in = deflated.len() as _;
strm.next_in = deflated.as_ptr();

let mut output = [0u8; 32];
strm.avail_out = output.len() as _;
strm.next_out = output.as_mut_ptr();

let err = unsafe { libz_rs_sys::inflate(&mut strm, libz_rs_sys::Z_FINISH) };
assert_eq!(err, libz_rs_sys::Z_STREAM_END);

let err = unsafe { libz_rs_sys::inflateEnd(&mut strm) };
assert_eq!(err, libz_rs_sys::Z_OK);

let inflated = &output[..strm.total_out as usize];

assert_eq!(inflated, input.as_bytes())

§Compression Levels

The zlib library supports compression levels 0 up to and including 9. The level indicates a tradeoff between time spent on the compression versus the compression ratio, the factor by which the input is reduced in size:

  • level 0: no compression at all
  • level 1: fastest compression
  • level 6: default (a good tradeoff between speed and compression ratio)
  • level 9: best compression

Beyond this intuition, the exact behavior of the compression levels is not specified. The implementation of zlib-rs follows the implementation of zlig-ng, and deviates from the one in stock zlib.

In particular, our compression level 1 is extremely fast, but also just does not compress that well. On the silesia-small.tar input file, we see these output sizes:

implementationcompression leveloutput size (mb)
-015.74
stock1 7.05
rs1 8.52
rs2 6.90
rs4 6.55

But, zlib-rs is much faster than stock zlib. In our benchmarks, it is only at level 4 that we spend roughly as much time as stock zlib on level 1:

implementationcompression levelwall time (ms)
stock1185
rs2139
rs4181

In our example, the main options are:

  • level 1: worse compression, but much faster
  • level 2: equivalent compression, but significantly faster
  • level 4: better compression, at the same speed

In summary, when you upgrade from stock zlib, we recommend that you benchmark on your data and target platform, and pick the right compression level for your use case.

§Safety

Most of the functions in this module are unsafe fns, meaning that their behavior may be undefined if certain assumptions are broken by the caller. In most cases, documentation in this module refers to the safety assumptions of standard library functions.

In most cases, pointers must be either NULL or satisfy the requirements of &*ptr or &mut *ptr. This requirement maps to the requirements of pointer::as_ref and pointer::as_mut for immutable and mutable pointers respectively.

For pointer and length pairs, describing some sequence of elements in memory, the requirements of core::slice::from_raw_parts or core::slice::from_raw_parts_mut apply. In some cases, the element type T is converted into MaybeUninit<T>, meaning that while the slice must be valid, the elements in the slice can be uninitialized. Using uninitialized buffers for output is more performant.

Finally, some functions accept a string argument, which must either be NULL or satisfy the requirements of core::ffi::CStr::from_ptr.

Structs§

gz_header
gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields.
z_stream

Enums§

internal_state

Constants§

Z_ASCII
Z_BEST_COMPRESSION
Z_BEST_SPEED
Z_BINARY
Z_BLOCK
Z_BUF_ERROR
Z_DATA_ERROR
Z_DEFAULT_COMPRESSION
Z_DEFAULT_STRATEGY
Z_DEFLATED
Z_ERRNO
Z_FILTERED
Z_FINISH
Z_FIXED
Z_FULL_FLUSH
Z_HUFFMAN_ONLY
Z_MEM_ERROR
Z_NEED_DICT
Z_NO_COMPRESSION
Z_NO_FLUSH
Z_OK
Z_PARTIAL_FLUSH
Z_RLE
Z_STREAM_END
Z_STREAM_ERROR
Z_SYNC_FLUSH
Z_TEXT
Z_TREES
Z_UNKNOWN
Z_VERSION_ERROR

Functions§

adler32
Calculates the adler32 checksum of a sequence of bytes.
adler32_combine
Combines the checksum of two slices into one.
compress
Compresses source into dest, and writes the final deflated size into destLen.
compress2
Compresses source into dest, and writes the final deflated size into destLen.
compressBound
Returns an upper bound on the compressed size after compress or compress2 on sourceLen bytes.
crc32
Calculates the crc32 checksum of a sequence of bytes.
crc32_combine
Combines the checksum of two slices into one.
deflate
Compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full.
deflateBound
Returns an upper bound on the compressed size after deflation of sourceLen bytes.
deflateCopy
Sets the destination stream as a complete copy of the source stream.
deflateEnd
Deallocates all dynamically allocated data structures for this stream.
deflateInit2_
Initializes the state for compression
deflateInit_
Initializes the state for compression
deflateParams
Dynamically update the compression level and compression strategy.
deflatePending
Returns the number of bytes and bits of output that have been generated, but not yet provided in the available output.
deflatePrime
Inserts bits in the deflate output stream.
deflateReset
This function is equivalent to deflateEnd followed by deflateInit_, but does not free and reallocate the internal compression state.
deflateSetDictionary
Initializes the compression dictionary from the given byte sequence without producing any compressed output.
deflateSetHeader
Provides gzip header information for when a gzip stream is requested by deflateInit2_.
deflateTune
Fine tune deflate’s internal compression parameters.
inflate
Decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full.
inflateBack
Decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full.
inflateBackEnd
Deallocates all dynamically allocated data structures for this stream.
inflateBackInit_
Initializes the state for decompression
inflateCopy
Sets the destination stream as a complete copy of the source stream.
inflateEnd
Deallocates all dynamically allocated data structures for this stream.
inflateGetHeader
Requests that gzip header information be stored in the provided gz_header structure.
inflateInit2_
Initializes the state for decompression
inflateInit_
Initializes the state for decompression
inflateMark
Gives information about the current location of the input stream.
inflatePrime
Inserts bits in the inflate input stream.
inflateReset
Equivalent to inflateEnd followed by inflateInit_, but does not free and reallocate the internal decompression state.
inflateReset2
This function is the same as inflateReset, but it also permits changing the wrap and window size requests.
inflateSetDictionary
Initializes the decompression dictionary from the given uncompressed byte sequence.
inflateSync
Skips invalid compressed data until
uncompress
Inflates source into dest, and writes the final inflated size into destLen.
zError
Get the error message for an error. This could be the value returned by e.g. compress or inflate.
zlibVersion
The version of the zlib library.

Type Aliases§

Bytef
alloc_func
free_func
gz_headerp
in_func
out_func
uInt
uLong
uLongf
voidp
voidpc
voidpf
z_off_t
z_streamp