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}