ios.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /**
  2. * Copyright (c) 2011-2022 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef ios_h
  26. #define ios_h
  27. #include "../FsLib/FsLib.h"
  28. /**
  29. * \file
  30. * \brief \ref ios_base and \ref ios classes
  31. */
  32. //==============================================================================
  33. /** For internal use in c++ streams */
  34. typedef fspos_t pos_t;
  35. //==============================================================================
  36. #if SDFAT_FILE_TYPE == 1 || defined(DOXYGEN)
  37. /** Set File type for iostreams. */
  38. typedef FatFile StreamBaseFile;
  39. #elif SDFAT_FILE_TYPE == 2
  40. typedef ExFatFile StreamBaseFile;
  41. #elif SDFAT_FILE_TYPE == 3
  42. typedef FsBaseFile StreamBaseFile;
  43. #else // SDFAT_FILE_TYPE
  44. #error Invalid SDFAT_FILE_TYPE
  45. #endif // SDFAT_FILE_TYPE
  46. /**
  47. * \class ios_base
  48. * \brief Base class for all streams
  49. */
  50. class ios_base {
  51. public:
  52. /** typedef for iostate bitmask */
  53. typedef unsigned char iostate;
  54. // State flags.
  55. /** iostate for no flags */
  56. static const iostate goodbit = 0x00;
  57. /** iostate bad bit for a nonrecoverable error. */
  58. static const iostate badbit = 0X01;
  59. /** iostate bit for end of file reached */
  60. static const iostate eofbit = 0x02;
  61. /** iostate fail bit for nonfatal error */
  62. static const iostate failbit = 0X04;
  63. #if SDFAT_FILE_TYPE == 1
  64. /**
  65. * unsigned size that can represent maximum file size.
  66. * (violates spec - should be signed)
  67. */
  68. typedef uint32_t streamsize;
  69. /** type for absolute seek position */
  70. typedef uint32_t pos_type;
  71. /** type for relative seek offset */
  72. typedef int32_t off_type;
  73. #else // SDFAT_FILE_TYPE
  74. /**
  75. * unsigned size that can represent maximum file size.
  76. * (violates spec - should be signed)
  77. */
  78. typedef uint64_t streamsize;
  79. /** type for absolute seek position */
  80. typedef uint64_t pos_type;
  81. /** type for relative seek offset */
  82. typedef int64_t off_type;
  83. #endif // SDFAT_FILE_TYPE
  84. /** enumerated type for the direction of relative seeks */
  85. enum seekdir {
  86. /** seek relative to the beginning of the stream */
  87. beg,
  88. /** seek relative to the current stream position */
  89. cur,
  90. /** seek relative to the end of the stream */
  91. end
  92. };
  93. /** type for format flags */
  94. typedef unsigned int fmtflags;
  95. /** left adjust fields */
  96. static const fmtflags left = 0x0001;
  97. /** right adjust fields */
  98. static const fmtflags right = 0x0002;
  99. /** fill between sign/base prefix and number */
  100. static const fmtflags internal = 0x0004;
  101. /** base 10 flag*/
  102. static const fmtflags dec = 0x0008;
  103. /** base 16 flag */
  104. static const fmtflags hex = 0x0010;
  105. /** base 8 flag */
  106. static const fmtflags oct = 0x0020;
  107. // static const fmtflags fixed = 0x0040;
  108. // static const fmtflags scientific = 0x0080;
  109. /** use strings true/false for bool */
  110. static const fmtflags boolalpha = 0x0100;
  111. /** use prefix 0X for hex and 0 for oct */
  112. static const fmtflags showbase = 0x0200;
  113. /** always show '.' for floating numbers */
  114. static const fmtflags showpoint = 0x0400;
  115. /** show + sign for nonnegative numbers */
  116. static const fmtflags showpos = 0x0800;
  117. /** skip initial white space */
  118. static const fmtflags skipws = 0x1000;
  119. // static const fmtflags unitbuf = 0x2000;
  120. /** use uppercase letters in number representations */
  121. static const fmtflags uppercase = 0x4000;
  122. /** mask for adjustfield */
  123. static const fmtflags adjustfield = left | right | internal;
  124. /** mask for basefield */
  125. static const fmtflags basefield = dec | hex | oct;
  126. // static const fmtflags floatfield = scientific | fixed;
  127. //----------------------------------------------------------------------------
  128. /** typedef for iostream open mode */
  129. typedef uint8_t openmode;
  130. // Openmode flags.
  131. /** seek to end before each write */
  132. static const openmode app = 0X4;
  133. /** open and seek to end immediately after opening */
  134. static const openmode ate = 0X8;
  135. /** perform input and output in binary mode (as opposed to text mode) */
  136. static const openmode binary = 0X10;
  137. /** open for input */
  138. static const openmode in = 0X20;
  139. /** open for output */
  140. static const openmode out = 0X40;
  141. /** truncate an existing stream when opening */
  142. static const openmode trunc = 0X80;
  143. //----------------------------------------------------------------------------
  144. ios_base() : m_fill(' '), m_fmtflags(dec | right | skipws)
  145. , m_precision(2), m_width(0) {}
  146. /** \return fill character */
  147. char fill() {
  148. return m_fill;
  149. }
  150. /** Set fill character
  151. * \param[in] c new fill character
  152. * \return old fill character
  153. */
  154. char fill(char c) {
  155. char r = m_fill;
  156. m_fill = c;
  157. return r;
  158. }
  159. /** \return format flags */
  160. fmtflags flags() const {
  161. return m_fmtflags;
  162. }
  163. /** set format flags
  164. * \param[in] fl new flag
  165. * \return old flags
  166. */
  167. fmtflags flags(fmtflags fl) {
  168. fmtflags tmp = m_fmtflags;
  169. m_fmtflags = fl;
  170. return tmp;
  171. }
  172. /** \return precision */
  173. int precision() const {
  174. return m_precision;
  175. }
  176. /** set precision
  177. * \param[in] n new precision
  178. * \return old precision
  179. */
  180. int precision(unsigned int n) {
  181. int r = m_precision;
  182. m_precision = n;
  183. return r;
  184. }
  185. /** set format flags
  186. * \param[in] fl new flags to be or'ed in
  187. * \return old flags
  188. */
  189. fmtflags setf(fmtflags fl) {
  190. fmtflags r = m_fmtflags;
  191. m_fmtflags |= fl;
  192. return r;
  193. }
  194. /** modify format flags
  195. * \param[in] mask flags to be removed
  196. * \param[in] fl flags to be set after mask bits have been cleared
  197. * \return old flags
  198. */
  199. fmtflags setf(fmtflags fl, fmtflags mask) {
  200. fmtflags r = m_fmtflags;
  201. m_fmtflags &= ~mask;
  202. m_fmtflags |= fl;
  203. return r;
  204. }
  205. /** clear format flags
  206. * \param[in] fl flags to be cleared
  207. */
  208. void unsetf(fmtflags fl) {
  209. m_fmtflags &= ~fl;
  210. }
  211. /** \return width */
  212. unsigned width() {
  213. return m_width;
  214. }
  215. /** set width
  216. * \param[in] n new width
  217. * \return old width
  218. */
  219. unsigned width(unsigned n) {
  220. unsigned r = m_width;
  221. m_width = n;
  222. return r;
  223. }
  224. protected:
  225. /** \return current number base */
  226. uint8_t flagsToBase() {
  227. uint8_t f = flags() & basefield;
  228. return f == oct ? 8 : f != hex ? 10 : 16;
  229. }
  230. private:
  231. char m_fill;
  232. fmtflags m_fmtflags;
  233. unsigned char m_precision;
  234. unsigned int m_width;
  235. };
  236. //------------------------------------------------------------------------------
  237. /** function for boolalpha manipulator
  238. * \param[in] str The stream
  239. * \return The stream
  240. */
  241. inline ios_base& boolalpha(ios_base& str) {
  242. str.setf(ios_base::boolalpha);
  243. return str;
  244. }
  245. /** function for dec manipulator
  246. * \param[in] str The stream
  247. * \return The stream
  248. */
  249. inline ios_base& dec(ios_base& str) {
  250. str.setf(ios_base::dec, ios_base::basefield);
  251. return str;
  252. }
  253. /** function for hex manipulator
  254. * \param[in] str The stream
  255. * \return The stream
  256. */
  257. inline ios_base& hex(ios_base& str) {
  258. str.setf(ios_base::hex, ios_base::basefield);
  259. return str;
  260. }
  261. /** function for internal manipulator
  262. * \param[in] str The stream
  263. * \return The stream
  264. */
  265. inline ios_base& internal(ios_base& str) {
  266. str.setf(ios_base::internal, ios_base::adjustfield);
  267. return str;
  268. }
  269. /** function for left manipulator
  270. * \param[in] str The stream
  271. * \return The stream
  272. */
  273. inline ios_base& left(ios_base& str) {
  274. str.setf(ios_base::left, ios_base::adjustfield);
  275. return str;
  276. }
  277. /** function for noboolalpha manipulator
  278. * \param[in] str The stream
  279. * \return The stream
  280. */
  281. inline ios_base& noboolalpha(ios_base& str) {
  282. str.unsetf(ios_base::boolalpha);
  283. return str;
  284. }
  285. /** function for noshowbase manipulator
  286. * \param[in] str The stream
  287. * \return The stream
  288. */
  289. inline ios_base& noshowbase(ios_base& str) {
  290. str.unsetf(ios_base::showbase);
  291. return str;
  292. }
  293. /** function for noshowpoint manipulator
  294. * \param[in] str The stream
  295. * \return The stream
  296. */
  297. inline ios_base& noshowpoint(ios_base& str) {
  298. str.unsetf(ios_base::showpoint);
  299. return str;
  300. }
  301. /** function for noshowpos manipulator
  302. * \param[in] str The stream
  303. * \return The stream
  304. */
  305. inline ios_base& noshowpos(ios_base& str) {
  306. str.unsetf(ios_base::showpos);
  307. return str;
  308. }
  309. /** function for noskipws manipulator
  310. * \param[in] str The stream
  311. * \return The stream
  312. */
  313. inline ios_base& noskipws(ios_base& str) {
  314. str.unsetf(ios_base::skipws);
  315. return str;
  316. }
  317. /** function for nouppercase manipulator
  318. * \param[in] str The stream
  319. * \return The stream
  320. */
  321. inline ios_base& nouppercase(ios_base& str) {
  322. str.unsetf(ios_base::uppercase);
  323. return str;
  324. }
  325. /** function for oct manipulator
  326. * \param[in] str The stream
  327. * \return The stream
  328. */
  329. inline ios_base& oct(ios_base& str) {
  330. str.setf(ios_base::oct, ios_base::basefield);
  331. return str;
  332. }
  333. /** function for right manipulator
  334. * \param[in] str The stream
  335. * \return The stream
  336. */
  337. inline ios_base& right(ios_base& str) {
  338. str.setf(ios_base::right, ios_base::adjustfield);
  339. return str;
  340. }
  341. /** function for showbase manipulator
  342. * \param[in] str The stream
  343. * \return The stream
  344. */
  345. inline ios_base& showbase(ios_base& str) {
  346. str.setf(ios_base::showbase);
  347. return str;
  348. }
  349. /** function for showpos manipulator
  350. * \param[in] str The stream
  351. * \return The stream
  352. */
  353. inline ios_base& showpos(ios_base& str) {
  354. str.setf(ios_base::showpos);
  355. return str;
  356. }
  357. /** function for showpoint manipulator
  358. * \param[in] str The stream
  359. * \return The stream
  360. */
  361. inline ios_base& showpoint(ios_base& str) {
  362. str.setf(ios_base::showpoint);
  363. return str;
  364. }
  365. /** function for skipws manipulator
  366. * \param[in] str The stream
  367. * \return The stream
  368. */
  369. inline ios_base& skipws(ios_base& str) {
  370. str.setf(ios_base::skipws);
  371. return str;
  372. }
  373. /** function for uppercase manipulator
  374. * \param[in] str The stream
  375. * \return The stream
  376. */
  377. inline ios_base& uppercase(ios_base& str) {
  378. str.setf(ios_base::uppercase);
  379. return str;
  380. }
  381. //==============================================================================
  382. /**
  383. * \class ios
  384. * \brief Error and state information for all streams
  385. */
  386. class ios : public ios_base {
  387. public:
  388. /** Create ios with no error flags set */
  389. ios() {}
  390. /** \return null pointer if fail() is true. */
  391. operator const void*() const {
  392. return !fail() ? reinterpret_cast<const void*>(this) : nullptr;
  393. }
  394. /** \return true if fail() else false. */
  395. bool operator!() const {
  396. return fail();
  397. }
  398. /** \return false if fail() else true. */
  399. explicit operator bool() const {return !fail();}
  400. /** \return The iostate flags for this file. */
  401. iostate rdstate() const {
  402. return m_iostate;
  403. }
  404. /** \return True if no iostate flags are set else false. */
  405. bool good() const {
  406. return m_iostate == goodbit;
  407. }
  408. /** \return true if end of file has been reached else false.
  409. *
  410. * Warning: An empty file returns false before the first read.
  411. *
  412. * Moral: eof() is only useful in combination with fail(), to find out
  413. * whether EOF was the cause for failure
  414. */
  415. bool eof() const {
  416. return m_iostate & eofbit;
  417. }
  418. /** \return true if any iostate bit other than eof are set else false. */
  419. bool fail() const {
  420. return m_iostate & (failbit | badbit);
  421. }
  422. /** \return true if bad bit is set else false. */
  423. bool bad() const {
  424. return m_iostate & badbit;
  425. }
  426. /** Clear iostate bits.
  427. *
  428. * \param[in] state The flags you want to set after clearing all flags.
  429. **/
  430. void clear(iostate state = goodbit) {
  431. m_iostate = state;
  432. }
  433. /** Set iostate bits.
  434. *
  435. * \param[in] state Bitts to set.
  436. **/
  437. void setstate(iostate state) {
  438. m_iostate |= state;
  439. }
  440. private:
  441. iostate m_iostate = 0;
  442. };
  443. #endif // ios_h