py: Make mp_binary_set_val work on big endian machine.
This commit is contained in:
parent
fcdb239815
commit
9336ee320a
@ -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);
|
set_aligned_basic(val_type & 6, self->addr + offset, val);
|
||||||
} else {
|
} else {
|
||||||
mp_binary_set_int(GET_SCALAR_SIZE(val_type & 7), self->flags == LAYOUT_BIG_ENDIAN,
|
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
|
return set_val; // just !MP_OBJ_NULL
|
||||||
}
|
}
|
||||||
|
58
py/binary.c
58
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
|
// 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
|
// most 8 (for q and Q), so we will always be able to parse the given data
|
||||||
// and fit it into a long long.
|
// 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;
|
int delta;
|
||||||
if (!big_endian) {
|
if (!big_endian) {
|
||||||
delta = -1;
|
delta = -1;
|
||||||
p += size - 1;
|
src += size - 1;
|
||||||
} else {
|
} else {
|
||||||
delta = 1;
|
delta = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long val = 0;
|
long long val = 0;
|
||||||
if (is_signed && *p & 0x80) {
|
if (is_signed && *src & 0x80) {
|
||||||
val = -1;
|
val = -1;
|
||||||
}
|
}
|
||||||
for (uint i = 0; i < size; i++) {
|
for (uint i = 0; i < size; i++) {
|
||||||
val <<= 8;
|
val <<= 8;
|
||||||
val |= *p;
|
val |= *src;
|
||||||
p += delta;
|
src += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
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) {
|
void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *dest, mp_uint_t val) {
|
||||||
int in_delta, out_delta;
|
if (MP_ENDIANNESS_LITTLE && !big_endian) {
|
||||||
if (big_endian) {
|
memcpy(dest, &val, val_sz);
|
||||||
in_delta = -1;
|
} else if (MP_ENDIANNESS_BIG && big_endian) {
|
||||||
out_delta = 1;
|
// only copy the least-significant val_sz bytes
|
||||||
val_ptr += val_sz - 1;
|
memcpy(dest, (byte*)&val + sizeof(mp_uint_t) - val_sz, val_sz);
|
||||||
} else {
|
} else {
|
||||||
in_delta = out_delta = 1;
|
const byte *src;
|
||||||
}
|
if (MP_ENDIANNESS_LITTLE) {
|
||||||
|
src = (const byte*)&val + val_sz;
|
||||||
for (uint i = val_sz; i > 0; i--) {
|
} else {
|
||||||
*p = *val_ptr;
|
src = (const byte*)&val + sizeof(mp_uint_t);
|
||||||
p += out_delta;
|
}
|
||||||
val_ptr += in_delta;
|
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 == '@') {
|
if (struct_type == '@') {
|
||||||
// Make pointer aligned
|
// Make pointer aligned
|
||||||
p = (byte*)(((mp_uint_t)p + align - 1) & ~((mp_uint_t)align - 1));
|
p = (byte*)(((mp_uint_t)p + align - 1) & ~((mp_uint_t)align - 1));
|
||||||
#if MP_ENDIANNESS_LITTLE
|
if (MP_ENDIANNESS_LITTLE) {
|
||||||
struct_type = '<';
|
struct_type = '<';
|
||||||
#else
|
} else {
|
||||||
struct_type = '>';
|
struct_type = '>';
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
*ptr = p + size;
|
*ptr = p + size;
|
||||||
|
|
||||||
#if MP_ENDIANNESS_BIG
|
mp_uint_t val;
|
||||||
#error Not implemented
|
|
||||||
#endif
|
|
||||||
mp_int_t val;
|
|
||||||
byte *in = (byte*)&val;
|
|
||||||
switch (val_type) {
|
switch (val_type) {
|
||||||
case 'O':
|
case 'O':
|
||||||
in = (byte*)&val_in;
|
val = (mp_uint_t)val_in;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
val = mp_obj_get_int(val_in);
|
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) {
|
void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t val_in) {
|
||||||
|
@ -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);
|
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);
|
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);
|
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);
|
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 *p, byte *val_ptr);
|
void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *dest, mp_uint_t val);
|
||||||
|
@ -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);
|
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."
|
// TODO: "The arguments must match the values required by the format exactly."
|
||||||
const char *fmt = mp_obj_str_get_str(args[0]);
|
const char *fmt = mp_obj_str_get_str(args[0]);
|
||||||
char fmt_type = get_fmt_type(&fmt);
|
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);
|
mp_obj_t res = mp_obj_str_builder_start(&mp_type_bytes, size, &p);
|
||||||
memset(p, 0, size);
|
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;
|
mp_uint_t sz = 1;
|
||||||
if (unichar_isdigit(*fmt)) {
|
if (unichar_isdigit(*fmt)) {
|
||||||
sz = get_fmt_num(&fmt);
|
sz = get_fmt_num(&fmt);
|
||||||
|
Loading…
Reference in New Issue
Block a user