/* Copyright (C) 2004 Garrett A. Kajmowicz This file is part of the uClibc++ Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifndef STD_HEADER_OSTREAM #define STD_HEADER_OSTREAM 1 #include #include #include #include namespace std { template class basic_ostream; typedef basic_ostream ostream; #ifdef __UCLIBCXX_HAS_WCHAR__ typedef basic_ostream wostream; #endif template basic_ostream& endl(basic_ostream& os); template basic_ostream& ends(basic_ostream& os); template basic_ostream& flush(basic_ostream& os); template class _UCXXEXPORT basic_ostream : 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 traits traits_type; _UCXXEXPORT basic_ostream(basic_streambuf* sb) : basic_ios(sb) { basic_ios::init(sb); } virtual _UCXXEXPORT ~basic_ostream(); class sentry; _UCXXEXPORT basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&)){ return pf(*this); } _UCXXEXPORT basic_ostream& operator<<(basic_ios& (*pf)(basic_ios&)){ pf(*this); return *this; } _UCXXEXPORT basic_ostream& operator<<(ios_base& (*pf)(ios_base&)){ pf(*this); return *this; } basic_ostream& operator<<(bool n); basic_ostream& operator<<(short n); basic_ostream& operator<<(unsigned short n); basic_ostream& operator<<(int n); basic_ostream& operator<<(unsigned int n); basic_ostream& operator<<(long n); basic_ostream& operator<<(unsigned long n); basic_ostream& operator<<(float f); basic_ostream& operator<<(double f); basic_ostream& operator<<(long double f); basic_ostream& operator<<(void* p); basic_ostream& operator<<(basic_streambuf* sb); _UCXXEXPORT basic_ostream& put(char_type c){ if(basic_ostream::traits_type::eq_int_type( basic_ios::mstreambuf->sputc(c), basic_ostream::traits_type::eof())) { basic_ios::setstate(ios_base::eofbit); } return *this; } _UCXXEXPORT basic_ostream& write(const char_type* s, streamsize n){ if(basic_ostream::traits_type::eq_int_type( basic_ios::mstreambuf->sputn(s, n), basic_ostream::traits_type::eof()) ){ basic_ios::setstate(ios_base::eofbit); } return *this; } _UCXXEXPORT basic_ostream& flush(){ if(basic_ios::mstreambuf->pubsync() == -1){ basic_ios::setstate(ios_base::badbit); } return *this; } _UCXXEXPORT pos_type tellp(){ if(basic_ios::fail() != false){ return pos_type(-1); } return basic_ios::rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); } _UCXXEXPORT basic_ostream& seekp(pos_type pos){ if( basic_ios::fail() != true ){ basic_ios::rdbuf()->pubseekpos(pos); } return *this; } _UCXXEXPORT basic_ostream& seekp(off_type off, ios_base::seekdir dir){ if( basic_ios::fail() != true){ basic_ios::rdbuf()->pubseekoff(off, dir); } return *this; } protected: basic_ostream(const basic_ostream &){ } basic_ostream & operator=(const basic_ostream &){ return *this; } }; //Implementations of template functions. To allow for partial specialization template _UCXXEXPORT basic_ostream::~basic_ostream(){ } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(bool n){ sentry s(*this); if( basic_ios::flags() & ios_base::boolalpha){ if(n){ write("true", 4); }else{ write("false", 5); } }else{ if(n){ write("1", 1); }else{ write("0", 1); } } if(basic_ios::flags() & ios_base::unitbuf){ flush(); } return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(unsigned short n){ sentry s(*this); __ostream_printout::printout(*this, n); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(short n){ sentry s(*this); __ostream_printout::printout(*this, n); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(int n){ sentry s(*this); __ostream_printout::printout(*this, n); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(unsigned int n){ sentry s(*this); __ostream_printout::printout(*this, n); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(long n){ sentry s(*this); __ostream_printout::printout(*this, n); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(unsigned long n) { sentry s(*this); __ostream_printout::printout(*this, n); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(float f){ sentry s(*this); __ostream_printout::printout(*this, f); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(double f){ sentry s(*this); __ostream_printout::printout(*this, f); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(long double f){ sentry s(*this); __ostream_printout::printout(*this, f); return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(void* p){ sentry s(*this); char buffer[20]; write(buffer, snprintf(buffer, 20, "%p", p) ); if(basic_ios::flags() & ios_base::unitbuf){ flush(); } return *this; } template _UCXXEXPORT basic_ostream& basic_ostream::operator<<(basic_streambuf* sb) { sentry s(*this); if(sb == 0){ basic_ios::setstate(ios_base::badbit); return *this; } typename traits::int_type c; while(basic_ios::good() && (c = sb->sbumpc()) != traits::eof() ){ put(c); } if(basic_ios::flags() & ios_base::unitbuf){ flush(); } return *this; } /*Template Specializations*/ #ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__ #ifndef __UCLIBCXX_COMPILE_OSTREAM__ #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT ostream::~basic_ostream(); #endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT ostream & ostream::flush(); template <> _UCXXEXPORT ostream & ostream::operator<<(bool n); template <> _UCXXEXPORT ostream & ostream::operator<<(short int n); template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned short int n); template <> _UCXXEXPORT ostream & ostream::operator<<(int n); template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned int n); template <> _UCXXEXPORT ostream & ostream::operator<<(long n); template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned long n); template <> _UCXXEXPORT ostream & ostream::operator<<(float f); template <> _UCXXEXPORT ostream & ostream::operator<<(double f); template <> _UCXXEXPORT ostream & ostream::operator<<(long double f); template <> _UCXXEXPORT ostream & ostream::operator<<(void* p); template <> _UCXXEXPORT ostream & ostream::operator<<(basic_streambuf >* sb); #endif #endif template > class _UCXXEXPORT basic_ostream::sentry { bool ok; public: explicit _UCXXEXPORT sentry(basic_ostream& os): ok(true){ if(os.good() !=0){ //Prepare for output } //Flush any tied buffer if(os.tie() !=0 ){ os.tie()->flush(); } } _UCXXEXPORT ~sentry() { } _UCXXEXPORT operator bool() { return ok; } }; #ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__ #ifndef __UCLIBCXX_COMPILE_OSTREAM__ #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT ostream::sentry::sentry(ostream & os); template <> _UCXXEXPORT ostream::sentry::~sentry(); #endif //__UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ #endif #endif //Non - class functions template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, charT c) { typename basic_ostream::sentry s(out); out.put(c); return out; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, char c) { typename basic_ostream::sentry s(out); out.put(c); return out; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, char c) { typename basic_ostream::sentry s(out); out.put(c); return out; } // signed and unsigned template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, signed char c) { typename basic_ostream::sentry s(out); out.put(c); return out; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, unsigned char c) { typename basic_ostream::sentry s(out); out.put(c); return out; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, const charT* c) { typename basic_ostream::sentry s(out); out.write(c, traits::length(c) ); return out; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, const char* c) { typename basic_ostream::sentry s(out); out.write(c, char_traits::length(c) ); return out; } // partial specializations template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, const char* c) { typename basic_ostream::sentry s(out); out.write(c, traits::length(c)); return out; } #ifdef __UCLIBCXX_HAS_WCHAR__ template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, const char* c) { typename basic_ostream::sentry s(out); size_t numChars = char_traits::length(c); wchar_t * temp = new wchar_t[numChars]; for(size_t i=0; i < numChars; ++i){ temp[i] = out.widen(c[i]); } out.write(temp, numChars); return out; } #endif // signed and unsigned template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, const signed char* c) { typename basic_ostream::sentry s(out); out.write(reinterpret_cast(c), traits::length( reinterpret_cast(c))); return out; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& out, const unsigned char* c) { typename basic_ostream::sentry s(out); out.write(reinterpret_cast(c), traits::length( reinterpret_cast(c))); return out; } template _UCXXEXPORT basic_ostream& endl(basic_ostream& os) { typename basic_ostream::sentry s(os); os.put('\n'); os.flush(); return os; } template _UCXXEXPORT basic_ostream& ends(basic_ostream& os) { typename basic_ostream::sentry s(os); os.put(traits::eos()); return os; } template _UCXXEXPORT basic_ostream& flush(basic_ostream& os){ typename basic_ostream::sentry s(os); os.flush(); return os; } #ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__ #ifndef __UCLIBCXX_COMPILE_OSTREAM__ template <> _UCXXEXPORT ostream & endl(ostream & os); template <> _UCXXEXPORT ostream & flush(ostream & os); template <> _UCXXEXPORT ostream & operator<<(ostream & out, char c); template <> _UCXXEXPORT ostream & operator<<(ostream & out, const char* c); template <> _UCXXEXPORT ostream & operator<<(ostream & out, unsigned char c); template <> _UCXXEXPORT ostream & operator<<(ostream & out, unsigned const char* c); #endif #endif #ifndef __STRICT_ANSI__ //Support for output of long long data types template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& os, signed long long int i) { typename basic_ostream::sentry s(os); __ostream_printout::printout(os, i); return os; } template _UCXXEXPORT basic_ostream& operator<<(basic_ostream& os, unsigned long long int i) { typename basic_ostream::sentry s(os); __ostream_printout::printout(os, i); return os; } #endif //__STRICT_ANSI__ } #endif