/* 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) extern "C++" { 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 CONFIG_HAVE_FLOAT 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 < n-1; ++i) { c = basic_ios::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 < n-1; ++i) { c = basic_ios::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 < n; ++i) { c = basic_ios::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 < n; ++i) { c = basic_ios::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 < n; ++i) { c = basic_ios::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 CONFIG_HAVE_FLOAT 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 CONFIG_HAVE_FLOAT 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 } // namespace } // extern "C++" #pragma GCC visibility pop #endif