Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

655 linhas
23KB

  1. /* Arduino RamDisk Library
  2. * Copyright (C) 2014 by William Greiman
  3. *
  4. * This file is part of the Arduino RamDisk 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 RamDisk Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef StdioStream_h
  21. #define StdioStream_h
  22. /**
  23. * \file
  24. * \brief StdioStream class
  25. */
  26. #include <limits.h>
  27. #include "FatFile.h"
  28. //------------------------------------------------------------------------------
  29. /** Total size of stream buffer. The entire buffer is used for output.
  30. * During input UNGETC_BUF_SIZE of this space is reserved for ungetc.
  31. */
  32. const uint8_t STREAM_BUF_SIZE = 64;
  33. /** Amount of buffer allocated for ungetc during input. */
  34. const uint8_t UNGETC_BUF_SIZE = 2;
  35. //------------------------------------------------------------------------------
  36. // Get rid of any macros defined in <stdio.h>.
  37. #include <stdio.h>
  38. #undef clearerr
  39. #undef fclose
  40. #undef feof
  41. #undef ferror
  42. #undef fflush
  43. #undef fgetc
  44. #undef fgetpos
  45. #undef fgets
  46. #undef fopen
  47. #undef fprintf
  48. #undef fputc
  49. #undef fputs
  50. #undef fread
  51. #undef freopen
  52. #undef fscanf
  53. #undef fseek
  54. #undef fsetpos
  55. #undef ftell
  56. #undef fwrite
  57. #undef getc
  58. #undef getchar
  59. #undef gets
  60. #undef perror
  61. #undef printf
  62. #undef putc
  63. #undef putchar
  64. #undef puts
  65. #undef remove
  66. #undef rename
  67. #undef rewind
  68. #undef scanf
  69. #undef setbuf
  70. #undef setvbuf
  71. #undef sprintf // NOLINT
  72. #undef sscanf
  73. #undef tmpfile
  74. #undef tmpnam
  75. #undef ungetc
  76. #undef vfprintf
  77. #undef vprintf
  78. #undef vsprintf
  79. // make sure needed macros are defined
  80. #ifndef EOF
  81. /** End-of-file return value. */
  82. #define EOF (-1)
  83. #endif // EOF
  84. #ifndef NULL
  85. /** Null pointer */
  86. #define NULL 0
  87. #endif // NULL
  88. #ifndef SEEK_CUR
  89. /** Seek relative to current position. */
  90. #define SEEK_CUR 1
  91. #endif // SEEK_CUR
  92. #ifndef SEEK_END
  93. /** Seek relative to end-of-file. */
  94. #define SEEK_END 2
  95. #endif // SEEK_END
  96. #ifndef SEEK_SET
  97. /** Seek relative to start-of-file. */
  98. #define SEEK_SET 0
  99. #endif // SEEK_SET
  100. //------------------------------------------------------------------------------
  101. /** \class StdioStream
  102. * \brief StdioStream implements a minimal stdio stream.
  103. *
  104. * StdioStream does not support subdirectories or long file names.
  105. */
  106. class StdioStream : private FatFile {
  107. public:
  108. /** Constructor
  109. *
  110. */
  111. StdioStream() {
  112. m_w = m_r = 0;
  113. m_p = m_buf;
  114. m_flags = 0;
  115. }
  116. //----------------------------------------------------------------------------
  117. /** Clear the stream's end-of-file and error indicators. */
  118. void clearerr() {m_flags &= ~(F_ERR | F_EOF);}
  119. //----------------------------------------------------------------------------
  120. /** Close a stream.
  121. *
  122. * A successful call to the fclose function causes the stream to be
  123. * flushed and the associated file to be closed. Any unwritten buffered
  124. * data is written to the file; any unread buffered data is discarded.
  125. * Whether or not the call succeeds, the stream is disassociated from
  126. * the file.
  127. *
  128. * \return zero if the stream was successfully closed, or EOF if any any
  129. * errors are detected.
  130. */
  131. int fclose();
  132. //----------------------------------------------------------------------------
  133. /** Test the stream's end-of-file indicator.
  134. * \return non-zero if and only if the end-of-file indicator is set.
  135. */
  136. int feof() {return (m_flags & F_EOF) != 0;}
  137. //----------------------------------------------------------------------------
  138. /** Test the stream's error indicator.
  139. * \return return non-zero if and only if the error indicator is set.
  140. */
  141. int ferror() {return (m_flags & F_ERR) != 0;}
  142. //----------------------------------------------------------------------------
  143. /** Flush the stream.
  144. *
  145. * If stream is an output stream or an update stream in which the most
  146. * recent operation was not input, any unwritten data is written to the
  147. * file; otherwise the call is an error since any buffered input data
  148. * would be lost.
  149. *
  150. * \return sets the error indicator for the stream and returns EOF if an
  151. * error occurs, otherwise it returns zero.
  152. */
  153. int fflush();
  154. //----------------------------------------------------------------------------
  155. /** Get a byte from the stream.
  156. *
  157. * \return If the end-of-file indicator for the stream is set, or if the
  158. * stream is at end-of-file, the end-of-file indicator for the stream is
  159. * set and the fgetc function returns EOF. Otherwise, the fgetc function
  160. * returns the next character from the input stream.
  161. */
  162. int fgetc() {return m_r-- == 0 ? fillGet() : *m_p++;}
  163. //----------------------------------------------------------------------------
  164. /** Get a string from a stream.
  165. *
  166. * The fgets function reads at most one less than the number of
  167. * characters specified by num from the stream into the array pointed
  168. * to by str. No additional characters are read after a new-line
  169. * character (which is retained) or after end-of-file. A null character
  170. * is written immediately after the last character read into the array.
  171. *
  172. * \param[out] str Pointer to an array of where the string is copied.
  173. *
  174. * \param[in] num Maximum number of characters including the null
  175. * character.
  176. *
  177. * \param[out] len If len is not null and fgets is successful, the
  178. * length of the string is returned.
  179. *
  180. * \return str if successful. If end-of-file is encountered and no
  181. * characters have been read into the array, the contents of the array
  182. * remain unchanged and a null pointer is returned. If a read error
  183. * occurs during the operation, the array contents are indeterminate
  184. * and a null pointer is returned.
  185. */
  186. char* fgets(char* str, size_t num, size_t* len = 0);
  187. //----------------------------------------------------------------------------
  188. /** Open a stream.
  189. *
  190. * Open a file and associates the stream with it.
  191. *
  192. * \param[in] filename name of the file to be opened.
  193. *
  194. * \param[in] mode a string that indicates the open mode.
  195. *
  196. * <table>
  197. * <tr>
  198. * <td>"r" or "rb"</td>
  199. * <td>Open a file for reading. The file must exist.</td>
  200. * </tr>
  201. * <tr>
  202. * <td>"w" or "wb"</td>
  203. * <td>Truncate an existing to zero length or create an empty file
  204. * for writing.</td>
  205. * </tr>
  206. * <tr>
  207. * <td>"wx" or "wbx"</td>
  208. * <td>Create a file for writing. Fails if the file already exists.</td>
  209. * </tr>
  210. * <tr>
  211. * <td>"a" or "ab"</td>
  212. * <td>Append; open or create file for writing at end-of-file.</td>
  213. * </tr>
  214. * <tr>
  215. * <td>"r+" or "rb+" or "r+b"</td>
  216. * <td>Open a file for update (reading and writing).</td>
  217. * </tr>
  218. * <tr>
  219. * <td>"w+" or "w+b" or "wb+"</td>
  220. * <td>Truncate an existing to zero length or create a file for update.</td>
  221. * </tr>
  222. * <tr>
  223. * <td>"w+x" or "w+bx" or "wb+x"</td>
  224. * <td>Create a file for update. Fails if the file already exists.</td>
  225. * </tr>
  226. * <tr>
  227. * <td>"a+" or "a+b" or "ab+"</td>
  228. * <td>Append; open or create a file for update, writing at end-of-file.</td>
  229. * </tr>
  230. * </table>
  231. * The character 'b' shall have no effect, but is allowed for ISO C
  232. * standard conformance.
  233. *
  234. * Opening a file with append mode causes all subsequent writes to the
  235. * file to be forced to the then current end-of-file, regardless of
  236. * intervening calls to the fseek function.
  237. *
  238. * When a file is opened with update mode, both input and output may be
  239. * performed on the associated stream. However, output shall not be
  240. * directly followed by input without an intervening call to the fflush
  241. * function or to a file positioning function (fseek, or rewind), and
  242. * input shall not be directly followed by output without an intervening
  243. * call to a file positioning function, unless the input operation
  244. * encounters end-of-file.
  245. *
  246. * \return true for success or false for failure.
  247. */
  248. bool fopen(const char* filename, const char * mode);
  249. //----------------------------------------------------------------------------
  250. /** Write a byte to a stream.
  251. *
  252. * \param[in] c the byte to be written (converted to an unsigned char).
  253. *
  254. * \return Upon successful completion, fputc() returns the value it
  255. * has written. Otherwise, it returns EOF and sets the error indicator for
  256. * the stream.
  257. */
  258. int fputc(int c) {return m_w-- == 0 ? flushPut(c) : *m_p++ = c;}
  259. //----------------------------------------------------------------------------
  260. /** Write a string to a stream.
  261. *
  262. * \param[in] str a pointer to the string to be written.
  263. *
  264. * \return for success, fputs() returns a non-negative
  265. * number. Otherwise, it returns EOF and sets the error indicator for
  266. * the stream.
  267. */
  268. int fputs(const char* str);
  269. //----------------------------------------------------------------------------
  270. /** Write a string stored in flash.
  271. *
  272. * \param[in] str string to be written.
  273. *
  274. * \return for success, fputs() returns a non-negative
  275. * number. Otherwise, it returns EOF and sets the error indicator for
  276. * the stream.
  277. */
  278. int fputs_P(PGM_P str);
  279. //----------------------------------------------------------------------------
  280. /** Binary input.
  281. *
  282. * Reads an array of up to count elements, each one with a size of size
  283. * bytes.
  284. * \param[out] ptr pointer to area of at least (size*count) bytes where
  285. * the data will be stored.
  286. *
  287. * \param[in] size the size, in bytes, of each element to be read.
  288. *
  289. * \param[in] count the number of elements to be read.
  290. *
  291. * \return number of elements successfully read, which may be less than
  292. * count if a read error or end-of-file is encountered. If size or count
  293. * is zero, fread returns zero and the contents of the array and the
  294. * state of the stream remain unchanged.
  295. */
  296. size_t fread(void* ptr, size_t size, size_t count);
  297. //----------------------------------------------------------------------------
  298. /** Set the file position for the stream.
  299. *
  300. * \param[in] offset number of offset from the origin.
  301. *
  302. * \param[in] origin position used as reference for the offset. It is
  303. * specified by one of the following constants.
  304. *
  305. * SEEK_SET - Beginning of file.
  306. *
  307. * SEEK_CUR - Current position of the file pointer.
  308. *
  309. * SEEK_END - End of file.
  310. *
  311. * \return zero for success. Otherwise, it returns non-zero and sets the
  312. * error indicator for the stream.
  313. */
  314. int fseek(int32_t offset, int origin);
  315. //----------------------------------------------------------------------------
  316. /** Get the current position in a stream.
  317. *
  318. * \return If successful, ftell return the current value of the position
  319. * indicator. On failure, ftell returns −1L.
  320. */
  321. int32_t ftell();
  322. //----------------------------------------------------------------------------
  323. /** Binary output.
  324. *
  325. * Writes an array of up to count elements, each one with a size of size
  326. * bytes.
  327. * \param[in] ptr pointer to (size*count) bytes of data to be written.
  328. *
  329. * \param[in] size the size, in bytes, of each element to be written.
  330. *
  331. * \param[in] count the number of elements to be written.
  332. *
  333. * \return number of elements successfully written. if this number is
  334. * less than count, an error has occurred. If size or count is zero,
  335. * fwrite returns zero.
  336. */
  337. size_t fwrite(const void * ptr, size_t size, size_t count);
  338. //----------------------------------------------------------------------------
  339. /** Get a byte from the stream.
  340. *
  341. * getc and fgetc are equivalent but getc is in-line so it is faster but
  342. * require more flash memory.
  343. *
  344. * \return If the end-of-file indicator for the stream is set, or if the
  345. * stream is at end-of-file, the end-of-file indicator for the stream is
  346. * set and the fgetc function returns EOF. Otherwise, the fgetc function
  347. * returns the next character from the input stream.
  348. */
  349. inline __attribute__((always_inline))
  350. int getc() {return m_r-- == 0 ? fillGet() : *m_p++;}
  351. //----------------------------------------------------------------------------
  352. /** Write a byte to a stream.
  353. *
  354. * putc and fputc are equivalent but putc is in-line so it is faster but
  355. * require more flash memory.
  356. *
  357. * \param[in] c the byte to be written (converted to an unsigned char).
  358. *
  359. * \return Upon successful completion, fputc() returns the value it
  360. * has written. Otherwise, it returns EOF and sets the error indicator for
  361. * the stream.
  362. */
  363. inline __attribute__((always_inline))
  364. int putc(int c) {return m_w-- == 0 ? flushPut(c) : *m_p++ = c;}
  365. //----------------------------------------------------------------------------
  366. /** Write a CR/LF.
  367. *
  368. * \return two, the number of bytes written, for success or -1 for failure.
  369. */
  370. inline __attribute__((always_inline))
  371. int putCRLF() {
  372. if (m_w < 2) {
  373. if (!flushBuf()) return -1;
  374. }
  375. *m_p++ = '\r';
  376. *m_p++ = '\n';
  377. m_w -= 2;
  378. return 2;
  379. }
  380. //----------------------------------------------------------------------------
  381. /** Write a character.
  382. * \param[in] c the character to write.
  383. * \return the number of bytes written.
  384. */
  385. size_t print(char c) {
  386. return putc(c) < 0 ? 0 : 1;
  387. }
  388. //----------------------------------------------------------------------------
  389. /** Write a string.
  390. *
  391. * \param[in] str the string to be written.
  392. *
  393. * \return the number of bytes written.
  394. */
  395. size_t print(const char* str) {
  396. int n = fputs(str);
  397. return n < 0 ? 0 : n;
  398. }
  399. //----------------------------------------------------------------------------
  400. /** Print a string stored in flash memory.
  401. *
  402. * \param[in] str the string to print.
  403. *
  404. * \return the number of bytes written.
  405. */
  406. size_t print(const __FlashStringHelper *str);
  407. //----------------------------------------------------------------------------
  408. /** Print a floating point number.
  409. *
  410. * \param[in] prec Number of digits after decimal point.
  411. *
  412. * \param[in] val the number to be printed.
  413. *
  414. * \return the number of bytes written.
  415. */
  416. size_t print(double val, uint8_t prec = 2) {
  417. return print(static_cast<float>(val), prec);
  418. }
  419. //----------------------------------------------------------------------------
  420. /** Print a floating point number.
  421. *
  422. * \param[in] prec Number of digits after decimal point.
  423. *
  424. * \param[in] val the number to be printed.
  425. *
  426. * \return the number of bytes written.
  427. */
  428. size_t print(float val, uint8_t prec = 2) {
  429. int n = printDec(val, prec);
  430. return n > 0 ? n : 0;
  431. }
  432. //----------------------------------------------------------------------------
  433. /** Print a number.
  434. *
  435. * \param[in] val the number to be printed.
  436. *
  437. * \return the number of bytes written.
  438. */
  439. template <typename T>
  440. size_t print(T val) {
  441. int n = printDec(val);
  442. return n > 0 ? n : 0;
  443. }
  444. //----------------------------------------------------------------------------
  445. /** Write a CR/LF.
  446. *
  447. * \return two, the number of bytes written, for success or zero for failure.
  448. */
  449. size_t println() {
  450. return putCRLF() > 0 ? 2 : 0;
  451. }
  452. //----------------------------------------------------------------------------
  453. /** Print a floating point number followed by CR/LF.
  454. *
  455. * \param[in] val the number to be printed.
  456. *
  457. * \param[in] prec Number of digits after decimal point.
  458. *
  459. * \return the number of bytes written.
  460. */
  461. size_t println(double val, uint8_t prec = 2) {
  462. return println(static_cast<float>(val), prec);
  463. }
  464. //----------------------------------------------------------------------------
  465. /** Print a floating point number followed by CR/LF.
  466. *
  467. * \param[in] val the number to be printed.
  468. *
  469. * \param[in] prec Number of digits after decimal point.
  470. *
  471. * \return the number of bytes written.
  472. */
  473. size_t println(float val, uint8_t prec = 2) {
  474. int n = printDec(val, prec);
  475. return n > 0 && putCRLF() > 0 ? n + 2 : 0;
  476. }
  477. //----------------------------------------------------------------------------
  478. /** Print an item followed by CR/LF
  479. *
  480. * \param[in] val the item to be printed.
  481. *
  482. * \return the number of bytes written.
  483. */
  484. template <typename T>
  485. size_t println(T val) {
  486. int n = print(val);
  487. return putCRLF() > 0 ? n + 2 : 0;
  488. }
  489. //----------------------------------------------------------------------------
  490. /** Print a char as a number.
  491. * \param[in] n number to be printed.
  492. * \return The number of bytes written or -1 if an error occurs.
  493. */
  494. int printDec(char n) {
  495. if (CHAR_MIN == 0) {
  496. return printDec((unsigned char)n);
  497. } else {
  498. return printDec((signed char)n);
  499. }
  500. }
  501. //----------------------------------------------------------------------------
  502. /** print a signed 8-bit integer
  503. * \param[in] n number to be printed.
  504. * \return The number of bytes written or -1 if an error occurs.
  505. */
  506. int printDec(signed char n);
  507. //----------------------------------------------------------------------------
  508. /** Print an unsigned 8-bit number.
  509. * \param[in] n number to be print.
  510. * \return The number of bytes written or -1 if an error occurs.
  511. */
  512. int printDec(unsigned char n) {
  513. return printDec((uint16_t)n);
  514. }
  515. //----------------------------------------------------------------------------
  516. /** Print a int16_t
  517. * \param[in] n number to be printed.
  518. * \return The number of bytes written or -1 if an error occurs.
  519. */
  520. int printDec(int16_t n);
  521. //----------------------------------------------------------------------------
  522. /** print a uint16_t.
  523. * \param[in] n number to be printed.
  524. * \return The number of bytes written or -1 if an error occurs.
  525. */
  526. int printDec(uint16_t n);
  527. //----------------------------------------------------------------------------
  528. /** Print a signed 32-bit integer.
  529. * \param[in] n number to be printed.
  530. * \return The number of bytes written or -1 if an error occurs.
  531. */
  532. int printDec(int32_t n);
  533. //----------------------------------------------------------------------------
  534. /** Write an unsigned 32-bit number.
  535. * \param[in] n number to be printed.
  536. * \return The number of bytes written or -1 if an error occurs.
  537. */
  538. int printDec(uint32_t n);
  539. //----------------------------------------------------------------------------
  540. /** Print a double.
  541. * \param[in] value The number to be printed.
  542. * \param[in] prec Number of digits after decimal point.
  543. * \return The number of bytes written or -1 if an error occurs.
  544. */
  545. int printDec(double value, uint8_t prec) {
  546. return printDec(static_cast<float>(value), prec);
  547. }
  548. //----------------------------------------------------------------------------
  549. /** Print a float.
  550. * \param[in] value The number to be printed.
  551. * \param[in] prec Number of digits after decimal point.
  552. * \return The number of bytes written or -1 if an error occurs.
  553. */
  554. int printDec(float value, uint8_t prec);
  555. //----------------------------------------------------------------------------
  556. /** Print a number followed by a field terminator.
  557. * \param[in] value The number to be printed.
  558. * \param[in] term The field terminator.
  559. * \param[in] prec Number of digits after decimal point.
  560. * \return The number of bytes written or -1 if an error occurs.
  561. */
  562. int printField(double value, char term, uint8_t prec = 2) {
  563. return printField(static_cast<float>(value), term, prec) > 0;
  564. }
  565. //----------------------------------------------------------------------------
  566. /** Print a number followed by a field terminator.
  567. * \param[in] value The number to be printed.
  568. * \param[in] term The field terminator.
  569. * \param[in] prec Number of digits after decimal point.
  570. * \return The number of bytes written or -1 if an error occurs.
  571. */
  572. int printField(float value, char term, uint8_t prec = 2) {
  573. int rtn = printDec(value, prec);
  574. return rtn < 0 || putc(term) < 0 ? -1 : rtn + 1;
  575. }
  576. //----------------------------------------------------------------------------
  577. /** Print a number followed by a field terminator.
  578. * \param[in] value The number to be printed.
  579. * \param[in] term The field terminator.
  580. * \return The number of bytes written or -1 if an error occurs.
  581. */
  582. template <typename T>
  583. int printField(T value, char term) {
  584. int rtn = printDec(value);
  585. return rtn < 0 || putc(term) < 0 ? -1 : rtn + 1;
  586. }
  587. //----------------------------------------------------------------------------
  588. /** Print HEX
  589. * \param[in] n number to be printed as HEX.
  590. *
  591. * \return The number of bytes written or -1 if an error occurs.
  592. */
  593. int printHex(uint32_t n);
  594. //----------------------------------------------------------------------------
  595. /** Print HEX with CRLF
  596. * \param[in] n number to be printed as HEX.
  597. *
  598. * \return The number of bytes written or -1 if an error occurs.
  599. */
  600. int printHexln(uint32_t n) {
  601. int rtn = printHex(n);
  602. return rtn < 0 || putCRLF() != 2 ? -1 : rtn + 2;
  603. }
  604. //----------------------------------------------------------------------------
  605. /** Set position of a stream to the beginning.
  606. *
  607. * The rewind function sets the file position to the beginning of the
  608. * file. It is equivalent to fseek(0L, SEEK_SET) except that the error
  609. * indicator for the stream is also cleared.
  610. *
  611. * \return true for success or false for failure.
  612. */
  613. bool rewind();
  614. //----------------------------------------------------------------------------
  615. /** Push a byte back into an input stream.
  616. *
  617. * \param[in] c the byte (converted to an unsigned char) to be pushed back.
  618. *
  619. * One character of push-back is guaranteed. If the ungetc function is
  620. * called too many times without an intervening read or file positioning
  621. * operation on that stream, the operation may fail.
  622. *
  623. * A successful intervening call to a file positioning function (fseek,
  624. * fsetpos, or rewind) discards any pushed-back characters for the stream.
  625. *
  626. * \return Upon successful completion, ungetc() returns the byte pushed
  627. * back after conversion. Otherwise it returns EOF.
  628. */
  629. int ungetc(int c);
  630. //============================================================================
  631. private:
  632. bool fillBuf();
  633. int fillGet();
  634. bool flushBuf();
  635. int flushPut(uint8_t c);
  636. char* fmtSpace(uint8_t len);
  637. int write(const void* buf, size_t count);
  638. //----------------------------------------------------------------------------
  639. // F_SRD and F_WR are never simultaneously asserted
  640. static const uint8_t F_SRD = 0x01; // OK to read
  641. static const uint8_t F_SWR = 0x02; // OK to write
  642. static const uint8_t F_SRW = 0x04; // open for reading & writing
  643. static const uint8_t F_EOF = 0x10; // found EOF
  644. static const uint8_t F_ERR = 0x20; // found error
  645. //----------------------------------------------------------------------------
  646. uint8_t m_flags;
  647. uint8_t* m_p;
  648. uint8_t m_r;
  649. uint8_t m_w;
  650. uint8_t m_buf[STREAM_BUF_SIZE];
  651. };
  652. //------------------------------------------------------------------------------
  653. #endif // StdioStream_h