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.

264 lines
7.6KB

  1. /* Arduino SdFat Library
  2. * Copyright (C) 2012 by William Greiman
  3. *
  4. * This file is part of the Arduino SdFat Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Arduino SdFat Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef SdStream_h
  21. #define SdStream_h
  22. /**
  23. * \file
  24. * \brief \ref fstream, \ref ifstream, and \ref ofstream classes
  25. */
  26. #include <SdBaseFile.h>
  27. #include <iostream.h>
  28. //==============================================================================
  29. /**
  30. * \class SdStreamBase
  31. * \brief Base class for SD streams
  32. */
  33. class SdStreamBase : protected SdBaseFile, virtual public ios {
  34. protected:
  35. /// @cond SHOW_PROTECTED
  36. int16_t getch();
  37. void putch(char c);
  38. void putstr(const char *str);
  39. void open(const char* path, ios::openmode mode);
  40. /** Internal do not use
  41. * \return mode
  42. */
  43. ios::openmode getmode() {return m_mode;}
  44. /** Internal do not use
  45. * \param[in] mode
  46. */
  47. void setmode(ios::openmode mode) {m_mode = mode;}
  48. bool seekoff(off_type off, seekdir way);
  49. bool seekpos(pos_type pos);
  50. int write(const void* buf, size_t n);
  51. void write(char c);
  52. /// @endcond
  53. private:
  54. ios::openmode m_mode;
  55. };
  56. //==============================================================================
  57. /**
  58. * \class fstream
  59. * \brief SD file input/output stream.
  60. */
  61. class fstream : public iostream, SdStreamBase {
  62. public:
  63. using iostream::peek;
  64. fstream() {}
  65. /** Constructor with open
  66. *
  67. * \param[in] path path to open
  68. * \param[in] mode open mode
  69. */
  70. explicit fstream(const char* path, openmode mode = in | out) {
  71. open(path, mode);
  72. }
  73. #if DESTRUCTOR_CLOSES_FILE
  74. ~fstream() {}
  75. #endif // DESTRUCTOR_CLOSES_FILE
  76. /** Clear state and writeError
  77. * \param[in] state new state for stream
  78. */
  79. void clear(iostate state = goodbit) {
  80. ios::clear(state);
  81. SdBaseFile::writeError = false;
  82. }
  83. /** Close a file and force cached data and directory information
  84. * to be written to the storage device.
  85. */
  86. void close() {SdBaseFile::close();}
  87. /** Open a fstream
  88. * \param[in] path file to open
  89. * \param[in] mode open mode
  90. *
  91. * Valid open modes are (at end, ios::ate, and/or ios::binary may be added):
  92. *
  93. * ios::in - Open file for reading.
  94. *
  95. * ios::out or ios::out | ios::trunc - Truncate to 0 length, if existent,
  96. * or create a file for writing only.
  97. *
  98. * ios::app or ios::out | ios::app - Append; open or create file for
  99. * writing at end-of-file.
  100. *
  101. * ios::in | ios::out - Open file for update (reading and writing).
  102. *
  103. * ios::in | ios::out | ios::trunc - Truncate to zero length, if existent,
  104. * or create file for update.
  105. *
  106. * ios::in | ios::app or ios::in | ios::out | ios::app - Append; open or
  107. * create text file for update, writing at end of file.
  108. */
  109. void open(const char* path, openmode mode = in | out) {
  110. SdStreamBase::open(path, mode);
  111. }
  112. /** \return True if stream is open else false. */
  113. bool is_open () {return SdBaseFile::isOpen();}
  114. protected:
  115. /// @cond SHOW_PROTECTED
  116. /** Internal - do not use
  117. * \return
  118. */
  119. int16_t getch() {return SdStreamBase::getch();}
  120. /** Internal - do not use
  121. * \param[out] pos
  122. */
  123. void getpos(FatPos_t* pos) {SdBaseFile::getpos(pos);}
  124. /** Internal - do not use
  125. * \param[in] c
  126. */
  127. void putch(char c) {SdStreamBase::putch(c);}
  128. /** Internal - do not use
  129. * \param[in] str
  130. */
  131. void putstr(const char *str) {SdStreamBase::putstr(str);}
  132. /** Internal - do not use
  133. * \param[in] pos
  134. */
  135. bool seekoff(off_type off, seekdir way) {
  136. return SdStreamBase::seekoff(off, way);
  137. }
  138. bool seekpos(pos_type pos) {return SdStreamBase::seekpos(pos);}
  139. void setpos(FatPos_t* pos) {SdBaseFile::setpos(pos);}
  140. bool sync() {return SdStreamBase::sync();}
  141. pos_type tellpos() {return SdStreamBase::curPosition();}
  142. /// @endcond
  143. };
  144. //==============================================================================
  145. /**
  146. * \class ifstream
  147. * \brief SD file input stream.
  148. */
  149. class ifstream : public istream, SdStreamBase {
  150. public:
  151. using istream::peek;
  152. ifstream() {}
  153. /** Constructor with open
  154. * \param[in] path file to open
  155. * \param[in] mode open mode
  156. */
  157. explicit ifstream(const char* path, openmode mode = in) {
  158. open(path, mode);
  159. }
  160. #if DESTRUCTOR_CLOSES_FILE
  161. ~ifstream() {}
  162. #endif // DESTRUCTOR_CLOSES_FILE
  163. /** Close a file and force cached data and directory information
  164. * to be written to the storage device.
  165. */
  166. void close() {SdBaseFile::close();}
  167. /** \return True if stream is open else false. */
  168. bool is_open() {return SdBaseFile::isOpen();}
  169. /** Open an ifstream
  170. * \param[in] path file to open
  171. * \param[in] mode open mode
  172. *
  173. * \a mode See fstream::open() for valid modes.
  174. */
  175. void open(const char* path, openmode mode = in) {
  176. SdStreamBase::open(path, mode | in);
  177. }
  178. protected:
  179. /// @cond SHOW_PROTECTED
  180. /** Internal - do not use
  181. * \return
  182. */
  183. int16_t getch() {return SdStreamBase::getch();}
  184. /** Internal - do not use
  185. * \param[out] pos
  186. */
  187. void getpos(FatPos_t* pos) {SdBaseFile::getpos(pos);}
  188. /** Internal - do not use
  189. * \param[in] pos
  190. */
  191. bool seekoff(off_type off, seekdir way) {
  192. return SdStreamBase::seekoff(off, way);
  193. }
  194. bool seekpos(pos_type pos) {return SdStreamBase::seekpos(pos);}
  195. void setpos(FatPos_t* pos) {SdBaseFile::setpos(pos);}
  196. pos_type tellpos() {return SdStreamBase::curPosition();}
  197. /// @endcond
  198. };
  199. //==============================================================================
  200. /**
  201. * \class ofstream
  202. * \brief SD card output stream.
  203. */
  204. class ofstream : public ostream, SdStreamBase {
  205. public:
  206. ofstream() {}
  207. /** Constructor with open
  208. * \param[in] path file to open
  209. * \param[in] mode open mode
  210. */
  211. explicit ofstream(const char* path, ios::openmode mode = out) {
  212. open(path, mode);
  213. }
  214. #if DESTRUCTOR_CLOSES_FILE
  215. ~ofstream() {}
  216. #endif // DESTRUCTOR_CLOSES_FILE
  217. /** Clear state and writeError
  218. * \param[in] state new state for stream
  219. */
  220. void clear(iostate state = goodbit) {
  221. ios::clear(state);
  222. SdBaseFile::writeError = false;
  223. }
  224. /** Close a file and force cached data and directory information
  225. * to be written to the storage device.
  226. */
  227. void close() {SdBaseFile::close();}
  228. /** Open an ofstream
  229. * \param[in] path file to open
  230. * \param[in] mode open mode
  231. *
  232. * \a mode See fstream::open() for valid modes.
  233. */
  234. void open(const char* path, openmode mode = out) {
  235. SdStreamBase::open(path, mode | out);
  236. }
  237. /** \return True if stream is open else false. */
  238. bool is_open() {return SdBaseFile::isOpen();}
  239. protected:
  240. /// @cond SHOW_PROTECTED
  241. /**
  242. * Internal do not use
  243. * \param[in] c
  244. */
  245. void putch(char c) {SdStreamBase::putch(c);}
  246. void putstr(const char* str) {SdStreamBase::putstr(str);}
  247. bool seekoff(off_type off, seekdir way) {
  248. return SdStreamBase::seekoff(off, way);
  249. }
  250. bool seekpos(pos_type pos) {return SdStreamBase::seekpos(pos);}
  251. /**
  252. * Internal do not use
  253. * \param[in] b
  254. */
  255. bool sync() {return SdStreamBase::sync();}
  256. pos_type tellpos() {return SdStreamBase::curPosition();}
  257. /// @endcond
  258. };
  259. //------------------------------------------------------------------------------
  260. #endif // SdStream_h