summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2019-01-21 00:31:45 -0800
committerGitHub <noreply@github.com>2019-01-21 00:31:45 -0800
commitb369fa9013d3d0be48bef113811c4acddcd53ba5 (patch)
tree00ebdb0656a8101363a7a1e16c44201045542b84 /py
parent6b88d0f94eb1459562d0f159688b504a6f5d408f (diff)
parent9558b3afa7d90e1f84070088b0f7c4c21def4683 (diff)
Merge pull request #1478 from dhalbert/struct-compat
Improve struct compatibility with CPython
Diffstat (limited to 'py')
-rw-r--r--py/binary.c7
-rw-r--r--py/modstruct.c16
2 files changed, 18 insertions, 5 deletions
diff --git a/py/binary.c b/py/binary.c
index ca851c936..9c3a49e8f 100644
--- a/py/binary.c
+++ b/py/binary.c
@@ -49,7 +49,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
switch (struct_type) {
case '<': case '>':
switch (val_type) {
- case 'b': case 'B':
+ case 'b': case 'B': case 'x':
size = 1; break;
case 'h': case 'H':
size = 2; break;
@@ -79,7 +79,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
// particular (or any) ABI.
switch (val_type) {
case BYTEARRAY_TYPECODE:
- case 'b': case 'B':
+ case 'b': case 'B': case 'x':
align = size = 1; break;
case 'h': case 'H':
align = alignof(short);
@@ -126,6 +126,7 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) {
break;
case BYTEARRAY_TYPECODE:
case 'B':
+ case 'x': // value will be discarded
val = ((unsigned char*)p)[index];
break;
case 'h':
@@ -364,6 +365,8 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m
case 'B':
((unsigned char*)p)[index] = val;
break;
+ case 'x':
+ ((unsigned char*)p)[index] = 0;
case 'h':
((short*)p)[index] = val;
break;
diff --git a/py/modstruct.c b/py/modstruct.c
index 3f1b2f8b8..a238d3935 100644
--- a/py/modstruct.c
+++ b/py/modstruct.c
@@ -97,7 +97,10 @@ STATIC size_t calc_size_items(const char *fmt, size_t *total_sz) {
total_cnt += 1;
size += cnt;
} else {
- total_cnt += cnt;
+ // Pad bytes are skipped and don't get included in the item count.
+ if (*fmt != 'x') {
+ total_cnt += cnt;
+ }
mp_uint_t align;
size_t sz = mp_binary_get_size(fmt_type, *fmt, &align);
while (cnt--) {
@@ -166,7 +169,10 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
} else {
while (cnt--) {
item = mp_binary_get_val(fmt_type, *fmt, &p);
- res->items[i++] = item;
+ // Pad bytes ('x') are just skipped.
+ if (*fmt != 'x') {
+ res->items[i++] = item;
+ }
}
}
fmt++;
@@ -204,7 +210,11 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c
} else {
// If we run out of args then we just finish; CPython would raise struct.error
while (cnt-- && i < n_args) {
- mp_binary_set_val(fmt_type, *fmt, args[i++], &p);
+ mp_binary_set_val(fmt_type, *fmt, args[i], &p);
+ // Pad bytes don't have a corresponding argument.
+ if (*fmt != 'x') {
+ i++;
+ }
}
}
fmt++;