summaryrefslogtreecommitdiffstatshomepage
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/fsusermount.c2
-rw-r--r--extmod/fsusermount.h1
-rw-r--r--extmod/machine_spi.c85
-rw-r--r--extmod/machine_spi.h42
-rw-r--r--extmod/modbtree.c1
-rw-r--r--extmod/modframebuf.c33
-rw-r--r--extmod/modubinascii.c15
-rw-r--r--extmod/modubinascii.h2
-rw-r--r--extmod/moduzlib.c153
-rw-r--r--extmod/modwebrepl.c7
-rw-r--r--extmod/uzlib/adler32.c6
-rw-r--r--extmod/uzlib/crc32.c63
-rw-r--r--extmod/uzlib/tinf.h78
-rw-r--r--extmod/uzlib/tinflate.c378
-rw-r--r--extmod/uzlib/tinfzlib.c53
-rw-r--r--extmod/vfs_fat.c8
16 files changed, 642 insertions, 285 deletions
diff --git a/extmod/fsusermount.c b/extmod/fsusermount.c
index 9ddc98f3dd..cbc1e36220 100644
--- a/extmod/fsusermount.c
+++ b/extmod/fsusermount.c
@@ -162,7 +162,7 @@ STATIC mp_obj_t fatfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
}
MP_DEFINE_CONST_FUN_OBJ_KW(fsuser_mount_obj, 2, fatfs_mount);
-STATIC mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in) {
+mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in) {
size_t i = 0;
if (MP_OBJ_IS_STR(bdev_or_path_in)) {
mp_uint_t mnt_len;
diff --git a/extmod/fsusermount.h b/extmod/fsusermount.h
index a25434b781..e1f26f2ce8 100644
--- a/extmod/fsusermount.h
+++ b/extmod/fsusermount.h
@@ -55,6 +55,7 @@ typedef struct _fs_user_mount_t {
} fs_user_mount_t;
fs_user_mount_t *fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, bool mkfs);
+mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in);
MP_DECLARE_CONST_FUN_OBJ(fsuser_mount_obj);
MP_DECLARE_CONST_FUN_OBJ(fsuser_umount_obj);
diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c
new file mode 100644
index 0000000000..6b6202a221
--- /dev/null
+++ b/extmod/machine_spi.c
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include "py/runtime.h"
+#include "extmod/machine_spi.h"
+
+#if MICROPY_PY_MACHINE_SPI
+
+STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t slen, const uint8_t *src, size_t dlen, uint8_t *dest) {
+ mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
+ mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
+ spi_p->transfer(s, slen, src, dlen, dest);
+}
+
+STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) {
+ uint8_t write_byte = 0;
+ if (n_args == 3) {
+ write_byte = mp_obj_get_int(args[2]);
+ }
+ vstr_t vstr;
+ vstr_init_len(&vstr, mp_obj_get_int(args[1]));
+ mp_machine_spi_transfer(args[0], 1, &write_byte, vstr.len, (uint8_t*)vstr.buf);
+ return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read);
+
+STATIC mp_obj_t mp_machine_spi_readinto(size_t n_args, const mp_obj_t *args) {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
+ uint8_t write_byte = 0;
+ if (n_args == 3) {
+ write_byte = mp_obj_get_int(args[2]);
+ }
+ mp_machine_spi_transfer(args[0], 1, &write_byte, bufinfo.len, (uint8_t*)bufinfo.buf);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machine_spi_readinto);
+
+STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self, mp_obj_t wr_buf) {
+ mp_buffer_info_t src;
+ mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
+ mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, 0, NULL);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj, mp_machine_spi_write);
+
+STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp_obj_t rd_buf) {
+ mp_buffer_info_t src;
+ mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
+ mp_buffer_info_t dest;
+ mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
+ if (src.len != dest.len) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buffers must be the same length"));
+ }
+ mp_machine_spi_transfer(self, src.len, (const uint8_t*)src.buf, dest.len, (uint8_t*)dest.buf);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);
+
+#endif // MICROPY_PY_MACHINE_SPI
diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h
new file mode 100644
index 0000000000..26d716fc11
--- /dev/null
+++ b/extmod/machine_spi.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
+#define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
+
+#include "py/obj.h"
+
+// SPI protocol
+typedef struct _mp_machine_spi_p_t {
+ void (*transfer)(mp_obj_base_t *obj, size_t slen, const uint8_t *src, size_t dlen, uint8_t *dest);
+} mp_machine_spi_p_t;
+
+MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_read_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_readinto_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_readinto_obj);
+
+#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
diff --git a/extmod/modbtree.c b/extmod/modbtree.c
index f21e7e4421..ea2ea582c8 100644
--- a/extmod/modbtree.c
+++ b/extmod/modbtree.c
@@ -133,6 +133,7 @@ STATIC mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) {
}
int res = __bt_seq(self->db, &key, &val, flags);
+ CHECK_ERROR(res);
if (res == RET_SPECIAL) {
return mp_const_none;
}
diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c
index d0ef238075..3c884c6898 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -33,7 +33,7 @@
#if MICROPY_PY_FRAMEBUF
-#include "font_petme128_8x8.h"
+#include "stmhal/font_petme128_8x8.h"
// 1-bit frame buffer, each byte is a column of 8 pixels
typedef struct _mp_obj_framebuf1_t {
@@ -68,7 +68,8 @@ STATIC mp_obj_t framebuf1_fill(mp_obj_t self_in, mp_obj_t col_in) {
if (col) {
col = 0xff;
}
- for (int y = 0; y < self->height / 8; ++y) {
+ int end = (self->height + 7) >> 3;
+ for (int y = 0; y < end; ++y) {
memset(self->buf + y * self->stride, col, self->width);
}
return mp_const_none;
@@ -83,7 +84,7 @@ STATIC mp_obj_t framebuf1_pixel(size_t n_args, const mp_obj_t *args) {
int index = (y / 8) * self->stride + x;
if (n_args == 3) {
// get
- return MP_OBJ_NEW_SMALL_INT(self->buf[index] >> (y & 7));
+ return MP_OBJ_NEW_SMALL_INT((self->buf[index] >> (y & 7)) & 1);
} else {
// set
if (mp_obj_get_int(args[3])) {
@@ -101,8 +102,9 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y
mp_obj_framebuf1_t *self = MP_OBJ_TO_PTR(self_in);
mp_int_t xstep = mp_obj_get_int(xstep_in);
mp_int_t ystep = mp_obj_get_int(ystep_in);
- if (xstep == 0 && ystep > 0) {
- for (int y = self->height / 8; y > 0;) {
+ int end = (self->height + 7) >> 3;
+ if (ystep > 0) {
+ for (int y = end; y > 0;) {
--y;
for (int x = 0; x < self->width; ++x) {
int prev = 0;
@@ -112,18 +114,31 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y
self->buf[y * self->stride + x] = (self->buf[y * self->stride + x] << ystep) | prev;
}
}
- } else if (xstep == 0 && ystep < 0) {
- for (int y = 0; y < self->height / 8; ++y) {
+ } else if (ystep < 0) {
+ for (int y = 0; y < end; ++y) {
for (int x = 0; x < self->width; ++x) {
int prev = 0;
- if (y + 1 < self->height / 8) {
+ if (y + 1 < end) {
prev = self->buf[(y + 1) * self->stride + x] << (8 + ystep);
}
self->buf[y * self->stride + x] = (self->buf[y * self->stride + x] >> -ystep) | prev;
}
}
}
- // TODO xstep!=0
+ if (xstep < 0) {
+ for (int y = 0; y < end; ++y) {
+ for (int x = 0; x < self->width + xstep; ++x) {
+ self->buf[y * self->stride + x] = self->buf[y * self->stride + x - xstep];
+ }
+ }
+ } else if (xstep > 0) {
+ for (int y = 0; y < end; ++y) {
+ for (int x = self->width - 1; x >= xstep; --x) {
+ self->buf[y * self->stride + x] = self->buf[y * self->stride + x - xstep];
+ }
+ }
+ }
+ // TODO: Should we clear the margin created by scrolling?
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf1_scroll_obj, framebuf1_scroll);
diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c
index 3cceb991f1..562c754b52 100644
--- a/extmod/modubinascii.c
+++ b/extmod/modubinascii.c
@@ -33,6 +33,7 @@
#include "py/binary.h"
#include "extmod/modubinascii.h"
+#include "uzlib/tinf.h"
mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
// Second argument is for an extension to allow a separator to be used
@@ -203,6 +204,17 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
}
MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);
+#if MICROPY_PY_UBINASCII_CRC32
+mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
+ uint32_t crc = (n_args > 1) ? mp_obj_get_int(args[1]) : 0;
+ crc = uzlib_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff);
+ return MP_OBJ_NEW_SMALL_INT(crc ^ 0xffffffff);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_crc32);
+#endif
+
#if MICROPY_PY_UBINASCII
STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = {
@@ -211,6 +223,9 @@ STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&mod_binascii_unhexlify_obj) },
{ MP_ROM_QSTR(MP_QSTR_a2b_base64), MP_ROM_PTR(&mod_binascii_a2b_base64_obj) },
{ MP_ROM_QSTR(MP_QSTR_b2a_base64), MP_ROM_PTR(&mod_binascii_b2a_base64_obj) },
+ #if MICROPY_PY_UBINASCII_CRC32
+ { MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_binascii_crc32_obj) },
+ #endif
};
STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globals_table);
diff --git a/extmod/modubinascii.h b/extmod/modubinascii.h
index 0f9b82c1cb..71dd8a6936 100644
--- a/extmod/modubinascii.h
+++ b/extmod/modubinascii.h
@@ -31,10 +31,12 @@ extern mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args);
extern mp_obj_t mod_binascii_unhexlify(mp_obj_t data);
extern mp_obj_t mod_binascii_a2b_base64(mp_obj_t data);
extern mp_obj_t mod_binascii_b2a_base64(mp_obj_t data);
+extern mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args);
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_hexlify_obj);
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_unhexlify_obj);
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_a2b_base64_obj);
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_b2a_base64_obj);
+MP_DECLARE_CONST_FUN_OBJ(mod_binascii_crc32_obj);
#endif /* MICROPY_EXTMOD_MODUBINASCII */
diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c
index 3d945abba5..65cbc5eb01 100644
--- a/extmod/moduzlib.c
+++ b/extmod/moduzlib.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2014 Paul Sokolovsky
+ * Copyright (c) 2014-2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,9 +25,12 @@
*/
#include <stdio.h>
+#include <string.h>
#include "py/nlr.h"
#include "py/runtime.h"
+#include "py/stream.h"
+#include "py/mperrno.h"
#if MICROPY_PY_UZLIB
@@ -39,16 +42,99 @@
#define DEBUG_printf(...) (void)0
#endif
-STATIC int mod_uzlib_grow_buf(TINF_DATA *d, unsigned alloc_req) {
- if (alloc_req < 256) {
- alloc_req = 256;
+typedef struct _mp_obj_decompio_t {
+ mp_obj_base_t base;
+ mp_obj_t src_stream;
+ TINF_DATA decomp;
+ bool eof;
+} mp_obj_decompio_t;
+
+STATIC unsigned char read_src_stream(TINF_DATA *data) {
+ byte *p = (void*)data;
+ p -= offsetof(mp_obj_decompio_t, decomp);
+ mp_obj_decompio_t *self = (mp_obj_decompio_t*)p;
+
+ const mp_stream_p_t *stream = mp_get_stream_raise(self->src_stream, MP_STREAM_OP_READ);
+ int err;
+ byte c;
+ mp_uint_t out_sz = stream->read(self->src_stream, &c, 1, &err);
+ if (out_sz == MP_STREAM_ERROR) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(err)));
}
- DEBUG_printf("uzlib: Resizing buffer to " UINT_FMT " bytes\n", d->destSize + alloc_req);
- d->destStart = m_renew(byte, d->destStart, d->destSize, d->destSize + alloc_req);
- d->destSize += alloc_req;
- return 0;
+ if (out_sz == 0) {
+ nlr_raise(mp_obj_new_exception(&mp_type_EOFError));
+ }
+ return c;
+}
+
+STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+ mp_arg_check_num(n_args, n_kw, 1, 2, false);
+ mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t);
+ o->base.type = type;
+ memset(&o->decomp, 0, sizeof(o->decomp));
+ o->decomp.readSource = read_src_stream;
+ o->src_stream = args[0];
+ o->eof = false;
+
+ mp_int_t dict_opt = 0;
+ int dict_sz;
+ if (n_args > 1) {
+ dict_opt = mp_obj_get_int(args[1]);
+ }
+ if (dict_opt >= 0) {
+ dict_opt = uzlib_zlib_parse_header(&o->decomp);
+ if (dict_opt < 0) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "zlib header"));
+ }
+ dict_sz = 1 << dict_opt;
+ } else {
+ dict_sz = 1 << -dict_opt;
+ }
+
+ uzlib_uncompress_init(&o->decomp, m_new(byte, dict_sz), dict_sz);
+ return MP_OBJ_FROM_PTR(o);
}
+STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
+ mp_obj_decompio_t *o = MP_OBJ_TO_PTR(o_in);
+ if (o->eof) {
+ return 0;
+ }
+
+ o->decomp.dest = buf;
+ o->decomp.destSize = size;
+ int st = uzlib_uncompress_chksum(&o->decomp);
+ if (st == TINF_DONE) {
+ o->eof = true;
+ }
+ if (st < 0) {
+ *errcode = MP_EINVAL;
+ return MP_STREAM_ERROR;
+ }
+ return o->decomp.dest - (byte*)buf;
+}
+
+STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
+
+STATIC const mp_stream_p_t decompio_stream_p = {
+ .read = decompio_read,
+};
+
+STATIC const mp_obj_type_t decompio_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_DecompIO,
+ .make_new = decompio_make_new,
+ .protocol = &decompio_stream_p,
+ .locals_dict = (void*)&decompio_locals_dict,
+};
+
STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
(void)n_args;
mp_obj_t data = args[0];
@@ -56,36 +142,62 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
TINF_DATA *decomp = m_new_obj(TINF_DATA);
+ memset(decomp, 0, sizeof(*decomp));
DEBUG_printf("sizeof(TINF_DATA)=" UINT_FMT "\n", sizeof(*decomp));
+ uzlib_uncompress_init(decomp, NULL, 0);
+ mp_uint_t dest_buf_size = (bufinfo.len + 15) & ~15;
+ byte *dest_buf = m_new(byte, dest_buf_size);
- decomp->destSize = (bufinfo.len + 15) & ~15;
- decomp->destStart = m_new(byte, decomp->destSize);
+ decomp->dest = dest_buf;
+ decomp->destSize = dest_buf_size;
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize);
- decomp->destGrow = mod_uzlib_grow_buf;
decomp->source = bufinfo.buf;
int st;
+ bool is_zlib = true;
+
if (n_args > 1 && MP_OBJ_SMALL_INT_VALUE(args[1]) < 0) {
- st = tinf_uncompress_dyn(decomp);
- } else {
- st = tinf_zlib_uncompress_dyn(decomp, bufinfo.len);
+ is_zlib = false;
}
- if (st != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st)));
+
+ if (is_zlib) {
+ st = uzlib_zlib_parse_header(decomp);
+ if (st < 0) {
+ goto error;
+ }
}
- mp_uint_t final_sz = decomp->dest - decomp->destStart;
- DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", decomp->destSize, final_sz);
- decomp->destStart = (byte*)m_renew(byte, decomp->destStart, decomp->destSize, final_sz);
- mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, decomp->destStart);
+ while (1) {
+ st = uzlib_uncompress_chksum(decomp);
+ if (st < 0) {
+ goto error;
+ }
+ if (st == TINF_DONE) {
+ break;
+ }
+ size_t offset = decomp->dest - dest_buf;
+ dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
+ dest_buf_size += 256;
+ decomp->dest = dest_buf + offset;
+ decomp->destSize = 256;
+ }
+
+ mp_uint_t final_sz = decomp->dest - dest_buf;
+ DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", dest_buf_size, final_sz);
+ dest_buf = (byte*)m_renew(byte, dest_buf, dest_buf_size, final_sz);
+ mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, dest_buf);
m_del_obj(TINF_DATA, decomp);
return res;
+
+error:
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st)));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_uzlib_decompress_obj, 1, 3, mod_uzlib_decompress);
STATIC const mp_rom_map_elem_t mp_module_uzlib_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uzlib) },
{ MP_ROM_QSTR(MP_QSTR_decompress), MP_ROM_PTR(&mod_uzlib_decompress_obj) },
+ { MP_ROM_QSTR(MP_QSTR_DecompIO), MP_ROM_PTR(&decompio_type) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_uzlib_globals, mp_module_uzlib_globals_table);
@@ -102,5 +214,6 @@ const mp_obj_module_t mp_module_uzlib = {
#include "uzlib/tinflate.c"
#include "uzlib/tinfzlib.c"
#include "uzlib/adler32.c"
+#include "uzlib/crc32.c"
#endif // MICROPY_PY_UZLIB
diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c
index 4e3780fa4d..858d2c1c0b 100644
--- a/extmod/modwebrepl.c
+++ b/extmod/modwebrepl.c
@@ -310,9 +310,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(webrepl_close_obj, webrepl_close);
STATIC mp_obj_t webrepl_set_password(mp_obj_t passwd_in) {
mp_uint_t len;
const char *passwd = mp_obj_str_get_data(passwd_in, &len);
- len = MIN(len, sizeof(webrepl_passwd) - 1);
- memcpy(webrepl_passwd, passwd, len);
- webrepl_passwd[len] = 0;
+ if (len > sizeof(webrepl_passwd) - 1) {
+ mp_raise_ValueError("");
+ }
+ strcpy(webrepl_passwd, passwd);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(webrepl_set_password_obj, webrepl_set_password);
diff --git a/extmod/uzlib/adler32.c b/extmod/uzlib/adler32.c
index f99b2d7f40..1f1759493b 100644
--- a/extmod/uzlib/adler32.c
+++ b/extmod/uzlib/adler32.c
@@ -41,12 +41,12 @@
#define A32_BASE 65521
#define A32_NMAX 5552
-unsigned int tinf_adler32(const void *data, unsigned int length)
+uint32_t uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum /* 1 */)
{
const unsigned char *buf = (const unsigned char *)data;
- unsigned int s1 = 1;
- unsigned int s2 = 0;
+ unsigned int s1 = prev_sum & 0xffff;
+ unsigned int s2 = prev_sum >> 16;
while (length > 0)
{
diff --git a/extmod/uzlib/crc32.c b/extmod/uzlib/crc32.c
new file mode 100644
index 0000000000..e24c643b6a
--- /dev/null
+++ b/extmod/uzlib/crc32.c
@@ -0,0 +1,63 @@
+/*
+ * CRC32 checksum
+ *
+ * Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
+ * All Rights Reserved
+ *
+ * http://www.ibsensoftware.com/
+ *
+ * This software is provided 'as-is', without any express
+ * or implied warranty. In no event will the authors be
+ * held liable for any damages arising from the use of
+ * this software.
+ *
+ * Permission is granted to anyone to use this software
+ * for any purpose, including commercial applications,
+ * and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The origin of this software must not be
+ * misrepresented; you must not claim that you
+ * wrote the original software. If you use this
+ * software in a product, an acknowledgment in
+ * the product documentation would be appreciated
+ * but is not required.
+ *
+ * 2. Altered source versions must be plainly marked
+ * as such, and must not be misrepresented as
+ * being the original software.
+ *
+ * 3. This notice may not be removed or altered from
+ * any source distribution.
+ */
+
+/*
+ * CRC32 algorithm taken from the zlib source, which is
+ * Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+ */
+
+#include "tinf.h"
+
+static const unsigned int tinf_crc32tab[16] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190,
+ 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344,
+ 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278,
+ 0xbdbdf21c
+};
+
+/* crc is previous value for incremental computation, 0xffffffff initially */
+uint32_t uzlib_crc32(const void *data, unsigned int length, uint32_t crc)
+{
+ const unsigned char *buf = (const unsigned char *)data;
+ unsigned int i;
+
+ for (i = 0; i < length; ++i)
+ {
+ crc ^= buf[i];
+ crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4);
+ crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4);
+ }
+
+ // return value suitable for passing in next time, for final value invert it
+ return crc/* ^ 0xffffffff*/;
+}
diff --git a/extmod/uzlib/tinf.h b/extmod/uzlib/tinf.h
index e9401f2de5..3545bbd883 100644
--- a/extmod/uzlib/tinf.h
+++ b/extmod/uzlib/tinf.h
@@ -5,7 +5,7 @@
* All Rights Reserved
* http://www.ibsensoftware.com/
*
- * Copyright (c) 2014 by Paul Sokolovsky
+ * Copyright (c) 2014-2016 by Paul Sokolovsky
*/
#ifndef TINF_H_INCLUDED
@@ -26,9 +26,17 @@
extern "C" {
#endif
+/* ok status, more data produced */
#define TINF_OK 0
+/* end of compressed stream reached */
+#define TINF_DONE 1
#define TINF_DATA_ERROR (-3)
-#define TINF_DEST_OVERFLOW (-4)
+#define TINF_CHKSUM_ERROR (-4)
+
+/* checksum types */
+#define TINF_CHKSUM_NONE 0
+#define TINF_CHKSUM_ADLER 1
+#define TINF_CHKSUM_CRC 2
/* data structures */
@@ -40,6 +48,10 @@ typedef struct {
struct TINF_DATA;
typedef struct TINF_DATA {
const unsigned char *source;
+ /* If source above is NULL, this function will be used to read
+ next byte from source stream */
+ unsigned char (*readSource)(struct TINF_DATA *data);
+
unsigned int tag;
unsigned int bitcount;
@@ -51,49 +63,51 @@ typedef struct TINF_DATA {
unsigned char *dest;
/* Remaining bytes in buffer */
unsigned int destRemaining;
- /* Argument is the allocation size which didn't fit into buffer. Note that
- exact mimumum size to grow buffer by is lastAlloc - destRemaining. But
- growing by this exact size is ineficient, as the next allocation will
- fail again. */
- int (*destGrow)(struct TINF_DATA *data, unsigned int lastAlloc);
+
+ /* Accumulating checksum */
+ unsigned int checksum;
+ char checksum_type;
+
+ int btype;
+ int bfinal;
+ unsigned int curlen;
+ int lzOff;
+ unsigned char *dict_ring;
+ unsigned int dict_size;
+ unsigned int dict_idx;
TINF_TREE ltree; /* dynamic length/symbol tree */
TINF_TREE dtree; /* dynamic distance tree */
} TINF_DATA;
+#define TINF_PUT(d, c) \
+ { \
+ *d->dest++ = c; \
+ if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \
+ }
-/* low-level API */
-
-/* Step 1: Allocate TINF_DATA structure */
-/* Step 2: Set destStart, destSize, and destGrow fields */
-/* Step 3: Set source field */
-/* Step 4: Call tinf_uncompress_dyn() */
-/* Step 5: In response to destGrow callback, update destStart and destSize fields */
-/* Step 6: When tinf_uncompress_dyn() returns, buf.dest points to a byte past last uncompressed byte */
-
-int TINFCC tinf_uncompress_dyn(TINF_DATA *d);
-int TINFCC tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen);
-
-/* high-level API */
-
-void TINFCC tinf_init(void);
+unsigned char TINFCC uzlib_get_byte(TINF_DATA *d);
-int TINFCC tinf_uncompress(void *dest, unsigned int *destLen,
- const void *source, unsigned int sourceLen);
+/* Decompression API */
-int TINFCC tinf_gzip_uncompress(void *dest, unsigned int *destLen,
- const void *source, unsigned int sourceLen);
+void TINFCC uzlib_init(void);
+void TINFCC uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen);
+int TINFCC uzlib_uncompress(TINF_DATA *d);
+int TINFCC uzlib_uncompress_chksum(TINF_DATA *d);
-int TINFCC tinf_zlib_uncompress(void *dest, unsigned int *destLen,
- const void *source, unsigned int sourceLen);
+int TINFCC uzlib_zlib_parse_header(TINF_DATA *d);
+int TINFCC uzlib_gzip_parse_header(TINF_DATA *d);
-unsigned int TINFCC tinf_adler32(const void *data, unsigned int length);
+/* Compression API */
-unsigned int TINFCC tinf_crc32(const void *data, unsigned int length);
+void TINFCC uzlib_compress(void *data, const uint8_t *src, unsigned slen);
-/* compression API */
+/* Checksum API */
-void TINFCC tinf_compress(void *data, const uint8_t *src, unsigned slen);
+/* prev_sum is previous value for incremental computation, 1 initially */
+uint32_t TINFCC uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum);
+/* crc is previous value for incremental computation, 0xffffffff initially */
+uint32_t TINFCC uzlib_crc32(const void *data, unsigned int length, uint32_t crc);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/extmod/uzlib/tinflate.c b/extmod/uzlib/tinflate.c
index faf27e5739..0e53f7f072 100644
--- a/extmod/uzlib/tinflate.c
+++ b/extmod/uzlib/tinflate.c
@@ -5,7 +5,7 @@
* All Rights Reserved
* http://www.ibsensoftware.com/
*
- * Copyright (c) 2014 by Paul Sokolovsky
+ * Copyright (c) 2014-2016 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
@@ -32,8 +32,12 @@
* any source distribution.
*/
+#include <assert.h>
#include "tinf.h"
+uint32_t tinf_get_le_uint32(TINF_DATA *d);
+uint32_t tinf_get_be_uint32(TINF_DATA *d);
+
/* --------------------------------------------------- *
* -- uninitialized global data (static structures) -- *
* --------------------------------------------------- */
@@ -89,21 +93,6 @@ const unsigned char clcidx[] = {
* -- utility functions -- *
* ----------------------- */
-/* Execute callback to grow destination buffer */
-static int tinf_grow_dest_buf(TINF_DATA *d, unsigned int lastAlloc)
-{
- unsigned int oldsize = d->dest - d->destStart;
- /* This will update only destStart and destSize */
- if (!d->destGrow)
- {
- return TINF_DEST_OVERFLOW;
- }
- d->destGrow(d, lastAlloc);
- d->dest = d->destStart + oldsize;
- d->destRemaining = d->destSize - oldsize;
- return 0;
-}
-
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first)
@@ -180,6 +169,34 @@ static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned
* -- decode functions -- *
* ---------------------- */
+unsigned char uzlib_get_byte(TINF_DATA *d)
+{
+ if (d->source) {
+ return *d->source++;
+ }
+ return d->readSource(d);
+}
+
+uint32_t tinf_get_le_uint32(TINF_DATA *d)
+{
+ uint32_t val = 0;
+ int i;
+ for (i = 4; i--;) {
+ val = val >> 8 | uzlib_get_byte(d) << 24;
+ }
+ return val;
+}
+
+uint32_t tinf_get_be_uint32(TINF_DATA *d)
+{
+ uint32_t val = 0;
+ int i;
+ for (i = 4; i--;) {
+ val = val << 8 | uzlib_get_byte(d);
+ }
+ return val;
+}
+
/* get one bit from source stream */
static int tinf_getbit(TINF_DATA *d)
{
@@ -189,7 +206,7 @@ static int tinf_getbit(TINF_DATA *d)
if (!d->bitcount--)
{
/* load next tag */
- d->tag = *d->source++;
+ d->tag = uzlib_get_byte(d);
d->bitcount = 7;
}
@@ -318,113 +335,83 @@ static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
/* given a stream and two trees, inflate a block of data */
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
- while (1)
- {
- int sym = tinf_decode_symbol(d, lt);
-
- /* check for end of block */
- if (sym == 256)
- {
- return TINF_OK;
- }
-
- if (sym < 256)
- {
- if (d->destRemaining == 0)
- {
- int res = tinf_grow_dest_buf(d, 1);
- if (res) return res;
- }
-
- *d->dest++ = sym;
- d->destRemaining--;
-
- } else {
-
- unsigned int length, offs, i;
- int dist;
-
- sym -= 257;
-
- /* possibly get more bits from length code */
- length = tinf_read_bits(d, length_bits[sym], length_base[sym]);
-
- dist = tinf_decode_symbol(d, dt);
-
- /* possibly get more bits from distance code */
- offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
-
- if (d->destRemaining < length)
- {
- int res = tinf_grow_dest_buf(d, length);
- if (res) return res;
- }
-
- /* copy match */
- for (i = 0; i < length; ++i)
- {
- d->dest[i] = d->dest[(int)(i - offs)];
- }
-
- d->dest += length;
- d->destRemaining -= length;
- }
- }
+ if (d->curlen == 0) {
+ unsigned int offs;
+ int dist;
+ int sym = tinf_decode_symbol(d, lt);
+ //printf("huff sym: %02x\n", sym);
+
+ /* literal byte */
+ if (sym < 256) {
+ TINF_PUT(d, sym);
+ return TINF_OK;
+ }
+
+ /* end of block */
+ if (sym == 256) {
+ return TINF_DONE;
+ }
+
+ /* substring from sliding dictionary */
+ sym -= 257;
+ /* possibly get more bits from length code */
+ d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]);
+
+ dist = tinf_decode_symbol(d, dt);
+ /* possibly get more bits from distance code */
+ offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
+ if (d->dict_ring) {
+ d->lzOff = d->dict_idx - offs;
+ if (d->lzOff < 0) {
+ d->lzOff += d->dict_size;
+ }
+ } else {
+ d->lzOff = -offs;
+ }
+ }
+
+ /* copy next byte from dict substring */
+ if (d->dict_ring) {
+ TINF_PUT(d, d->dict_ring[d->lzOff]);
+ if ((unsigned)++d->lzOff == d->dict_size) {
+ d->lzOff = 0;
+ }
+ } else {
+ d->dest[0] = d->dest[d->lzOff];
+ d->dest++;
+ }
+ d->curlen--;
+ return TINF_OK;
}
/* inflate an uncompressed block of data */
static int tinf_inflate_uncompressed_block(TINF_DATA *d)
{
- unsigned int length, invlength;
- unsigned int i;
-
- /* get length */
- length = d->source[1];
- length = 256*length + d->source[0];
-
- /* get one's complement of length */
- invlength = d->source[3];
- invlength = 256*invlength + d->source[2];
-
- /* check length */
- if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR;
-
- if (d->destRemaining < length)
- {
- int res = tinf_grow_dest_buf(d, length);
- if (res) return res;
- }
-
- d->source += 4;
-
- /* copy block */
- for (i = length; i; --i) *d->dest++ = *d->source++;
- d->destRemaining -= length;
-
- /* make sure we start next block on a byte boundary */
- d->bitcount = 0;
-
- return TINF_OK;
-}
-
-/* inflate a block of data compressed with fixed huffman trees */
-static int tinf_inflate_fixed_block(TINF_DATA *d)
-{
- /* build fixed huffman trees */
- tinf_build_fixed_trees(&d->ltree, &d->dtree);
-
- /* decode block using fixed trees */
- return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
-}
-
-/* inflate a block of data compressed with dynamic huffman trees */
-static int tinf_inflate_dynamic_block(TINF_DATA *d)
-{
- /* decode trees from stream */
- tinf_decode_trees(d, &d->ltree, &d->dtree);
-
- /* decode block using decoded trees */
- return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
+ if (d->curlen == 0) {
+ unsigned int length, invlength;
+
+ /* get length */
+ length = uzlib_get_byte(d) + 256 * uzlib_get_byte(d);
+ /* get one's complement of length */
+ invlength = uzlib_get_byte(d) + 256 * uzlib_get_byte(d);
+ /* check length */
+ if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR;
+
+ /* increment length to properly return TINF_DONE below, without
+ producing data at the same time */
+ d->curlen = length + 1;
+
+ /* make sure we start next block on a byte boundary */
+ d->bitcount = 0;
+ }
+
+ if (--d->curlen == 0) {
+ return TINF_DONE;
+ }
+
+ unsigned char c = uzlib_get_byte(d);
+ TINF_PUT(d, c);
+ return TINF_OK;
}
/* ---------------------- *
@@ -432,7 +419,7 @@ static int tinf_inflate_dynamic_block(TINF_DATA *d)
* ---------------------- */
/* initialize global (static) data */
-void tinf_init(void)
+void uzlib_init(void)
{
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
@@ -445,72 +432,117 @@ void tinf_init(void)
#endif
}
-/* inflate stream from source to dest */
-int tinf_uncompress(void *dest, unsigned int *destLen,
- const void *source, unsigned int sourceLen)
+/* initialize decompression structure */
+void uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen)
{
- (void)sourceLen;
- TINF_DATA d;
- int res;
-
- /* initialise data */
- d.source = (const unsigned char *)source;
-
- d.destStart = (unsigned char *)dest;
- d.destRemaining = *destLen;
- d.destSize = *destLen;
-
- res = tinf_uncompress_dyn(&d);
-
- *destLen = d.dest - d.destStart;
+ d->bitcount = 0;
+ d->bfinal = 0;
+ d->btype = -1;
+ d->dict_size = dictLen;
+ d->dict_ring = dict;
+ d->dict_idx = 0;
+ d->curlen = 0;
+}
- return res;
+/* inflate next byte of compressed stream */
+int uzlib_uncompress(TINF_DATA *d)
+{
+ do {
+ int res;
+
+ /* start a new block */
+ if (d->btype == -1) {
+next_blk:
+ /* read final block flag */
+ d->bfinal = tinf_getbit(d);
+ /* read block type (2 bits) */
+ d->btype = tinf_read_bits(d, 2, 0);
+
+ //printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal);
+
+ if (d->btype == 1) {
+ /* build fixed huffman trees */
+ tinf_build_fixed_trees(&d->ltree, &d->dtree);
+ } else if (d->btype == 2) {
+ /* decode trees from stream */
+ tinf_decode_trees(d, &d->ltree, &d->dtree);
+ }
+ }
+
+ /* process current block */
+ switch (d->btype)
+ {
+ case 0:
+ /* decompress uncompressed block */
+ res = tinf_inflate_uncompressed_block(d);
+ break;
+ case 1:
+ case 2:
+ /* decompress block with fixed/dyanamic huffman trees */
+ /* trees were decoded previously, so it's the same routine for both */
+ res = tinf_inflate_block_data(d, &d->ltree, &d->dtree);
+ break;
+ default:
+ return TINF_DATA_ERROR;
+ }
+
+ if (res == TINF_DONE && !d->bfinal) {
+ /* the block has ended (without producing more data), but we
+ can't return without data, so start procesing next block */
+ goto next_blk;
+ }
+
+ if (res != TINF_OK) {
+ return res;
+ }
+
+ } while (--d->destSize);
+
+ return TINF_OK;
}
-/* inflate stream from source to dest */
-int tinf_uncompress_dyn(TINF_DATA *d)
+int uzlib_uncompress_chksum(TINF_DATA *d)
{
- int bfinal;
+ int res;
+ unsigned char *data = d->dest;
- /* initialise data */
- d->bitcount = 0;
+ res = uzlib_uncompress(d);
- d->dest = d->destStart;
- d->destRemaining = d->destSize;
+ if (res < 0) return res;
- do {
+ switch (d->checksum_type) {
- unsigned int btype;
- int res;
+ case TINF_CHKSUM_ADLER:
+ d->checksum = uzlib_adler32(data, d->dest - data, d->checksum);
+ break;
- /* read final block flag */
- bfinal = tinf_getbit(d);
+ case TINF_CHKSUM_CRC:
+ d->checksum = uzlib_crc32(data, d->dest - data, d->checksum);
+ break;
+ }
- /* read block type (2 bits) */
- btype = tinf_read_bits(d, 2, 0);
+ if (res == TINF_DONE) {
+ unsigned int val;
- /* decompress block */
- switch (btype)
- {
- case 0:
- /* decompress uncompressed block */
- res = tinf_inflate_uncompressed_block(d);
- break;
- case 1:
- /* decompress block with fixed huffman trees */
- res = tinf_inflate_fixed_block(d);
- break;
- case 2:
- /* decompress block with dynamic huffman trees */
- res = tinf_inflate_dynamic_block(d);
- break;
- default:
- return TINF_DATA_ERROR;
- }
+ switch (d->checksum_type) {
- if (res != TINF_OK) return TINF_DATA_ERROR;
+ case TINF_CHKSUM_ADLER:
+ val = tinf_get_be_uint32(d);
+ if (d->checksum != val) {
+ return TINF_CHKSUM_ERROR;
+ }
+ break;
- } while (!bfinal);
+ case TINF_CHKSUM_CRC:
+ val = tinf_get_le_uint32(d);
+ if (~d->checksum != val) {
+ return TINF_CHKSUM_ERROR;
+ }
+ // Uncompressed size. TODO: Check
+ val = tinf_get_le_uint32(d);
+ break;
+ }
+ }
- return TINF_OK;
+ return res;
}
diff --git a/extmod/uzlib/tinfzlib.c b/extmod/uzlib/tinfzlib.c
index dbacc1d9db..74fade3b9d 100644
--- a/extmod/uzlib/tinfzlib.c
+++ b/extmod/uzlib/tinfzlib.c
@@ -6,6 +6,8 @@
*
* http://www.ibsensoftware.com/
*
+ * Copyright (c) 2014-2016 by Paul Sokolovsky
+ *
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
@@ -33,35 +35,14 @@
#include "tinf.h"
-int tinf_zlib_uncompress(void *dest, unsigned int *destLen,
- const void *source, unsigned int sourceLen)
-{
- TINF_DATA d;
- int res;
-
- /* initialise data */
- d.source = (const unsigned char *)source;
-
- d.destStart = (unsigned char *)dest;
- d.destRemaining = *destLen;
-
- res = tinf_zlib_uncompress_dyn(&d, sourceLen);
-
- *destLen = d.dest - d.destStart;
-
- return res;
-}
-
-int tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen)
+int uzlib_zlib_parse_header(TINF_DATA *d)
{
- unsigned int a32;
- int res;
unsigned char cmf, flg;
/* -- get header bytes -- */
- cmf = d->source[0];
- flg = d->source[1];
+ cmf = uzlib_get_byte(d);
+ flg = uzlib_get_byte(d);
/* -- check format -- */
@@ -77,25 +58,9 @@ int tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen)
/* check there is no preset dictionary */
if (flg & 0x20) return TINF_DATA_ERROR;
- /* -- get adler32 checksum -- */
+ /* initialize for adler32 checksum */
+ d->checksum_type = TINF_CHKSUM_ADLER;
+ d->checksum = 1;
- a32 = d->source[sourceLen - 4];
- a32 = 256*a32 + d->source[sourceLen - 3];
- a32 = 256*a32 + d->source[sourceLen - 2];
- a32 = 256*a32 + d->source[sourceLen - 1];
-
- d->source += 2;
-
- /* -- inflate -- */
-
- res = tinf_uncompress_dyn(d);
-
- if (res != TINF_OK) return res;
-
- /* -- check adler32 checksum -- */
-
- if (a32 != tinf_adler32(d->destStart, d->dest - d->destStart)) return TINF_DATA_ERROR;
-
- return TINF_OK;
+ return cmf >> 4;
}
-
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index a691ee062c..eea075f6b0 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -250,6 +250,13 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
+// Unmount the filesystem
+STATIC mp_obj_t fat_vfs_umount(mp_obj_t vfs_in) {
+ fatfs_umount(((fs_user_mount_t *)vfs_in)->readblocks[1]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, fat_vfs_umount);
+
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) },
@@ -261,6 +268,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) },
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) },
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) },
+ { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
};
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);