You cannot 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
10 KiB
C
380 lines
10 KiB
C
7 years ago
|
/* FatLib Library
|
||
|
* Copyright (C) 2013 by William Greiman
|
||
|
*
|
||
|
* This file is part of the FatLib 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 FatLib 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 m_gcount;
|
||
|
}
|
||
|
/**
|
||
|
* Extract a character if one is available.
|
||
|
*
|
||
|
* \return The character or -1 if a failure occurs. A failure is indicated
|
||
|
* by the stream state.
|
||
|
*/
|
||
|
int get();
|
||
|
/**
|
||
|
* Extract a character if one is available.
|
||
|
*
|
||
|
* \param[out] ch location to receive the extracted character.
|
||
|
*
|
||
|
* \return always returns *this. A failure is indicated by the stream state.
|
||
|
*/
|
||
|
istream& get(char& ch);
|
||
|
/**
|
||
|
* Extract characters.
|
||
|
*
|
||
|
* \param[out] str Location to receive extracted characters.
|
||
|
* \param[in] n Size of str.
|
||
|
* \param[in] delim Delimiter
|
||
|
*
|
||
|
* Characters are extracted until extraction fails, n is less than 1,
|
||
|
* n-1 characters are extracted, or the next character equals
|
||
|
* \a delim (delim is not extracted). If no characters are extracted
|
||
|
* failbit is set. If end-of-file occurs the eofbit is set.
|
||
|
*
|
||
|
* \return always returns *this. A failure is indicated by the stream state.
|
||
|
*/
|
||
|
istream& get(char *str, streamsize n, char delim = '\n');
|
||
|
/**
|
||
|
* Extract characters
|
||
|
*
|
||
|
* \param[out] str Location to receive extracted characters.
|
||
|
* \param[in] n Size of str.
|
||
|
* \param[in] delim Delimiter
|
||
|
*
|
||
|
* Characters are extracted until extraction fails,
|
||
|
* the next character equals \a delim (delim is extracted), or n-1
|
||
|
* characters are extracted.
|
||
|
*
|
||
|
* The failbit is set if no characters are extracted or n-1 characters
|
||
|
* are extracted. If end-of-file occurs the eofbit is set.
|
||
|
*
|
||
|
* \return always returns *this. A failure is indicated by the stream state.
|
||
|
*/
|
||
|
istream& getline(char *str, streamsize n, char delim = '\n');
|
||
|
/**
|
||
|
* Extract characters and discard them.
|
||
|
*
|
||
|
* \param[in] n maximum number of characters to ignore.
|
||
|
* \param[in] delim Delimiter.
|
||
|
*
|
||
|
* Characters are extracted until extraction fails, \a n characters
|
||
|
* are extracted, or the next input character equals \a delim
|
||
|
* (the delimiter is extracted). If end-of-file occurs the eofbit is set.
|
||
|
*
|
||
|
* Failures are indicated by the state of the stream.
|
||
|
*
|
||
|
* \return *this
|
||
|
*
|
||
|
*/
|
||
|
istream& ignore(streamsize n = 1, int delim = -1);
|
||
|
/**
|
||
|
* Return the next available character without consuming it.
|
||
|
*
|
||
|
* \return The character if the stream state is good else -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 <typename T> 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 <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
|