2424 * THE SOFTWARE.
2525 */
2626
27+ #include <assert.h>
28+ #include <string.h>
29+
30+ #include "py/runtime.h"
2731#include "py/builtin.h"
32+ #include "py/stream.h"
2833
2934#if MICROPY_PY_IO
3035
3136extern const mp_obj_type_t mp_type_fileio ;
3237extern const mp_obj_type_t mp_type_textio ;
3338
39+ #if MICROPY_PY_IO_BUFFEREDWRITER
40+ typedef struct _mp_obj_bufwriter_t {
41+ mp_obj_base_t base ;
42+ mp_obj_t stream ;
43+ size_t alloc ;
44+ size_t len ;
45+ byte buf [0 ];
46+ } mp_obj_bufwriter_t ;
47+
48+ STATIC mp_obj_t bufwriter_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
49+ mp_arg_check_num (n_args , n_kw , 2 , 2 , false);
50+ size_t alloc = mp_obj_get_int (args [1 ]);
51+ mp_obj_bufwriter_t * o = m_new_obj_var (mp_obj_bufwriter_t , byte , alloc );
52+ o -> base .type = type ;
53+ o -> stream = args [0 ];
54+ o -> alloc = alloc ;
55+ o -> len = 0 ;
56+ return o ;
57+ }
58+
59+ STATIC mp_uint_t bufwriter_write (mp_obj_t self_in , const void * buf , mp_uint_t size , int * errcode ) {
60+ mp_obj_bufwriter_t * self = MP_OBJ_TO_PTR (self_in );
61+
62+ mp_uint_t org_size = size ;
63+
64+ while (size > 0 ) {
65+ mp_uint_t rem = self -> alloc - self -> len ;
66+ if (size < rem ) {
67+ memcpy (self -> buf + self -> len , buf , size );
68+ self -> len += size ;
69+ return org_size ;
70+ }
71+
72+ memcpy (self -> buf + self -> len , buf , rem );
73+ buf = (byte * )buf + rem ;
74+ size -= rem ;
75+ mp_uint_t out_sz = mp_stream_writeall (self -> stream , self -> buf , self -> alloc , errcode );
76+ if (out_sz == MP_STREAM_ERROR ) {
77+ return MP_STREAM_ERROR ;
78+ }
79+ self -> len = 0 ;
80+ }
81+
82+ return org_size ;
83+ }
84+
85+ STATIC const mp_map_elem_t bufwriter_locals_dict_table [] = {
86+ { MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& mp_stream_write_obj },
87+ };
88+ STATIC MP_DEFINE_CONST_DICT (bufwriter_locals_dict , bufwriter_locals_dict_table );
89+
90+ STATIC const mp_stream_p_t bufwriter_stream_p = {
91+ .write = bufwriter_write ,
92+ };
93+
94+ STATIC const mp_obj_type_t bufwriter_type = {
95+ { & mp_type_type },
96+ .name = MP_QSTR_BufferedWriter ,
97+ .make_new = bufwriter_make_new ,
98+ .stream_p = & bufwriter_stream_p ,
99+ .locals_dict = (mp_obj_t )& bufwriter_locals_dict ,
100+ };
101+ #endif // MICROPY_PY_IO_BUFFEREDWRITER
102+
34103STATIC const mp_rom_map_elem_t mp_module_io_globals_table [] = {
35104 { MP_ROM_QSTR (MP_QSTR___name__ ), MP_ROM_QSTR (MP_QSTR__io ) },
36105 // Note: mp_builtin_open_obj should be defined by port, it's not
@@ -46,6 +115,9 @@ STATIC const mp_rom_map_elem_t mp_module_io_globals_table[] = {
46115 #if MICROPY_PY_IO_BYTESIO
47116 { MP_ROM_QSTR (MP_QSTR_BytesIO ), MP_ROM_PTR (& mp_type_bytesio ) },
48117 #endif
118+ #if MICROPY_PY_IO_BUFFEREDWRITER
119+ { MP_ROM_QSTR (MP_QSTR_BufferedWriter ), MP_ROM_PTR (& bufwriter_type ) },
120+ #endif
49121};
50122
51123STATIC MP_DEFINE_CONST_DICT (mp_module_io_globals , mp_module_io_globals_table );
0 commit comments