44#include "mpconfig.h"
55#include "qstr.h"
66#include "obj.h"
7+ #include "runtime.h"
8+ #include "stream.h"
79#include "file.h"
810#include "ff.h"
911
@@ -16,27 +18,18 @@ void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, m
1618 printf ("<file %p>" , self_in );
1719}
1820
19- mp_obj_t file_obj_read (mp_obj_t self_in , mp_obj_t arg ) {
21+ STATIC machine_int_t file_read (mp_obj_t self_in , void * buf , machine_uint_t size , int * errcode ) {
2022 pyb_file_obj_t * self = self_in ;
21- int n = mp_obj_get_int (arg );
22- byte * buf = m_new (byte , n );
23- UINT n_out ;
24- f_read (& self -> fp , buf , n , & n_out );
25- return mp_obj_new_str (buf , n_out , false);
23+ UINT sz_out ;
24+ * errcode = f_read (& self -> fp , buf , size , & sz_out );
25+ return sz_out ;
2626}
2727
28- mp_obj_t file_obj_write (mp_obj_t self_in , mp_obj_t arg ) {
28+ STATIC machine_int_t file_write (mp_obj_t self_in , const void * buf , machine_uint_t size , int * errcode ) {
2929 pyb_file_obj_t * self = self_in ;
30- uint l ;
31- const char * s = mp_obj_str_get_data (arg , & l );
32- UINT n_out ;
33- FRESULT res = f_write (& self -> fp , s , l , & n_out );
34- if (res != FR_OK ) {
35- printf ("File error: could not write to file; error code %d\n" , res );
36- } else if (n_out != l ) {
37- printf ("File error: could not write all data to file; wrote %d / %d bytes\n" , n_out , l );
38- }
39- return mp_const_none ;
30+ UINT sz_out ;
31+ * errcode = f_write (& self -> fp , buf , size , & sz_out );
32+ return sz_out ;
4033}
4134
4235mp_obj_t file_obj_close (mp_obj_t self_in ) {
@@ -45,30 +38,49 @@ mp_obj_t file_obj_close(mp_obj_t self_in) {
4538 return mp_const_none ;
4639}
4740
48- static MP_DEFINE_CONST_FUN_OBJ_2 (file_obj_read_obj , file_obj_read ) ;
49- static MP_DEFINE_CONST_FUN_OBJ_2 (file_obj_write_obj , file_obj_write ) ;
50- static MP_DEFINE_CONST_FUN_OBJ_1 (file_obj_close_obj , file_obj_close ) ;
41+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (file_obj_close_obj , file_obj_close );
42+
43+ mp_obj_t file_obj___exit__ (uint n_args , const mp_obj_t * args ) {
44+ return file_obj_close (args [0 ]);
45+ }
46+ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (file_obj___exit___obj , 4 , 4 , file_obj___exit__ ) ;
5147
5248// TODO gc hook to close the file if not already closed
5349
5450STATIC const mp_map_elem_t file_locals_dict_table [] = {
55- { MP_OBJ_NEW_QSTR (MP_QSTR_read ), (mp_obj_t )& file_obj_read_obj },
56- { MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& file_obj_write_obj },
51+ { MP_OBJ_NEW_QSTR (MP_QSTR_read ), (mp_obj_t )& mp_stream_read_obj },
52+ { MP_OBJ_NEW_QSTR (MP_QSTR_readall ), (mp_obj_t )& mp_stream_readall_obj },
53+ { MP_OBJ_NEW_QSTR (MP_QSTR_readline ), (mp_obj_t )& mp_stream_unbuffered_readline_obj },
54+ { MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& mp_stream_write_obj },
5755 { MP_OBJ_NEW_QSTR (MP_QSTR_close ), (mp_obj_t )& file_obj_close_obj },
56+ { MP_OBJ_NEW_QSTR (MP_QSTR___enter__ ), (mp_obj_t )& mp_identity_obj },
57+ { MP_OBJ_NEW_QSTR (MP_QSTR___exit__ ), (mp_obj_t )& file_obj___exit___obj },
5858};
5959
6060STATIC MP_DEFINE_CONST_DICT (file_locals_dict , file_locals_dict_table );
6161
62+ STATIC mp_obj_t file_obj_make_new (mp_obj_t type_in , uint n_args , uint n_kw , const mp_obj_t * args );
6263static const mp_obj_type_t file_obj_type = {
6364 { & mp_type_type },
6465 .name = MP_QSTR_File ,
66+ .make_new = file_obj_make_new ,
6567 .print = file_obj_print ,
68+ .getiter = mp_identity ,
69+ .iternext = mp_stream_unbuffered_iter ,
70+ .stream_p = {
71+ .read = file_read ,
72+ .write = file_write ,
73+ },
6674 .locals_dict = (mp_obj_t )& file_locals_dict ,
6775};
6876
69- STATIC mp_obj_t pyb_io_open (mp_obj_t o_filename , mp_obj_t o_mode ) {
70- const char * filename = mp_obj_str_get_str (o_filename );
71- const char * mode = mp_obj_str_get_str (o_mode );
77+ STATIC mp_obj_t file_obj_make_new (mp_obj_t type_in , uint n_args , uint n_kw , const mp_obj_t * args ) {
78+ mp_check_nargs (n_args , 1 , 2 , n_kw , false);
79+ const char * filename = mp_obj_str_get_str (args [0 ]);
80+ const char * mode = "r" ;
81+ if (n_args > 1 ) {
82+ mode = mp_obj_str_get_str (args [1 ]);
83+ }
7284 pyb_file_obj_t * self = m_new_obj (pyb_file_obj_t );
7385 self -> base .type = & file_obj_type ;
7486 if (mode [0 ] == 'r' ) {
@@ -92,4 +104,10 @@ STATIC mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) {
92104 return self ;
93105}
94106
95- MP_DEFINE_CONST_FUN_OBJ_2 (mp_builtin_open_obj , pyb_io_open );
107+ // Factory function for I/O stream classes
108+ STATIC mp_obj_t pyb_io_open (uint n_args , const mp_obj_t * args ) {
109+ // TODO: analyze mode and buffering args and instantiate appropriate type
110+ return file_obj_make_new ((mp_obj_t )& file_obj_type , n_args , 0 , args );
111+ }
112+
113+ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (mp_builtin_open_obj , 1 , 2 , pyb_io_open );
0 commit comments