/*************************************************************************** * * _ioinsert.cc - definitions for the C++ Standard Library inserter * helper templates * * $Id: _ioinsert.cc 590052 2007-10-30 12:44:14Z faridz $ * *************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * Copyright 1994-2006 Rogue Wave Software. * **************************************************************************/ #include _RWSTD_NAMESPACE (__rw) { _EXPORT template _STD::basic_ostream<_CharT, _Traits>& __rw_insert (_STD::basic_ostream<_CharT, _Traits> &__strm, _NativeType __val) { const _TYPENAME _STD::basic_ostream<_CharT, _Traits>::sentry __opfx (__strm); _TRY { typedef _STD::ostreambuf_iterator<_CharT, _Traits> _Iter; typedef _STD::num_put<_CharT, _Iter> _NumPut; if (__opfx && _STD_USE_FACET (_NumPut, __strm.getloc ()) .put (_Iter (__strm), __strm, __strm.fill (), __val).failed ()) { // this may throw but the exception will just be caught // and rethrown below; this optimizes for the common case // (i.e., success) but pessimizes the case of failure __strm.setstate (_STD::ios_base::badbit); } } _CATCH (...) { __strm.setstate (_STD::ios_base::badbit | _RW::__rw_rethrow); } return __strm; } // optimized for when stream's char_type is the same // as the type of the character string being inserted, // i.e., ostream and char* and wostream and wchar_t* template inline _RWSTD_STREAMSIZE __rw_sputn (_STD::basic_ostream<_CharT, _Traits> &__strm, const _CharT *__s, _RWSTD_STREAMSIZE __len, __rw_true_t) { _RWSTD_ASSERT (!__len || __len > 0 && 0 != __s); if (1 == __len) { typedef _TYPENAME _Traits::int_type _IntT; const _IntT __ic = __strm.rdbuf ()->sputc (*__s); return 0 + !_Traits::eq_int_type (_Traits::eof (), __ic); } return __strm.rdbuf ()->sputn (__s, __len); } // special case for char* insertion into a stream whose // char_type is not char (e.g., wostream or user-defined) template inline _RWSTD_STREAMSIZE __rw_sputn (_STD::basic_ostream<_CharT, _Traits> &__strm, const char *__s, _RWSTD_STREAMSIZE __len, __rw_false_t) { _RWSTD_ASSERT (!__len || __len > 0 && 0 != __s); const _STD::ctype<_CharT>& __ctp = _STD_USE_FACET (_STD::ctype<_CharT>, __strm.getloc ()); for (_RWSTD_STREAMSIZE __i = 0; __i < __len; ++__i) { typedef _TYPENAME _Traits::int_type _IntT; const _IntT __ic = __strm.rdbuf ()->sputc (__ctp.widen (__s [__i])); if (_Traits::eq_int_type (__ic, _Traits::eof ())) return __i; } return __len; } _EXPORT template _STD::basic_ostream<_CharT, _Traits>& __rw_insert (_STD::basic_ostream<_CharT, _Traits> &__strm, const _StringT *__s, _RWSTD_STREAMSIZE __len, _RWSTD_STREAMSIZE __width) { _RWSTD_ASSERT (0 != __strm.rdbuf ()); _RWSTD_ASSERT (0 != __s); _STD::ios_base::iostate __err = _STD::ios_base::goodbit; // writes out max(len, width) characters, padding appropriately // with the fill character if (len < width); // calls width(0) if and only if the write has been successful // (i.e., will leave it unchanged if sputn fails or throws an // exception) _TRY { const _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 _RWSTD_STREAMSIZE __pad = __width - __len; typedef _TYPENAME __rw_is_same<_CharT, _StringT>::_C_type _Same; if (__pad > 0) { 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) // write out (not necessarily null-terminated) string || __len != __rw_sputn (__strm, __s, __len, _Same ()) // output right padding (output is left-aligned) || _STD::ios_base::left == __padbits && __pad != __strm._C_pad (__pad)) __err = _STD::ios_base::badbit; #ifndef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE else __strm.width (0); // reset width only on success #else // if defined (_RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE) __strm.width (0); // reset width unconditionally #endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE } else if (__len == __rw_sputn (__strm, __s, __len, _Same ())) { __strm.width (0); // reset width only on success } else { __err = _STD::ios_base::badbit; #ifdef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE __strm.width (0); #endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE } } } _CATCH (...) { // set badbit and rethrow the caught exception if badbit // is also set in exceptions() __strm.setstate (_STD::ios_base::badbit | _RW::__rw_rethrow); } if (__err) { // set badbit which may throw ios_base::failure __strm.setstate (__err); } return __strm; } } // namespace __rw