You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
4.7KB

  1. /* Teensyduino Core Library - File base class
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2020 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #ifndef FS_H
  31. #define FS_H
  32. #ifdef __cplusplus
  33. #include <Arduino.h>
  34. #define FILE_READ 0
  35. #define FILE_WRITE 1
  36. enum SeekMode {
  37. SeekSet = 0,
  38. SeekCur = 1,
  39. SeekEnd = 2
  40. };
  41. #define FILE_WHOAMI
  42. class File : public Stream {
  43. public:
  44. constexpr File() : f(nullptr) { }
  45. File(File *file) {
  46. // "file" must only be a class derived from File
  47. // can we use is_same or is_polymorphic with static_assert?
  48. // or is_base_of
  49. //static_assert(std::is_same<decltype(*file),File>::value,
  50. //"File(File *file) constructor only accepts pointers "
  51. //"to derived classes, not File itself");
  52. f = file;
  53. if (f) f->refcount++;
  54. }
  55. File(const File &file) {
  56. //Serial.println("File copy constructor");
  57. //static int copycount=0;
  58. //if (++copycount > 20) while (1) ;
  59. f = file.f;
  60. if (f) f->refcount++;
  61. }
  62. File& operator = (const File &file) {
  63. //Serial.println("File assignment");
  64. //static int assigncount=0;
  65. //if (++assigncount > 20) while (1) ;
  66. invalidate();
  67. f = file.f;
  68. if (f) f->refcount++;
  69. return *this;
  70. }
  71. virtual ~File() {
  72. invalidate();
  73. }
  74. #ifdef FILE_WHOAMI
  75. virtual void whoami() { // testing only
  76. Serial.printf(" File this=%x, f=%x\n", (int)this, (int)f);
  77. if (f) f->whoami();
  78. }
  79. unsigned int getRefcount() { // testing only
  80. return refcount;
  81. }
  82. #endif
  83. virtual size_t read(void *buf, size_t nbyte) {
  84. return (f) ? f->read(buf, nbyte) : 0;
  85. }
  86. virtual size_t write(const void *buf, size_t size) {
  87. return (f) ? f->write(buf, size) : 0;
  88. }
  89. virtual int available() {
  90. return (f) ? f->available() : 0;
  91. }
  92. virtual int peek() {
  93. return (f) ? f->peek() : -1;
  94. }
  95. virtual void flush() {
  96. if (f) f->flush();
  97. }
  98. virtual bool seek(uint32_t pos, int mode) {
  99. return (f) ? f->seek(pos, mode) : false;
  100. }
  101. virtual uint32_t position() {
  102. return (f) ? f->position() : 0;
  103. }
  104. virtual uint32_t size() {
  105. return (f) ? f->size() : 0;
  106. }
  107. virtual void close() {
  108. if (f) f->close();
  109. }
  110. virtual operator bool() {
  111. return (f) ? (bool)*f : false;
  112. }
  113. virtual const char* name() {
  114. return (f) ? f->name() : "";
  115. }
  116. virtual bool isDirectory() {
  117. return (f) ? f->isDirectory() : false;
  118. }
  119. virtual File openNextFile(uint8_t mode=0) {
  120. return (f) ? f->openNextFile(mode) : *this;
  121. }
  122. virtual void rewindDirectory(void) {
  123. if (f) f->rewindDirectory();
  124. }
  125. bool seek(uint32_t pos) {
  126. return seek(pos, SeekSet);
  127. }
  128. int read() {
  129. if (!f) return -1;
  130. unsigned char b;
  131. if (f->read(&b, 1) < 1) return -1;
  132. return b;
  133. }
  134. size_t write(uint8_t b) {
  135. return write(&b, 1);
  136. }
  137. size_t write(const char *str) {
  138. return write(str, strlen(str));
  139. }
  140. size_t readBytes(char *buffer, size_t length) {
  141. return read(buffer, length);
  142. }
  143. private:
  144. void invalidate() {
  145. if (f && --(f->refcount) == 0) delete f;
  146. }
  147. union {
  148. // instances of base File class use this pointer
  149. File *f;
  150. // instances of derived classes (which actually access media)
  151. // use this reference count which is managed by the base class
  152. unsigned int refcount;
  153. };
  154. };
  155. class FS
  156. {
  157. public:
  158. FS() {}
  159. virtual File open(const char *filename, uint8_t mode = FILE_READ);
  160. virtual bool exists(const char *filepath);
  161. virtual bool mkdir(const char *filepath);
  162. virtual bool rename(const char *oldfilepath, const char *newfilepath);
  163. virtual bool remove(const char *filepath);
  164. virtual bool rmdir(const char *filepath);
  165. };
  166. #endif // __cplusplus
  167. #endif // FS_H