diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 3e35ed682a..bc18247656 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -401,7 +401,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set set_aligned_basic(val_type & 6, self->addr + offset, val); } else { mp_binary_set_int(GET_SCALAR_SIZE(val_type & 7), self->flags == LAYOUT_BIG_ENDIAN, - self->addr + offset, (byte*)&val); + self->addr + offset, val); } return set_val; // just !MP_OBJ_NULL } diff --git a/py/binary.c b/py/binary.c index 1201ec34fa..fed69f9d1b 100644 --- a/py/binary.c +++ b/py/binary.c @@ -140,23 +140,23 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { // The long long type is guaranteed to hold at least 64 bits, and size is at // most 8 (for q and Q), so we will always be able to parse the given data // and fit it into a long long. -long long mp_binary_get_int(mp_uint_t size, bool is_signed, bool big_endian, byte *p) { +long long mp_binary_get_int(mp_uint_t size, bool is_signed, bool big_endian, const byte *src) { int delta; if (!big_endian) { delta = -1; - p += size - 1; + src += size - 1; } else { delta = 1; } long long val = 0; - if (is_signed && *p & 0x80) { + if (is_signed && *src & 0x80) { val = -1; } for (uint i = 0; i < size; i++) { val <<= 8; - val |= *p; - p += delta; + val |= *src; + src += delta; } return val; @@ -201,20 +201,22 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) { } } -void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *p, byte *val_ptr) { - int in_delta, out_delta; - if (big_endian) { - in_delta = -1; - out_delta = 1; - val_ptr += val_sz - 1; +void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *dest, mp_uint_t val) { + if (MP_ENDIANNESS_LITTLE && !big_endian) { + memcpy(dest, &val, val_sz); + } else if (MP_ENDIANNESS_BIG && big_endian) { + // only copy the least-significant val_sz bytes + memcpy(dest, (byte*)&val + sizeof(mp_uint_t) - val_sz, val_sz); } else { - in_delta = out_delta = 1; - } - - for (uint i = val_sz; i > 0; i--) { - *p = *val_ptr; - p += out_delta; - val_ptr += in_delta; + const byte *src; + if (MP_ENDIANNESS_LITTLE) { + src = (const byte*)&val + val_sz; + } else { + src = (const byte*)&val + sizeof(mp_uint_t); + } + while (val_sz--) { + *dest++ = *--src; + } } } @@ -226,28 +228,24 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** if (struct_type == '@') { // Make pointer aligned p = (byte*)(((mp_uint_t)p + align - 1) & ~((mp_uint_t)align - 1)); - #if MP_ENDIANNESS_LITTLE - struct_type = '<'; - #else - struct_type = '>'; - #endif + if (MP_ENDIANNESS_LITTLE) { + struct_type = '<'; + } else { + struct_type = '>'; + } } *ptr = p + size; -#if MP_ENDIANNESS_BIG -#error Not implemented -#endif - mp_int_t val; - byte *in = (byte*)&val; + mp_uint_t val; switch (val_type) { case 'O': - in = (byte*)&val_in; + val = (mp_uint_t)val_in; break; default: val = mp_obj_get_int(val_in); } - mp_binary_set_int(MIN(size, sizeof(val)), struct_type == '>', p, in); + mp_binary_set_int(MIN(size, sizeof(val)), struct_type == '>', p, val); } void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t val_in) { diff --git a/py/binary.h b/py/binary.h index 2a63ba9928..dc9d3f6808 100644 --- a/py/binary.h +++ b/py/binary.h @@ -34,5 +34,5 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, mp_int_t val); mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr); void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **ptr); -long long mp_binary_get_int(mp_uint_t size, bool is_signed, bool big_endian, byte *p); -void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *p, byte *val_ptr); +long long mp_binary_get_int(mp_uint_t size, bool is_signed, bool big_endian, const byte *src); +void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *dest, mp_uint_t val); diff --git a/py/modstruct.c b/py/modstruct.c index 8122a96685..8c0cafda07 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -160,7 +160,7 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) { } MP_DEFINE_CONST_FUN_OBJ_2(struct_unpack_obj, struct_unpack); -STATIC mp_obj_t struct_pack(uint n_args, mp_obj_t *args) { +STATIC mp_obj_t struct_pack(mp_uint_t n_args, const mp_obj_t *args) { // TODO: "The arguments must match the values required by the format exactly." const char *fmt = mp_obj_str_get_str(args[0]); char fmt_type = get_fmt_type(&fmt); @@ -169,7 +169,7 @@ STATIC mp_obj_t struct_pack(uint n_args, mp_obj_t *args) { mp_obj_t res = mp_obj_str_builder_start(&mp_type_bytes, size, &p); memset(p, 0, size); - for (uint i = 1; i < n_args; i++) { + for (mp_uint_t i = 1; i < n_args; i++) { mp_uint_t sz = 1; if (unichar_isdigit(*fmt)) { sz = get_fmt_num(&fmt);