ios.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /**
  2. * Copyright (c) 2011-2018 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 "FatFile.h"
  28. /**
  29. * \file
  30. * \brief \ref ios_base and \ref ios classes
  31. */
  32. //==============================================================================
  33. /**
  34. * \class ios_base
  35. * \brief Base class for all streams
  36. */
  37. class ios_base {
  38. public:
  39. /** typedef for iostate bitmask */
  40. typedef unsigned char iostate;
  41. // State flags.
  42. /** iostate for no flags */
  43. static const iostate goodbit = 0x00;
  44. /** iostate bad bit for a nonrecoverable error. */
  45. static const iostate badbit = 0X01;
  46. /** iostate bit for end of file reached */
  47. static const iostate eofbit = 0x02;
  48. /** iostate fail bit for nonfatal error */
  49. static const iostate failbit = 0X04;
  50. /**
  51. * unsigned size that can represent maximum file size.
  52. * (violates spec - should be signed)
  53. */
  54. typedef uint32_t streamsize;
  55. /** type for absolute seek position */
  56. typedef uint32_t pos_type;
  57. /** type for relative seek offset */
  58. typedef int32_t off_type;
  59. /** enumerated type for the direction of relative seeks */
  60. enum seekdir {
  61. /** seek relative to the beginning of the stream */
  62. beg,
  63. /** seek relative to the current stream position */
  64. cur,
  65. /** seek relative to the end of the stream */
  66. end
  67. };
  68. /** type for format flags */
  69. typedef unsigned int fmtflags;
  70. /** left adjust fields */
  71. static const fmtflags left = 0x0001;
  72. /** right adjust fields */
  73. static const fmtflags right = 0x0002;
  74. /** fill between sign/base prefix and number */
  75. static const fmtflags internal = 0x0004;
  76. /** base 10 flag*/
  77. static const fmtflags dec = 0x0008;
  78. /** base 16 flag */
  79. static const fmtflags hex = 0x0010;
  80. /** base 8 flag */
  81. static const fmtflags oct = 0x0020;
  82. // static const fmtflags fixed = 0x0040;
  83. // static const fmtflags scientific = 0x0080;
  84. /** use strings true/false for bool */
  85. static const fmtflags boolalpha = 0x0100;
  86. /** use prefix 0X for hex and 0 for oct */
  87. static const fmtflags showbase = 0x0200;
  88. /** always show '.' for floating numbers */
  89. static const fmtflags showpoint = 0x0400;
  90. /** show + sign for nonnegative numbers */
  91. static const fmtflags showpos = 0x0800;
  92. /** skip initial white space */
  93. static const fmtflags skipws = 0x1000;
  94. // static const fmtflags unitbuf = 0x2000;
  95. /** use uppercase letters in number representations */
  96. static const fmtflags uppercase = 0x4000;
  97. /** mask for adjustfield */
  98. static const fmtflags adjustfield = left | right | internal;
  99. /** mask for basefield */
  100. static const fmtflags basefield = dec | hex | oct;
  101. // static const fmtflags floatfield = scientific | fixed;
  102. //----------------------------------------------------------------------------
  103. /** typedef for iostream open mode */
  104. typedef uint8_t openmode;
  105. // Openmode flags.
  106. /** seek to end before each write */
  107. static const openmode app = 0X4;
  108. /** open and seek to end immediately after opening */
  109. static const openmode ate = 0X8;
  110. /** perform input and output in binary mode (as opposed to text mode) */
  111. static const openmode binary = 0X10;
  112. /** open for input */
  113. static const openmode in = 0X20;
  114. /** open for output */
  115. static const openmode out = 0X40;
  116. /** truncate an existing stream when opening */
  117. static const openmode trunc = 0X80;
  118. //----------------------------------------------------------------------------
  119. ios_base() : m_fill(' '), m_fmtflags(dec | right | skipws)
  120. , m_precision(2), m_width(0) {}
  121. /** \return fill character */
  122. char fill() {
  123. return m_fill;
  124. }
  125. /** Set fill character
  126. * \param[in] c new fill character
  127. * \return old fill character
  128. */
  129. char fill(char c) {
  130. char r = m_fill;
  131. m_fill = c;
  132. return r;
  133. }
  134. /** \return format flags */
  135. fmtflags flags() const {
  136. return m_fmtflags;
  137. }
  138. /** set format flags
  139. * \param[in] fl new flag
  140. * \return old flags
  141. */
  142. fmtflags flags(fmtflags fl) {
  143. fmtflags tmp = m_fmtflags;
  144. m_fmtflags = fl;
  145. return tmp;
  146. }
  147. /** \return precision */
  148. int precision() const {
  149. return m_precision;
  150. }
  151. /** set precision
  152. * \param[in] n new precision
  153. * \return old precision
  154. */
  155. int precision(unsigned int n) {
  156. int r = m_precision;
  157. m_precision = n;
  158. return r;
  159. }
  160. /** set format flags
  161. * \param[in] fl new flags to be or'ed in
  162. * \return old flags
  163. */
  164. fmtflags setf(fmtflags fl) {
  165. fmtflags r = m_fmtflags;
  166. m_fmtflags |= fl;
  167. return r;
  168. }
  169. /** modify format flags
  170. * \param[in] mask flags to be removed
  171. * \param[in] fl flags to be set after mask bits have been cleared
  172. * \return old flags
  173. */
  174. fmtflags setf(fmtflags fl, fmtflags mask) {
  175. fmtflags r = m_fmtflags;
  176. m_fmtflags &= ~mask;
  177. m_fmtflags |= fl;
  178. return r;
  179. }
  180. /** clear format flags
  181. * \param[in] fl flags to be cleared
  182. * \return old flags
  183. */
  184. void unsetf(fmtflags fl) {
  185. m_fmtflags &= ~fl;
  186. }
  187. /** \return width */
  188. unsigned width() {
  189. return m_width;
  190. }
  191. /** set width
  192. * \param[in] n new width
  193. * \return old width
  194. */
  195. unsigned width(unsigned n) {
  196. unsigned r = m_width;
  197. m_width = n;
  198. return r;
  199. }
  200. protected:
  201. /** \return current number base */
  202. uint8_t flagsToBase() {
  203. uint8_t f = flags() & basefield;
  204. return f == oct ? 8 : f != hex ? 10 : 16;
  205. }
  206. private:
  207. char m_fill;
  208. fmtflags m_fmtflags;
  209. unsigned char m_precision;
  210. unsigned int m_width;
  211. };
  212. //------------------------------------------------------------------------------
  213. /** function for boolalpha manipulator
  214. * \param[in] str The stream
  215. * \return The stream
  216. */
  217. inline ios_base& boolalpha(ios_base& str) {
  218. str.setf(ios_base::boolalpha);
  219. return str;
  220. }
  221. /** function for dec manipulator
  222. * \param[in] str The stream
  223. * \return The stream
  224. */
  225. inline ios_base& dec(ios_base& str) {
  226. str.setf(ios_base::dec, ios_base::basefield);
  227. return str;
  228. }
  229. /** function for hex manipulator
  230. * \param[in] str The stream
  231. * \return The stream
  232. */
  233. inline ios_base& hex(ios_base& str) {
  234. str.setf(ios_base::hex, ios_base::basefield);
  235. return str;
  236. }
  237. /** function for internal manipulator
  238. * \param[in] str The stream
  239. * \return The stream
  240. */
  241. inline ios_base& internal(ios_base& str) {
  242. str.setf(ios_base::internal, ios_base::adjustfield);
  243. return str;
  244. }
  245. /** function for left manipulator
  246. * \param[in] str The stream
  247. * \return The stream
  248. */
  249. inline ios_base& left(ios_base& str) {
  250. str.setf(ios_base::left, ios_base::adjustfield);
  251. return str;
  252. }
  253. /** function for noboolalpha manipulator
  254. * \param[in] str The stream
  255. * \return The stream
  256. */
  257. inline ios_base& noboolalpha(ios_base& str) {
  258. str.unsetf(ios_base::boolalpha);
  259. return str;
  260. }
  261. /** function for noshowbase manipulator
  262. * \param[in] str The stream
  263. * \return The stream
  264. */
  265. inline ios_base& noshowbase(ios_base& str) {
  266. str.unsetf(ios_base::showbase);
  267. return str;
  268. }
  269. /** function for noshowpoint manipulator
  270. * \param[in] str The stream
  271. * \return The stream
  272. */
  273. inline ios_base& noshowpoint(ios_base& str) {
  274. str.unsetf(ios_base::showpoint);
  275. return str;
  276. }
  277. /** function for noshowpos manipulator
  278. * \param[in] str The stream
  279. * \return The stream
  280. */
  281. inline ios_base& noshowpos(ios_base& str) {
  282. str.unsetf(ios_base::showpos);
  283. return str;
  284. }
  285. /** function for noskipws manipulator
  286. * \param[in] str The stream
  287. * \return The stream
  288. */
  289. inline ios_base& noskipws(ios_base& str) {
  290. str.unsetf(ios_base::skipws);
  291. return str;
  292. }
  293. /** function for nouppercase manipulator
  294. * \param[in] str The stream
  295. * \return The stream
  296. */
  297. inline ios_base& nouppercase(ios_base& str) {
  298. str.unsetf(ios_base::uppercase);
  299. return str;
  300. }
  301. /** function for oct manipulator
  302. * \param[in] str The stream
  303. * \return The stream
  304. */
  305. inline ios_base& oct(ios_base& str) {
  306. str.setf(ios_base::oct, ios_base::basefield);
  307. return str;
  308. }
  309. /** function for right manipulator
  310. * \param[in] str The stream
  311. * \return The stream
  312. */
  313. inline ios_base& right(ios_base& str) {
  314. str.setf(ios_base::right, ios_base::adjustfield);
  315. return str;
  316. }
  317. /** function for showbase manipulator
  318. * \param[in] str The stream
  319. * \return The stream
  320. */
  321. inline ios_base& showbase(ios_base& str) {
  322. str.setf(ios_base::showbase);
  323. return str;
  324. }
  325. /** function for showpos manipulator
  326. * \param[in] str The stream
  327. * \return The stream
  328. */
  329. inline ios_base& showpos(ios_base& str) {
  330. str.setf(ios_base::showpos);
  331. return str;
  332. }
  333. /** function for showpoint manipulator
  334. * \param[in] str The stream
  335. * \return The stream
  336. */
  337. inline ios_base& showpoint(ios_base& str) {
  338. str.setf(ios_base::showpoint);
  339. return str;
  340. }
  341. /** function for skipws manipulator
  342. * \param[in] str The stream
  343. * \return The stream
  344. */
  345. inline ios_base& skipws(ios_base& str) {
  346. str.setf(ios_base::skipws);
  347. return str;
  348. }
  349. /** function for uppercase manipulator
  350. * \param[in] str The stream
  351. * \return The stream
  352. */
  353. inline ios_base& uppercase(ios_base& str) {
  354. str.setf(ios_base::uppercase);
  355. return str;
  356. }
  357. //==============================================================================
  358. /**
  359. * \class ios
  360. * \brief Error and state information for all streams
  361. */
  362. class ios : public ios_base {
  363. public:
  364. /** Create ios with no error flags set */
  365. ios() : m_iostate(0) {}
  366. /** \return null pointer if fail() is true. */
  367. operator const void*() const {
  368. return !fail() ? reinterpret_cast<const void*>(this) : 0;
  369. }
  370. /** \return true if fail() else false. */
  371. bool operator!() const {
  372. return fail();
  373. }
  374. /** \return The iostate flags for this file. */
  375. iostate rdstate() const {
  376. return m_iostate;
  377. }
  378. /** \return True if no iostate flags are set else false. */
  379. bool good() const {
  380. return m_iostate == goodbit;
  381. }
  382. /** \return true if end of file has been reached else false.
  383. *
  384. * Warning: An empty file returns false before the first read.
  385. *
  386. * Moral: eof() is only useful in combination with fail(), to find out
  387. * whether EOF was the cause for failure
  388. */
  389. bool eof() const {
  390. return m_iostate & eofbit;
  391. }
  392. /** \return true if any iostate bit other than eof are set else false. */
  393. bool fail() const {
  394. return m_iostate & (failbit | badbit);
  395. }
  396. /** \return true if bad bit is set else false. */
  397. bool bad() const {
  398. return m_iostate & badbit;
  399. }
  400. /** Clear iostate bits.
  401. *
  402. * \param[in] state The flags you want to set after clearing all flags.
  403. **/
  404. void clear(iostate state = goodbit) {
  405. m_iostate = state;
  406. }
  407. /** Set iostate bits.
  408. *
  409. * \param[in] state Bitts to set.
  410. **/
  411. void setstate(iostate state) {
  412. m_iostate |= state;
  413. }
  414. private:
  415. iostate m_iostate;
  416. };
  417. #endif // ios_h