X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Fstl%2Fstl%2F_ostream.c;fp=include%2Fc%2B%2B%2Fstl%2Fstl%2F_ostream.c;h=6baf4ab8929bb6627b642e82fdf5ccc6c467f3a7;hp=0000000000000000000000000000000000000000;hb=173d8903eb9d51a4ea7d7fa3e52dc86c9bb6d4f1;hpb=b024710fe2b60cd4a42a8993b61333d6cdb56ca3 diff --git a/include/c++/stl/stl/_ostream.c b/include/c++/stl/stl/_ostream.c new file mode 100644 index 0000000..6baf4ab --- /dev/null +++ b/include/c++/stl/stl/_ostream.c @@ -0,0 +1,446 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Copyright (c) 1999 + * Boris Fomitchev + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ +#ifndef _STLP_OSTREAM_C +#define _STLP_OSTREAM_C + +#ifndef _STLP_INTERNAL_OSTREAM_H +# include +#endif + +#if !defined (_STLP_INTERNAL_NUM_PUT_H) +# include // For basic_streambuf and iterators +#endif + +_STLP_BEGIN_NAMESPACE + +//---------------------------------------------------------------------- +// Definitions of non-inline member functions. + +// Constructor, destructor + +template +basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<_CharT, _Traits>* __buf) + : basic_ios<_CharT, _Traits>() { + this->init(__buf); +} + +template +basic_ostream<_CharT, _Traits>::~basic_ostream() +{} + +// Output directly from a streambuf. +template +basic_ostream<_CharT, _Traits>& +basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<_CharT, _Traits>* __from) { + sentry __sentry(*this); + if (__sentry) { + if (__from) { + bool __any_inserted = __from->gptr() != __from->egptr() + ? this->_M_copy_buffered(__from, this->rdbuf()) + : this->_M_copy_unbuffered(__from, this->rdbuf()); + if (!__any_inserted) + this->setstate(ios_base::failbit); + } + else + this->setstate(ios_base::badbit); + } + + return *this; +} + +// Helper functions for the streambuf version of operator<<. The +// exception-handling code is complicated because exceptions thrown +// while extracting characters are treated differently than exceptions +// thrown while inserting characters. + +template +bool basic_ostream<_CharT, _Traits> + ::_M_copy_buffered(basic_streambuf<_CharT, _Traits>* __from, + basic_streambuf<_CharT, _Traits>* __to) { + bool __any_inserted = false; + + while (__from->egptr() != __from->gptr()) { + const ptrdiff_t __avail = __from->egptr() - __from->gptr(); + + streamsize __nwritten; + _STLP_TRY { + __nwritten = __to->sputn(__from->gptr(), __avail); + __from->gbump((int)__nwritten); + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + return __any_inserted; + } + + if (__nwritten == __avail) { + _STLP_TRY { + if (this->_S_eof(__from->sgetc())) + return true; + else + __any_inserted = true; + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::failbit); + return false; + } + } + else if (__nwritten != 0) + return true; + else + return __any_inserted; + } + + // No characters are in the buffer, but we aren't at EOF. Switch to + // unbuffered mode. + return __any_inserted || this->_M_copy_unbuffered(__from, __to); +} + +/* + * Helper struct (guard) to put back a character in a streambuf + * whenever an exception or an eof occur. + */ +template +struct _SPutBackC { + typedef basic_streambuf<_CharT, _Traits> _StreamBuf; + typedef typename _StreamBuf::int_type int_type; + _SPutBackC(_StreamBuf *pfrom) + : __pfrom(pfrom), __c(0), __do_guard(false) {} + ~_SPutBackC() { + if (__do_guard) { + __pfrom->sputbackc(_Traits::to_char_type(__c)); + } + } + + void guard(int_type c) { + __c = c; + __do_guard = true; + } + void release() { + __do_guard = false; + } + +private: + _StreamBuf *__pfrom; + int_type __c; + bool __do_guard; +}; + +template +bool basic_ostream<_CharT, _Traits> + ::_M_copy_unbuffered(basic_streambuf<_CharT, _Traits>* __from, + basic_streambuf<_CharT, _Traits>* __to) { + typedef _SPutBackC<_CharT, _Traits> _SPutBackCGuard; + bool __any_inserted = false; + int_type __c; + + _STLP_TRY { + _SPutBackCGuard __cguard(__from); + for (;;) { + _STLP_TRY { + __c = __from->sbumpc(); + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::failbit); + return __any_inserted; + } + + if ( this->_S_eof(__c) ) + return __any_inserted; + + __cguard.guard(__c); + if ( this->_S_eof( __to->sputc(_Traits::to_char_type(__c)) ) ) { + return __any_inserted; + } + + __cguard.release(); + __any_inserted = true; + } + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + return __any_inserted; + } +} + +_STLP_MOVE_TO_PRIV_NAMESPACE + +// Helper function for numeric output. +template +basic_ostream<_CharT, _Traits>& _STLP_CALL +__put_num(basic_ostream<_CharT, _Traits>& __os, _Number __x) { + typedef typename basic_ostream<_CharT, _Traits>::sentry _Sentry; + _Sentry __sentry(__os); + bool __failed = true; + + if (__sentry) { + _STLP_TRY { + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > _NumPut; + __failed = (use_facet<_NumPut>(__os.getloc())).put(ostreambuf_iterator<_CharT, _Traits>(__os.rdbuf()), + __os, __os.fill(), + __x).failed(); + } + _STLP_CATCH_ALL { + __os._M_handle_exception(ios_base::badbit); + } + } + if (__failed) + __os.setstate(ios_base::badbit); + return __os; +} + +_STLP_MOVE_TO_STD_NAMESPACE + +/* + * In the following operators we try to limit code bloat by limiting the + * number of __put_num instanciations. + */ +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(short __x) { + _STLP_STATIC_ASSERT( sizeof(short) <= sizeof(long) ) + long __tmp = ((this->flags() & _Basic_ios::basefield) != ios_base::dec) ? + __STATIC_CAST(long, __STATIC_CAST(unsigned short, __x)): __x; + return _STLP_PRIV __put_num(*this, __tmp); +} + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned short __x) { + _STLP_STATIC_ASSERT( sizeof(unsigned short) <= sizeof(unsigned long) ) + return _STLP_PRIV __put_num(*this, __STATIC_CAST(unsigned long,__x)); +} + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(int __x) { + _STLP_STATIC_ASSERT( sizeof(int) <= sizeof(long) ) + long __tmp = ((this->flags() & _Basic_ios::basefield) != ios_base::dec) ? + __STATIC_CAST(long, __STATIC_CAST(unsigned int, __x)): __x; + return _STLP_PRIV __put_num(*this, __tmp); +} + +template +#if defined (_WIN64) || !defined (_STLP_MSVC) || (_STLP_MSVC < 1300) +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned int __x) { + _STLP_STATIC_ASSERT( sizeof(unsigned int) <= sizeof(unsigned long) ) +#else +/* We define this operator with size_t rather than unsigned int to avoid + * 64 bits warning. + */ +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(size_t __x) { + _STLP_STATIC_ASSERT( sizeof(size_t) <= sizeof(unsigned long) ) +#endif + return _STLP_PRIV __put_num(*this, __STATIC_CAST(unsigned long,__x)); +} + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __x) +{ return _STLP_PRIV __put_num(*this, __x); } + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __x) +{ return _STLP_PRIV __put_num(*this, __x); } + +#ifdef _STLP_LONG_LONG +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (_STLP_LONG_LONG __x) +{ return _STLP_PRIV __put_num(*this, __x); } + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (unsigned _STLP_LONG_LONG __x) +{ return _STLP_PRIV __put_num(*this, __x); } +#endif + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __x) +{ return _STLP_PRIV __put_num(*this, __STATIC_CAST(double,__x)); } + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __x) +{ return _STLP_PRIV __put_num(*this, __x); } + +#ifndef _STLP_NO_LONG_DOUBLE +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __x) +{ return _STLP_PRIV __put_num(*this, __x); } +#endif + +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __x) +{ return _STLP_PRIV __put_num(*this, __x); } + +#ifndef _STLP_NO_BOOL +template +basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __x) +{ return _STLP_PRIV __put_num(*this, __x); } +#endif + +template +void basic_ostream<_CharT, _Traits>::_M_put_char(_CharT __c) { + sentry __sentry(*this); + if (__sentry) { + bool __failed = true; + _STLP_TRY { + streamsize __npad = this->width() > 0 ? this->width() - 1 : 0; + // if (__npad <= 1) + if (__npad == 0) + __failed = this->_S_eof(this->rdbuf()->sputc(__c)); + else if ((this->flags() & ios_base::adjustfield) == ios_base::left) { + __failed = this->_S_eof(this->rdbuf()->sputc(__c)); + __failed = __failed || + this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; + } + else { + __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; + __failed = __failed || this->_S_eof(this->rdbuf()->sputc(__c)); + } + + this->width(0); + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + } + + if (__failed) + this->setstate(ios_base::badbit); + } +} + +template +void basic_ostream<_CharT, _Traits>::_M_put_nowiden(const _CharT* __s) { + sentry __sentry(*this); + if (__sentry) { + bool __failed = true; + streamsize __n = _Traits::length(__s); + streamsize __npad = this->width() > __n ? this->width() - __n : 0; + + _STLP_TRY { + if (__npad == 0) + __failed = this->rdbuf()->sputn(__s, __n) != __n; + else if ((this->flags() & ios_base::adjustfield) == ios_base::left) { + __failed = this->rdbuf()->sputn(__s, __n) != __n; + __failed = __failed || + this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; + } + else { + __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; + __failed = __failed || this->rdbuf()->sputn(__s, __n) != __n; + } + + this->width(0); + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + } + + if (__failed) + this->setstate(ios_base::failbit); + } +} + +template +void basic_ostream<_CharT, _Traits>::_M_put_widen(const char* __s) { + sentry __sentry(*this); + if (__sentry) { + bool __failed = true; + streamsize __n = char_traits::length(__s); + streamsize __npad = this->width() > __n ? this->width() - __n : 0; + + _STLP_TRY { + if (__npad == 0) + __failed = !this->_M_put_widen_aux(__s, __n); + else if ((this->flags() & ios_base::adjustfield) == ios_base::left) { + __failed = !this->_M_put_widen_aux(__s, __n); + __failed = __failed || + this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; + } + else { + __failed = this->rdbuf()->_M_sputnc(this->fill(), __npad) != __npad; + __failed = __failed || !this->_M_put_widen_aux(__s, __n); + } + + this->width(0); + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + } + + if (__failed) + this->setstate(ios_base::failbit); + } +} + +template +bool basic_ostream<_CharT, _Traits>::_M_put_widen_aux(const char* __s, + streamsize __n) { + basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); + + for ( ; __n > 0 ; --__n) + if (this->_S_eof(__buf->sputc(this->widen(*__s++)))) + return false; + return true; +} + +// Unformatted output of a single character. +template +basic_ostream<_CharT, _Traits>& +basic_ostream<_CharT, _Traits>::put(char_type __c) { + sentry __sentry(*this); + bool __failed = true; + + if (__sentry) { + _STLP_TRY { + __failed = this->_S_eof(this->rdbuf()->sputc(__c)); + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + } + } + + if (__failed) + this->setstate(ios_base::badbit); + + return *this; +} + +// Unformatted output of a single character. +template +basic_ostream<_CharT, _Traits>& +basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n) { + sentry __sentry(*this); + bool __failed = true; + + if (__sentry) { + _STLP_TRY { + __failed = this->rdbuf()->sputn(__s, __n) != __n; + } + _STLP_CATCH_ALL { + this->_M_handle_exception(ios_base::badbit); + } + } + + if (__failed) + this->setstate(ios_base::badbit); + + return *this; +} + +_STLP_END_NAMESPACE + +#endif /* _STLP_OSTREAM_C */ + +// Local Variables: +// mode:C++ +// End: