summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-04-09 00:40:58 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-04-09 01:07:37 +0300
commita985b4593d3f0c788c5e6ef0066bf82ae550cfb8 (patch)
treee21b447b57350f1261596c2d7cc81fdb30de722f /py
parent3aa8ee7c9e2e9fd50ffb4b588518bd84b40fef84 (diff)
downloadmicropython-a985b4593d3f0c788c5e6ef0066bf82ae550cfb8.tar.gz
micropython-a985b4593d3f0c788c5e6ef0066bf82ae550cfb8.zip
objint: Implement int.from_bytes() class method and .to_bytes() method.
These two are apprerently the most concise and efficient way to convert int to/from bytes in Python. The alternatives are struct and array modules, but methods using them are more verbose in Python code and less efficient in memory/cycles.
Diffstat (limited to 'py')
-rw-r--r--py/objint.c38
-rw-r--r--py/qstrdefs.h2
2 files changed, 40 insertions, 0 deletions
diff --git a/py/objint.c b/py/objint.c
index e1b67a16b3..05269ce379 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -261,6 +261,43 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(int op, mp_obj_t lhs_in, mp_obj_t rhs_
return MP_OBJ_NULL;
}
+STATIC mp_obj_t int_from_bytes(uint n_args, const mp_obj_t *args) {
+ buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[0], &bufinfo);
+
+ assert(bufinfo.len >= sizeof(machine_int_t));
+ // TODO: Support long ints
+ // TODO: Support byteorder param
+ // TODO: Support signed param
+ return mp_obj_new_int_from_uint(*(machine_uint_t*)bufinfo.buf);
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_from_bytes_obj, 1, 3, int_from_bytes);
+
+STATIC mp_obj_t int_to_bytes(uint n_args, const mp_obj_t *args) {
+ machine_int_t val = mp_obj_int_get_checked(args[0]);
+
+ uint len = MP_OBJ_SMALL_INT_VALUE(args[1]);
+ byte *data;
+
+ // TODO: Support long ints
+ // TODO: Support byteorder param
+ // TODO: Support signed param
+ mp_obj_t o = mp_obj_str_builder_start(&mp_type_bytes, len, &data);
+ memset(data, 0, len);
+ memcpy(data, &val, len < sizeof(machine_int_t) ? len : sizeof(machine_int_t));
+ return mp_obj_str_builder_end(o);
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_to_bytes_obj, 2, 4, int_to_bytes);
+
+STATIC const mp_map_elem_t int_locals_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_from_bytes), (mp_obj_t)&int_from_bytes_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_to_bytes), (mp_obj_t)&int_to_bytes_obj },
+};
+
+STATIC MP_DEFINE_CONST_DICT(int_locals_dict, int_locals_dict_table);
+
const mp_obj_type_t mp_type_int = {
{ &mp_type_type },
.name = MP_QSTR_int,
@@ -268,4 +305,5 @@ const mp_obj_type_t mp_type_int = {
.make_new = mp_obj_int_make_new,
.unary_op = mp_obj_int_unary_op,
.binary_op = mp_obj_int_binary_op,
+ .locals_dict = (mp_obj_t)&int_locals_dict,
};
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 29eb51d0ba..0c2c032f29 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -96,6 +96,7 @@ Q(eval)
Q(exec)
Q(filter)
Q(float)
+Q(from_bytes)
Q(getattr)
Q(globals)
Q(hash)
@@ -127,6 +128,7 @@ Q(sum)
Q(super)
Q(str)
Q(sys)
+Q(to_bytes)
Q(tuple)
Q(type)
Q(value)