2626
2727#include <stdio.h>
2828#include <string.h>
29+ #include <stdlib.h>
2930
3031#include "py/runtime.h"
3132#include "py/stream.h"
3435
3536#if MICROPY_READER_VFS
3637
38+ #ifndef MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE
39+ #define MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE (2 * MICROPY_BYTES_PER_GC_BLOCK - offsetof(mp_reader_vfs_t, buf))
40+ #endif
41+ #define MICROPY_READER_VFS_MIN_BUFFER_SIZE (MICROPY_BYTES_PER_GC_BLOCK - offsetof(mp_reader_vfs_t, buf))
42+ #define MICROPY_READER_VFS_MAX_BUFFER_SIZE (255)
43+
3744typedef struct _mp_reader_vfs_t {
3845 mp_obj_t file ;
39- uint16_t len ;
40- uint16_t pos ;
41- byte buf [24 ];
46+ uint8_t bufpos ;
47+ uint8_t buflen ;
48+ uint8_t bufsize ;
49+ byte buf [];
4250} mp_reader_vfs_t ;
4351
4452STATIC mp_uint_t mp_reader_vfs_readbyte (void * data ) {
4553 mp_reader_vfs_t * reader = (mp_reader_vfs_t * )data ;
46- if (reader -> pos >= reader -> len ) {
47- if (reader -> len < sizeof ( reader -> buf ) ) {
54+ if (reader -> bufpos >= reader -> buflen ) {
55+ if (reader -> buflen < reader -> bufsize ) {
4856 return MP_READER_EOF ;
4957 } else {
5058 int errcode ;
51- reader -> len = mp_stream_rw (reader -> file , reader -> buf , sizeof (reader -> buf ),
52- & errcode , MP_STREAM_RW_READ | MP_STREAM_RW_ONCE );
59+ reader -> buflen = mp_stream_rw (reader -> file , reader -> buf , reader -> bufsize , & errcode , MP_STREAM_RW_READ | MP_STREAM_RW_ONCE );
5360 if (errcode != 0 ) {
5461 // TODO handle errors properly
5562 return MP_READER_EOF ;
5663 }
57- if (reader -> len == 0 ) {
64+ if (reader -> buflen == 0 ) {
5865 return MP_READER_EOF ;
5966 }
60- reader -> pos = 0 ;
67+ reader -> bufpos = 0 ;
6168 }
6269 }
63- return reader -> buf [reader -> pos ++ ];
70+ return reader -> buf [reader -> bufpos ++ ];
6471}
6572
6673STATIC void mp_reader_vfs_close (void * data ) {
@@ -70,18 +77,31 @@ STATIC void mp_reader_vfs_close(void *data) {
7077}
7178
7279void mp_reader_new_file (mp_reader_t * reader , qstr filename ) {
73- mp_reader_vfs_t * rf = m_new_obj (mp_reader_vfs_t );
7480 mp_obj_t args [2 ] = {
7581 MP_OBJ_NEW_QSTR (filename ),
7682 MP_OBJ_NEW_QSTR (MP_QSTR_rb ),
7783 };
78- rf -> file = mp_vfs_open (MP_ARRAY_SIZE (args ), & args [0 ], (mp_map_t * )& mp_const_empty_map );
79- int errcode ;
80- rf -> len = mp_stream_rw (rf -> file , rf -> buf , sizeof (rf -> buf ), & errcode , MP_STREAM_RW_READ | MP_STREAM_RW_ONCE );
84+ mp_obj_t file = mp_vfs_open (MP_ARRAY_SIZE (args ), & args [0 ], (mp_map_t * )& mp_const_empty_map );
85+
86+ const mp_stream_p_t * stream_p = mp_get_stream (file );
87+ int errcode = 0 ;
88+ mp_uint_t bufsize = stream_p -> ioctl (file , MP_STREAM_GET_BUFFER_SIZE , 0 , & errcode );
89+ if (bufsize == MP_STREAM_ERROR || bufsize == 0 ) {
90+ // bufsize == 0 is included here to support mpremote v1.21 and older where mount file ioctl
91+ // returned 0 by default.
92+ bufsize = MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE ;
93+ } else {
94+ bufsize = MIN (MICROPY_READER_VFS_MAX_BUFFER_SIZE , MAX (MICROPY_READER_VFS_MIN_BUFFER_SIZE , bufsize ));
95+ }
96+
97+ mp_reader_vfs_t * rf = m_new_obj_var (mp_reader_vfs_t , buf , byte , bufsize );
98+ rf -> file = file ;
99+ rf -> bufsize = bufsize ;
100+ rf -> buflen = mp_stream_rw (rf -> file , rf -> buf , rf -> bufsize , & errcode , MP_STREAM_RW_READ | MP_STREAM_RW_ONCE );
81101 if (errcode != 0 ) {
82102 mp_raise_OSError (errcode );
83103 }
84- rf -> pos = 0 ;
104+ rf -> bufpos = 0 ;
85105 reader -> data = rf ;
86106 reader -> readbyte = mp_reader_vfs_readbyte ;
87107 reader -> close = mp_reader_vfs_close ;
0 commit comments