reader.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013-2016 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. #include <stdio.h>
  27. #include <assert.h>
  28. #include "py/runtime.h"
  29. #include "py/mperrno.h"
  30. #include "py/mpthread.h"
  31. #include "py/reader.h"
  32. typedef struct _mp_reader_mem_t {
  33. size_t free_len; // if >0 mem is freed on close by: m_free(beg, free_len)
  34. const byte *beg;
  35. const byte *cur;
  36. const byte *end;
  37. } mp_reader_mem_t;
  38. static mp_uint_t mp_reader_mem_readbyte(void *data) {
  39. mp_reader_mem_t *reader = (mp_reader_mem_t *)data;
  40. if (reader->cur < reader->end) {
  41. return *reader->cur++;
  42. } else {
  43. return MP_READER_EOF;
  44. }
  45. }
  46. static void mp_reader_mem_close(void *data) {
  47. mp_reader_mem_t *reader = (mp_reader_mem_t *)data;
  48. if (reader->free_len > 0) {
  49. m_del(char, (char *)reader->beg, reader->free_len);
  50. }
  51. m_del_obj(mp_reader_mem_t, reader);
  52. }
  53. void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) {
  54. mp_reader_mem_t *rm = m_new_obj(mp_reader_mem_t);
  55. rm->free_len = free_len;
  56. rm->beg = buf;
  57. rm->cur = buf;
  58. rm->end = buf + len;
  59. reader->data = rm;
  60. reader->readbyte = mp_reader_mem_readbyte;
  61. reader->close = mp_reader_mem_close;
  62. }
  63. #if MICROPY_READER_POSIX
  64. #include <sys/stat.h>
  65. #include <fcntl.h>
  66. #include <unistd.h>
  67. typedef struct _mp_reader_posix_t {
  68. bool close_fd;
  69. int fd;
  70. size_t len;
  71. size_t pos;
  72. byte buf[20];
  73. } mp_reader_posix_t;
  74. static mp_uint_t mp_reader_posix_readbyte(void *data) {
  75. mp_reader_posix_t *reader = (mp_reader_posix_t *)data;
  76. if (reader->pos >= reader->len) {
  77. if (reader->len == 0) {
  78. return MP_READER_EOF;
  79. } else {
  80. MP_THREAD_GIL_EXIT();
  81. int n = read(reader->fd, reader->buf, sizeof(reader->buf));
  82. MP_THREAD_GIL_ENTER();
  83. if (n <= 0) {
  84. reader->len = 0;
  85. return MP_READER_EOF;
  86. }
  87. reader->len = n;
  88. reader->pos = 0;
  89. }
  90. }
  91. return reader->buf[reader->pos++];
  92. }
  93. static void mp_reader_posix_close(void *data) {
  94. mp_reader_posix_t *reader = (mp_reader_posix_t *)data;
  95. if (reader->close_fd) {
  96. MP_THREAD_GIL_EXIT();
  97. close(reader->fd);
  98. MP_THREAD_GIL_ENTER();
  99. }
  100. m_del_obj(mp_reader_posix_t, reader);
  101. }
  102. void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
  103. mp_reader_posix_t *rp = m_new_obj(mp_reader_posix_t);
  104. rp->close_fd = close_fd;
  105. rp->fd = fd;
  106. MP_THREAD_GIL_EXIT();
  107. int n = read(rp->fd, rp->buf, sizeof(rp->buf));
  108. if (n == -1) {
  109. if (close_fd) {
  110. close(fd);
  111. }
  112. MP_THREAD_GIL_ENTER();
  113. mp_raise_OSError(errno);
  114. }
  115. MP_THREAD_GIL_ENTER();
  116. rp->len = n;
  117. rp->pos = 0;
  118. reader->data = rp;
  119. reader->readbyte = mp_reader_posix_readbyte;
  120. reader->close = mp_reader_posix_close;
  121. }
  122. #if !MICROPY_VFS_POSIX
  123. // If MICROPY_VFS_POSIX is defined then this function is provided by the VFS layer
  124. void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
  125. MP_THREAD_GIL_EXIT();
  126. int fd = open(qstr_str(filename), O_RDONLY, 0644);
  127. MP_THREAD_GIL_ENTER();
  128. if (fd < 0) {
  129. mp_raise_OSError_with_filename(errno, qstr_str(filename));
  130. }
  131. mp_reader_new_file_from_fd(reader, fd, true);
  132. }
  133. #endif
  134. #endif