/* Copyright (C) 2004 Garrett A. Kajmowicz This file is part of the uClibc C++ 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 2, 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 this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #ifndef __STD_HEADER_ISTREAM #define __STD_HEADER_ISTREAM 1 #pragma GCC visibility push(default) namespace std{ typedef basic_istream istream; #ifdef __UCLIBCXX_HAS_WCHAR__ typedef basic_istream wistream; #endif template basic_istream& ws(basic_istream& is); template class _UCXXEXPORT basic_istream : virtual public basic_ios { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef basic_streambuf streambuf_type; typedef traits traits_type; explicit basic_istream(basic_streambuf* sb) : basic_ios(sb), count_last_ufmt_input(0) { basic_ios::init(sb); } virtual ~basic_istream() { } class sentry; basic_istream& operator>>(basic_istream& (*pf)(basic_istream&)); basic_istream& operator>>(basic_ios& (*pf)(basic_ios&)); basic_istream& operator>>(ios_base& (*pf)(ios_base&)); basic_istream& operator>>(bool& n); basic_istream& operator>>(short& n); basic_istream& operator>>(unsigned short& n); basic_istream& operator>>(int& n); basic_istream& operator>>(unsigned int& n); basic_istream& operator>>(long& n); basic_istream& operator>>(unsigned long& n); basic_istream& operator>>(void*& p); basic_istream& operator>>(basic_streambuf* sb); #ifdef __UCLIBCXX_HAS_FLOATS__ basic_istream& operator>>(float& f); basic_istream& operator>>(double& f); basic_istream& operator>>(long double& f); #endif _UCXXEXPORT streamsize gcount() const{ return count_last_ufmt_input; } _UCXXEXPORT int_type get(); //below _UCXXEXPORT basic_istream& get(char_type& c); //Below _UCXXEXPORT basic_istream& get(char_type* s, streamsize n){ return get(s, n, basic_ios::widen('\n')); } _UCXXEXPORT basic_istream& get(char_type* s, streamsize n, char_type delim){ sentry(*this, true); streamsize i = 0; int_type c; for(i=0;i::mstreambuf->sgetc(); basic_ios::mstreambuf->sbumpc(); if(c == traits::eof() ){ if(i==0){ basic_ios::setstate(ios_base::failbit); }else{ basic_ios::setstate(ios_base::eofbit); } break; } if(c == delim){ if(i==0){ basic_ios::setstate(ios_base::failbit); } basic_ios::mstreambuf->sputbackc(c); break; } s[i] = c; } s[i] = traits::eos(); count_last_ufmt_input = i; return *this; } _UCXXEXPORT basic_istream& get(basic_streambuf& sb){ return get(sb, basic_ios::widen('\n')); } _UCXXEXPORT basic_istream& get(basic_streambuf& sb, char_type delim){ sentry(*this, true); streamsize i = 0; int_type c; while(1){ //We will exit internally based upon error conditions c = basic_ios::mstreambuf->sgetc(); if(c == traits::eof()){ if(i==0){ basic_ios::setstate(ios_base::failbit); }else{ basic_ios::setstate(ios_base::eofbit); } count_last_ufmt_input = i; return *this; } if(c == delim){ if(i==0){ basic_ios::setstate(ios_base::failbit); } count_last_ufmt_input = i; return *this; } if(sb.sputc(c) != c){ //Error doing output count_last_ufmt_input = i; return *this; } ++i; basic_ios::mstreambuf->sbumpc(); } } _UCXXEXPORT basic_istream& getline(char_type* s, streamsize n){ return getline(s, n, basic_ios::widen('\n')); } _UCXXEXPORT basic_istream& getline(char_type* s, streamsize n, char_type delim){ sentry(*this, true); streamsize i = 0; int_type c; for(i=0;i::mstreambuf->sgetc(); if(c == traits::eof() ){ if( basic_ios::eof() ){ basic_ios::setstate(ios_base::failbit); }else{ basic_ios::setstate(ios_base::eofbit); } count_last_ufmt_input = i; s[i] = traits::eos(); return *this; } if(basic_ios::mstreambuf->sbumpc()==traits::eof() ){ basic_ios::setstate(ios_base::eofbit); } if(c == delim){ count_last_ufmt_input = i+1; s[i] = traits::eos(); return *this; } s[i] = c; } s[n-1] = traits::eos(); return *this; } _UCXXEXPORT basic_istream& ignore (streamsize n = 1, int_type delim = traits::eof()){ sentry(*this, true); streamsize i; int_type c; for(i=0;i::mstreambuf->sgetc(); if(c == traits::eof()){ basic_ios::setstate(ios_base::eofbit); return *this; } basic_ios::mstreambuf->sbumpc(); if(c == delim){ return *this; } } return *this; } _UCXXEXPORT int_type peek(){ if(basic_ios::good() == false){ return traits::eof(); }else{ int_type c = basic_ios::mstreambuf->sgetc(); if(c == traits::eof()){ basic_ios::setstate(ios_base::eofbit); } return basic_ios::mstreambuf->sgetc(); } } _UCXXEXPORT basic_istream& read (char_type* s, streamsize n){ sentry(*this, true); streamsize i; int_type c; for(i=0;i::mstreambuf->sgetc(); if(c == traits::eof()){ basic_ios::setstate(ios_base::failbit); basic_ios::setstate(ios_base::eofbit); count_last_ufmt_input = i; return *this; } basic_ios::mstreambuf->sbumpc(); s[i] = c; } count_last_ufmt_input = n; return *this; } _UCXXEXPORT streamsize readsome(char_type* s, streamsize n){ sentry(*this, true); if(!basic_ios::good()){ count_last_ufmt_input = 0; basic_ios::setstate(ios_base::failbit); return 0; } if( basic_ios::mstreambuf->in_avail() == -1){ count_last_ufmt_input=0; basic_ios::setstate(ios_base::eofbit); return 0; } if(n > basic_ios::mstreambuf->in_avail() ){ n = basic_ios::mstreambuf->in_avail(); } streamsize i; int_type c; for(i=0;i::mstreambuf->sgetc(); basic_ios::mstreambuf->sbumpc(); s[i] = c; } count_last_ufmt_input = n; return n; } _UCXXEXPORT basic_istream& putback(char_type c){ sentry(*this, true); if(!basic_ios::good()){ basic_ios::setstate(ios_base::failbit); return *this; } if(basic_ios::mstreambuf == 0){ basic_ios::setstate(ios_base::badbit); return *this; } if(basic_ios::mstreambuf->sputbackc(c) == traits::eof()){ basic_ios::setstate(ios_base::badbit); return *this; } return *this; } _UCXXEXPORT basic_istream& unget(){ sentry(*this, true); if(!basic_ios::good()){ basic_ios::setstate(ios_base::failbit); return *this; } if(basic_ios::mstreambuf == 0){ basic_ios::setstate(ios_base::failbit); return *this; } if(basic_ios::mstreambuf->sungetc() == traits::eof()){ basic_ios::setstate(ios_base::failbit); } return *this; } _UCXXEXPORT int sync(){ sentry(*this, true); if(basic_ios::mstreambuf == 0){ return -1; } if(basic_ios::mstreambuf->pubsync() == -1){ basic_ios::setstate(ios_base::badbit); return traits::eof(); } return 0; } _UCXXEXPORT pos_type tellg(){ if(basic_ios::fail() !=false){ return pos_type(-1); } return basic_ios::mstreambuf->pubseekoff(0, ios_base::cur, ios_base::in); } _UCXXEXPORT basic_istream& seekg(pos_type pos){ if(basic_ios::fail() !=true){ basic_ios::mstreambuf->pubseekpos(pos); } return *this; } _UCXXEXPORT basic_istream& seekg(off_type off, ios_base::seekdir dir){ if(basic_ios::fail() !=true){ basic_ios::mstreambuf->pubseekoff(off, dir); } return *this; } protected: _UCXXEXPORT basic_istream(const basic_istream &): basic_ios() { } _UCXXEXPORT basic_istream & operator=(const basic_istream &){ return *this; } streamsize count_last_ufmt_input; }; template > class _UCXXEXPORT basic_istream::sentry { bool ok; public: explicit _UCXXEXPORT sentry(basic_istream& os, bool noskipws = false){ if(os.good() !=0){ //Prepare for output } //Flush any tied buffer if(os.tie() != 0){ os.tie()->flush(); } if(!noskipws){ __skipws(os); } ok = true; } _UCXXEXPORT ~sentry() { } _UCXXEXPORT operator bool() { return ok; } }; //Template implementations of basic_istream functions which may be partially specialized //For code reduction template _UCXXEXPORT typename basic_istream::int_type basic_istream::get(){ sentry(*this, true); int_type retval = basic_ios::mstreambuf->sgetc(); if(retval == traits::eof()){ count_last_ufmt_input = 0; basic_ios::setstate(ios_base::eofbit); }else{ count_last_ufmt_input = 1; basic_ios::mstreambuf->sbumpc(); } return retval; } template _UCXXEXPORT basic_istream& basic_istream::get(char_type& c){ sentry(*this, true); int_type retval = basic_ios::mstreambuf->sgetc(); if(retval == traits::eof()){ count_last_ufmt_input = 0; basic_ios::setstate(ios_base::eofbit); basic_ios::setstate(ios_base::failbit); }else{ count_last_ufmt_input = 1; c = traits::to_char_type(retval); basic_ios::mstreambuf->sbumpc(); } return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(bool& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(short& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(unsigned short& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(int& n){ sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(unsigned int& n){ sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(long int& n){ sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(unsigned long int& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } #ifdef __UCLIBCXX_HAS_FLOATS__ template _UCXXEXPORT basic_istream& basic_istream::operator>>(float& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(double& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(long double& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } #endif template _UCXXEXPORT basic_istream& basic_istream::operator>>(void *& n) { sentry(*this); __istream_readin::readin(*this, n); return *this; } template _UCXXEXPORT basic_istream& operator>>(basic_istream& is, charT& c) { typename basic_istream::sentry s(is); is.get(c); return is; } template _UCXXEXPORT basic_istream& operator>>(basic_istream& is, unsigned char& c) { typename basic_istream::sentry s(is); char b; is.get(b); c = b; return is; } template _UCXXEXPORT basic_istream& operator>>(basic_istream& is, signed char& c) { typename basic_istream::sentry s(is); is.get(c); return is; } template _UCXXEXPORT basic_istream& operator>>(basic_istream& is, charT* c) { typename basic_istream::sentry s(is); int n = is.width(); if(n == 0){ n = __STRING_MAX_UNITS; } is.get(c, n); return is; } template _UCXXEXPORT basic_istream& operator>>(basic_istream& is, unsigned char* c) { typename basic_istream::sentry s(is); int n = is.width(); if(n == 0){ n = __STRING_MAX_UNITS; } is.get(c, n); return is; } template _UCXXEXPORT basic_istream& operator>>(basic_istream& is, signed char* c) { typename basic_istream::sentry s(is); int n = is.width(); if(n == 0){ n = __STRING_MAX_UNITS; } is.get(c, n); return is; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(basic_istream& (*pf)(basic_istream&)) { sentry(*this); pf(*this); return *this; } template _UCXXEXPORT basic_istream& basic_istream::operator>>(basic_ios& (*pf)(basic_ios&)) { sentry(*this); pf(*this); return *this; } template _UCXXEXPORT basic_istream& ws(basic_istream& is) { __skipws(is); return is; } #ifdef __UCLIBCXX_EXPAND_ISTREAM_CHAR__ #ifndef __UCLIBCXX_COMPILE_ISTREAM__ template <> _UCXXEXPORT istream & basic_istream >::get(char & c); template <> _UCXXEXPORT istream::int_type basic_istream >::get(); template <> _UCXXEXPORT istream & istream::operator>>(bool &n); template <> _UCXXEXPORT istream & istream::operator>>(short &n); template <> _UCXXEXPORT istream & istream::operator>>(unsigned short &n); template <> _UCXXEXPORT istream & istream::operator>>(int &n); template <> _UCXXEXPORT istream & istream::operator>>(unsigned int &n); template <> _UCXXEXPORT istream & istream::operator>>(long unsigned &n); template <> _UCXXEXPORT istream & istream::operator>>(long int &n); template <> _UCXXEXPORT istream & istream::operator>>(void *& p); #ifdef __UCLIBCXX_HAS_FLOATS__ template <> _UCXXEXPORT istream & istream::operator>>(float &f); template <> _UCXXEXPORT istream & istream::operator>>(double &f); template <> _UCXXEXPORT istream & istream::operator>>(long double &f); #endif template <> _UCXXEXPORT istream & operator>>(istream & is, char & c); template <> _UCXXEXPORT void __skipws(basic_istream >& is); #endif #endif } #pragma GCC visibility pop #endif