@@ -240,6 +240,52 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
240240}
241241STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_send_obj , socket_send );
242242
243+
244+ // helper function for socket_recv and socket_recv_into to handle common operations of both
245+ STATIC mp_int_t _socket_recv_into (mod_network_socket_obj_t * sock , byte * buf , mp_int_t len ) {
246+ int _errno ;
247+ mp_int_t ret = sock -> nic_type -> recv (sock , buf , len , & _errno );
248+ if (ret == -1 ) {
249+ mp_raise_OSError (_errno );
250+ }
251+ return len ;
252+ }
253+
254+
255+ //| .. method:: recv_into(buffer[, bufsize])
256+ //|
257+ //| Reads some bytes from the connected remote address, writing
258+ //| into the provided buffer. If bufsize <= len(buffer) is given,
259+ //| a maximum of bufsize bytes will be read into the buffer. If no
260+ //| valid value is given for bufsize, the default is the length of
261+ //| the given buffer.
262+ //|
263+ //| Suits sockets of type SOCK_STREAM
264+ //| Returns an int of number of bytes read.
265+ //|
266+ //| :param bytearray buffer: buffer to receive into
267+ //| :param int bufsize: optionally, a maximum number of bytes to read.
268+
269+ STATIC mp_obj_t socket_recv_into (size_t n_args , const mp_obj_t * args ) {
270+ mod_network_socket_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
271+ if (self -> nic == MP_OBJ_NULL ) {
272+ // not connected
273+ mp_raise_OSError (MP_ENOTCONN );
274+ }
275+ mp_buffer_info_t bufinfo ;
276+ mp_get_buffer_raise (args [1 ], & bufinfo , MP_BUFFER_WRITE );
277+ mp_int_t len ;
278+ if (n_args == 3 ) {
279+ len = mp_obj_get_int (args [2 ]);
280+ }
281+ if (n_args == 2 || (size_t ) len > bufinfo .len ) {
282+ len = bufinfo .len ;
283+ }
284+ mp_int_t ret = _socket_recv_into (self , (byte * )bufinfo .buf , len );
285+ return mp_obj_new_int_from_uint (ret );
286+ }
287+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (socket_recv_into_obj , 2 , 3 , socket_recv_into );
288+
243289//| .. method:: recv(bufsize)
244290//|
245291//| Reads some bytes from the connected remote address.
@@ -257,11 +303,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
257303 mp_int_t len = mp_obj_get_int (len_in );
258304 vstr_t vstr ;
259305 vstr_init_len (& vstr , len );
260- int _errno ;
261- mp_int_t ret = self -> nic_type -> recv (self , (byte * )vstr .buf , len , & _errno );
262- if (ret == -1 ) {
263- mp_raise_OSError (_errno );
264- }
306+ mp_int_t ret = _socket_recv_into (self , (byte * )vstr .buf , len );
265307 if (ret == 0 ) {
266308 return mp_const_empty_bytes ;
267309 }
@@ -436,6 +478,7 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
436478 { MP_ROM_QSTR (MP_QSTR_recv ), MP_ROM_PTR (& socket_recv_obj ) },
437479 { MP_ROM_QSTR (MP_QSTR_sendto ), MP_ROM_PTR (& socket_sendto_obj ) },
438480 { MP_ROM_QSTR (MP_QSTR_recvfrom ), MP_ROM_PTR (& socket_recvfrom_obj ) },
481+ { MP_ROM_QSTR (MP_QSTR_recv_into ), MP_ROM_PTR (& socket_recv_into_obj ) },
439482 { MP_ROM_QSTR (MP_QSTR_setsockopt ), MP_ROM_PTR (& socket_setsockopt_obj ) },
440483 { MP_ROM_QSTR (MP_QSTR_settimeout ), MP_ROM_PTR (& socket_settimeout_obj ) },
441484 { MP_ROM_QSTR (MP_QSTR_setblocking ), MP_ROM_PTR (& socket_setblocking_obj ) },
0 commit comments