/* Arduino SdFat Library * Copyright (C) 2012 by William Greiman * * This file is part of the Arduino SdFat Library * * This Library is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the Arduino SdFat Library. If not, see * . */ #ifndef istream_h #define istream_h /** * \file * \brief \ref istream class */ #include /** * \class istream * \brief Input Stream */ class istream : public virtual ios { public: istream() {} /** call manipulator * \param[in] pf function to call * \return the stream */ istream& operator>>(istream& (*pf)(istream& str)) { return pf(*this); } /** call manipulator * \param[in] pf function to call * \return the stream */ istream& operator>>(ios_base& (*pf)(ios_base& str)) { pf(*this); return *this; } /** call manipulator * \param[in] pf function to call * \return the stream */ istream& operator>>(ios& (*pf)(ios& str)) { pf(*this); return *this; } /** * Extract a character string * \param[out] str location to store the string. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(char *str) { getStr(str); return *this; } /** * Extract a character * \param[out] ch location to store the character. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(char& ch) { getChar(&ch); return *this; } /** * Extract a character string * \param[out] str location to store the string. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(signed char *str) { getStr(reinterpret_cast(str)); return *this; } /** * Extract a character * \param[out] ch location to store the character. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(signed char& ch) { getChar(reinterpret_cast(&ch)); return *this; } /** * Extract a character string * \param[out] str location to store the string. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(unsigned char *str) { getStr(reinterpret_cast(str)); return *this; } /** * Extract a character * \param[out] ch location to store the character. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(unsigned char& ch) { getChar(reinterpret_cast(&ch)); return *this; } /** * Extract a value of type bool. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>>(bool& arg) { getBool(&arg); return *this; } /** * Extract a value of type short. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>>(short& arg) { // NOLINT getNumber(&arg); return *this; } /** * Extract a value of type unsigned short. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>>(unsigned short& arg) { // NOLINT getNumber(&arg); return *this; } /** * Extract a value of type int. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>>(int& arg) { getNumber(&arg); return *this; } /** * Extract a value of type unsigned int. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>>(unsigned int& arg) { getNumber(&arg); return *this; } /** * Extract a value of type long. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>>(long& arg) { // NOLINT getNumber(&arg); return *this; } /** * Extract a value of type unsigned long. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>>(unsigned long& arg) { // NOLINT getNumber(&arg); return *this; } /** * Extract a value of type double. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>> (double& arg) { getDouble(&arg); return *this; } /** * Extract a value of type float. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream &operator>> (float& arg) { double v; getDouble(&v); arg = v; return *this; } /** * Extract a value of type void*. * \param[out] arg location to store the value. * \return Is always *this. Failure is indicated by the state of *this. */ istream& operator>> (void*& arg) { uint32_t val; getNumber(&val); arg = reinterpret_cast(val); return *this; } /** * \return The number of characters extracted by the last unformatted * input function. */ streamsize gcount() const {return m_gcount;} int get(); istream& get(char& ch); istream& get(char *str, streamsize n, char delim = '\n'); istream& getline(char *str, streamsize count, char delim = '\n'); istream& ignore(streamsize n = 1, int delim= -1); int peek(); // istream& read(char *str, streamsize count); // streamsize readsome(char *str, streamsize count); /** * \return the stream position */ pos_type tellg() {return tellpos();} /** * Set the stream position * \param[in] pos The absolute position in which to move the read pointer. * \return Is always *this. Failure is indicated by the state of *this. */ istream& seekg(pos_type pos) { if (!seekpos(pos)) setstate(failbit); return *this; } /** * Set the stream position. * * \param[in] off An offset to move the read pointer relative to way. * \a off is a signed 32-bit int so the offset is limited to +- 2GB. * \param[in] way One of ios::beg, ios::cur, or ios::end. * \return Is always *this. Failure is indicated by the state of *this. */ istream& seekg(off_type off, seekdir way) { if (!seekoff(off, way)) setstate(failbit); return *this; } void skipWhite(); protected: /// @cond SHOW_PROTECTED /** * Internal - do not use * \return */ virtual int16_t getch() = 0; /** * Internal - do not use * \param[out] pos * \return */ int16_t getch(FatPos_t* pos) { getpos(pos); return getch(); } /** * Internal - do not use * \param[out] pos */ virtual void getpos(FatPos_t* pos) = 0; /** * Internal - do not use * \param[in] pos */ virtual bool seekoff(off_type off, seekdir way) = 0; virtual bool seekpos(pos_type pos) = 0; virtual void setpos(FatPos_t* pos) = 0; virtual pos_type tellpos() = 0; /// @endcond private: void getBool(bool *b); void getChar(char* ch); bool getDouble(double* value); template void getNumber(T* value); bool getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num); void getStr(char *str); int16_t readSkip(); size_t m_gcount; }; //------------------------------------------------------------------------------ template void istream::getNumber(T* value) { uint32_t tmp; if ((T)-1 < 0) { // number is signed, max positive value uint32_t const m = ((uint32_t)-1) >> (33 - sizeof(T) * 8); // max absolute value of negative number is m + 1. if (getNumber(m, m + 1, &tmp)) { *value = (T)tmp; } } else { // max unsigned value for T uint32_t const m = (T)-1; if (getNumber(m, m, &tmp)) { *value = (T)tmp; } } } #endif // istream_h