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}