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