lz4_sys/
lib.rs

1#![no_std]
2extern crate libc;
3
4#[cfg(not(all(
5    target_arch = "wasm32",
6    not(any(target_env = "wasi", target_os = "wasi"))
7)))]
8pub use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
9
10#[cfg(all(
11    target_arch = "wasm32",
12    not(any(target_env = "wasi", target_os = "wasi"))
13))]
14extern crate alloc;
15
16#[cfg(all(
17    target_arch = "wasm32",
18    not(any(target_env = "wasi", target_os = "wasi"))
19))]
20mod wasm_shim;
21
22#[cfg(all(
23    target_arch = "wasm32",
24    not(any(target_env = "wasi", target_os = "wasi"))
25))]
26extern crate std;
27
28#[cfg(all(
29    target_arch = "wasm32",
30    not(any(target_env = "wasi", target_os = "wasi"))
31))]
32pub use std::os::raw::{c_char, c_int, c_uint, c_ulonglong, c_void};
33
34#[cfg(all(
35    target_arch = "wasm32",
36    not(any(target_env = "wasi", target_os = "wasi"))
37))]
38#[allow(non_camel_case_types)]
39pub type size_t = usize;
40
41#[derive(Clone, Copy, Debug)]
42#[repr(C)]
43pub struct LZ4FCompressionContext(pub *mut c_void);
44unsafe impl Send for LZ4FCompressionContext {}
45
46#[derive(Clone, Copy, Debug)]
47#[repr(C)]
48pub struct LZ4FDecompressionContext(pub *mut c_void);
49unsafe impl Send for LZ4FDecompressionContext {}
50
51pub type LZ4FErrorCode = size_t;
52
53#[derive(Clone, Debug)]
54#[repr(u32)]
55pub enum BlockSize {
56    Default = 0, // Default - 64KB
57    Max64KB = 4,
58    Max256KB = 5,
59    Max1MB = 6,
60    Max4MB = 7,
61}
62
63impl BlockSize {
64    pub fn get_size(&self) -> usize {
65        match self {
66            &BlockSize::Default |
67            &BlockSize::Max64KB => 64 * 1024,
68            &BlockSize::Max256KB => 256 * 1024,
69            &BlockSize::Max1MB => 1 * 1024 * 1024,
70            &BlockSize::Max4MB => 4 * 1024 * 1024,
71        }
72    }
73}
74
75#[derive(Clone, Debug)]
76#[repr(u32)]
77pub enum BlockMode {
78    Linked = 0,
79    Independent,
80}
81
82#[derive(Clone, Debug)]
83#[repr(u32)]
84pub enum ContentChecksum {
85    NoChecksum = 0,
86    ChecksumEnabled,
87}
88
89#[derive(Clone, Debug)]
90#[repr(u32)]
91pub enum FrameType {
92    Frame = 0,
93    SkippableFrame,
94}
95
96
97#[derive(Clone, Debug)]
98#[repr(u32)]
99pub enum BlockChecksum {
100    NoBlockChecksum = 0,
101    BlockChecksumEnabled,
102}
103
104#[derive(Debug)]
105#[repr(C)]
106pub struct LZ4FFrameInfo {
107    pub block_size_id: BlockSize,
108    pub block_mode: BlockMode,
109    pub content_checksum_flag: ContentChecksum,
110    pub frame_type: FrameType,
111    pub content_size: c_ulonglong,
112    pub dict_id: c_uint,
113    pub block_checksum_flag: BlockChecksum,
114}
115
116#[derive(Debug)]
117#[repr(C)]
118pub struct LZ4FPreferences {
119    pub frame_info: LZ4FFrameInfo,
120    pub compression_level: c_uint, // 0 == default (fast mode); values above 16 count as 16
121    pub auto_flush: c_uint, // 1 == always flush : reduce need for tmp buffer
122    pub favor_dec_speed: c_uint, // 1 == favor decompression speed over ratio, requires level 10+
123    pub reserved: [c_uint; 3],
124}
125
126#[derive(Debug)]
127#[repr(C)]
128pub struct LZ4FCompressOptions {
129    pub stable_src: c_uint, /* 1 == src content will remain available on future calls
130                             * to LZ4F_compress(); avoid saving src content within tmp
131                             * buffer as future dictionary */
132    pub reserved: [c_uint; 3],
133}
134
135#[derive(Debug)]
136#[repr(C)]
137pub struct LZ4FDecompressOptions {
138    pub stable_dst: c_uint, /* guarantee that decompressed data will still be there on next
139                             * function calls (avoid storage into tmp buffers) */
140    pub reserved: [c_uint; 3],
141}
142
143#[derive(Debug)]
144#[repr(C)]
145pub struct LZ4StreamEncode(c_void);
146
147#[derive(Debug)]
148#[repr(C)]
149pub struct LZ4StreamDecode(c_void);
150
151pub const LZ4F_VERSION: c_uint = 100;
152
153extern "C" {
154
155    // int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
156    #[allow(non_snake_case)]
157    pub fn LZ4_compress_default (source: *const c_char, dest: *mut c_char, sourceSize: c_int, maxDestSize: c_int) -> c_int;
158
159    // int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
160    #[allow(non_snake_case)]
161    pub fn LZ4_compress_fast (source: *const c_char, dest: *mut c_char, sourceSize: c_int, maxDestSize: c_int, acceleration: c_int) -> c_int;
162
163    // int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
164    #[allow(non_snake_case)]
165    pub fn LZ4_compress_HC (src: *const c_char, dst: *mut c_char, srcSize: c_int, dstCapacity: c_int, compressionLevel: c_int) -> c_int;
166
167    // int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
168    #[allow(non_snake_case)]
169    pub fn LZ4_decompress_safe (source: *const c_char, dest: *mut c_char, compressedSize: c_int, maxDecompressedSize: c_int) -> c_int;
170
171    // unsigned    LZ4F_isError(LZ4F_errorCode_t code);
172    pub fn LZ4F_isError(code: size_t) -> c_uint;
173
174    // const char* LZ4F_getErrorName(LZ4F_errorCode_t code);
175    pub fn LZ4F_getErrorName(code: size_t) -> *const c_char;
176
177    // LZ4F_createCompressionContext() :
178    // The first thing to do is to create a compressionContext object, which will be used in all
179    // compression operations.
180    // This is achieved using LZ4F_createCompressionContext(), which takes as argument a version
181    // and an LZ4F_preferences_t structure.
182    // The version provided MUST be LZ4F_VERSION. It is intended to track potential version
183    // differences between different binaries.
184    // The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object.
185    // If the result LZ4F_errorCode_t is not zero, there was an error during context creation.
186    // Object can release its memory using LZ4F_freeCompressionContext();
187    //
188    // LZ4F_errorCode_t LZ4F_createCompressionContext(
189    //                                   LZ4F_compressionContext_t* LZ4F_compressionContextPtr,
190    //                                   unsigned version);
191    pub fn LZ4F_createCompressionContext(ctx: &mut LZ4FCompressionContext,
192                                         version: c_uint)
193                                         -> LZ4FErrorCode;
194
195    // LZ4F_errorCode_t LZ4F_freeCompressionContext(
196    //                                  LZ4F_compressionContext_t LZ4F_compressionContext);
197    pub fn LZ4F_freeCompressionContext(ctx: LZ4FCompressionContext) -> LZ4FErrorCode;
198
199    // LZ4F_compressBegin() :
200    // will write the frame header into dstBuffer.
201    // dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header
202    // size is 19 bytes.
203    // The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all
204    // preferences will then be set to default.
205    // The result of the function is the number of bytes written into dstBuffer for the header
206    // or an error code (can be tested using LZ4F_isError())
207    //
208    // size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext,
209    //                           void* dstBuffer,
210    //                           size_t dstMaxSize,
211    //                           const LZ4F_preferences_t* preferencesPtr);
212    pub fn LZ4F_compressBegin(ctx: LZ4FCompressionContext,
213                              dstBuffer: *mut u8,
214                              dstMaxSize: size_t,
215                              preferencesPtr: *const LZ4FPreferences)
216                              -> LZ4FErrorCode;
217
218    // LZ4F_compressBound() :
219    // Provides the minimum size of Dst buffer given srcSize to handle worst case situations.
220    // preferencesPtr is optional : you can provide NULL as argument, all preferences will then
221    // be set to default.
222    // Note that different preferences will produce in different results.
223    //
224    // size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
225    pub fn LZ4F_compressBound(srcSize: size_t,
226                              preferencesPtr: *const LZ4FPreferences)
227                              -> LZ4FErrorCode;
228
229    // LZ4F_compressUpdate()
230    // LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
231    // The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure
232    // compression completion even in worst case.
233    // If this condition is not respected, LZ4F_compress() will fail (result is an errorCode)
234    // You can get the minimum value of dstMaxSize by using LZ4F_compressBound()
235    // The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
236    // The result of the function is the number of bytes written into dstBuffer : it can be zero,
237    // meaning input data was just buffered.
238    // The function outputs an error code if it fails (can be tested using LZ4F_isError())
239    //
240    // size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext,
241    //                            void* dstBuffer,
242    //                            size_t dstMaxSize,
243    //                            const void* srcBuffer,
244    //                            size_t srcSize,
245    //                            const LZ4F_compressOptions_t* compressOptionsPtr);
246    pub fn LZ4F_compressUpdate(ctx: LZ4FCompressionContext,
247                               dstBuffer: *mut u8,
248                               dstMaxSize: size_t,
249                               srcBuffer: *const u8,
250                               srcSize: size_t,
251                               compressOptionsPtr: *const LZ4FCompressOptions)
252                               -> size_t;
253
254    // LZ4F_flush()
255    // Should you need to create compressed data immediately, without waiting for a block
256    // to be be filled, you can call LZ4_flush(), which will immediately compress any remaining
257    // data buffered within compressionContext.
258    // The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
259    // The result of the function is the number of bytes written into dstBuffer
260    // (it can be zero, this means there was no data left within compressionContext)
261    // The function outputs an error code if it fails (can be tested using LZ4F_isError())
262    //
263    // size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext,
264    //                   void* dstBuffer,
265    //                   size_t dstMaxSize,
266    //                   const LZ4F_compressOptions_t* compressOptionsPtr);
267    pub fn LZ4F_flush(ctx: LZ4FCompressionContext,
268                      dstBuffer: *mut u8,
269                      dstMaxSize: size_t,
270                      compressOptionsPtr: *const LZ4FCompressOptions)
271                      -> LZ4FErrorCode;
272
273    // LZ4F_compressEnd()
274    // When you want to properly finish the compressed frame, just call LZ4F_compressEnd().
275    // It will flush whatever data remained within compressionContext (like LZ4_flush())
276    // but also properly finalize the frame, with an endMark and a checksum.
277    // The result of the function is the number of bytes written into dstBuffer
278    // (necessarily >= 4 (endMark size))
279    // The function outputs an error code if it fails (can be tested using LZ4F_isError())
280    // The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
281    // compressionContext can then be used again, starting with LZ4F_compressBegin().
282    //
283    // size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext,
284    //                         void* dstBuffer,
285    //                         size_t dstMaxSize,
286    //                         const LZ4F_compressOptions_t* compressOptionsPtr);
287    pub fn LZ4F_compressEnd(ctx: LZ4FCompressionContext,
288                            dstBuffer: *mut u8,
289                            dstMaxSize: size_t,
290                            compressOptionsPtr: *const LZ4FCompressOptions)
291                            -> LZ4FErrorCode;
292
293    // LZ4F_createDecompressionContext() :
294    // The first thing to do is to create a decompressionContext object, which will be used
295    // in all decompression operations.
296    // This is achieved using LZ4F_createDecompressionContext().
297    // The version provided MUST be LZ4F_VERSION. It is intended to track potential version
298    // differences between different binaries.
299    // The function will provide a pointer to a fully allocated and initialized
300    // LZ4F_decompressionContext_t object.
301    // If the result LZ4F_errorCode_t is not OK_NoError, there was an error during
302    // context creation.
303    // Object can release its memory using LZ4F_freeDecompressionContext();
304    //
305    // LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* ctxPtr,
306    //                                                  unsigned version);
307    pub fn LZ4F_createDecompressionContext(ctx: &mut LZ4FDecompressionContext,
308                                           version: c_uint)
309                                           -> LZ4FErrorCode;
310
311    // LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t ctx);
312    pub fn LZ4F_freeDecompressionContext(ctx: LZ4FDecompressionContext) -> LZ4FErrorCode;
313
314    // LZ4F_getFrameInfo()
315    // This function decodes frame header information, such as blockSize.
316    // It is optional : you could start by calling directly LZ4F_decompress() instead.
317    // The objective is to extract header information without starting decompression, typically
318    // for allocation purposes.
319    // LZ4F_getFrameInfo() can also be used *after* starting decompression, on a
320    // valid LZ4F_decompressionContext_t.
321    // The number of bytes read from srcBuffer will be provided within *srcSizePtr
322    // (necessarily <= original value).
323    // You are expected to resume decompression from where it stopped (srcBuffer + *srcSizePtr)
324    // The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for
325    // next call, or an error code which can be tested using LZ4F_isError().
326    //
327    // size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t ctx,
328    // 					LZ4F_frameInfo_t* frameInfoPtr,
329    // 					const void* srcBuffer, size_t* srcSizePtr);
330    pub fn LZ4F_getFrameInfo(ctx: LZ4FDecompressionContext,
331                             frameInfoPtr: &mut LZ4FFrameInfo,
332                             srcBuffer: *const u8,
333                             srcSizePtr: &mut size_t)
334                             -> LZ4FErrorCode;
335
336    // LZ4F_decompress()
337    // Call this function repetitively to regenerate data compressed within srcBuffer.
338    // The function will attempt to decode *srcSizePtr bytes from srcBuffer, into dstBuffer of
339    // maximum size *dstSizePtr.
340    //
341    // The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr
342    // (necessarily <= original value).
343    //
344    // The number of bytes read from srcBuffer will be provided within *srcSizePtr
345    // (necessarily <= original value).
346    // If number of bytes read is < number of bytes provided, then decompression operation
347    // is not completed. It typically happens when dstBuffer is not large enough to contain
348    // all decoded data.
349    // LZ4F_decompress() must be called again, starting from where it stopped
350    // (srcBuffer + *srcSizePtr)
351    // The function will check this condition, and refuse to continue if it is not respected.
352    //
353    // dstBuffer is supposed to be flushed between each call to the function, since its content
354    // will be overwritten.
355    // dst arguments can be changed at will with each consecutive call to the function.
356    //
357    // The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for
358    // next call.
359    // Schematically, it's the size of the current (or remaining) compressed block + header of
360    // next block.
361    // Respecting the hint provides some boost to performance, since it does skip intermediate
362    // buffers.
363    // This is just a hint, you can always provide any srcSize you want.
364    // When a frame is fully decoded, the function result will be 0. (no more data expected)
365    // If decompression failed, function result is an error code, which can be tested
366    // using LZ4F_isError().
367    //
368    // size_t LZ4F_decompress(LZ4F_decompressionContext_t ctx,
369    //                        void* dstBuffer, size_t* dstSizePtr,
370    //                        const void* srcBuffer, size_t* srcSizePtr,
371    //                        const LZ4F_decompressOptions_t* optionsPtr);
372    pub fn LZ4F_decompress(ctx: LZ4FDecompressionContext,
373                           dstBuffer: *mut u8,
374                           dstSizePtr: &mut size_t,
375                           srcBuffer: *const u8,
376                           srcSizePtr: &mut size_t,
377                           optionsPtr: *const LZ4FDecompressOptions)
378                           -> LZ4FErrorCode;
379
380    // int LZ4_versionNumber(void)
381    pub fn LZ4_versionNumber() -> c_int;
382
383    // int LZ4_compressBound(int isize)
384    pub fn LZ4_compressBound(size: c_int) -> c_int;
385
386    // LZ4_stream_t* LZ4_createStream(void)
387    pub fn LZ4_createStream() -> *mut LZ4StreamEncode;
388
389    // int LZ4_compress_continue(LZ4_stream_t* LZ4_streamPtr,
390    //                           const char* source,
391    //                           char* dest,
392    //                           int inputSize)
393    pub fn LZ4_compress_continue(LZ4_stream: *mut LZ4StreamEncode,
394                                 source: *const u8,
395                                 dest: *mut u8,
396                                 input_size: c_int)
397                                 -> c_int;
398
399    // int LZ4_freeStream(LZ4_stream_t* LZ4_streamPtr)
400    pub fn LZ4_freeStream(LZ4_stream: *mut LZ4StreamEncode) -> c_int;
401
402    // int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode,
403    //                          const char* dictionary,
404    //                          int dictSize)
405    pub fn LZ4_setStreamDecode(LZ4_stream: *mut LZ4StreamDecode,
406                               dictionary: *const u8,
407                               dict_size: c_int)
408                               -> c_int;
409
410    // LZ4_streamDecode_t* LZ4_createStreamDecode(void)
411    pub fn LZ4_createStreamDecode() -> *mut LZ4StreamDecode;
412
413    // int LZ4_decompress_safe_continue(LZ4_streamDecode_t* LZ4_streamDecode,
414    //                                  const char* source,
415    //                                  char* dest,
416    //                                  int compressedSize,
417    //                                  int maxDecompressedSize)
418    pub fn LZ4_decompress_safe_continue(LZ4_stream: *mut LZ4StreamDecode,
419                                        source: *const u8,
420                                        dest: *mut u8,
421                                        compressed_size: c_int,
422                                        max_decompressed_size: c_int)
423                                        -> c_int;
424
425    // int LZ4_freeStreamDecode(LZ4_streamDecode_t* LZ4_stream)
426    pub fn LZ4_freeStreamDecode(LZ4_stream: *mut LZ4StreamDecode) -> c_int;
427
428    // LZ4F_resetDecompressionContext()
429    // In case of an error, the context is left in "undefined" state.
430    // In which case, it's necessary to reset it, before re-using it.
431    // This method can also be used to abruptly stop any unfinished decompression,
432    // and start a new one using same context resources.
433    pub fn LZ4F_resetDecompressionContext(ctx: LZ4FDecompressionContext);
434
435}
436
437#[test]
438fn test_version_number() {
439    unsafe { LZ4_versionNumber(); }
440}
441
442#[test]
443fn test_frame_info_size() {
444    assert_eq!(core::mem::size_of::<LZ4FFrameInfo>(), 32);
445}