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.

380 lines
10KB

  1. /* FatLib Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the FatLib 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 FatLib 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 {
  210. return m_gcount;
  211. }
  212. /**
  213. * Extract a character if one is available.
  214. *
  215. * \return The character or -1 if a failure occurs. A failure is indicated
  216. * by the stream state.
  217. */
  218. int get();
  219. /**
  220. * Extract a character if one is available.
  221. *
  222. * \param[out] ch location to receive the extracted character.
  223. *
  224. * \return always returns *this. A failure is indicated by the stream state.
  225. */
  226. istream& get(char& ch);
  227. /**
  228. * Extract characters.
  229. *
  230. * \param[out] str Location to receive extracted characters.
  231. * \param[in] n Size of str.
  232. * \param[in] delim Delimiter
  233. *
  234. * Characters are extracted until extraction fails, n is less than 1,
  235. * n-1 characters are extracted, or the next character equals
  236. * \a delim (delim is not extracted). If no characters are extracted
  237. * failbit is set. If end-of-file occurs the eofbit is set.
  238. *
  239. * \return always returns *this. A failure is indicated by the stream state.
  240. */
  241. istream& get(char *str, streamsize n, char delim = '\n');
  242. /**
  243. * Extract characters
  244. *
  245. * \param[out] str Location to receive extracted characters.
  246. * \param[in] n Size of str.
  247. * \param[in] delim Delimiter
  248. *
  249. * Characters are extracted until extraction fails,
  250. * the next character equals \a delim (delim is extracted), or n-1
  251. * characters are extracted.
  252. *
  253. * The failbit is set if no characters are extracted or n-1 characters
  254. * are extracted. If end-of-file occurs the eofbit is set.
  255. *
  256. * \return always returns *this. A failure is indicated by the stream state.
  257. */
  258. istream& getline(char *str, streamsize n, char delim = '\n');
  259. /**
  260. * Extract characters and discard them.
  261. *
  262. * \param[in] n maximum number of characters to ignore.
  263. * \param[in] delim Delimiter.
  264. *
  265. * Characters are extracted until extraction fails, \a n characters
  266. * are extracted, or the next input character equals \a delim
  267. * (the delimiter is extracted). If end-of-file occurs the eofbit is set.
  268. *
  269. * Failures are indicated by the state of the stream.
  270. *
  271. * \return *this
  272. *
  273. */
  274. istream& ignore(streamsize n = 1, int delim = -1);
  275. /**
  276. * Return the next available character without consuming it.
  277. *
  278. * \return The character if the stream state is good else -1;
  279. *
  280. */
  281. int peek();
  282. // istream& read(char *str, streamsize count);
  283. // streamsize readsome(char *str, streamsize count);
  284. /**
  285. * \return the stream position
  286. */
  287. pos_type tellg() {
  288. return tellpos();
  289. }
  290. /**
  291. * Set the stream position
  292. * \param[in] pos The absolute position in which to move the read pointer.
  293. * \return Is always *this. Failure is indicated by the state of *this.
  294. */
  295. istream& seekg(pos_type pos) {
  296. if (!seekpos(pos)) {
  297. setstate(failbit);
  298. }
  299. return *this;
  300. }
  301. /**
  302. * Set the stream position.
  303. *
  304. * \param[in] off An offset to move the read pointer relative to way.
  305. * \a off is a signed 32-bit int so the offset is limited to +- 2GB.
  306. * \param[in] way One of ios::beg, ios::cur, or ios::end.
  307. * \return Is always *this. Failure is indicated by the state of *this.
  308. */
  309. istream& seekg(off_type off, seekdir way) {
  310. if (!seekoff(off, way)) {
  311. setstate(failbit);
  312. }
  313. return *this;
  314. }
  315. void skipWhite();
  316. protected:
  317. /// @cond SHOW_PROTECTED
  318. /**
  319. * Internal - do not use
  320. * \return
  321. */
  322. virtual int16_t getch() = 0;
  323. /**
  324. * Internal - do not use
  325. * \param[out] pos
  326. * \return
  327. */
  328. int16_t getch(FatPos_t* pos) {
  329. getpos(pos);
  330. return getch();
  331. }
  332. /**
  333. * Internal - do not use
  334. * \param[out] pos
  335. */
  336. virtual void getpos(FatPos_t* pos) = 0;
  337. /**
  338. * Internal - do not use
  339. * \param[in] pos
  340. */
  341. virtual bool seekoff(off_type off, seekdir way) = 0;
  342. virtual bool seekpos(pos_type pos) = 0;
  343. virtual void setpos(FatPos_t* pos) = 0;
  344. virtual pos_type tellpos() = 0;
  345. /// @endcond
  346. private:
  347. void getBool(bool *b);
  348. void getChar(char* ch);
  349. bool getDouble(double* value);
  350. template <typename T> void getNumber(T* value);
  351. bool getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num);
  352. void getStr(char *str);
  353. int16_t readSkip();
  354. size_t m_gcount;
  355. };
  356. //------------------------------------------------------------------------------
  357. template <typename T>
  358. void istream::getNumber(T* value) {
  359. uint32_t tmp;
  360. if ((T)-1 < 0) {
  361. // number is signed, max positive value
  362. uint32_t const m = ((uint32_t)-1) >> (33 - sizeof(T) * 8);
  363. // max absolute value of negative number is m + 1.
  364. if (getNumber(m, m + 1, &tmp)) {
  365. *value = (T)tmp;
  366. }
  367. } else {
  368. // max unsigned value for T
  369. uint32_t const m = (T)-1;
  370. if (getNumber(m, m, &tmp)) {
  371. *value = (T)tmp;
  372. }
  373. }
  374. }
  375. #endif // istream_h