diff options
author | Damien George <damien.p.george@gmail.com> | 2017-01-27 15:10:09 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-01-27 17:19:06 +1100 |
commit | dcb9ea72157f1d9f3b0dc306c2c31cbd647f5ee1 (patch) | |
tree | 2c93fc3589bb3a5879d24ace7a7e55a124a90db3 /extmod/vfs_reader.c | |
parent | 32a1138b9f66b76808906064a76c5f9533cc825c (diff) | |
download | micropython-dcb9ea72157f1d9f3b0dc306c2c31cbd647f5ee1.tar.gz micropython-dcb9ea72157f1d9f3b0dc306c2c31cbd647f5ee1.zip |
extmod: Add generic VFS sub-system.
This provides mp_vfs_XXX functions (eg mount, open, listdir) which are
agnostic to the underlying filesystem type, and just require an object with
the relevant filesystem-like methods (eg .mount, .open, .listidr) which can
then be mounted.
These mp_vfs_XXX functions would typically be used by a port to implement
the "uos" module, and mp_vfs_open would be the builtin open function.
This feature is controlled by MICROPY_VFS, disabled by default.
Diffstat (limited to 'extmod/vfs_reader.c')
-rw-r--r-- | extmod/vfs_reader.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/extmod/vfs_reader.c b/extmod/vfs_reader.c new file mode 100644 index 0000000000..718bdeeb65 --- /dev/null +++ b/extmod/vfs_reader.c @@ -0,0 +1,97 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> + +#include "py/nlr.h" +#include "py/stream.h" +#include "py/reader.h" +#include "extmod/vfs.h" + +#if MICROPY_READER_VFS + +typedef struct _mp_reader_vfs_t { + mp_obj_t file; + uint16_t len; + uint16_t pos; + byte buf[24]; +} 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)) { + return MP_READER_EOF; + } else { + int errcode; + reader->len = mp_stream_rw(reader->file, reader->buf, sizeof(reader->buf), + &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE); + if (errcode != 0) { + // TODO handle errors properly + return MP_READER_EOF; + } + if (reader->len == 0) { + return MP_READER_EOF; + } + reader->pos = 0; + } + } + return reader->buf[reader->pos++]; +} + +STATIC void mp_reader_vfs_close(void *data) { + mp_reader_vfs_t *reader = (mp_reader_vfs_t*)data; + mp_stream_close(reader->file); + m_del_obj(mp_reader_vfs_t, reader); +} + +int mp_reader_new_file(mp_reader_t *reader, const char *filename) { + mp_reader_vfs_t *rf = m_new_obj_maybe(mp_reader_vfs_t); + if (rf == NULL) { + return MP_ENOMEM; + } + // TODO we really should just let this function raise a uPy exception + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false); + rf->file = mp_vfs_open(1, &arg, (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); + if (errcode != 0) { + return errcode; + } + } else { + return MP_ENOENT; // assume error was "file not found" + } + rf->pos = 0; + reader->data = rf; + reader->readbyte = mp_reader_vfs_readbyte; + reader->close = mp_reader_vfs_close; + return 0; // success +} + +#endif // MICROPY_READER_VFS |