From d1f288c041c85793de17da9f8b38ff20af2a6f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20de=20Giessen?= Date: Wed, 23 Nov 2022 14:26:26 +0100 Subject: [PATCH] py/modstruct: Support pad bytes in struct format. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for the x format code in struct.pack and struct.unpack. The primary use case for this is ignoring bytes while unpacking. When interfacing with existing systems, it may often happen that you either have fields in a struct that aren't properly specified or you simply don't care about them. Being able to easily skip them is useful. Signed-off-by: Daniƫl van de Giessen --- py/modstruct.c | 13 ++++++++++--- tests/basics/struct1.py | 9 +++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/py/modstruct.c b/py/modstruct.c index 42f91b282..b3edc9632 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -92,7 +92,9 @@ STATIC size_t calc_size_items(const char *fmt, size_t *total_sz) { cnt = get_fmt_num(&fmt); } - if (*fmt == 's') { + if (*fmt == 'x') { + size += cnt; + } else if (*fmt == 's') { total_cnt += 1; size += cnt; } else { @@ -159,7 +161,9 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { cnt = get_fmt_num(&fmt); } mp_obj_t item; - if (*fmt == 's') { + if (*fmt == 'x') { + p += cnt; + } else if (*fmt == 's') { item = mp_obj_new_bytes(p, cnt); p += cnt; res->items[i++] = item; @@ -192,7 +196,10 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c cnt = get_fmt_num(&fmt); } - if (*fmt == 's') { + if (*fmt == 'x') { + memset(p, 0, cnt); + p += cnt; + } else if (*fmt == 's') { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); mp_uint_t to_copy = cnt; diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index a18655517..e473ffcc1 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -20,6 +20,8 @@ print(struct.pack("h", 1)) print(struct.pack("b", 1)) +print(struct.pack("x")) print(struct.pack("bI", -128, 256)) @@ -29,6 +31,13 @@ print(struct.calcsize("97sI")) print(struct.unpack("<6sH", b"foo\0\0\0\x12\x34")) print(struct.pack("<6sH", b"foo", 10000)) +print(struct.calcsize("7xx")) +print(struct.pack("7xx")) + +print(struct.calcsize(">bxI3xH")) +print(struct.pack(">bxI3xH", 1, 2, 3)) +print(struct.unpack(">bxI3xH", b"\x01\0\0\0\0\x02\0\0\0\0\x03")) + s = struct.pack("BHBI", 10, 100, 200, 300) v = struct.unpack("BHBI", s) print(v == (10, 100, 200, 300))