/*
 * 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 <stl/_ostream.h>
#endif

#if !defined (_STLP_INTERNAL_NUM_PUT_H)
#  include <stl/_num_put.h>            // For basic_streambuf and iterators
#endif

_STLP_BEGIN_NAMESPACE

//----------------------------------------------------------------------
// Definitions of non-inline member functions.

// Constructor, destructor

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<_CharT, _Traits>* __buf)
    : basic_ios<_CharT, _Traits>() {
  this->init(__buf);
}

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>::~basic_ostream()
{}

// Output directly from a streambuf.
template <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits, class _Number>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
#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 <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __x)
{ return _STLP_PRIV __put_num(*this,  __x); }

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __x)
{ return _STLP_PRIV __put_num(*this,  __x); }

#ifdef _STLP_LONG_LONG
template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (_STLP_LONG_LONG __x)
{ return _STLP_PRIV __put_num(*this,  __x); }

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<< (unsigned _STLP_LONG_LONG __x)
{ return _STLP_PRIV __put_num(*this,  __x); }
#endif

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __x)
{ return _STLP_PRIV __put_num(*this,  __STATIC_CAST(double,__x)); }

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __x)
{ return _STLP_PRIV __put_num(*this,  __x); }

#ifndef _STLP_NO_LONG_DOUBLE
template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __x)
{ return _STLP_PRIV __put_num(*this,  __x); }
#endif

template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __x)
{ return _STLP_PRIV __put_num(*this,  __x); }

#ifndef _STLP_NO_BOOL
template <class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __x)
{ return _STLP_PRIV __put_num(*this,  __x); }
#endif

template <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
void basic_ostream<_CharT, _Traits>::_M_put_widen(const char* __s) {
  sentry __sentry(*this);
  if (__sentry) {
    bool __failed = true;
    streamsize __n = char_traits<char>::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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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 <class _CharT, class _Traits>
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:
