You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
8.8 KiB
285 lines
8.8 KiB
5 years ago
|
/***************************************************************************
|
||
|
*
|
||
|
* ostream.cc - Definitions for the Standard Library ostream classes
|
||
|
*
|
||
|
* $Id: ostream.cc 172106 2011-11-02 17:04:12Z statham $
|
||
|
*
|
||
|
***************************************************************************
|
||
|
*
|
||
|
* Copyright (c) 1994-2001 Rogue Wave Software, Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This computer software is owned by Rogue Wave Software, Inc. and is
|
||
|
* protected by U.S. copyright laws and other laws and by international
|
||
|
* treaties. This computer software is furnished by Rogue Wave Software,
|
||
|
* Inc. pursuant to a written license agreement and may be used, copied,
|
||
|
* transmitted, and stored only in accordance with the terms of such
|
||
|
* license and with the inclusion of the above copyright notice. This
|
||
|
* computer software or any other copies thereof may not be provided or
|
||
|
* otherwise made available to any other person.
|
||
|
*
|
||
|
* U.S. Government Restricted Rights. This computer software is provided
|
||
|
* with Restricted Rights. Use, duplication, or disclosure by the
|
||
|
* Government is subject to restrictions as set forth in subparagraph (c)
|
||
|
* (1) (ii) of The Rights in Technical Data and Computer Software clause
|
||
|
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
|
||
|
* Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19,
|
||
|
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
|
||
|
* Flatiron Parkway, Boulder, Colorado 80301 USA.
|
||
|
*
|
||
|
**************************************************************************/
|
||
|
|
||
|
_RWSTD_NAMESPACE_BEGIN (__rw)
|
||
|
|
||
|
template <class _CharT, class _Traits, class _NativeType>
|
||
|
_STD::basic_ostream<_CharT, _Traits>&
|
||
|
__rw_insert (_STD::basic_ostream<_CharT, _Traits> &__strm,
|
||
|
_NativeType __val)
|
||
|
{
|
||
|
_STD::ios_base::iostate __err = _STD::ios_base::goodbit;
|
||
|
|
||
|
_TYPENAME _STD::basic_ostream<_CharT, _Traits>::sentry __opfx (__strm);
|
||
|
|
||
|
_TRY {
|
||
|
|
||
|
if (__opfx) {
|
||
|
|
||
|
typedef _STD::ostreambuf_iterator<_CharT, _Traits> _Iter;
|
||
|
typedef _STD::num_put<_CharT, _Iter> _NumPut;
|
||
|
|
||
|
if (_USE_FACET (_NumPut, __strm.getloc ())
|
||
|
.put (_Iter(__strm), __strm,
|
||
|
__strm.fill (), __val).failed ())
|
||
|
__err = _STD::ios_base::badbit;
|
||
|
|
||
|
__strm.width (0);
|
||
|
}
|
||
|
}
|
||
|
_CATCH (...) {
|
||
|
if (__strm.setstate (_STD::ios_base::badbit, 0))
|
||
|
_RETHROW;
|
||
|
}
|
||
|
|
||
|
if (__err)
|
||
|
__strm.setstate (__err);
|
||
|
|
||
|
return __strm;
|
||
|
}
|
||
|
|
||
|
|
||
|
// generic case (e.g., basic_ostream<wchar_t>, wchar_t*)
|
||
|
template <class _CharT, class _Traits>
|
||
|
inline _STD::streamsize
|
||
|
__rw_sputn (_STD::basic_ostream<_CharT, _Traits> &__strm,
|
||
|
const _CharT*__s, _STD::streamsize __len)
|
||
|
{
|
||
|
return __strm.rdbuf ()->sputn (__s, __len);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_FUNC_PARTIAL_SPEC
|
||
|
|
||
|
// specialized for char* (e.g., basic_ostream<wchar_t>, char*)
|
||
|
template <class _CharT, class _Traits>
|
||
|
inline _STD::streamsize
|
||
|
__rw_sputn (_STD::basic_ostream<_CharT, _Traits> &__strm,
|
||
|
const char *__s, _STD::streamsize __len)
|
||
|
{
|
||
|
_RWSTD_ASSERT (!__len || __len > 0 && 0 != __s);
|
||
|
|
||
|
const _STD::ctype<_CharT>& __ctp =
|
||
|
_USE_FACET (_STD::ctype<_CharT>, __strm.getloc ());
|
||
|
|
||
|
for (_STD::streamsize __i = 0; __i < __len; ++__i) {
|
||
|
_TYPENAME _STD::basic_ostream<_CharT, _Traits>::int_type __n =
|
||
|
__strm.rdbuf ()->sputc (__ctp.widen (__s [__i]));
|
||
|
if (_Traits::eq_int_type (__n, _Traits::eof ()))
|
||
|
return __i;
|
||
|
}
|
||
|
|
||
|
return __len;
|
||
|
}
|
||
|
|
||
|
|
||
|
// specialized for basic_ostream<char> and char*
|
||
|
template <class _Traits>
|
||
|
inline _STD::streamsize
|
||
|
__rw_sputn (_STD::basic_ostream<char, _Traits> &__strm,
|
||
|
const char*__s, _STD::streamsize __len)
|
||
|
{
|
||
|
return __strm.rdbuf ()->sputn (__s, __len);
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_FUNC_PARTIAL_SPEC)
|
||
|
|
||
|
// specialized for basic_ostream<[w]char[_t], char_traits<[w]char[_t]> >
|
||
|
// and char*; any other specialization (e.g., user-defined traits) will be
|
||
|
// generated from the primary template
|
||
|
|
||
|
_RWSTD_SPECIALIZED_FUNCTION
|
||
|
inline _STD::streamsize
|
||
|
__rw_sputn (_STD::basic_ostream<char, _STD::char_traits<char> > &__strm,
|
||
|
const char*__s, _STD::streamsize __len)
|
||
|
{
|
||
|
return __strm.rdbuf ()->sputn (__s, __len);
|
||
|
}
|
||
|
|
||
|
|
||
|
inline _STD::streamsize
|
||
|
__rw_sputn (_STD::basic_ostream<wchar_t, _STD::char_traits<wchar_t> > &__strm,
|
||
|
const char*__s, _STD::streamsize __len)
|
||
|
{
|
||
|
_RWSTD_ASSERT (!__len || __len > 0 && 0 != __s);
|
||
|
|
||
|
const _STD::ctype<wchar_t>& __ctp =
|
||
|
_USE_FACET (_STD::ctype<wchar_t>, __strm.getloc ());
|
||
|
|
||
|
for (_STD::streamsize __i = 0; __i < __len; ++__i) {
|
||
|
_STD::basic_ostream<wchar_t, _STD::char_traits<wchar_t> >::int_type __n
|
||
|
= __strm.rdbuf ()->sputc (__ctp.widen (__s [__i]));
|
||
|
if (_STD::char_traits<wchar_t>::eq_int_type (__n,
|
||
|
_STD::char_traits<wchar_t>::eof ()))
|
||
|
return __i;
|
||
|
}
|
||
|
|
||
|
return __len;
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_FUNC_PARTIAL_SPEC
|
||
|
|
||
|
|
||
|
template<class _CharT, class _Traits, class _StringT>
|
||
|
_STD::basic_ostream<_CharT, _Traits>&
|
||
|
__rw_insert (_STD::basic_ostream<_CharT, _Traits> &__strm,
|
||
|
_StringT *__s,
|
||
|
_STD::streamsize __len,
|
||
|
_STD::streamsize __width)
|
||
|
{
|
||
|
_RWSTD_ASSERT (0 != __strm.rdbuf ());
|
||
|
_RWSTD_ASSERT (0 != __s);
|
||
|
|
||
|
_STD::ios_base::iostate __err = _STD::ios_base::goodbit;
|
||
|
|
||
|
_TRY {
|
||
|
|
||
|
_TYPENAME _STD::basic_ostream<_CharT, _Traits>::sentry __opfx (__strm);
|
||
|
|
||
|
if (__opfx) {
|
||
|
|
||
|
// compute the number of fill chars to pad with
|
||
|
// according to the rules described in 22.2.2.2.2, p19
|
||
|
const _STD::streamsize __pad = __width - __len;
|
||
|
const int __padbits = _STD::ios_base::adjustfield & __strm.flags ();
|
||
|
|
||
|
// output left padding (output is right-aligned by default)
|
||
|
if ( _STD::ios_base::left != __padbits
|
||
|
&& __pad != __strm._C_pad (__pad))
|
||
|
__err = _STD::ios_base::badbit;
|
||
|
|
||
|
// write out (not necessarily null-terminated) string
|
||
|
if ( _STD::ios_base::goodbit == __err
|
||
|
&& __len && __len != __rw_sputn (__strm, __s, __len))
|
||
|
__err = _STD::ios_base::badbit;
|
||
|
|
||
|
// output right padding (output is left-aligned)
|
||
|
if ( _STD::ios_base::goodbit == __err
|
||
|
&& _STD::ios_base::left == __padbits
|
||
|
&& __pad != __strm._C_pad (__pad))
|
||
|
__err = _STD::ios_base::badbit;
|
||
|
}
|
||
|
}
|
||
|
_CATCH (...) {
|
||
|
if (__strm.setstate (_STD::ios_base::badbit, 0 /* nothrow */))
|
||
|
_RETHROW;
|
||
|
}
|
||
|
|
||
|
if (__err)
|
||
|
__strm.setstate (__err);
|
||
|
|
||
|
return __strm;
|
||
|
}
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_END // __rw
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_BEGIN (std)
|
||
|
|
||
|
|
||
|
template<class _CharT, class _Traits>
|
||
|
basic_ostream<_CharT, _Traits>&
|
||
|
basic_ostream<_CharT, _Traits>::_C_opfx ()
|
||
|
{
|
||
|
if (this->tie ())
|
||
|
this->tie ()->flush ();
|
||
|
|
||
|
if (this->_C_is_sync ()) {
|
||
|
|
||
|
if (_C_is_cout ()) // [w]cout
|
||
|
fflush (stdout);
|
||
|
else if (_C_is_std ()) // [w]cerr or [w]clog
|
||
|
fflush (stderr);
|
||
|
}
|
||
|
|
||
|
// cast to ios_base::seekdir makes MSVC 6.0/sp3 happy
|
||
|
if ( this->rdbuf ()
|
||
|
&& this->rdbuf ()->_C_mode () & ios_base::app)
|
||
|
this->rdbuf ()->pubseekoff (0, ios_base::seekdir (ios_base::end),
|
||
|
ios_base::out);
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
template<class _CharT, class _Traits>
|
||
|
basic_ostream<_CharT, _Traits>&
|
||
|
basic_ostream<_CharT, _Traits>::
|
||
|
operator<< (basic_streambuf<_CharT, _Traits>& __sb)
|
||
|
{
|
||
|
ios_base::iostate __err = ios_base::goodbit;
|
||
|
|
||
|
bool __extracted = false; // successfully extracted chars from __sb?
|
||
|
|
||
|
if (__sb._C_mode () & ios_base::in) {
|
||
|
|
||
|
sentry __opfx (*this);
|
||
|
|
||
|
_TRY {
|
||
|
|
||
|
if (__opfx) {
|
||
|
if (_Traits::eq_int_type (__sb.sgetc (), _Traits::eof ()))
|
||
|
__err = ios_base::failbit;
|
||
|
else {
|
||
|
for ( ; ; ) {
|
||
|
int_type __c = __sb.sbumpc ();
|
||
|
if (_Traits::eq_int_type (__c, _Traits::eof ()))
|
||
|
break;
|
||
|
if (_Traits::eq_int_type (this->rdbuf ()->sputc (__c),
|
||
|
_Traits::eof ())) {
|
||
|
__err = ios_base::failbit;
|
||
|
break;
|
||
|
}
|
||
|
__extracted = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
_CATCH (...) {
|
||
|
if (this->setstate (ios_base::badbit, 0))
|
||
|
_RETHROW;
|
||
|
}
|
||
|
}
|
||
|
// 27.6.2.5.3.8
|
||
|
if (!__extracted)
|
||
|
__err = ios_base::failbit;
|
||
|
|
||
|
if (__err)
|
||
|
this->setstate (__err);
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_END // std
|
||
|
|