Skip to content

Commit 1a55b6a

Browse files
committed
unix, stmhal: Implement file.readinto() method.
Also, usocket.readinto(). Known issue is that .readinto() should be available only for binary files, but micropython uses single method table for both binary and text files.
1 parent c92672d commit 1a55b6a

8 files changed

Lines changed: 35 additions & 0 deletions

File tree

py/qstrdefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ Q(BF_LEN)
437437
#if MICROPY_PY_IO
438438
Q(_io)
439439
Q(readall)
440+
Q(readinto)
440441
Q(readline)
441442
Q(readlines)
442443
Q(FileIO)

py/stream.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,27 @@ STATIC mp_obj_t stream_write_method(mp_obj_t self_in, mp_obj_t arg) {
215215
return mp_stream_write(self_in, bufinfo.buf, bufinfo.len);
216216
}
217217

218+
STATIC mp_obj_t stream_readinto(mp_obj_t self_in, mp_obj_t arg) {
219+
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
220+
if (o->type->stream_p == NULL || o->type->stream_p->read == NULL) {
221+
// CPython: io.UnsupportedOperation, OSError subclass
222+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
223+
}
224+
mp_buffer_info_t bufinfo;
225+
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_WRITE);
226+
227+
int error;
228+
mp_uint_t out_sz = o->type->stream_p->read(o, bufinfo.buf, bufinfo.len, &error);
229+
if (out_sz == MP_STREAM_ERROR) {
230+
if (is_nonblocking_error(error)) {
231+
return mp_const_none;
232+
}
233+
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error)));
234+
} else {
235+
return MP_OBJ_NEW_SMALL_INT(out_sz);
236+
}
237+
}
238+
218239
STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
219240
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
220241
if (o->type->stream_p == NULL || o->type->stream_p->read == NULL) {
@@ -349,6 +370,7 @@ mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self) {
349370
}
350371

351372
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj, 1, 2, stream_read);
373+
MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_readinto_obj, stream_readinto);
352374
MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_readall_obj, stream_readall);
353375
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj, 1, 2, stream_unbuffered_readline);
354376
MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_write_obj, stream_write_method);

py/stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626

2727
MP_DECLARE_CONST_FUN_OBJ(mp_stream_read_obj);
28+
MP_DECLARE_CONST_FUN_OBJ(mp_stream_readinto_obj);
2829
MP_DECLARE_CONST_FUN_OBJ(mp_stream_readall_obj);
2930
MP_DECLARE_CONST_FUN_OBJ(mp_stream_unbuffered_readline_obj);
3031
MP_DECLARE_CONST_FUN_OBJ(mp_stream_unbuffered_readlines_obj);

stmhal/file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ STATIC mp_obj_t file_obj_make_new(mp_obj_t type, mp_uint_t n_args, mp_uint_t n_k
222222
STATIC const mp_map_elem_t rawfile_locals_dict_table[] = {
223223
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
224224
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
225+
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
225226
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
226227
{ MP_OBJ_NEW_QSTR(MP_QSTR_readlines), (mp_obj_t)&mp_stream_unbuffered_readlines_obj},
227228
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },

tests/io/data/file2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1234

tests/io/file_readinto.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
b = bytearray(30)
2+
f = open("io/data/file1", "rb")
3+
print(f.readinto(b))
4+
print(b)
5+
f = open("io/data/file2", "rb")
6+
print(f.readinto(b))
7+
print(b)

unix/file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ STATIC const mp_map_elem_t rawfile_locals_dict_table[] = {
177177
{ MP_OBJ_NEW_QSTR(MP_QSTR_fileno), (mp_obj_t)&fdfile_fileno_obj },
178178
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
179179
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
180+
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
180181
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
181182
{ MP_OBJ_NEW_QSTR(MP_QSTR_readlines), (mp_obj_t)&mp_stream_unbuffered_readlines_obj},
182183
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },

unix/modsocket.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ STATIC const mp_map_elem_t usocket_locals_dict_table[] = {
289289
{ MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&socket_makefile_obj },
290290
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
291291
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
292+
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
292293
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
293294
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
294295
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },

0 commit comments

Comments
 (0)