@@ -240,6 +240,52 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
240
240
}
241
241
STATIC MP_DEFINE_CONST_FUN_OBJ_2 (socket_send_obj , socket_send );
242
242
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
+
243
289
//| .. method:: recv(bufsize)
244
290
//|
245
291
//| 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) {
257
303
mp_int_t len = mp_obj_get_int (len_in );
258
304
vstr_t vstr ;
259
305
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 );
265
307
if (ret == 0 ) {
266
308
return mp_const_empty_bytes ;
267
309
}
@@ -436,6 +478,7 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
436
478
{ MP_ROM_QSTR (MP_QSTR_recv ), MP_ROM_PTR (& socket_recv_obj ) },
437
479
{ MP_ROM_QSTR (MP_QSTR_sendto ), MP_ROM_PTR (& socket_sendto_obj ) },
438
480
{ 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 ) },
439
482
{ MP_ROM_QSTR (MP_QSTR_setsockopt ), MP_ROM_PTR (& socket_setsockopt_obj ) },
440
483
{ MP_ROM_QSTR (MP_QSTR_settimeout ), MP_ROM_PTR (& socket_settimeout_obj ) },
441
484
{ MP_ROM_QSTR (MP_QSTR_setblocking ), MP_ROM_PTR (& socket_setblocking_obj ) },
0 commit comments