Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2013-2017 Damien P. George
7 : : *
8 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : * of this software and associated documentation files (the "Software"), to deal
10 : : * in the Software without restriction, including without limitation the rights
11 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : * copies of the Software, and to permit persons to whom the Software is
13 : : * furnished to do so, subject to the following conditions:
14 : : *
15 : : * The above copyright notice and this permission notice shall be included in
16 : : * all copies or substantial portions of the Software.
17 : : *
18 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 : : * THE SOFTWARE.
25 : : */
26 : :
27 : : #include <stdio.h>
28 : : #include <string.h>
29 : : #include <stdlib.h>
30 : :
31 : : #include "py/runtime.h"
32 : : #include "py/stream.h"
33 : : #include "py/reader.h"
34 : : #include "extmod/vfs.h"
35 : :
36 : : #if MICROPY_READER_VFS
37 : :
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 : :
44 : : typedef struct _mp_reader_vfs_t {
45 : : mp_obj_t file;
46 : : uint8_t bufpos;
47 : : uint8_t buflen;
48 : : uint8_t bufsize;
49 : : byte buf[];
50 : : } mp_reader_vfs_t;
51 : :
52 : 4365948 : static mp_uint_t mp_reader_vfs_readbyte(void *data) {
53 : 4365948 : mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
54 [ + + ]: 4365948 : if (reader->bufpos >= reader->buflen) {
55 [ + + ]: 87407 : if (reader->buflen < reader->bufsize) {
56 : : return MP_READER_EOF;
57 : : } else {
58 : 80439 : int errcode;
59 : 80439 : reader->buflen = mp_stream_rw(reader->file, reader->buf, reader->bufsize, &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
60 [ + - ]: 80439 : if (errcode != 0) {
61 : : // TODO handle errors properly
62 : 50 : return MP_READER_EOF;
63 : : }
64 [ + + ]: 80439 : if (reader->buflen == 0) {
65 : : return MP_READER_EOF;
66 : : }
67 : 80389 : reader->bufpos = 0;
68 : : }
69 : : }
70 : 4358930 : return reader->buf[reader->bufpos++];
71 : : }
72 : :
73 : 3711 : static void mp_reader_vfs_close(void *data) {
74 : 3711 : mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
75 : 3711 : mp_stream_close(reader->file);
76 : 3711 : m_del_obj(mp_reader_vfs_t, reader);
77 : 3711 : }
78 : :
79 : 3715 : void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
80 : 3715 : mp_obj_t args[2] = {
81 : 3715 : MP_OBJ_NEW_QSTR(filename),
82 : : MP_OBJ_NEW_QSTR(MP_QSTR_rb),
83 : : };
84 : 3715 : mp_obj_t file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);
85 : :
86 : 3711 : const mp_stream_p_t *stream_p = mp_get_stream(file);
87 : 3711 : int errcode = 0;
88 : 3711 : mp_uint_t bufsize = stream_p->ioctl(file, MP_STREAM_GET_BUFFER_SIZE, 0, &errcode);
89 [ + + ]: 3711 : 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 [ + + ]: 12 : bufsize = MIN(MICROPY_READER_VFS_MAX_BUFFER_SIZE, MAX(MICROPY_READER_VFS_MIN_BUFFER_SIZE, bufsize));
95 : : }
96 : :
97 : 3711 : mp_reader_vfs_t *rf = m_new_obj_var(mp_reader_vfs_t, buf, byte, bufsize);
98 : 3711 : rf->file = file;
99 : 3711 : rf->bufsize = bufsize;
100 : 3711 : rf->buflen = mp_stream_rw(rf->file, rf->buf, rf->bufsize, &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
101 [ - + ]: 3711 : if (errcode != 0) {
102 : 0 : mp_raise_OSError(errcode);
103 : : }
104 : 3711 : rf->bufpos = 0;
105 : 3711 : reader->data = rf;
106 : 3711 : reader->readbyte = mp_reader_vfs_readbyte;
107 : 3711 : reader->close = mp_reader_vfs_close;
108 : 3711 : }
109 : :
110 : : #endif // MICROPY_READER_VFS
|