@@ -68,10 +68,23 @@ STATIC mp_uint_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
6868 return size ;
6969}
7070
71+ STATIC void stringio_copy_on_write (mp_obj_stringio_t * o ) {
72+ const void * buf = o -> vstr -> buf ;
73+ o -> vstr -> buf = m_new (char , o -> vstr -> len );
74+ memcpy (o -> vstr -> buf , buf , o -> vstr -> len );
75+ o -> vstr -> fixed_buf = false;
76+ o -> ref_obj = MP_OBJ_NULL ;
77+ }
78+
7179STATIC mp_uint_t stringio_write (mp_obj_t o_in , const void * buf , mp_uint_t size , int * errcode ) {
7280 (void )errcode ;
7381 mp_obj_stringio_t * o = MP_OBJ_TO_PTR (o_in );
7482 check_stringio_is_open (o );
83+
84+ if (o -> vstr -> fixed_buf ) {
85+ stringio_copy_on_write (o );
86+ }
87+
7588 mp_uint_t new_pos = o -> pos + size ;
7689 if (new_pos < size ) {
7790 // Writing <size> bytes will overflow o->pos beyond limit of mp_uint_t.
@@ -155,11 +168,11 @@ STATIC mp_obj_t stringio___exit__(size_t n_args, const mp_obj_t *args) {
155168}
156169STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (stringio___exit___obj , 4 , 4 , stringio___exit__ );
157170
158- STATIC mp_obj_stringio_t * stringio_new (const mp_obj_type_t * type , mp_uint_t alloc ) {
171+ STATIC mp_obj_stringio_t * stringio_new (const mp_obj_type_t * type ) {
159172 mp_obj_stringio_t * o = m_new_obj (mp_obj_stringio_t );
160173 o -> base .type = type ;
161- o -> vstr = vstr_new (alloc );
162174 o -> pos = 0 ;
175+ o -> ref_obj = MP_OBJ_NULL ;
163176 return o ;
164177}
165178
@@ -170,17 +183,28 @@ STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, s
170183 bool initdata = false;
171184 mp_buffer_info_t bufinfo ;
172185
186+ mp_obj_stringio_t * o = stringio_new (type_in );
187+
173188 if (n_args > 0 ) {
174189 if (MP_OBJ_IS_INT (args [0 ])) {
175190 sz = mp_obj_get_int (args [0 ]);
176191 } else {
177192 mp_get_buffer_raise (args [0 ], & bufinfo , MP_BUFFER_READ );
193+
194+ if (MP_OBJ_IS_STR_OR_BYTES (args [0 ])) {
195+ o -> vstr = m_new_obj (vstr_t );
196+ vstr_init_fixed_buf (o -> vstr , bufinfo .len , bufinfo .buf );
197+ o -> vstr -> len = bufinfo .len ;
198+ o -> ref_obj = args [0 ];
199+ return MP_OBJ_FROM_PTR (o );
200+ }
201+
178202 sz = bufinfo .len ;
179203 initdata = true;
180204 }
181205 }
182206
183- mp_obj_stringio_t * o = stringio_new ( type_in , sz );
207+ o -> vstr = vstr_new ( sz );
184208
185209 if (initdata ) {
186210 stringio_write (MP_OBJ_FROM_PTR (o ), bufinfo .buf , bufinfo .len , NULL );
0 commit comments