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.

308 lines
8.3KB

  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 istream_h
  21. #define istream_h
  22. /**
  23. * \file
  24. * \brief \ref istream class
  25. */
  26. #include <ios.h>
  27. /**
  28. * \class istream
  29. * \brief Input Stream
  30. */
  31. class istream : public virtual ios {
  32. public:
  33. istream() {}
  34. /** call manipulator
  35. * \param[in] pf function to call
  36. * \return the stream
  37. */
  38. istream& operator>>(istream& (*pf)(istream& str)) {
  39. return pf(*this);
  40. }
  41. /** call manipulator
  42. * \param[in] pf function to call
  43. * \return the stream
  44. */
  45. istream& operator>>(ios_base& (*pf)(ios_base& str)) {
  46. pf(*this);
  47. return *this;
  48. }
  49. /** call manipulator
  50. * \param[in] pf function to call
  51. * \return the stream
  52. */
  53. istream& operator>>(ios& (*pf)(ios& str)) {
  54. pf(*this);
  55. return *this;
  56. }
  57. /**
  58. * Extract a character string
  59. * \param[out] str location to store the string.
  60. * \return Is always *this. Failure is indicated by the state of *this.
  61. */
  62. istream& operator>>(char *str) {
  63. getStr(str);
  64. return *this;
  65. }
  66. /**
  67. * Extract a character
  68. * \param[out] ch location to store the character.
  69. * \return Is always *this. Failure is indicated by the state of *this.
  70. */
  71. istream& operator>>(char& ch) {
  72. getChar(&ch);
  73. return *this;
  74. }
  75. /**
  76. * Extract a character string
  77. * \param[out] str location to store the string.
  78. * \return Is always *this. Failure is indicated by the state of *this.
  79. */
  80. istream& operator>>(signed char *str) {
  81. getStr(reinterpret_cast<char*>(str));
  82. return *this;
  83. }
  84. /**
  85. * Extract a character
  86. * \param[out] ch location to store the character.
  87. * \return Is always *this. Failure is indicated by the state of *this.
  88. */
  89. istream& operator>>(signed char& ch) {
  90. getChar(reinterpret_cast<char*>(&ch));
  91. return *this;
  92. }
  93. /**
  94. * Extract a character string
  95. * \param[out] str location to store the string.
  96. * \return Is always *this. Failure is indicated by the state of *this.
  97. */
  98. istream& operator>>(unsigned char *str) {
  99. getStr(reinterpret_cast<char*>(str));
  100. return *this;
  101. }
  102. /**
  103. * Extract a character
  104. * \param[out] ch location to store the character.
  105. * \return Is always *this. Failure is indicated by the state of *this.
  106. */
  107. istream& operator>>(unsigned char& ch) {
  108. getChar(reinterpret_cast<char*>(&ch));
  109. return *this;
  110. }
  111. /**
  112. * Extract a value of type bool.
  113. * \param[out] arg location to store the value.
  114. * \return Is always *this. Failure is indicated by the state of *this.
  115. */
  116. istream& operator>>(bool& arg) {
  117. getBool(&arg);
  118. return *this;
  119. }
  120. /**
  121. * Extract a value of type short.
  122. * \param[out] arg location to store the value.
  123. * \return Is always *this. Failure is indicated by the state of *this.
  124. */
  125. istream &operator>>(short& arg) { // NOLINT
  126. getNumber(&arg);
  127. return *this;
  128. }
  129. /**
  130. * Extract a value of type unsigned short.
  131. * \param[out] arg location to store the value.
  132. * \return Is always *this. Failure is indicated by the state of *this.
  133. */
  134. istream &operator>>(unsigned short& arg) { // NOLINT
  135. getNumber(&arg);
  136. return *this;
  137. }
  138. /**
  139. * Extract a value of type int.
  140. * \param[out] arg location to store the value.
  141. * \return Is always *this. Failure is indicated by the state of *this.
  142. */
  143. istream &operator>>(int& arg) {
  144. getNumber(&arg);
  145. return *this;
  146. }
  147. /**
  148. * Extract a value of type unsigned int.
  149. * \param[out] arg location to store the value.
  150. * \return Is always *this. Failure is indicated by the state of *this.
  151. */
  152. istream &operator>>(unsigned int& arg) {
  153. getNumber(&arg);
  154. return *this;
  155. }
  156. /**
  157. * Extract a value of type long.
  158. * \param[out] arg location to store the value.
  159. * \return Is always *this. Failure is indicated by the state of *this.
  160. */
  161. istream &operator>>(long& arg) { // NOLINT
  162. getNumber(&arg);
  163. return *this;
  164. }
  165. /**
  166. * Extract a value of type unsigned long.
  167. * \param[out] arg location to store the value.
  168. * \return Is always *this. Failure is indicated by the state of *this.
  169. */
  170. istream &operator>>(unsigned long& arg) { // NOLINT
  171. getNumber(&arg);
  172. return *this;
  173. }
  174. /**
  175. * Extract a value of type double.
  176. * \param[out] arg location to store the value.
  177. * \return Is always *this. Failure is indicated by the state of *this.
  178. */
  179. istream &operator>> (double& arg) {
  180. getDouble(&arg);
  181. return *this;
  182. }
  183. /**
  184. * Extract a value of type float.
  185. * \param[out] arg location to store the value.
  186. * \return Is always *this. Failure is indicated by the state of *this.
  187. */
  188. istream &operator>> (float& arg) {
  189. double v;
  190. getDouble(&v);
  191. arg = v;
  192. return *this;
  193. }
  194. /**
  195. * Extract a value of type void*.
  196. * \param[out] arg location to store the value.
  197. * \return Is always *this. Failure is indicated by the state of *this.
  198. */
  199. istream& operator>> (void*& arg) {
  200. uint32_t val;
  201. getNumber(&val);
  202. arg = reinterpret_cast<void*>(val);
  203. return *this;
  204. }
  205. /**
  206. * \return The number of characters extracted by the last unformatted
  207. * input function.
  208. */
  209. streamsize gcount() const {return m_gcount;}
  210. int get();
  211. istream& get(char& ch);
  212. istream& get(char *str, streamsize n, char delim = '\n');
  213. istream& getline(char *str, streamsize count, char delim = '\n');
  214. istream& ignore(streamsize n = 1, int delim= -1);
  215. int peek();
  216. // istream& read(char *str, streamsize count);
  217. // streamsize readsome(char *str, streamsize count);
  218. /**
  219. * \return the stream position
  220. */
  221. pos_type tellg() {return tellpos();}
  222. /**
  223. * Set the stream position
  224. * \param[in] pos The absolute position in which to move the read pointer.
  225. * \return Is always *this. Failure is indicated by the state of *this.
  226. */
  227. istream& seekg(pos_type pos) {
  228. if (!seekpos(pos)) setstate(failbit);
  229. return *this;
  230. }
  231. /**
  232. * Set the stream position.
  233. *
  234. * \param[in] off An offset to move the read pointer relative to way.
  235. * \a off is a signed 32-bit int so the offset is limited to +- 2GB.
  236. * \param[in] way One of ios::beg, ios::cur, or ios::end.
  237. * \return Is always *this. Failure is indicated by the state of *this.
  238. */
  239. istream& seekg(off_type off, seekdir way) {
  240. if (!seekoff(off, way)) setstate(failbit);
  241. return *this;
  242. }
  243. void skipWhite();
  244. protected:
  245. /// @cond SHOW_PROTECTED
  246. /**
  247. * Internal - do not use
  248. * \return
  249. */
  250. virtual int16_t getch() = 0;
  251. /**
  252. * Internal - do not use
  253. * \param[out] pos
  254. * \return
  255. */
  256. int16_t getch(FatPos_t* pos) {
  257. getpos(pos);
  258. return getch();
  259. }
  260. /**
  261. * Internal - do not use
  262. * \param[out] pos
  263. */
  264. virtual void getpos(FatPos_t* pos) = 0;
  265. /**
  266. * Internal - do not use
  267. * \param[in] pos
  268. */
  269. virtual bool seekoff(off_type off, seekdir way) = 0;
  270. virtual bool seekpos(pos_type pos) = 0;
  271. virtual void setpos(FatPos_t* pos) = 0;
  272. virtual pos_type tellpos() = 0;
  273. /// @endcond
  274. private:
  275. void getBool(bool *b);
  276. void getChar(char* ch);
  277. bool getDouble(double* value);
  278. template <typename T> void getNumber(T* value);
  279. bool getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num);
  280. void getStr(char *str);
  281. int16_t readSkip();
  282. size_t m_gcount;
  283. };
  284. //------------------------------------------------------------------------------
  285. template <typename T>
  286. void istream::getNumber(T* value) {
  287. uint32_t tmp;
  288. if ((T)-1 < 0) {
  289. // number is signed, max positive value
  290. uint32_t const m = ((uint32_t)-1) >> (33 - sizeof(T) * 8);
  291. // max absolute value of negative number is m + 1.
  292. if (getNumber(m, m + 1, &tmp)) {
  293. *value = (T)tmp;
  294. }
  295. } else {
  296. // max unsigned value for T
  297. uint32_t const m = (T)-1;
  298. if (getNumber(m, m, &tmp)) {
  299. *value = (T)tmp;
  300. }
  301. }
  302. }
  303. #endif // istream_h