307 lines
8.3 KiB
C
307 lines
8.3 KiB
C
|
/* 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
|
||
|
* <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
#ifndef istream_h
|
||
|
#define istream_h
|
||
|
/**
|
||
|
* \file
|
||
|
* \brief \ref istream class
|
||
|
*/
|
||
|
#include <ios.h>
|
||
|
|
||
|
/**
|
||
|
* \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<char*>(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<char*>(&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<char*>(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<char*>(&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<void*>(val);
|
||
|
return *this;
|
||
|
}
|
||
|
/**
|
||
|
* \return The number of characters extracted by the last unformatted
|
||
|
* input function.
|
||
|
*/
|
||
|
streamsize gcount() const {return 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:
|
||
|
size_t gcount_;
|
||
|
void getBool(bool *b);
|
||
|
void getChar(char* ch);
|
||
|
bool getDouble(double* value);
|
||
|
template <typename T> void getNumber(T* value);
|
||
|
bool getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num);
|
||
|
void getStr(char *str);
|
||
|
int16_t readSkip();
|
||
|
};
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <typename T>
|
||
|
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
|