cloudflare_zlib_sys/
lib.rs

1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3//! It requires x86-64 CPU with SSE 4.2 or ARM64 with NEON & CRC.
4
5use std::os::raw::*;
6
7pub type alloc_func = unsafe extern "C" fn(voidpf, uInt, uInt) -> voidpf;
8pub type Bytef = u8;
9pub type free_func = unsafe extern "C" fn(voidpf, voidpf);
10pub type gzFile = *mut gzFile_s;
11pub type in_func = unsafe extern "C" fn(*mut c_void, *mut *const c_uchar) -> c_uint;
12pub type out_func = unsafe extern "C" fn(*mut c_void, *mut c_uchar, c_uint) -> c_int;
13pub type uInt = u32; // zconf.h says so
14pub type uLong = u64; // zconf.h says so
15pub type uLongf = uLong;
16pub type voidp = *mut c_void;
17pub type voidpc = *const c_void;
18pub type voidpf = *mut c_void;
19
20pub enum gzFile_s {}
21pub enum internal_state {}
22
23pub type z_off_t = isize;
24
25pub const ZLIB_VERSION: &[u8] = b"1.2.8";
26
27pub unsafe fn deflateInit2(strm: z_streamp, level: c_int, method: c_int, window_bits: c_int, mem_level: c_int, strategy: c_int) -> c_int {
28    deflateInit2_(strm, level, method, window_bits, mem_level, strategy, ZLIB_VERSION.as_ptr() as *const _, ::std::mem::size_of::<z_stream>() as c_int)
29}
30
31pub unsafe fn deflateInit(strm: z_streamp, level: c_int) -> c_int {
32    deflateInit_(strm, level, ZLIB_VERSION.as_ptr() as *const _, ::std::mem::size_of::<z_stream>() as c_int)
33}
34
35pub unsafe fn inflateInit(strm: z_streamp) -> c_int {
36    inflateInit_(strm, ZLIB_VERSION.as_ptr() as *const _, ::std::mem::size_of::<z_stream>() as c_int)
37}
38
39pub unsafe fn inflateInit2(strm: z_streamp, window_bits: c_int) -> c_int {
40    inflateInit2_(strm, window_bits, ZLIB_VERSION.as_ptr() as *const _, ::std::mem::size_of::<z_stream>() as c_int)
41}
42
43pub unsafe fn inflateBackInit(strm: z_streamp, window_bits: c_int, window: *mut c_uchar) -> c_int {
44    inflateBackInit_(strm, window_bits, window, ZLIB_VERSION.as_ptr() as *const _, ::std::mem::size_of::<z_stream>() as c_int)
45}
46
47#[repr(C)]
48#[derive(Copy, Clone)]
49pub struct gz_header {
50    pub text: c_int,
51    pub time: uLong,
52    pub xflags: c_int,
53    pub os: c_int,
54    pub extra: *mut Bytef,
55    pub extra_len: uInt,
56    pub extra_max: uInt,
57    pub name: *mut Bytef,
58    pub name_max: uInt,
59    pub comment: *mut Bytef,
60    pub comm_max: uInt,
61    pub hcrc: c_int,
62    pub done: c_int,
63}
64pub type gz_headerp = *mut gz_header;
65
66#[repr(C)]
67#[derive(Copy, Clone)]
68pub struct z_stream {
69    pub next_in: *mut Bytef,
70    pub avail_in: uInt,
71    pub total_in: uLong,
72    pub next_out: *mut Bytef,
73    pub avail_out: uInt,
74    pub total_out: uLong,
75    pub msg: *mut c_char,
76    pub state: *mut internal_state,
77    pub zalloc: Option<alloc_func>,
78    pub zfree: Option<free_func>,
79    pub opaque: voidpf,
80    pub data_type: c_int,
81    pub adler: uLong,
82    pub reserved: uLong,
83}
84pub type z_streamp = *mut z_stream;
85
86extern "C" {
87    pub fn adler32(adler: uLong, buf: *const Bytef, len: uInt) -> uLong;
88    pub fn adler32_combine(adler1: uLong, adler2: uLong, len2: z_off_t) -> uLong;
89    pub fn compress(dest: *mut Bytef, destLen: *mut uLongf, source: *const Bytef, sourceLen: uLong) -> c_int;
90    pub fn compress2(dest: *mut Bytef, destLen: *mut uLongf, source: *const Bytef, sourceLen: uLong, level: c_int) -> c_int;
91    pub fn compressBound(sourceLen: uLong) -> uLong;
92    pub fn crc32(crc: uLong, buf: *const Bytef, len: uInt) -> uLong;
93    pub fn crc32_combine(crc1: uLong, crc2: uLong, len2: z_off_t) -> uLong;
94    pub fn deflate(strm: z_streamp, flush: c_int) -> c_int;
95    pub fn deflateBound(strm: z_streamp, sourceLen: uLong) -> uLong;
96    pub fn deflateCopy(dest: z_streamp, source: z_streamp) -> c_int;
97    pub fn deflateEnd(strm: z_streamp) -> c_int;
98    pub fn deflateInit2_(strm: z_streamp, level: c_int, method: c_int, windowBits: c_int, memLevel: c_int, strategy: c_int, version: *const c_char, stream_size: c_int) -> c_int;
99    pub fn deflateInit_(strm: z_streamp, level: c_int, version: *const c_char, stream_size: c_int) -> c_int;
100    pub fn deflateParams(strm: z_streamp, level: c_int, strategy: c_int) -> c_int;
101    pub fn deflatePending(strm: z_streamp, pending: *mut c_uint, bits: *mut c_int) -> c_int;
102    pub fn deflatePrime(strm: z_streamp, bits: c_int, value: c_int) -> c_int;
103    pub fn deflateReset(strm: z_streamp) -> c_int;
104    pub fn deflateResetKeep(arg1: z_streamp) -> c_int;
105    pub fn deflateSetDictionary(strm: z_streamp, dictionary: *const Bytef, dictLength: uInt) -> c_int;
106    pub fn deflateSetHeader(strm: z_streamp, head: gz_headerp) -> c_int;
107    pub fn deflateTune(strm: z_streamp, good_length: c_int, max_lazy: c_int, nice_length: c_int, max_chain: c_int) -> c_int;
108    pub fn gzclearerr(file: gzFile);
109    pub fn gzclose(file: gzFile) -> c_int;
110    pub fn gzdirect(file: gzFile) -> c_int;
111    pub fn gzdopen(fd: c_int, mode: *const c_char) -> gzFile;
112    pub fn gzeof(file: gzFile) -> c_int;
113    pub fn gzerror(file: gzFile, errnum: *mut c_int) -> *const c_char;
114    pub fn gzflush(file: gzFile, flush: c_int) -> c_int;
115    pub fn gzgetc(file: gzFile) -> c_int;
116    pub fn gzgets(file: gzFile, buf: *mut c_char, len: c_int) -> *mut c_char;
117    pub fn gzopen(path: *const c_char, mode: *const c_char) -> gzFile;
118    pub fn gzoffset(arg1: gzFile) -> c_long;
119    pub fn gzputc(file: gzFile, c: c_int) -> c_int;
120    pub fn gzputs(file: gzFile, s: *const c_char) -> c_int;
121    pub fn gzread(file: gzFile, buf: voidp, len: c_uint) -> c_int;
122    pub fn gzrewind(file: gzFile) -> c_int;
123    pub fn gzseek(file: gzFile, offset: z_off_t, whence: c_int) -> z_off_t;
124    pub fn gzsetparams(file: gzFile, level: c_int, strategy: c_int) -> c_int;
125    pub fn gztell(file: gzFile) -> z_off_t;
126    pub fn gzungetc(c: c_int, file: gzFile) -> c_int;
127    pub fn gzwrite(file: gzFile, buf: voidpc, len: c_uint) -> c_int;
128    pub fn inflate(strm: z_streamp, flush: c_int) -> c_int;
129    pub fn inflateBack(strm: z_streamp, _in: in_func, in_desc: *mut c_void, out: out_func, out_desc: *mut c_void) -> c_int;
130    pub fn inflateBackEnd(strm: z_streamp) -> c_int;
131    pub fn inflateBackInit_(strm: z_streamp, windowBits: c_int, window: *mut c_uchar, version: *const c_char, stream_size: c_int) -> c_int;
132    pub fn inflateCopy(dest: z_streamp, source: z_streamp) -> c_int;
133    pub fn inflateEnd(strm: z_streamp) -> c_int;
134    pub fn inflateGetDictionary(strm: z_streamp, dictionary: *mut Bytef, dictLength: *mut uInt) -> c_int;
135    pub fn inflateGetHeader(strm: z_streamp, head: gz_headerp) -> c_int;
136    pub fn inflateInit2_(strm: z_streamp, windowBits: c_int, version: *const c_char, stream_size: c_int) -> c_int;
137    pub fn inflateInit_(strm: z_streamp, version: *const c_char, stream_size: c_int) -> c_int;
138    pub fn inflateMark(strm: z_streamp) -> c_long;
139    pub fn inflatePrime(strm: z_streamp, bits: c_int, value: c_int) -> c_int;
140    pub fn inflateReset(strm: z_streamp) -> c_int;
141    pub fn inflateReset2(strm: z_streamp, windowBits: c_int) -> c_int;
142    pub fn inflateResetKeep(arg1: z_streamp) -> c_int;
143    pub fn inflateSetDictionary(strm: z_streamp, dictionary: *const Bytef, dictLength: uInt) -> c_int;
144    pub fn inflateSync(strm: z_streamp) -> c_int;
145    pub fn inflateSyncPoint(arg1: z_streamp) -> c_int;
146    pub fn inflateUndermine(arg1: z_streamp, arg2: c_int) -> c_int;
147    pub fn inflateValidate(arg1: z_streamp, arg2: c_int) -> c_int;
148    pub fn uncompress(dest: *mut Bytef, destLen: *mut uLongf, source: *const Bytef, sourceLen: uLong) -> c_int;
149    pub fn uncompress2(dest: *mut Bytef, destLen: *mut uLongf, source: *const Bytef, sourceLen: *mut uLong) -> c_int;
150    pub fn zError(arg1: c_int) -> *const c_char;
151    pub fn zlibCompileFlags() -> uLong;
152    pub fn zlibVersion() -> *const c_char;
153}
154
155pub const Z_NO_FLUSH: c_int = 0;
156pub const Z_PARTIAL_FLUSH: c_int = 1;
157pub const Z_SYNC_FLUSH: c_int = 2;
158pub const Z_FULL_FLUSH: c_int = 3;
159pub const Z_FINISH: c_int = 4;
160pub const Z_BLOCK: c_int = 5;
161pub const Z_TREES: c_int = 6;
162
163pub const Z_OK: c_int = 0;
164pub const Z_STREAM_END: c_int = 1;
165pub const Z_NEED_DICT: c_int = 2;
166pub const Z_ERRNO: c_int = -1;
167pub const Z_STREAM_ERROR: c_int = -2;
168pub const Z_DATA_ERROR: c_int = -3;
169pub const Z_MEM_ERROR: c_int = -4;
170pub const Z_BUF_ERROR: c_int = -5;
171pub const Z_VERSION_ERROR: c_int = -6;
172
173pub const Z_NO_COMPRESSION: c_int = 0;
174pub const Z_BEST_SPEED: c_int = 1;
175pub const Z_BEST_COMPRESSION: c_int = 9;
176pub const Z_DEFAULT_COMPRESSION: c_int = -1;
177
178pub const Z_FILTERED: c_int = 1;
179pub const Z_HUFFMAN_ONLY: c_int = 2;
180pub const Z_RLE: c_int = 3;
181pub const Z_FIXED: c_int = 4;
182pub const Z_DEFAULT_STRATEGY: c_int = 0;
183
184pub const Z_BINARY: c_int = 0;
185pub const Z_TEXT: c_int = 1;
186pub const Z_ASCII: c_int = Z_TEXT;
187pub const Z_UNKNOWN: c_int = 2;
188
189pub const Z_DEFLATED: c_int = 8;
190pub const MAX_MEM_LEVEL: c_int = 8;
191pub const DEF_MEM_LEVEL: c_int = 8;
192
193#[cfg(test)]
194mod test {
195    use super::*;
196
197    #[test]
198    fn test_files() {
199        for i in 1..=1 {
200            assert_roundtrips(&std::fs::read(format!("rust/test_files/test{i}")).unwrap());
201        }
202    }
203
204    #[test]
205    fn test_synthetic() {
206        assert_roundtrips(&[0; 0]);
207        assert_roundtrips(&[0; 1]);
208        assert_roundtrips(&[0; 10]);
209        assert_roundtrips(&vec![0; 1000]);
210        assert_roundtrips(&[0xff; 1]);
211        assert_roundtrips(&[0xff; 2]);
212        assert_roundtrips(&[0xff; 3]);
213    }
214
215    #[test]
216    fn test_compress() {
217        let source = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
218tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
219quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
220consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
221cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
222proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
223        assert_eq!(446, source.len());
224        let compressed = assert_roundtrips(source.as_bytes());
225        assert_eq!(271, compressed.len());
226    }
227
228    fn assert_roundtrips(source: &[u8]) -> Vec<u8> {
229        let mut gzbuf = Vec::with_capacity(100 + source.len());
230        let mut gzbuf_len = gzbuf.capacity() as uLong;
231        unsafe {
232            assert_eq!(0, compress2(gzbuf.as_mut_ptr(), &mut gzbuf_len, source.as_ptr(), source.len() as uLong, Z_BEST_COMPRESSION));
233            gzbuf.set_len(gzbuf_len as usize);
234        }
235
236        let mut ungzbuf = vec![0x55; 100 + source.len()];
237        let mut ungzbuf_len = source.len() as uLong;
238        unsafe {
239            assert_eq!(0, uncompress(ungzbuf.as_mut_ptr(), &mut ungzbuf_len, gzbuf.as_ptr(), gzbuf.len() as uLong));
240        }
241        let (ungzipped, rest) = ungzbuf.split_at(source.len());
242        assert_eq!(source, ungzipped);
243        rest.iter().for_each(|&x| assert_eq!(x, 0x55));
244        gzbuf
245    }
246}