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.

395 lines
11KB

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