modstruct: Fix alignment handling issues.
Also, factor out mp_binary_get_int() function.
This commit is contained in:
parent
5aa740c3e2
commit
7a2f166949
44
py/binary.c
44
py/binary.c
|
@ -125,6 +125,28 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, int index) {
|
|||
return MP_OBJ_NEW_SMALL_INT(val);
|
||||
}
|
||||
|
||||
machine_int_t mp_binary_get_int(uint size, bool is_signed, bool big_endian, byte *p) {
|
||||
int delta;
|
||||
if (!big_endian) {
|
||||
delta = -1;
|
||||
p += size - 1;
|
||||
} else {
|
||||
delta = 1;
|
||||
}
|
||||
|
||||
machine_int_t val = 0;
|
||||
if (is_signed && *p & 0x80) {
|
||||
val = -1;
|
||||
}
|
||||
for (uint i = 0; i < size; i++) {
|
||||
val <<= 8;
|
||||
val |= *p;
|
||||
p += delta;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#define is_signed(typecode) (typecode > 'Z')
|
||||
mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
|
||||
byte *p = *ptr;
|
||||
|
@ -140,26 +162,10 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
|
|||
struct_type = '>';
|
||||
#endif
|
||||
}
|
||||
*ptr = p + size;
|
||||
|
||||
int delta;
|
||||
if (struct_type == '<') {
|
||||
delta = -1;
|
||||
p += size - 1;
|
||||
} else {
|
||||
delta = 1;
|
||||
}
|
||||
machine_int_t val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p);
|
||||
|
||||
machine_int_t val = 0;
|
||||
if (is_signed(val_type) && *p & 0x80) {
|
||||
val = -1;
|
||||
}
|
||||
for (uint i = 0; i < size; i++) {
|
||||
val <<= 8;
|
||||
val |= *p;
|
||||
p += delta;
|
||||
}
|
||||
|
||||
*ptr += size;
|
||||
if (val_type == 'O') {
|
||||
return (mp_obj_t)val;
|
||||
} else if (val_type == 'S') {
|
||||
|
@ -185,6 +191,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
|
|||
struct_type = '>';
|
||||
#endif
|
||||
}
|
||||
*ptr = p + size;
|
||||
|
||||
#if MP_ENDIANNESS_BIG
|
||||
#error Not implemented
|
||||
|
@ -215,7 +222,6 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
|
|||
in += in_delta;
|
||||
}
|
||||
|
||||
*ptr += size;
|
||||
}
|
||||
|
||||
void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in) {
|
||||
|
|
|
@ -34,3 +34,4 @@ void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in)
|
|||
void mp_binary_set_val_array_from_int(char typecode, void *p, int index, machine_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);
|
||||
machine_int_t mp_binary_get_int(uint size, bool is_signed, bool big_endian, byte *p);
|
||||
|
|
|
@ -21,3 +21,7 @@ print(struct.calcsize("100sI"))
|
|||
print(struct.calcsize("97sI"))
|
||||
print(struct.unpack("<6sH", b"foo\0\0\0\x12\x34"))
|
||||
print(struct.pack("<6sH", b"foo", 10000))
|
||||
|
||||
s = struct.pack("BHBI", 10, 100, 200, 300)
|
||||
v = struct.unpack("BHBI", s)
|
||||
print(v == (10, 100, 200, 300))
|
||||
|
|
Loading…
Reference in New Issue