Skip to content

Commit d5f5b2f

Browse files
committed
py, stream: Implement readlines for a stream.
1 parent 5320bff commit d5f5b2f

File tree

6 files changed

+30
-12
lines changed

6 files changed

+30
-12
lines changed

py/qstrdefs.h

+1
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ Q(unpack)
314314
Q(io)
315315
Q(readall)
316316
Q(readline)
317+
Q(readlines)
317318
Q(StringIO)
318319
Q(BytesIO)
319320
Q(getvalue)

py/stream.c

+20-8
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
123123
while (max_size == -1 || max_size-- != 0) {
124124
char *p = vstr_add_len(vstr, 1);
125125
if (p == NULL) {
126-
// TODO
127-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError/*&mp_type_RuntimeError*/, "Out of memory"));
126+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, "out of memory"));
128127
}
129128

130129
machine_int_t out_sz = o->type->stream_p->read(o, p, 1, &error);
@@ -143,16 +142,29 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
143142
break;
144143
}
145144
}
146-
// TODO don't intern this string
147-
vstr_shrink(vstr);
148-
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(vstr_str(vstr), vstr->alloc, vstr_len(vstr)));
145+
// TODO need a string creation API that doesn't copy the given data
146+
mp_obj_t ret = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
147+
vstr_free(vstr);
148+
return ret;
149+
}
150+
151+
// TODO take an optional extra argument (what does it do exactly?)
152+
STATIC mp_obj_t stream_unbuffered_readlines(mp_obj_t self) {
153+
mp_obj_t lines = mp_obj_new_list(0, NULL);
154+
for (;;) {
155+
mp_obj_t line = stream_unbuffered_readline(1, &self);
156+
if (mp_obj_str_get_len(line) == 0) {
157+
break;
158+
}
159+
mp_obj_list_append(lines, line);
160+
}
161+
return lines;
149162
}
163+
MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_unbuffered_readlines_obj, stream_unbuffered_readlines);
150164

151165
mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self) {
152166
mp_obj_t l_in = stream_unbuffered_readline(1, &self);
153-
uint sz;
154-
mp_obj_str_get_data(l_in, &sz);
155-
if (sz != 0) {
167+
if (mp_obj_str_get_len(l_in) != 0) {
156168
return l_in;
157169
}
158170
return MP_OBJ_STOP_ITERATION;

py/stream.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
extern const mp_obj_fun_native_t mp_stream_read_obj;
2-
extern const mp_obj_fun_native_t mp_stream_readall_obj;
3-
extern const mp_obj_fun_native_t mp_stream_unbuffered_readline_obj;
4-
extern const mp_obj_fun_native_t mp_stream_write_obj;
1+
MP_DECLARE_CONST_FUN_OBJ(mp_stream_read_obj);
2+
MP_DECLARE_CONST_FUN_OBJ(mp_stream_readall_obj);
3+
MP_DECLARE_CONST_FUN_OBJ(mp_stream_unbuffered_readline_obj);
4+
MP_DECLARE_CONST_FUN_OBJ(mp_stream_unbuffered_readlines_obj);
5+
MP_DECLARE_CONST_FUN_OBJ(mp_stream_write_obj);
56

67
// Iterator which uses mp_stream_unbuffered_readline_obj
78
mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self);

stmhal/file.c

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ STATIC const mp_map_elem_t file_locals_dict_table[] = {
5151
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
5252
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
5353
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
54+
{ MP_OBJ_NEW_QSTR(MP_QSTR_readlines), (mp_obj_t)&mp_stream_unbuffered_readlines_obj},
5455
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
5556
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&file_obj_close_obj },
5657
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&file_obj_close_obj },

tests/io/file1.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
print(f.read(5))
33
print(f.readline())
44
print(f.read())
5+
f = open("io/data/file1")
6+
print(f.readlines())

unix/file.c

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ STATIC const mp_map_elem_t rawfile_locals_dict_table[] = {
132132
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
133133
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
134134
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
135+
{ MP_OBJ_NEW_QSTR(MP_QSTR_readlines), (mp_obj_t)&mp_stream_unbuffered_readlines_obj},
135136
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
136137
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&fdfile_close_obj },
137138
{ MP_OBJ_NEW_QSTR(MP_QSTR___enter__), (mp_obj_t)&mp_identity_obj },

0 commit comments

Comments
 (0)