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.

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