summaryrefslogtreecommitdiffstatshomepage
path: root/py/binary.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/binary.c')
-rw-r--r--py/binary.c58
1 files changed, 28 insertions, 30 deletions
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) {