Skip to content

Commit c094509

Browse files
committed
py/objint.c: Code review of int_from_bytes().
Support signed param: result = int.int_from_bytes(bytearray(), order='big'|'little', signed=False|True) Signed-off-by: Ihor Nehrutsa <[email protected]>
1 parent 8987b39 commit c094509

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

py/objint.c

+92
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include <math.h>
4040
#endif
4141

42+
#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, "\n"); // mp_printf(&mp_plat_print, " | func:%s line:%d at %s\n", __FUNCTION__, __LINE__, __FILE__);
43+
4244
// This dispatcher function is expected to be independent of the implementation of long int
4345
static mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
4446
(void)type_in;
@@ -387,6 +389,7 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp
387389
return MP_OBJ_NULL; // op not supported
388390
}
389391

392+
/*
390393
// this is a classmethod
391394
static mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *args) {
392395
// TODO: Support signed param (assumes signed=False at the moment)
@@ -416,6 +419,89 @@ static mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *args) {
416419
}
417420
return mp_obj_new_int_from_uint(value);
418421
}
422+
*/
423+
static void *reverce_memcpy(void *dest, const void *src, size_t len) {
424+
char *d = dest + len - 1;
425+
const char *s = src;
426+
while (len--) {
427+
*d-- = *s++;
428+
}
429+
return dest;
430+
}
431+
432+
// this is a classmethod
433+
// result = int.int_from_bytes(bytearray(), order='big', signed=False)
434+
static mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *args) {
435+
mp_buffer_info_t bufinfo;
436+
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
437+
const byte *buf = (const byte *)bufinfo.buf;
438+
bool big_endian = (n_args < 3) || (args[2] != MP_OBJ_NEW_QSTR(MP_QSTR_little));
439+
bool signd = (n_args > 3) && mp_obj_is_true(args[3]);
440+
441+
//debug_printf("mp_obj_is_bool(args[3])=%d", mp_obj_is_bool(args[3]));
442+
//debug_printf("n_args=%d, MP_SMALL_INT_MAX=%d, MP_SMALL_INT_MIN=%d", n_args, MP_SMALL_INT_MAX, MP_SMALL_INT_MIN);
443+
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
444+
//if (((1U << (bufinfo.len * 8 - 2)) > (MP_SMALL_INT_MAX + 1)) || (big_endian ? buf[0] & 0x80 : buf[bufinfo.len - 1] & 0x80)) {
445+
if ((1ULL << (bufinfo.len * 8 - 2)) > (MP_SMALL_INT_MAX + 1)) {
446+
debug_printf("//1 Result will overflow a small-int so construct a big-int");
447+
return mp_obj_int_from_bytes_impl(big_endian, bufinfo.len, bufinfo.buf);
448+
}
449+
#endif
450+
451+
union {
452+
mp_int_t ival;
453+
mp_uint_t uval;
454+
} result;
455+
if (big_endian) {
456+
reverce_memcpy(&result.uval, buf, bufinfo.len);
457+
} else {
458+
memcpy(&result.uval, buf, bufinfo.len);
459+
}
460+
if (signd) {
461+
debug_printf("big_endian:%d signed:%d bufinfo.len:%d sizeof(result.ival):%d result.ival:%ld", big_endian, signd, bufinfo.len, sizeof(result.ival), result.ival);
462+
if ((result.ival > MP_SMALL_INT_MAX) || (result.ival < MP_SMALL_INT_MIN)) {
463+
debug_printf("//2 Result will overflow a small-int so construct a big-int");
464+
return mp_obj_int_from_bytes_impl(big_endian, bufinfo.len, bufinfo.buf);
465+
}
466+
return mp_obj_new_int(result.ival);
467+
} else {
468+
debug_printf("big_endian:%d signed:%d bufinfo.len:%d sizeof(result.uval):%d result.uval:%ld", big_endian, signd, bufinfo.len, sizeof(result.uval), result.uval);
469+
if (result.uval > MP_SMALL_INT_MAX) {
470+
debug_printf("//3 Result will overflow a small-int so construct a big-int");
471+
return mp_obj_int_from_bytes_impl(big_endian, bufinfo.len, bufinfo.buf);
472+
}
473+
return mp_obj_new_int_from_uint(result.uval);
474+
}
475+
/*
476+
if (signd) {
477+
mp_int_t result = 0;
478+
if (big_endian) {
479+
reverce_memcpy(&result, buf, bufinfo.len);
480+
} else {
481+
memcpy(&result, buf, bufinfo.len);
482+
}
483+
debug_printf("big_endian:%d signed:%d bufinfo.len:%d sizeof(result):%d result:%ld", big_endian, signd, bufinfo.len, sizeof(result), result);
484+
if ((result > MP_SMALL_INT_MAX) || (result < MP_SMALL_INT_MIN)) {
485+
debug_printf("// Result will overflow a small-int so construct a big-int");
486+
return mp_obj_int_from_bytes_impl(big_endian, bufinfo.len, bufinfo.buf);
487+
}
488+
return mp_obj_new_int(result);
489+
} else {
490+
mp_uint_t result = 0;
491+
if (big_endian) {
492+
reverce_memcpy(&result, buf, bufinfo.len);
493+
} else {
494+
memcpy(&result, buf, bufinfo.len);
495+
}
496+
debug_printf("big_endian:%d unsigned:%d bufinfo.len:%d sizeof(result):%d result:%ld", big_endian, signd, bufinfo.len, sizeof(result), result);
497+
if ((result > MP_SMALL_INT_MAX) || (result < MP_SMALL_INT_MIN)) {
498+
debug_printf("// Result will overflow a small-int so construct a big-int");
499+
return mp_obj_int_from_bytes_impl(big_endian, bufinfo.len, bufinfo.buf);
500+
}
501+
return mp_obj_new_int_from_uint(result);
502+
}
503+
*/
504+
}
419505

420506
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_from_bytes_fun_obj, 2, 4, int_from_bytes);
421507
static MP_DEFINE_CONST_CLASSMETHOD_OBJ(int_from_bytes_obj, MP_ROM_PTR(&int_from_bytes_fun_obj));
@@ -470,9 +556,15 @@ static mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *args) {
470556
}
471557
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_to_bytes_obj, 1, 4, int_to_bytes);
472558

559+
static mp_obj_t int_value(mp_obj_t self_in) {
560+
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(self_in));
561+
}
562+
static MP_DEFINE_CONST_FUN_OBJ_1(int_value_obj, int_value);
563+
473564
static const mp_rom_map_elem_t int_locals_dict_table[] = {
474565
{ MP_ROM_QSTR(MP_QSTR_from_bytes), MP_ROM_PTR(&int_from_bytes_obj) },
475566
{ MP_ROM_QSTR(MP_QSTR_to_bytes), MP_ROM_PTR(&int_to_bytes_obj) },
567+
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&int_value_obj) },
476568
};
477569

478570
static MP_DEFINE_CONST_DICT(int_locals_dict, int_locals_dict_table);

0 commit comments

Comments
 (0)