Skip to content

Commit

Permalink
extmod/vfs_reader: Add file ioctl to set read buffer size.
Browse files Browse the repository at this point in the history
Can be used to speed up importing a file from a vfs based filesystem.

Signed-off-by: Andrew Leech <[email protected]>
  • Loading branch information
pi-anl committed Nov 1, 2023
1 parent a614c1d commit 06f7ce7
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 7 deletions.
25 changes: 18 additions & 7 deletions extmod/vfs_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,18 @@ typedef struct _mp_reader_vfs_t {
mp_obj_t file;
uint16_t len;
uint16_t pos;
byte buf[24];
uint8_t bufsize;
byte buf[];
} mp_reader_vfs_t;

STATIC mp_uint_t mp_reader_vfs_readbyte(void *data) {
mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
if (reader->pos >= reader->len) {
if (reader->len < sizeof(reader->buf)) {
if (reader->len < reader->bufsize) {
return MP_READER_EOF;
} else {
int errcode;
reader->len = mp_stream_rw(reader->file, reader->buf, sizeof(reader->buf),
reader->len = mp_stream_rw(reader->file, reader->buf, reader->bufsize,
&errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
if (errcode != 0) {
// TODO handle errors properly
Expand All @@ -70,14 +71,24 @@ STATIC void mp_reader_vfs_close(void *data) {
}

void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
mp_reader_vfs_t *rf = m_new_obj(mp_reader_vfs_t);
mp_obj_t args[2] = {
MP_OBJ_NEW_QSTR(filename),
MP_OBJ_NEW_QSTR(MP_QSTR_rb),
};
rf->file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);
int errcode;
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
mp_obj_t file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);

const mp_stream_p_t *stream_p = mp_get_stream(file);
int errcode = 0;
mp_uint_t bufsize = stream_p->ioctl(file, MP_STREAM_BUFFER_SIZE, 0, &errcode);
if (bufsize < 7 || bufsize > 255) {
errcode = 0;
bufsize = MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE;
}

mp_reader_vfs_t *rf = m_new_obj_var(mp_reader_vfs_t, uint8_t, bufsize);
rf->file = file;
rf->bufsize = bufsize;
rf->len = mp_stream_rw(rf->file, rf->buf, rf->bufsize, &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
if (errcode != 0) {
mp_raise_OSError(errcode);
}
Expand Down
4 changes: 4 additions & 0 deletions py/mpconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,10 @@
#define MICROPY_READER_VFS (0)
#endif

#ifndef MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE
#define MICROPY_READER_VFS_DEFAULT_BUFFER_SIZE (23)
#endif

// Whether any readers have been defined
#ifndef MICROPY_HAS_FILE_READER
#define MICROPY_HAS_FILE_READER (MICROPY_READER_POSIX || MICROPY_READER_VFS)
Expand Down
1 change: 1 addition & 0 deletions py/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define MP_STREAM_GET_DATA_OPTS (8) // Get data/message options
#define MP_STREAM_SET_DATA_OPTS (9) // Set data/message options
#define MP_STREAM_GET_FILENO (10) // Get fileno of underlying file
#define MP_STREAM_BUFFER_SIZE (11) // Get preferred buffer size for file

// These poll ioctl values are compatible with Linux
#define MP_STREAM_POLL_RD (0x0001)
Expand Down
4 changes: 4 additions & 0 deletions tests/extmod/vfs_userfs.py.exp
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@ some data in a text file
stat /usermod1
stat /usermod1.py
open /usermod1.py rb
ioctl 11 0
ioctl 4 0
in usermod1
stat /usermod2
stat /usermod2.py
open /usermod2.py rb
ioctl 11 0
ioctl 4 0
in usermod2
stat /usermod3
stat /usermod3.py
open /usermod3.py rb
ioctl 11 0
ioctl 4 0
SyntaxError in usermod3
stat /usermod4
stat /usermod4.py
stat /usermod4.mpy
open /usermod4.mpy rb
ioctl 11 0
ioctl 4 0
ValueError in usermod4

0 comments on commit 06f7ce7

Please sign in to comment.