Skip to content

Commit ed4ce19

Browse files
committed
extmod/moduzlib: Refactor to new stream-compatible uzlib 2.0 API.
1 parent ff1c2b0 commit ed4ce19

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

extmod/moduzlib.c

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626

2727
#include <stdio.h>
28+
#include <string.h>
2829

2930
#include "py/nlr.h"
3031
#include "py/runtime.h"
@@ -39,47 +40,62 @@
3940
#define DEBUG_printf(...) (void)0
4041
#endif
4142

42-
STATIC int mod_uzlib_grow_buf(TINF_DATA *d, unsigned alloc_req) {
43-
if (alloc_req < 256) {
44-
alloc_req = 256;
45-
}
46-
DEBUG_printf("uzlib: Resizing buffer to " UINT_FMT " bytes\n", d->destSize + alloc_req);
47-
d->destStart = m_renew(byte, d->destStart, d->destSize, d->destSize + alloc_req);
48-
d->destSize += alloc_req;
49-
return 0;
50-
}
51-
5243
STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
5344
(void)n_args;
5445
mp_obj_t data = args[0];
5546
mp_buffer_info_t bufinfo;
5647
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
5748

5849
TINF_DATA *decomp = m_new_obj(TINF_DATA);
50+
memset(decomp, 0, sizeof(*decomp));
5951
DEBUG_printf("sizeof(TINF_DATA)=" UINT_FMT "\n", sizeof(*decomp));
52+
uzlib_uncompress_init(decomp, NULL, 0);
53+
mp_uint_t dest_buf_size = (bufinfo.len + 15) & ~15;
54+
byte *dest_buf = m_new(byte, dest_buf_size);
6055

61-
decomp->destSize = (bufinfo.len + 15) & ~15;
62-
decomp->destStart = m_new(byte, decomp->destSize);
56+
decomp->dest = dest_buf;
57+
decomp->destSize = dest_buf_size;
6358
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize);
64-
decomp->destGrow = mod_uzlib_grow_buf;
6559
decomp->source = bufinfo.buf;
6660

6761
int st;
62+
bool is_zlib = true;
63+
6864
if (n_args > 1 && MP_OBJ_SMALL_INT_VALUE(args[1]) < 0) {
69-
st = tinf_uncompress_dyn(decomp);
70-
} else {
71-
st = tinf_zlib_uncompress_dyn(decomp, bufinfo.len);
65+
is_zlib = false;
7266
}
73-
if (st != 0) {
74-
nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st)));
67+
68+
if (is_zlib) {
69+
st = uzlib_zlib_parse_header(decomp);
70+
if (st < 0) {
71+
goto error;
72+
}
73+
}
74+
75+
while (1) {
76+
st = uzlib_uncompress_chksum(decomp);
77+
if (st < 0) {
78+
goto error;
79+
}
80+
if (st == TINF_DONE) {
81+
break;
82+
}
83+
size_t offset = decomp->dest - dest_buf;
84+
dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
85+
dest_buf_size += 256;
86+
decomp->dest = dest_buf + offset;
87+
decomp->destSize = 256;
7588
}
7689

77-
mp_uint_t final_sz = decomp->dest - decomp->destStart;
78-
DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", decomp->destSize, final_sz);
79-
decomp->destStart = (byte*)m_renew(byte, decomp->destStart, decomp->destSize, final_sz);
80-
mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, decomp->destStart);
90+
mp_uint_t final_sz = decomp->dest - dest_buf;
91+
DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", dest_buf_size, final_sz);
92+
dest_buf = (byte*)m_renew(byte, dest_buf, dest_buf_size, final_sz);
93+
mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, dest_buf);
8194
m_del_obj(TINF_DATA, decomp);
8295
return res;
96+
97+
error:
98+
nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st)));
8399
}
84100
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_uzlib_decompress_obj, 1, 3, mod_uzlib_decompress);
85101

@@ -102,5 +118,6 @@ const mp_obj_module_t mp_module_uzlib = {
102118
#include "uzlib/tinflate.c"
103119
#include "uzlib/tinfzlib.c"
104120
#include "uzlib/adler32.c"
121+
#include "uzlib/crc32.c"
105122

106123
#endif // MICROPY_PY_UZLIB

0 commit comments

Comments
 (0)