@@ -92,6 +92,50 @@ static mp_obj_t stream_readall(mp_obj_t self_in) {
9292 return mp_obj_new_str (qstr_from_str_take (buf , total_size + 1 ));
9393}
9494
95+ // Unbuffered, inefficient implementation of readline() for raw I/O files.
96+ static mp_obj_t stream_unbuffered_readline (int n_args , const mp_obj_t * args ) {
97+ struct _mp_obj_base_t * o = (struct _mp_obj_base_t * )args [0 ];
98+ if (o -> type -> stream_p .read == NULL ) {
99+ // CPython: io.UnsupportedOperation, OSError subclass
100+ nlr_jump (mp_obj_new_exception_msg (MP_QSTR_OSError , "Operation not supported" ));
101+ }
102+
103+ machine_int_t max_size = -1 ;
104+ if (n_args > 1 ) {
105+ max_size = MP_OBJ_SMALL_INT_VALUE (args [1 ]);
106+ }
107+
108+ vstr_t * vstr ;
109+ if (max_size != -1 ) {
110+ vstr = vstr_new_size (max_size + 1 ); // TODO: \0
111+ } else {
112+ vstr = vstr_new ();
113+ }
114+
115+ int error ;
116+ while (max_size == -1 || max_size -- != 0 ) {
117+ char * p = vstr_add_len (vstr , 1 );
118+ if (p == NULL ) {
119+ // TODO
120+ nlr_jump (mp_obj_new_exception_msg_varg (MP_QSTR_OSError /*MP_QSTR_RuntimeError*/ , "Out of memory" ));
121+ }
122+
123+ machine_int_t out_sz = o -> type -> stream_p .read (o , p , 1 , & error );
124+ if (out_sz == -1 ) {
125+ nlr_jump (mp_obj_new_exception_msg_varg (MP_QSTR_OSError , "[Errno %d]" , error ));
126+ }
127+ if (out_sz == 0 || * p == '\n' ) {
128+ break ;
129+ }
130+ }
131+ // TODO: \0
132+ vstr_add_byte (vstr , 0 );
133+ vstr_shrink (vstr );
134+ return mp_obj_new_str (qstr_from_str_take (vstr_str (vstr ), vstr_len (vstr )));
135+ }
136+
137+
95138MP_DEFINE_CONST_FUN_OBJ_2 (mp_stream_read_obj , stream_read );
96139MP_DEFINE_CONST_FUN_OBJ_1 (mp_stream_readall_obj , stream_readall );
140+ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (mp_stream_unbuffered_readline_obj , 1 , 2 , stream_unbuffered_readline );
97141MP_DEFINE_CONST_FUN_OBJ_2 (mp_stream_write_obj , stream_write );
0 commit comments