summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/obj.c18
-rw-r--r--py/obj.h2
-rw-r--r--py/objint.c38
-rw-r--r--py/qstrdefs.h2
-rw-r--r--tests/basics/int-bytes.py6
-rw-r--r--unix/modsocket.c21
6 files changed, 69 insertions, 18 deletions
diff --git a/py/obj.c b/py/obj.c
index 8d5467c5e7..d1db53690f 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -330,3 +330,21 @@ mp_obj_t mp_identity(mp_obj_t self) {
return self;
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity);
+
+bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) {
+ mp_obj_base_t *o = (mp_obj_base_t *)obj;
+ if (o->type->buffer_p.get_buffer == NULL) {
+ return false;
+ }
+ o->type->buffer_p.get_buffer(o, bufinfo, BUFFER_READ);
+ if (bufinfo->buf == NULL) {
+ return false;
+ }
+ return true;
+}
+
+void mp_get_buffer_raise(mp_obj_t obj, buffer_info_t *bufinfo) {
+ if (!mp_get_buffer(obj, bufinfo)) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Object with buffer protocol required"));
+ }
+}
diff --git a/py/obj.h b/py/obj.h
index 92dd6a8a0b..ab1685d4d0 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -196,6 +196,8 @@ typedef struct _buffer_info_t {
typedef struct _mp_buffer_p_t {
machine_int_t (*get_buffer)(mp_obj_t obj, buffer_info_t *bufinfo, int flags);
} mp_buffer_p_t;
+bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo);
+void mp_get_buffer_raise(mp_obj_t obj, buffer_info_t *bufinfo);
// Stream protocol
typedef struct _mp_stream_p_t {
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)
diff --git a/tests/basics/int-bytes.py b/tests/basics/int-bytes.py
new file mode 100644
index 0000000000..45965ed464
--- /dev/null
+++ b/tests/basics/int-bytes.py
@@ -0,0 +1,6 @@
+print((10).to_bytes(1, "little"))
+print((111111).to_bytes(4, "little"))
+print((100).to_bytes(10, "little"))
+print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little"))
+print(int.from_bytes(b"\x01\0\0\0\0\0\0\0", "little"))
+print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little"))
diff --git a/unix/modsocket.c b/unix/modsocket.c
index 62f10300f8..8f47a8b157 100644
--- a/unix/modsocket.c
+++ b/unix/modsocket.c
@@ -34,21 +34,6 @@ STATIC const mp_obj_type_t microsocket_type;
{ if (err_flag == -1) \
{ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error_val)); } }
-STATIC void get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) {
- mp_obj_base_t *o = (mp_obj_base_t *)obj;
- if (o->type->buffer_p.get_buffer == NULL) {
- goto error;
- }
- o->type->buffer_p.get_buffer(o, bufinfo, BUFFER_READ);
- if (bufinfo->buf == NULL) {
- goto error;
- }
- return;
-
-error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Operation not supported"));
-}
-
STATIC mp_obj_socket_t *socket_new(int fd) {
mp_obj_socket_t *o = m_new_obj(mp_obj_socket_t);
o->base.type = &microsocket_type;
@@ -96,7 +81,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_fileno_obj, socket_fileno);
STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
mp_obj_socket_t *self = self_in;
buffer_info_t bufinfo;
- get_buffer(addr_in, &bufinfo);
+ mp_get_buffer_raise(addr_in, &bufinfo);
int r = connect(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len);
RAISE_ERRNO(r, errno);
return mp_const_none;
@@ -106,7 +91,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
mp_obj_socket_t *self = self_in;
buffer_info_t bufinfo;
- get_buffer(addr_in, &bufinfo);
+ mp_get_buffer_raise(addr_in, &bufinfo);
int r = bind(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len);
RAISE_ERRNO(r, errno);
return mp_const_none;
@@ -184,7 +169,7 @@ STATIC mp_obj_t socket_setsockopt(uint n_args, const mp_obj_t *args) {
optlen = sizeof(val);
} else {
buffer_info_t bufinfo;
- get_buffer(args[3], &bufinfo);
+ mp_get_buffer_raise(args[3], &bufinfo);
optval = bufinfo.buf;
optlen = bufinfo.len;
}