Skip to content

Commit d235075

Browse files
committedNov 7, 2021
fix(miniz_oxide_c_api): Add missing funcs, tweak types/functions to make cbindgen work-ish
1 parent 94411d7 commit d235075

28 files changed

+9697
-7928
lines changed
 

‎benches/bench.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ macro_rules! compress_bench {
8383
}
8484

8585
mod oxide {
86-
use miniz_oxide_c_api::{tdefl_compress_mem_to_heap, tinfl_decompress_mem_to_heap};
8786
use super::*;
87+
use miniz_oxide_c_api::{tdefl_compress_mem_to_heap, tinfl_decompress_mem_to_heap};
8888

8989
compress_bench!(
9090
compress_short_lvl_1,
@@ -221,8 +221,8 @@ mod oxide {
221221
}
222222

223223
mod miniz {
224-
use libc::{c_int, c_void};
225224
use super::*;
225+
use libc::{c_int, c_void};
226226

227227
/// Functions from miniz
228228
/// We add the link attribute to make sure

‎cbindgen.toml

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
header = """/* This library (excluding the miniz C code used for tests) is licensed under the MIT license. The library is based on the miniz C library, of which the parts used are dual-licensed under the MIT license and also the unlicense. The parts of miniz that are not covered by the unlicense is some Zip64 code which is only MIT licensed. This and other Zip functionality in miniz is not part of the miniz_oxidde and miniz_oxide_c_api rust libraries."""
1+
header = """/* This library (excluding the miniz C code used for tests) is licensed under the MIT license. The library is based on the miniz C library, of which the parts used are dual-licensed under the MIT license and also the unlicense. The parts of miniz that are not covered by the unlicense is some Zip64 code which is only MIT licensed. This and other Zip functionality in miniz is not part of the miniz_oxidde and miniz_oxide_c_api rust libraries.*/"""
22
autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
33
* To generate this file:
44
* 1. Get the latest cbindgen using `cargo install --force cbindgen`
@@ -7,13 +7,22 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi
77
*/"""
88
include_version = true
99
language = "C"
10+
includes = ["miniz_extra_defs.h"]
11+
# An optional name to use as an include guard
12+
# default: doesn't emit an include guard
13+
# include_guard = "MINIZ_OXIDE_INCLUDED"
14+
15+
# Whether to add a `#pragma once` guard
16+
# default: doesn't emit a `#pragma once`
17+
pragma_once = true
18+
cpp_compat = true
1019

1120
[export]
12-
include = ["CAPIReturnStatus", "CAPIFlush", "CAPICompressionStrategy"]
21+
include = ["CAPIReturnStatus", "CAPIFlush", "CAPICompressionStrategy", "CAPICompressionLevel", "mz_alloc_func", "mz_free_func", "mz_realloc_func", "tinfl_status", "tdefl_flush"]
1322

1423
[export.rename]
15-
"DecompressorOxide" = "tinfl_decompressor"
16-
"Compressor" = "tinfl_compressor"
24+
# "DecompressorOxide" = "tinfl_decompressor"
25+
"Compressor" = "tdefl_compressor"
1726

1827
[parse]
1928
# Whether to parse dependent crates and include their types in the output

‎clippy.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
msrv = "1.40.0"

‎examples/example1.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// example1.c - Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's).
22
// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
33
#include <stdio.h>
4-
#include "miniz.h"
4+
#include "miniz_test.h"
55
typedef unsigned char uint8;
66
typedef unsigned short uint16;
77
typedef unsigned int uint;

‎examples/example5.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ static uint8 s_outbuf[OUT_BUF_SIZE];
3939

4040
// tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k).
4141
// This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it.
42-
tdefl_compressor g_deflator;
42+
// NOTE: miniz_oxide: changed to dynamic alloc for now, TODO: See whether we will support alloc on stack or not.
43+
// tdefl_compressor g_deflator;
4344

4445
int main(int argc, char *argv[])
4546
{
@@ -165,7 +166,8 @@ int main(int argc, char *argv[])
165166
comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
166167

167168
// Initialize the low-level compressor.
168-
status = tdefl_init(&g_deflator, NULL, NULL, comp_flags);
169+
tdefl_compressor* g_deflator = tdefl_allocate();
170+
status = tdefl_init(g_deflator, NULL, NULL, comp_flags);
169171
if (status != TDEFL_STATUS_OKAY)
170172
{
171173
printf("tdefl_init() failed!\n");
@@ -200,7 +202,7 @@ int main(int argc, char *argv[])
200202
in_bytes = avail_in;
201203
out_bytes = avail_out;
202204
// Compress as much of the input as possible (or all of it) to the output buffer.
203-
status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
205+
status = tdefl_compress(g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
204206

205207
next_in = (const char *)next_in + in_bytes;
206208
avail_in -= in_bytes;
@@ -235,6 +237,7 @@ int main(int argc, char *argv[])
235237
return EXIT_FAILURE;
236238
}
237239
}
240+
tdefl_deallocate(g_deflator);
238241
}
239242
else if ((pMode[0] == 'd') || (pMode[0] == 'D'))
240243
{

‎miniz.h

+494-451
Large diffs are not rendered by default.

‎miniz/ChangeLog.md

+196
Large diffs are not rendered by default.

‎miniz/LICENSE

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright 2013-2014 RAD Game Tools and Valve Software
2+
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
3+
4+
All Rights Reserved.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.

‎miniz/miniz.c

+7,139-8
Large diffs are not rendered by default.

‎miniz/miniz.h

+1,350
Large diffs are not rendered by default.

‎miniz/miniz_tdef.c

-1,561
This file was deleted.

‎miniz/miniz_tinfl.c

-733
This file was deleted.

‎miniz/miniz_zip.c

-4,661
This file was deleted.

‎miniz/readme.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
## Miniz
2+
3+
Miniz is a lossless, high performance data compression library in a single source file that implements the zlib (RFC 1950) and Deflate (RFC 1951) compressed data format specification standards. It supports the most commonly used functions exported by the zlib library, but is a completely independent implementation so zlib's licensing requirements do not apply. Miniz also contains simple to use functions for writing .PNG format image files and reading/writing/appending .ZIP format archives. Miniz's compression speed has been tuned to be comparable to zlib's, and it also has a specialized real-time compressor function designed to compare well against fastlz/minilzo.
4+
5+
## Usage
6+
7+
Please use the files from the [releases page](https://github.com/richgel999/miniz/releases) in your projects. Do not use the git checkout directly! The different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) into one `miniz.c`/`miniz.h` pair in a build step (`amalgamate.sh`). Include `miniz.c` and `miniz.h` in your project to use Miniz.
8+
9+
## Features
10+
11+
* MIT licensed
12+
* A portable, single source and header file library written in plain C. Tested with GCC, clang and Visual Studio.
13+
* Easily tuned and trimmed down by defines
14+
* A drop-in replacement for zlib's most used API's (tested in several open source projects that use zlib, such as libpng and libzip).
15+
* Fills a single threaded performance vs. compression ratio gap between several popular real-time compressors and zlib. For example, at level 1, miniz.c compresses around 5-9% better than minilzo, but is approx. 35% slower. At levels 2-9, miniz.c is designed to compare favorably against zlib's ratio and speed. See the miniz performance comparison page for example timings.
16+
* Not a block based compressor: miniz.c fully supports stream based processing using a coroutine-style implementation. The zlib-style API functions can be called a single byte at a time if that's all you've got.
17+
* Easy to use. The low-level compressor (tdefl) and decompressor (tinfl) have simple state structs which can be saved/restored as needed with simple memcpy's. The low-level codec API's don't use the heap in any way.
18+
* Entire inflater (including optional zlib header parsing and Adler-32 checking) is implemented in a single function as a coroutine, which is separately available in a small (~550 line) source file: miniz_tinfl.c
19+
* A fairly complete (but totally optional) set of .ZIP archive manipulation and extraction API's. The archive functionality is intended to solve common problems encountered in embedded, mobile, or game development situations. (The archive API's are purposely just powerful enough to write an entire archiver given a bit of additional higher-level logic.)
20+
21+
## Known Problems
22+
23+
* No support for encrypted archives. Not sure how useful this stuff is in practice.
24+
* Minimal documentation. The assumption is that the user is already familiar with the basic zlib API. I need to write an API wiki - for now I've tried to place key comments before each enum/API, and I've included 6 examples that demonstrate how to use the module's major features.
25+
26+
## Special Thanks
27+
28+
Thanks to Alex Evans for the PNG writer function. Also, thanks to Paul Holden and Thorsten Scheuermann for feedback and testing, Matt Pritchard for all his encouragement, and Sean Barrett's various public domain libraries for inspiration (and encouraging me to write miniz.c in C, which was much more enjoyable and less painful than I thought it would be considering I've been programming in C++ for so long).
29+
30+
Thanks to Bruce Dawson for reporting a problem with the level_and_flags archive API parameter (which is fixed in v1.12) and general feedback, and Janez Zemva for indirectly encouraging me into writing more examples.
31+
32+
## Patents
33+
34+
I was recently asked if miniz avoids patent issues. miniz purposely uses the same core algorithms as the ones used by zlib. The compressor uses vanilla hash chaining as described [here](https://datatracker.ietf.org/doc/html/rfc1951#section-4). Also see the [gzip FAQ](https://web.archive.org/web/20160308045258/http://www.gzip.org/#faq11). In my opinion, if miniz falls prey to a patent attack then zlib/gzip are likely to be at serious risk too.

‎miniz_common.h

-91
This file was deleted.

‎miniz_extra_defs.h

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#pragma once
2+
#include <assert.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
/* ------------------- Types and macros */
8+
typedef unsigned char mz_uint8;
9+
typedef signed short mz_int16;
10+
typedef unsigned short mz_uint16;
11+
typedef unsigned int mz_uint32;
12+
typedef unsigned int mz_uint;
13+
typedef int64_t mz_int64;
14+
typedef uint64_t mz_uint64;
15+
typedef int mz_bool;
16+
17+
#define MZ_VERSION "0.0"
18+
19+
#define MZ_FALSE (0)
20+
#define MZ_TRUE (1)
21+
22+
/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */
23+
#ifdef _MSC_VER
24+
#define MZ_MACRO_END while (0, 0)
25+
#else
26+
#define MZ_MACRO_END while (0)
27+
#endif
28+
29+
#ifdef MINIZ_NO_STDIO
30+
#define MZ_FILE void *
31+
#else
32+
#include <stdio.h>
33+
#define MZ_FILE FILE
34+
#endif /* #ifdef MINIZ_NO_STDIO */
35+
36+
#ifdef MINIZ_NO_TIME
37+
typedef struct mz_dummy_time_t_tag
38+
{
39+
int m_dummy;
40+
} mz_dummy_time_t;
41+
#define MZ_TIME_T mz_dummy_time_t
42+
#else
43+
#define MZ_TIME_T time_t
44+
#endif
45+
46+
#define MZ_ASSERT(x) assert(x)
47+
48+
#ifdef MINIZ_NO_MALLOC
49+
#define MZ_MALLOC(x) NULL
50+
#define MZ_FREE(x) (void)x, ((void)0)
51+
#define MZ_REALLOC(p, x) NULL
52+
#else
53+
#define MZ_MALLOC(x) malloc(x)
54+
#define MZ_FREE(x) free(x)
55+
#define MZ_REALLOC(p, x) realloc(p, x)
56+
#endif
57+
58+
#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
59+
#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
60+
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
61+
62+
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
63+
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
64+
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
65+
#else
66+
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
67+
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
68+
#endif
69+
70+
#define MZ_READ_LE64(p) (((mz_uint64)MZ_READ_LE32(p)) | (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) << 32U))
71+
72+
#ifdef _MSC_VER
73+
#define MZ_FORCEINLINE __forceinline
74+
#elif defined(__GNUC__)
75+
#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__))
76+
#else
77+
#define MZ_FORCEINLINE inline
78+
#endif
79+
80+
#ifdef __cplusplus
81+
extern "C" {
82+
#endif
83+
84+
#define MZ_UINT16_MAX (0xFFFFU)
85+
#define MZ_UINT32_MAX (0xFFFFFFFFU)
86+
87+
/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */
88+
typedef unsigned long mz_ulong;
89+
90+
/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */
91+
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
92+
#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
93+
typedef unsigned char Byte;
94+
typedef unsigned int uInt;
95+
typedef mz_ulong uLong;
96+
typedef Byte Bytef;
97+
typedef uInt uIntf;
98+
typedef char charf;
99+
typedef int intf;
100+
typedef void *voidpf;
101+
typedef uLong uLongf;
102+
typedef void *voidp;
103+
typedef void *const voidpc;
104+
#define Z_NULL 0
105+
#define Z_NO_FLUSH MZ_NO_FLUSH
106+
#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
107+
#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
108+
#define Z_FULL_FLUSH MZ_FULL_FLUSH
109+
#define Z_FINISH MZ_FINISH
110+
#define Z_BLOCK MZ_BLOCK
111+
#define Z_OK MZ_OK
112+
#define Z_STREAM_END MZ_STREAM_END
113+
#define Z_NEED_DICT MZ_NEED_DICT
114+
#define Z_ERRNO MZ_ERRNO
115+
#define Z_STREAM_ERROR MZ_STREAM_ERROR
116+
#define Z_DATA_ERROR MZ_DATA_ERROR
117+
#define Z_MEM_ERROR MZ_MEM_ERROR
118+
#define Z_BUF_ERROR MZ_BUF_ERROR
119+
#define Z_VERSION_ERROR MZ_VERSION_ERROR
120+
#define Z_PARAM_ERROR MZ_PARAM_ERROR
121+
#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
122+
#define Z_BEST_SPEED MZ_BEST_SPEED
123+
#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
124+
#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
125+
#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
126+
#define Z_FILTERED MZ_FILTERED
127+
#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
128+
#define Z_RLE MZ_RLE
129+
#define Z_FIXED MZ_FIXED
130+
#define Z_DEFLATED MZ_DEFLATED
131+
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
132+
#define alloc_func mz_alloc_func
133+
#define free_func mz_free_func
134+
#define internal_state mz_internal_state
135+
#define z_stream mz_stream
136+
#define deflateInit mz_deflateInit
137+
#define deflateInit2 mz_deflateInit2
138+
#define deflateReset mz_deflateReset
139+
#define deflate mz_deflate
140+
#define deflateEnd mz_deflateEnd
141+
#define deflateBound mz_deflateBound
142+
#define compress mz_compress
143+
#define compress2 mz_compress2
144+
#define compressBound mz_compressBound
145+
#define inflateInit mz_inflateInit
146+
#define inflateInit2 mz_inflateInit2
147+
#define inflateReset mz_inflateReset
148+
#define inflate mz_inflate
149+
#define inflateEnd mz_inflateEnd
150+
#define uncompress mz_uncompress
151+
#define uncompress2 mz_uncompress2
152+
#define crc32 mz_crc32
153+
#define adler32 mz_adler32
154+
#define MAX_WBITS 15
155+
#define MAX_MEM_LEVEL 9
156+
#define zError mz_error
157+
#define ZLIB_VERSION MZ_VERSION
158+
#define ZLIB_VERNUM MZ_VERNUM
159+
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
160+
#define ZLIB_VER_MINOR MZ_VER_MINOR
161+
#define ZLIB_VER_REVISION MZ_VER_REVISION
162+
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
163+
#define zlibVersion mz_version
164+
#define zlib_version mz_version()
165+
#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
166+
167+
void mz_free(void *p);
168+
169+
typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
170+
/* Not implemented yet.*/
171+
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
172+
173+
/* Compresses an image to a compressed PNG file in memory. */
174+
/* On entry: */
175+
/* pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. */
176+
/* The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. */
177+
/* level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */
178+
/* If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). */
179+
/* On return: */
180+
/* Function returns a pointer to the compressed data, or NULL on failure. */
181+
/* *pLen_out will be set to the size of the PNG image file. */
182+
/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
183+
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
184+
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
185+
186+
#ifdef __cplusplus
187+
}
188+
#endif

‎miniz_stub/miniz_tdef.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
**************************************************************************/
2626

27-
#include "../miniz_tdef.h"
27+
/* #include "../miniz_tdef.h" */
2828
#include "../miniz.h"
2929

3030
#ifdef __cplusplus
@@ -1481,8 +1481,8 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
14811481
#pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */
14821482
#endif
14831483

1484-
tdefl_compressor* tdefl_allocate();
1485-
void tdefl_deallocate(tdefl_compressor* c);
1484+
/* tdefl_compressor* tdefl_allocate(); */
1485+
/* void tdefl_deallocate(tdefl_compressor* c); */
14861486

14871487
/* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
14881488
http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.

‎miniz_stub/miniz_tinfl.c

+13-12
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
*
2525
**************************************************************************/
2626

27-
#include "../miniz_tinfl.h"
27+
/* #include "../miniz_tinfl.h" */
28+
#include "../miniz.h"
2829

2930
#ifdef __cplusplus
3031
extern "C" {
@@ -724,18 +725,18 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
724725
return result;
725726
}
726727

727-
tinfl_decompressor *tinfl_decompressor_alloc()
728-
{
729-
tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
730-
if (pDecomp)
731-
tinfl_init(pDecomp);
732-
return pDecomp;
733-
}
728+
/* tinfl_decompressor *tinfl_decompressor_alloc() */
729+
/* { */
730+
/* tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor)); */
731+
/* if (pDecomp) */
732+
/* tinfl_init(pDecomp); */
733+
/* return pDecomp; */
734+
/* } */
734735

735-
void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
736-
{
737-
MZ_FREE(pDecomp);
738-
}
736+
/* void tinfl_decompressor_free(tinfl_decompressor *pDecomp) */
737+
/* { */
738+
/* MZ_FREE(pDecomp); */
739+
/* } */
739740

740741
#ifdef __cplusplus
741742
}

‎miniz_stub/miniz_zip.c

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* THE SOFTWARE.
2525
*
2626
**************************************************************************/
27+
#define MINIZ_OXIDE_UNIMPLEMENTED
2728
#include "../miniz_zip.h"
2829

2930
#ifndef MINIZ_NO_ARCHIVE_APIS

‎miniz_tdef.h

-188
This file was deleted.

‎miniz_tinfl.h

-143
This file was deleted.

‎miniz_zip.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
21
#pragma once
2+
#include <time.h>
33
#include "miniz.h"
44

55
/* ------------------- ZIP archive reading/writing */

‎src/build.rs

-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ fn main() {
2121
cc::Build::new()
2222
.files(&[
2323
"miniz/miniz.c",
24-
"miniz/miniz_zip.c",
25-
"miniz/miniz_tinfl.c",
26-
"miniz/miniz_tdef.c",
2724
])
2825
.compile("miniz");
2926
}

‎src/c_export.rs

+40-5
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,32 @@ use std::marker::PhantomData;
33
use std::{ptr, slice};
44

55
pub use crate::tinfl::{
6-
tinfl_decompress, tinfl_decompress_mem_to_heap, tinfl_decompress_mem_to_mem, tinfl_decompressor,
6+
tinfl_decompress, tinfl_decompress_mem_to_heap, tinfl_decompress_mem_to_mem,
7+
tinfl_decompressor, tinfl_status,
78
};
89

9-
use libc::*;
1010
pub use crate::tdef::{
1111
tdefl_allocate, tdefl_compress, tdefl_compress_buffer, tdefl_compress_mem_to_heap,
1212
tdefl_compress_mem_to_mem, tdefl_compress_mem_to_output,
1313
tdefl_create_comp_flags_from_zip_params, tdefl_deallocate, tdefl_get_adler32,
14-
tdefl_get_prev_return_status, tdefl_init,
14+
tdefl_get_prev_return_status, tdefl_init, tdefl_flush,
1515
};
16+
use libc::*;
1617

1718
use crate::lib_oxide::{InternalState, StateType, StateTypeEnum, StreamOxide, MZ_ADLER32_INIT};
1819

1920
use miniz_oxide::{mz_adler32_oxide, MZError};
2021

22+
#[allow(bad_style)]
23+
mod mz_typedefs {
24+
use libc::*;
25+
26+
pub type mz_uint32 = c_uint;
27+
pub type mz_uint = c_uint;
28+
pub type mz_bool = c_int;
29+
}
30+
pub use mz_typedefs::*;
31+
2132
#[allow(bad_style)]
2233
#[repr(C)]
2334
#[derive(PartialEq, Eq)]
@@ -58,6 +69,19 @@ pub enum CAPICompressionStrategy {
5869
MZ_FIXED = 4,
5970
}
6071

72+
/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */
73+
#[allow(bad_style)]
74+
#[repr(C)]
75+
#[derive(PartialEq, Eq)]
76+
pub enum CAPICompressionLevel {
77+
MZ_NO_COMPRESSION = 0,
78+
MZ_BEST_SPEED = 1,
79+
MZ_BEST_COMPRESSION = 9,
80+
MZ_UBER_COMPRESSION = 10,
81+
MZ_DEFAULT_LEVEL = 6,
82+
MZ_DEFAULT_COMPRESSION = -1
83+
}
84+
6185
pub const MZ_CRC32_INIT: c_ulong = 0;
6286

6387
pub fn mz_crc32_oxide(crc32: c_uint, data: &[u8]) -> c_uint {
@@ -73,6 +97,17 @@ pub type mz_alloc_func = unsafe extern "C" fn(*mut c_void, size_t, size_t) -> *m
7397
#[allow(bad_style)]
7498
pub type mz_free_func = unsafe extern "C" fn(*mut c_void, *mut c_void);
7599

100+
#[allow(bad_style)]
101+
pub type mz_realloc_func =
102+
unsafe extern "C" fn(*mut c_void, *mut c_void, size_t, size_t) -> *mut c_void;
103+
104+
#[allow(bad_style)]
105+
pub type mz_alloc_callback =
106+
Option<unsafe extern "C" fn(*mut c_void, size_t, size_t) -> *mut c_void>;
107+
108+
#[allow(bad_style)]
109+
pub type mz_free_callback = Option<unsafe extern "C" fn(*mut c_void, *mut c_void)>;
110+
76111
/// Inner stream state containing pointers to the used buffers and internal state.
77112
#[repr(C)]
78113
#[allow(bad_style)]
@@ -99,10 +134,10 @@ pub struct mz_stream {
99134

100135
/// Allocation function to use for allocating the internal compressor/decompressor.
101136
/// Uses `mz_default_alloc_func` if set to `None`.
102-
pub zalloc: Option<mz_alloc_func>,
137+
pub zalloc: mz_alloc_callback,
103138
/// Free function to use for allocating the internal compressor/decompressor.
104139
/// Uses `mz_default_free_func` if `None`.
105-
pub zfree: Option<mz_free_func>,
140+
pub zfree: mz_free_callback,
106141
/// Extra data to provide the allocation/deallocation functions.
107142
/// (Not used for the default ones)
108143
pub opaque: *mut c_void,

‎src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub use crate::c_export::*;
8282
pub use crate::tdef::Compressor as tdefl_compressor;
8383

8484
pub const MZ_DEFLATED: c_int = 8;
85-
pub const MZ_DEFAULT_WINDOW_BITS: c_int = 15;
85+
pub use miniz_oxide::MZ_DEFAULT_WINDOW_BITS;
8686

8787
fn as_c_return_code(r: MZResult) -> c_int {
8888
match r {
@@ -156,7 +156,7 @@ unmangle!(
156156
match stream.as_mut() {
157157
None => MZError::Stream as c_int,
158158
Some(stream) => {
159-
stream.data_type = StateTypeEnum::Deflate;
159+
stream.data_type = StateTypeEnum::DeflateType;
160160
// Make sure we catch a potential panic, as
161161
// this is called from C.
162162
match catch_unwind(AssertUnwindSafe(|| match StreamOxide::try_new(stream) {
@@ -188,7 +188,7 @@ unmangle!(
188188
match stream.as_mut() {
189189
None => MZError::Stream as c_int,
190190
Some(stream) => {
191-
stream.data_type = StateTypeEnum::Inflate;
191+
stream.data_type = StateTypeEnum::InflateType;
192192
// Make sure we catch a potential panic, as
193193
// this is called from C.
194194
match catch_unwind(AssertUnwindSafe(|| match StreamOxide::try_new(stream) {
@@ -243,7 +243,7 @@ unmangle!(
243243
avail_in: source_len as c_uint,
244244
next_out: dest,
245245
avail_out: (*dest_len) as c_uint,
246-
data_type: StateTypeEnum::Deflate,
246+
data_type: StateTypeEnum::DeflateType,
247247
..Default::default()
248248
};
249249

@@ -281,7 +281,7 @@ unmangle!(
281281
avail_in: source_len as c_uint,
282282
next_out: dest,
283283
avail_out: (*dest_len) as c_uint,
284-
data_type: StateTypeEnum::Inflate,
284+
data_type: StateTypeEnum::InflateType,
285285
..Default::default()
286286
};
287287

‎src/lib_oxide.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ use std::{fmt, mem};
55

66
use libc::c_ulong;
77

8+
use crate::tdef::Compressor;
89
use miniz_oxide::deflate::core::{
910
create_comp_flags_from_zip_params, deflate_flags, CompressionStrategy, CompressorOxide,
1011
};
1112
use miniz_oxide::deflate::stream::deflate;
1213
use miniz_oxide::inflate::stream::{inflate, InflateState};
13-
use crate::tdef::Compressor;
1414

1515
use miniz_oxide::*;
1616

1717
const MZ_DEFLATED: i32 = 8;
1818

19-
pub const MZ_ADLER32_INIT: u32 = 1;
19+
pub use miniz_oxide::MZ_ADLER32_INIT;
2020

21-
#[repr(C)]
2221
pub enum InternalState {
2322
Inflate(Box<InflateState>),
2423
Deflate(Box<Compressor>),
@@ -41,8 +40,8 @@ pub type MZResult = Result<MZStatus, MZError>;
4140
#[derive(Debug, Copy, Clone, PartialEq)]
4241
pub enum StateTypeEnum {
4342
None = 0,
44-
Inflate,
45-
Deflate,
43+
InflateType,
44+
DeflateType,
4645
}
4746

4847
/// Trait used for states that can be carried by BoxedState.
@@ -52,7 +51,7 @@ pub trait StateType {
5251
}
5352

5453
impl StateType for InflateState {
55-
const STATE_TYPE: StateTypeEnum = StateTypeEnum::Inflate;
54+
const STATE_TYPE: StateTypeEnum = StateTypeEnum::InflateType;
5655
fn from_enum(value: &mut InternalState) -> Option<&mut Self> {
5756
if let InternalState::Inflate(state) = value {
5857
Some(state.as_mut())
@@ -63,7 +62,7 @@ impl StateType for InflateState {
6362
}
6463

6564
impl StateType for Compressor {
66-
const STATE_TYPE: StateTypeEnum = StateTypeEnum::Deflate;
65+
const STATE_TYPE: StateTypeEnum = StateTypeEnum::DeflateType;
6766
fn from_enum(value: &mut InternalState) -> Option<&mut Self> {
6867
if let InternalState::Deflate(state) = value {
6968
Some(state.as_mut())

‎src/tdef.rs

+65-34
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,20 @@ use miniz_oxide::deflate::core::{
88
};
99

1010
/// Compression callback function type.
11-
pub type PutBufFuncPtrNotNull = unsafe extern "C" fn(*const c_void, c_int, *mut c_void) -> bool;
11+
pub type PutBufFuncPtrNotNull = unsafe extern "C" fn(*const c_void, c_int, *mut c_void) -> i32;
12+
#[allow(bad_style)]
13+
pub type tdefl_put_buf_func_ptr = Option<unsafe extern "C" fn(*const c_void, c_int, *mut c_void) -> i32>;
1214
/// `Option` alias for compression callback function type.
13-
pub type PutBufFuncPtr = Option<PutBufFuncPtrNotNull>;
15+
/// cbindgen.rename = "SnakeCase""
16+
// typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
1417

1518
pub struct CallbackFunc {
1619
pub put_buf_func: PutBufFuncPtrNotNull,
1720
pub put_buf_user: *mut c_void,
1821
}
1922

2023
/// Main compression struct. Not the same as `CompressorOxide`
21-
#[repr(C)]
24+
/// #[repr(C)]
2225
pub struct Compressor {
2326
pub(crate) inner: Option<CompressorOxide>,
2427
pub(crate) callback: Option<CallbackFunc>,
@@ -55,18 +58,48 @@ impl From<TDEFLStatus> for tdefl_status {
5558
}
5659
}
5760

61+
#[allow(bad_style)]
62+
#[repr(C)]
63+
#[derive(PartialEq, Eq)]
64+
pub enum tdefl_flush {
65+
TDEFL_NO_FLUSH = 0,
66+
TDEFL_SYNC_FLUSH = 2,
67+
TDEFL_FULL_FLUSH = 3,
68+
TDEFL_FINISH = 4,
69+
}
70+
71+
impl From<tdefl_flush> for TDEFLFlush {
72+
fn from(flush: tdefl_flush) -> TDEFLFlush {
73+
use tdefl_flush::*;
74+
match flush {
75+
TDEFL_NO_FLUSH => TDEFLFlush::None,
76+
TDEFL_SYNC_FLUSH => TDEFLFlush::Sync,
77+
TDEFL_FULL_FLUSH => TDEFLFlush::Full,
78+
TDEFL_FINISH => TDEFLFlush::Finish,
79+
}
80+
}
81+
}
82+
83+
// pub type tdefl_flush = c_int;
84+
// pub mod tdefl_flush_e {
85+
// pub const TDEFL_NO_FLUSH: tdefl_flush = 0;
86+
// pub const TDEFL_SYNC_FLUSH: tdefl_flush = 2;
87+
// pub const TDEFL_FULL_FLUSH: tdefl_flush = 3;
88+
// pub const TDEFL_FINISH: tdefl_flush = 4;
89+
// }
90+
5891
/// Convert an i32 to a TDEFLFlush
5992
///
6093
/// Returns TDEFLFLush::None flush value is unknown.
6194
/// For use with c interface.
62-
pub fn i32_to_tdefl_flush(flush: i32) -> TDEFLFlush {
63-
match flush {
64-
2 => TDEFLFlush::Sync,
65-
3 => TDEFLFlush::Full,
66-
4 => TDEFLFlush::Finish,
67-
_ => TDEFLFlush::None,
68-
}
69-
}
95+
// pub fn i32_to_tdefl_flush(flush: i32) -> TDEFLFlush {
96+
// match flush {
97+
// 2 => TDEFLFlush::Sync,
98+
// 3 => TDEFLFlush::Full,
99+
// 4 => TDEFLFlush::Finish,
100+
// _ => TDEFLFlush::None,
101+
// }
102+
// }
70103

71104
impl Compressor {
72105
pub(crate) fn new_with_callback(flags: u32, func: CallbackFunc) -> Self {
@@ -114,9 +147,11 @@ unmangle!(
114147
in_size: Option<&mut usize>,
115148
out_buf: *mut c_void,
116149
out_size: Option<&mut usize>,
117-
flush: i32,
150+
// TODO: See if we should use an enum here or not as it could
151+
// cause UB.
152+
flush: tdefl_flush,
118153
) -> tdefl_status {
119-
let flush = i32_to_tdefl_flush(flush);
154+
let flush = flush.into();
120155
match d {
121156
None => {
122157
if let Some(size) = in_size {
@@ -180,7 +215,7 @@ unmangle!(
180215
&(out[0]) as *const u8 as *const c_void,
181216
out.len() as i32,
182217
func.put_buf_user,
183-
)
218+
) != 0
184219
});
185220
(res.0, res.1, 0)
186221
}
@@ -204,7 +239,7 @@ unmangle!(
204239
d: Option<&mut Compressor>,
205240
in_buf: *const c_void,
206241
mut in_size: usize,
207-
flush: i32,
242+
flush: tdefl_flush,
208243
) -> tdefl_status {
209244
tdefl_compress(d, in_buf, Some(&mut in_size), ptr::null_mut(), None, flush)
210245
}
@@ -238,7 +273,7 @@ unmangle!(
238273
/// tdefl_allocate and tdefl_deallocate
239274
pub unsafe extern "C" fn tdefl_init(
240275
d: Option<&mut Compressor>,
241-
put_buf_func: PutBufFuncPtr,
276+
put_buf_func: tdefl_put_buf_func_ptr,
242277
put_buf_user: *mut c_void,
243278
flags: c_int,
244279
) -> tdefl_status {
@@ -280,10 +315,10 @@ unmangle!(
280315
pub unsafe extern "C" fn tdefl_compress_mem_to_output(
281316
buf: *const c_void,
282317
buf_len: usize,
283-
put_buf_func: PutBufFuncPtr,
318+
put_buf_func: tdefl_put_buf_func_ptr,
284319
put_buf_user: *mut c_void,
285320
flags: c_int,
286-
) -> bool {
321+
) -> c_int {
287322
if let Some(put_buf_func) = put_buf_func {
288323
let compressor =
289324
crate::miniz_def_alloc_func(ptr::null_mut(), 1, mem::size_of::<Compressor>())
@@ -301,15 +336,15 @@ unmangle!(
301336
);
302337

303338
let res =
304-
tdefl_compress_buffer(compressor.as_mut(), buf, buf_len, TDEFLFlush::Finish as i32)
339+
tdefl_compress_buffer(compressor.as_mut(), buf, buf_len, tdefl_flush::TDEFL_FINISH)
305340
== tdefl_status::TDEFL_STATUS_DONE;
306341
if let Some(c) = compressor.as_mut() {
307342
c.drop_inner();
308343
}
309344
crate::miniz_def_free_func(ptr::null_mut(), compressor as *mut c_void);
310-
res
345+
res.into()
311346
} else {
312-
false
347+
false.into()
313348
}
314349
}
315350
);
@@ -325,15 +360,15 @@ pub unsafe extern "C" fn output_buffer_putter(
325360
buf: *const c_void,
326361
len: c_int,
327362
user: *mut c_void,
328-
) -> bool {
363+
) -> i32 {
329364
let user = (user as *mut BufferUser).as_mut();
330365
match user {
331-
None => false,
366+
None => false.into(),
332367
Some(user) => {
333368
let new_size = user.size + len as usize;
334369
if new_size > user.capacity {
335370
if !user.expandable {
336-
return false;
371+
return false.into();
337372
}
338373
let mut new_capacity = cmp::max(user.capacity, 128);
339374
while new_size > new_capacity {
@@ -348,20 +383,16 @@ pub unsafe extern "C" fn output_buffer_putter(
348383
);
349384

350385
if new_buf.is_null() {
351-
return false;
386+
return false.into();
352387
}
353388

354389
user.buf = new_buf as *mut u8;
355390
user.capacity = new_capacity;
356391
}
357392

358-
ptr::copy_nonoverlapping(
359-
buf as *const u8,
360-
user.buf.add(user.size),
361-
len as usize,
362-
);
393+
ptr::copy_nonoverlapping(buf as *const u8, user.buf.add(user.size), len as usize);
363394
user.size = new_size;
364-
true
395+
true.into()
365396
}
366397
}
367398
}
@@ -385,13 +416,13 @@ unmangle!(
385416
expandable: true,
386417
};
387418

388-
if !tdefl_compress_mem_to_output(
419+
if tdefl_compress_mem_to_output(
389420
src_buf,
390421
src_buf_len,
391422
Some(output_buffer_putter),
392423
&mut buffer_user as *mut BufferUser as *mut c_void,
393424
flags,
394-
) {
425+
) == 0 {
395426
ptr::null_mut()
396427
} else {
397428
*len = buffer_user.size;
@@ -424,7 +455,7 @@ unmangle!(
424455
Some(output_buffer_putter),
425456
&mut buffer_user as *mut BufferUser as *mut c_void,
426457
flags,
427-
) {
458+
) != 0 {
428459
buffer_user.size
429460
} else {
430461
0

‎src/tinfl.rs

+117-12
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,80 @@
22

33
use libc::*;
44
use miniz_oxide::inflate::core::DecompressorOxide;
5-
pub use miniz_oxide::inflate::core::DecompressorOxide as tinfl_decompressor;
5+
// pub use miniz_oxide::inflate::core::DecompressorOxide as tinfl_decompressor;
66
pub use miniz_oxide::inflate::core::{decompress, inflate_flags};
77
use miniz_oxide::inflate::TINFLStatus;
88
use std::{ptr, slice, usize};
99

1010
pub const TINFL_DECOMPRESS_MEM_TO_MEM_FAILED: size_t = usize::MAX;
1111

12+
#[allow(bad_style)]
13+
#[repr(C)]
14+
pub enum tinfl_status {
15+
/* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
16+
/* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
17+
/* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
18+
TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,
19+
20+
/* This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.) */
21+
TINFL_STATUS_BAD_PARAM = -3,
22+
23+
/* This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE. */
24+
TINFL_STATUS_ADLER32_MISMATCH = -2,
25+
26+
/* This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code. */
27+
TINFL_STATUS_FAILED = -1,
28+
29+
/* Any status code less than TINFL_STATUS_DONE must indicate a failure. */
30+
31+
/* This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and */
32+
/* if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again. */
33+
TINFL_STATUS_DONE = 0,
34+
35+
/* This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT */
36+
/* flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to */
37+
/* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */
38+
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
39+
40+
/* This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer. */
41+
/* Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect */
42+
/* (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible */
43+
/* so I may need to add some code to address this. */
44+
TINFL_STATUS_HAS_MORE_OUTPUT = 2,
45+
}
46+
47+
impl From<TINFLStatus> for tinfl_status {
48+
fn from(status: TINFLStatus) -> tinfl_status {
49+
use self::tinfl_status::*;
50+
match status {
51+
TINFLStatus::FailedCannotMakeProgress => TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS,
52+
TINFLStatus::BadParam => TINFL_STATUS_BAD_PARAM,
53+
TINFLStatus::Adler32Mismatch => TINFL_STATUS_ADLER32_MISMATCH,
54+
TINFLStatus::Failed => TINFL_STATUS_FAILED,
55+
TINFLStatus::Done => TINFL_STATUS_DONE,
56+
TINFLStatus::NeedsMoreInput => TINFL_STATUS_NEEDS_MORE_INPUT,
57+
TINFLStatus::HasMoreOutput => TINFL_STATUS_HAS_MORE_OUTPUT
58+
}
59+
}
60+
}
61+
62+
#[allow(bad_style)]
63+
#[repr(C)]
64+
pub struct tinfl_decompressor {
65+
inner: Option<Box<DecompressorOxide>>,
66+
}
67+
68+
impl Default for tinfl_decompressor {
69+
fn default() -> tinfl_decompressor {
70+
tinfl_decompressor {
71+
inner: Some(Box::<DecompressorOxide>::default()),
72+
}
73+
}
74+
}
75+
1276
unmangle!(
1377
pub unsafe extern "C" fn tinfl_decompress(
14-
r: *mut DecompressorOxide,
78+
r: *mut tinfl_decompressor,
1579
in_buf: *const u8,
1680
in_buf_size: *mut usize,
1781
out_buf_start: *mut u8,
@@ -21,17 +85,22 @@ unmangle!(
2185
) -> i32 {
2286
let next_pos = out_buf_next as usize - out_buf_start as usize;
2387
let out_size = *out_buf_size + next_pos;
24-
let (status, in_consumed, out_consumed) = decompress(
25-
r.as_mut().expect("bad decompressor pointer"),
26-
slice::from_raw_parts(in_buf, *in_buf_size),
27-
slice::from_raw_parts_mut(out_buf_start, out_size),
28-
next_pos,
29-
flags,
30-
);
88+
let r_ref = r.as_mut().expect("bad decompressor pointer");
89+
if let Some(decompressor) = r_ref.inner.as_mut() {
90+
let (status, in_consumed, out_consumed) = decompress(
91+
decompressor.as_mut(),
92+
slice::from_raw_parts(in_buf, *in_buf_size),
93+
slice::from_raw_parts_mut(out_buf_start, out_size),
94+
next_pos,
95+
flags,
96+
);
3197

32-
*in_buf_size = in_consumed;
33-
*out_buf_size = out_consumed;
34-
status as i32
98+
*in_buf_size = in_consumed;
99+
*out_buf_size = out_consumed;
100+
status as i32
101+
} else {
102+
TINFLStatus::BadParam as i32
103+
}
35104
}
36105

37106
pub unsafe extern "C" fn tinfl_decompress_mem_to_mem(
@@ -139,6 +208,42 @@ unmangle!(
139208

140209
p_buf
141210
}
211+
212+
/// Allocate a compressor.
213+
///
214+
/// This does initialize the struct, but not the inner constructor,
215+
/// tdefl_init has to be called before doing anything with it.
216+
pub unsafe extern "C" fn tinfl_decompressor_alloc() -> *mut tinfl_decompressor {
217+
Box::into_raw(Box::<tinfl_decompressor>::new(tinfl_decompressor::default()))
218+
}
219+
/// Deallocate the compressor. (Does nothing if the argument is null).
220+
///
221+
/// This also calles the compressor's destructor, freeing the internal memory
222+
/// allocated by it.
223+
pub unsafe extern "C" fn tinfl_decompressor_free(c: *mut tinfl_decompressor) {
224+
if !c.is_null() {
225+
Box::from_raw(c);
226+
}
227+
}
228+
229+
pub unsafe extern "C" fn tinfl_init(c: *mut tinfl_decompressor) {
230+
let wrapped = c.as_mut().unwrap();
231+
if let Some(decomp) = wrapped.inner.as_mut() {
232+
decomp.init();
233+
} else {
234+
wrapped.inner.replace(Box::default());
235+
}
236+
}
237+
238+
pub unsafe extern "C" fn tinfl_get_adler32(c: *mut tinfl_decompressor) -> c_int {
239+
let wrapped = c.as_mut().unwrap();
240+
if let Some(decomp) = wrapped.inner.as_mut() {
241+
// TODO: Need to test if conversion is ok.
242+
decomp.adler32().unwrap_or(0) as c_int
243+
} else {
244+
0
245+
}
246+
}
142247
);
143248

144249
#[cfg(test)]

0 commit comments

Comments
 (0)
Please sign in to comment.