// -*- C++ -*-
/***************************************************************************
 *
 * fstream.cc - Definition for the Standard Library file streams
 *
 * $Id$
 *
 ***************************************************************************
 *
 * 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 1997-2008 Rogue Wave Software, Inc.
 * 
 **************************************************************************/

_RWSTD_NAMESPACE (std) {


template<class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::
open (const char *__name, ios_base::openmode __mode, long __prot)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    // fail if `mode' has invalid bits set or if the file is already open
    if ((__mode & ~_RWSTD_IOS_OPENMODE_MASK) || is_open ())
        return 0;

    _C_file = _RW::__rw_fopen (__name, __mode, __prot);

    if (!_C_file)
        return 0;

    pos_type __pos = pos_type ();

    if (__mode & ios_base::ate) {

        // the end of a file is assumed to be in the initial shift state
        // this assumption is safe as long as the file has been properly
        // closed (or unshifted) after the last write operation on it
        __pos = _RW::__rw_fseek (_C_file, 0, 0, ios_base::end);

        if (-1L == __pos) {
            _RW::__rw_fclose (_C_file, 0);
            _C_file = 0;
            return 0;
        }
    }

    _C_beg_pos = _C_cur_pos = __pos;

    this->_C_state &= ~_RWSTD_IOS_OPENMODE_MASK;
    this->_C_state |= __mode;

    return this;
}


template<class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::
close (bool __close_file /* = true */)
{
    // close_file is false when close() is called from detach()

    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!is_open ())
        return 0;   // failure

    // close() returns this on success, 0 on failure
    basic_filebuf *__retval = this;

    _TRY {
        // avoid expensive call to overflow() unless necessary
        if (this->pptr () != this->pbase () && this->_C_is_eof (overflow ()))
            __retval = 0;   // failure

        // write out any unshift sequence if necessary
        // (applies to multibyte, state dependent encodings only)
        if (__retval && this->_C_out_last () && !_C_unshift ())
            __retval = 0;   // failure
    }
    _CATCH (...) {
        // either overflow() or codecvt::unshift() threw

        if (__close_file) {
            _RW::__rw_fclose (_C_file, this->_C_state);

            // zero out the file pointer except when detaching fd
            _C_file    = 0;
            _C_cur_pos = _C_beg_pos = pos_type (off_type (-1));

        }

        // rethrow the caught exception
        _RETHROW;
    }

    if (__close_file) {
        if (_RW::__rw_fclose (_C_file, this->_C_state))
            __retval = 0;

        // zero out the file pointer except when detaching fd
        _C_file    = 0;
        _C_cur_pos = _C_beg_pos = pos_type (off_type (-1));
    }

    return __retval;
}


template<class _CharT, class _Traits>
streamsize
basic_filebuf<_CharT, _Traits>::
showmanyc ()
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (   !this->_C_is_in () || !is_open ()
        || _C_cur_pos == pos_type (off_type (-1)))
        return -1;

    // start with the number of chars in get area
    _RWSTD_STREAMSIZE __retval = this->egptr () - this->gptr ();

    // no prob if this fails for non-seekable devices
    const pos_type __end_pos =
        _RW::__rw_fseek (_C_file, this->_C_state, 0, ios_base::end);

    if (__end_pos != pos_type (off_type (-1))) {

        // restore position within file only if seek succeeded
        _RW::__rw_fseek (_C_file, this->_C_state, _C_cur_pos, ios_base::beg);

        typedef _TYPENAME traits_type::state_type _StateT;
        typedef codecvt<char_type, char, _StateT> _Codecvt;

        const _Codecvt &__cvt = _USE_FACET (_Codecvt, this->getloc ());

        if (__cvt.always_noconv ())
            __retval += __end_pos - _C_cur_pos;
        else
            // make most pessimistic conversion estimate
            __retval += (__end_pos - _C_cur_pos) / __cvt.max_length ();
    }

    return __retval > 0 ? __retval : 0;
}


template<class _CharT, class _Traits>
_TYPENAME basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
underflow ()
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    this->setp (0, 0);          // invalidate put area

    this->_C_out_last (false);  // needed by close ()

    if (!this->_C_is_in () || !is_open())
        return traits_type::eof ();

    char_type* const __to_end = this->_C_buffer + this->_C_bufsize;

    typedef _TYPENAME traits_type::int_type _IntType;

    _IntType __ret = _IntType ();

    // fill the buffer if it's empty

    if (this->gptr () == this->egptr()) {  // N.B.: gptr() could be null here

        // determine the maximum possible size of putback area (if any)
        // make sure putback area isn't too big - try to honor
        // _RWSTD_PBACK_SIZE if possible, otherwise shrink

        const _RWSTD_SIZE_T __pbackavail = this->_C_putback_avail ();
        _C_pbacksize = __pbackavail < _RWSTD_PBACK_SIZE ?
            __pbackavail : _RWSTD_PBACK_SIZE;

        _RWSTD_ASSERT (0 != this->_C_bufsize);

        if (_C_pbacksize == this->_C_bufsize)
            _C_pbacksize = this->_C_bufsize - 1;

        traits_type::move (this->eback(), this->gptr () - _C_pbacksize,
                           _C_pbacksize);

        //  fill the get area from the file, performing code conversion if
        //  necessary

        _RWSTD_STREAMSIZE __nread = 0; // number of bytes read from file

        _C_beg_pos = _C_cur_pos;

        typedef _TYPENAME traits_type::state_type _StateT;
        typedef codecvt<char_type, char, _StateT> _Codecvt;

        const _Codecvt &__cvt = _USE_FACET (_Codecvt, this->getloc ());

        if (__cvt.always_noconv ()) {
            // no conversion required
            __nread = (__to_end - this->_C_buffer) - _C_pbacksize;
            __nread = _RW::__rw_fread (_C_file, this->_C_state,
                                       this->_C_buffer + _C_pbacksize,
                                       sizeof (char_type) * __nread);
            if (__nread < 0)
                return traits_type::eof ();       // error while reading

            this->setg (this->_C_buffer,
                        this->_C_buffer + _C_pbacksize,
                        this->_C_buffer + _C_pbacksize + __nread);

            // adjust the current position in the file,
            // taking into account CR/LF conversion on windows
            __nread += _C_crlf_intern_count (this->gptr (),
                                             this->gptr () + __nread);
        }
        else { // conversion required

            char          __xbuf [_RWSTD_DEFAULT_BUFSIZE];
            char*         __from_base = __xbuf;
            const char*   __from_next = 0;
            char_type*    __to_base   = this->_C_buffer + _C_pbacksize;
            char_type*    __to_next   = __to_base;

            _StateT       __state     = _C_cur_pos.state ();

            codecvt_base::result __res = codecvt_base::ok;

            const ctype<char_type> &__ctp =
                _USE_FACET (ctype<char_type>, this->getloc ());

            while (__to_next != __to_end && codecvt_base::error != __res) {

                // read only as many characters as we have positions left in
                //   internal buffer - guarantees we won't read more characters
                //   than we can put into the internal buffer after conversion
                //   and ending file position isn't in the middle of a shift
                //   sequence
                // N.B.: area between __xbuf and __from_base contains partially
                //   converted sequences left from previous read
                _RWSTD_STREAMSIZE __n = __to_end - __to_next;
                if (_RWSTD_DEFAULT_BUFSIZE - (__from_base - __xbuf) < __n)
                    __n = _RWSTD_DEFAULT_BUFSIZE - (__from_base - __xbuf);

                __n = _RW::__rw_fread (_C_file, this->_C_state,
                                       __from_base, __n);

                if (0 > __n)
                    return traits_type::eof ();   // error while reading

                if (0 == __n)
                    break;   // reached eof

                // take into account CR/LF conversion on Win32
                __nread += __n +
                    _C_crlf_extern_count (__from_base, __from_base + __n);

                // adjust 'n' to hold the number of external chars in buffer
                __n += __from_base - __xbuf;

                // convert any partially converted sequence from the previous
                // iteration (possibly empty) plus what we just read in
                __res = __cvt.in (__state, __xbuf, __xbuf + __n, __from_next,
                                  __to_base, __to_end, __to_next);

                switch (__res) {
                case codecvt_base::ok:
                    // there may be yet unconverted elements at the end
                    // of the source sequence, fall through and treat
                    // as partial (`n' below may be 0)

                case codecvt_base::partial:
                    // compute the length of partially converted sequence
                    __n -= __from_next - __xbuf;

                    typedef char_traits<char> CharTraits;

                    // copy the sequence to beginning of xbuf
                    CharTraits::move (__xbuf, __from_next, __n);

                    // will append external chars to end of the sequence
                    __from_base = __xbuf + __n;
                    break;

                case codecvt_base::noconv:
                    // note that according to lwg issue 19, codecvt<wchar_t,
                    // char>::in() may not return noconv since internT and
                    // externT are not the same type

                    // since codecvt<char, char>::always_noconv() is required
                    // to return true, this branch only executes for a user-
                    // defined codecvt<T, T> facet with internT and externT
                    // being the same type

                    // FIXME: do not widen external buffer just memcpy it
                    //        to internal buffer (externT == internT)
                    __ctp.widen (__xbuf, __xbuf + __n, __to_base);
                    __to_next = __to_base + __n;
                    break;

                case codecvt_base::error:
                    // failed to convert part of the buffer
                    // retain the part that has been successfully
                    // converted, and disregard the rest
                    __ret = traits_type::eof ();
                    break;

                default:
                    // bad return value from codecvt
                    return traits_type::eof ();
                }
                __to_base = __to_next;  // continue at end of converted seq
            }

            _C_cur_pos.state (__state);

            this->setg (this->_C_buffer, this->_C_buffer + _C_pbacksize,
                        __to_next);
        }   // end conversion block

        if (__nread == 0)
            return traits_type::eof ();

        _C_cur_pos += __nread;
    }

    return traits_type::eq_int_type (__ret, _IntType ()) ?
        traits_type::to_int_type (*this->gptr ()) : __ret;
}


template<class _CharT, class _Traits>
_TYPENAME basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
overflow (int_type __c /* = eof () */)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!this->_C_is_out () || !is_open ())
        return traits_type::eof ();

    this->setg (0, 0, 0);            // invalidate the get area

    const bool __unbuf = this->_C_is_unbuffered ();

    const char_type __c_to_char = traits_type::to_char_type (__c);

    if (this->pptr () == 0 && !__unbuf) {
        // put area not valid yet - just need to initialize it
        this->setp (this->_C_buffer, this->_C_buf_end ());
    }
    else if (   this->pptr () == this->epptr ()
             || this->_C_is_eof (__c)
             || __unbuf) {

        const char_type*  __buf;
        _RWSTD_STREAMSIZE __nchars;

        if (__unbuf) {
            if (this->_C_is_eof (__c)){
                __buf    = 0;
                __nchars = 0;
            }
            else {
                __buf    = &__c_to_char;
                __nchars = 1;
            }
        }
        else {
            // call xsputn() with a special value to have it flush
            // the controlled sequence to the file
            __buf    = _RWSTD_REINTERPRET_CAST (char_type*, this);
            __nchars = this->pptr () - this->pbase ();
        }

        // typedef helps HP aCC 3.27
        typedef basic_filebuf _FileBuf;

        if (__nchars != _FileBuf::xsputn (__buf, __nchars))
            return traits_type::eof ();  // error while writing
    }

    // now that there's room in the buffer, call sputc() recursively
    // to actually place the character in the buffer (unless we're
    // in unbuffered mode because we just wrote it out)
    if (!this->_C_is_eof (__c) && !__unbuf)
        this->sputc (__c_to_char);

    this->_C_out_last (true);   // needed by close ()

    return traits_type::not_eof (__c);
}


template <class _CharT, class _Traits>
_RWSTD_STREAMSIZE
basic_filebuf<_CharT, _Traits>::
xsputn (const char_type* __buf, _RWSTD_STREAMSIZE __nchars)
{
    _RWSTD_ASSERT (0 != __buf || 0 == __nchars);
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (0 == __nchars)
        return 0;   // not an error

    if (__nchars < 0 || !this->_C_is_out () || !is_open ())
        return -1;   // error

    if (0 == this->pptr () && !this->_C_is_unbuffered ())
        // put area not valid yet - just need to initialize it
        this->setp (this->_C_buffer, this->_C_buf_end ());

    const _RWSTD_STREAMSIZE __navail = this->epptr () - this->pptr ();

    const char_type* const __special =
        _RWSTD_REINTERPRET_CAST (char_type*, this);

    if (__buf == __special) {
        __buf = this->pbase ();
    }
    else if (__nchars <= __navail) {
        // the amount of available space is big enough

        // append the contents of the buffer to the controlled sequence
        traits_type::copy (this->pptr (), __buf, __nchars);

        this->pbump (__nchars);

        return __nchars;
    }
    else {
        // call self recursively to flush the controlled sequence first
        const _RWSTD_STREAMSIZE __nwrite = this->pptr () - this->pbase ();

        // typedef helps HP aCC 3.27
        typedef basic_filebuf _FileBuf;

        // return -1 on error to flush the controlled sequence
        if (__nwrite != _FileBuf::xsputn (__special, __nwrite))
            return -1;
    }

    //  flush buffer to file, performing code conversion if necessary

    _RWSTD_ASSERT (this->_C_is_valid ());
    _RWSTD_ASSERT (this->_C_is_out ());
    _RWSTD_ASSERT (is_open ());

    const char_type* const __end = __buf + __nchars;

    typedef _TYPENAME traits_type::state_type _StateT;

    _RWSTD_STREAMSIZE __nwrote = 0;          // num chars to write
    _StateT __state = _C_cur_pos.state ();   // state of stream

    _C_beg_pos = _C_cur_pos;

    typedef codecvt<char_type, char, _StateT> _Codecvt;

    const _Codecvt &__cvt = _USE_FACET (_Codecvt, this->getloc ());

    if (__cvt.always_noconv ()) {

        // no conversion

        __nwrote = __end - __buf;

        const _RWSTD_STREAMSIZE __nbytes = sizeof (char_type) * __nwrote;

        if (__nbytes != _RW::__rw_fwrite (_C_file, this->_C_state,
                                          __buf, __nbytes))
            return -1;  // error while writing
    }
    else {

        // perform codeset conversion in chunks to avoid dynamic
        // memory allocation

        char             __xbuf [_RWSTD_DEFAULT_BUFSIZE];
        char*            __xbuf_end  = __xbuf + sizeof __xbuf;
        char*            __to_next   = 0;
        const char_type* __from_next = 0;

        for (const char_type* __base = __buf; __from_next != __end;
             __base = __from_next) {

            // avoid using const codecvt_base::result here
            // to prevent HP aCC 3.27 errors
            const int __res =
                __cvt.out (__state, __base, __end, __from_next,
                           __xbuf, __xbuf_end, __to_next);

            _RWSTD_STREAMSIZE __nbytes =
                sizeof (char_type) * (__end - __base);

            switch (__res) {
            case codecvt_base::error:
                // write out the sequence successfully converted up
                // to the point of the error in the internal sequence
                // and fail
                _RW::__rw_fwrite (_C_file, this->_C_state, __base, __nbytes);
                    return traits_type::eof ();

            case codecvt_base::noconv:
                // write the entire sequence
                if (__nbytes != _RW::__rw_fwrite (_C_file, this->_C_state,
                                                  __base, __nbytes))
                    return traits_type::eof ();

                __nwrote += __end - __base
                    + _C_crlf_intern_count (__base, __end);

                __from_next = __end; // effectively 'break'
                break;

            default:
                _RWSTD_ASSERT (   codecvt_base::ok == __res
                               || codecvt_base::partial == __res);

                // partial conversion will result if there isn't enough
                // space in the conversion buffer to hold the converted
                // sequence, but we're O.K. since we'll be passing any
                // remaining unconverted characters (starting at
                // __from_next) in the next iteration

                __nbytes = __to_next - __xbuf;

                if (__nbytes != _RW::__rw_fwrite (_C_file, this->_C_state,
                                                  __xbuf, __nbytes))
                    return -1;

                __nwrote += __nbytes
                    + _C_crlf_extern_count (__xbuf, __to_next);
            }
        }
    }

    // adjust the current position in the file
    _C_cur_pos += __nwrote;
    _C_cur_pos.state (__state);

    // reset the put area
    if (!this->_C_is_unbuffered ())
        this->setp (this->_C_buffer, this->_C_buf_end ());

    this->_C_out_last (true);   // needed by close ()

    // return the number of characters (not bytes) in the buffer
    // successfully written to the file
    return __nchars;
}


template<class _CharT, class _Traits>
_TYPENAME basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
pbackfail (int_type __c)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!is_open ())
        return traits_type::eof ();

    // we could get here if gptr = eback or if __c != *(gptr-1)
    if (!this->_C_putback_avail ()) {
        // try to make a putback area available

        if (this->seekoff (-1, ios_base::cur) == pos_type (off_type (-1)))
            return traits_type::eof ();

        if (this->_C_is_eof (underflow ()))
            return traits_type::eof ();

        this->gbump (1);
    }

    if (traits_type::eq (traits_type::to_char_type (__c), *(this->gptr () - 1))
        || this->_C_is_eof (__c)) {
        // "put back" original value
        this->gbump (-1);
        return traits_type::not_eof (__c);
    }
    else if (this->_C_is_out ()) {
        // overwrite existing value with new value
        this->gbump (-1);
        *this->gptr () = traits_type::to_char_type (__c);
        return __c;
    }
    else
        return traits_type::eof ();
}


template<class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::
setbuf (char_type *__buf, streamsize __ssize)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (__ssize < 0)
        return 0;

    const _RWSTD_SIZE_T __bufsize =
        _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, __ssize);

    // sync the buffer to the external file so it can be deallocated
    if ((this->gptr () || this->pptr ()) && is_open () && sync () != 0)
        return 0;

    bool __reset = true;

    if (0 < __bufsize) {

        if (!__buf && (this->_C_bufsize < __bufsize || !this->_C_buffer)) {
            // if `buf' is 0 and the requested size is greater than
            // the size of the object's buffer, or of the object's
            // buffer is 0, try to allocate a new buffer of the
            // specified size
            __buf = new char_type [__bufsize];

            // delete old buffer if the object owns it
            if (this->_C_own_buf ())
                delete [] this->_C_buffer;

            // take ownership of the newly allocated buffer
            this->_C_own_buf (true);
        }
        else if (!__buf && __bufsize <= this->_C_bufsize) {
            // if `buf' is 0 and the requested size is less than
            // the size of the object's buffer, simply reuse the
            // object's buffer

            __buf   = this->_C_buffer;
            __reset = false;
        }
        else if (__buf && __buf != this->_C_buffer) {
            // if `buf' is non-0 and different from the existing
            // buffer, use it

            // delete old buffer if the object owns it
            if (this->_C_own_buf ())
                delete [] this->_C_buffer;

            // the object does not own of the new buffer
            this->_C_own_buf (false);
        }

        this->_C_buffer  = __buf;
        this->_C_bufsize = __bufsize;
        this->_C_set_unbuffered (false);
    }
    else {
        // unbuffer this stream object

        // character buffer is preserved (used as get area only),
        // streambuf object unbuffered for writing

        // to put a streambuf object into an unbuffered mode (see 27.8.1.4,
        // p10) and affect the size of the get area, setbuf() should first
        // be called with the desired (non-zero) size and then again with
        // both arguments being 0
        this->_C_set_unbuffered (true);
    }

    if (__reset) {
        this->setg (0, 0, 0);
        this->setp (0, 0);
    }

    // a character buffer of nonzero size must exist even in unbuffered mode
    _RWSTD_ASSERT (0 != this->_C_buffer);
    _RWSTD_ASSERT (0 != this->_C_bufsize);

    return this;
}


// 27.8.1.4, p 11
template<class _CharT, class _Traits>
_TYPENAME basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::
seekoff (off_type __off, ios_base::seekdir __way, ios_base::openmode)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!is_open ())
        return pos_type (off_type (-1));

    typedef _TYPENAME traits_type::state_type _StateT;
    typedef codecvt<char_type, char, _StateT> _Codecvt;

    const int __width = _USE_FACET (_Codecvt, this->getloc ()).encoding ();

    // offset must be zero with state-dependent encoding
    if (0 != __off && __width <= 0)
        return pos_type (off_type (-1));

    // sync the buffer... (this also invalidates the get/put area)
    if (sync () != 0)
        return pos_type (off_type (-1));

    // ...and, if last operation was output, append an unshift sequence
    if (this->_C_out_last ())
        _C_unshift ();

    if (__width > 1)
        __off *= __width;

    // perform the seek and save the result
    pos_type __pos = _RW::__rw_fseek (_C_file, this->_C_state, __off, __way);

    if (__pos != pos_type (off_type (-1))) {

        // preserve the current state if not changing position
        // (only matters for state-dependent encodings for which
        // the offset is required and guaranteed to be 0)
        if (__way == ios_base::cur)
            __pos.state (_C_cur_pos.state ());

        _C_beg_pos = _C_cur_pos = __pos;
    }

    this->_C_out_last (false);  // needed by close()

    return __pos;
}


template<class _CharT, class _Traits>
_TYPENAME basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::
seekpos (pos_type __pos, ios_base::openmode)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!is_open ())
        return pos_type (off_type (-1));

    // flush the output area if it exists
    if (this->pptr () != 0) {
        if (this->_C_is_eof (this->overflow (traits_type::eof ())))
            return pos_type (off_type (-1));
    }

    if (   _RW::__rw_fseek (_C_file, this->_C_state, __pos, ios_base::beg)
        == pos_type (off_type (-1)))
        return pos_type (off_type (-1));

    _C_cur_pos = _C_beg_pos = __pos;

    this->setg (0, 0, 0);
    this->setp (0, 0);

    this->_C_out_last (false);  // needed by close()

    return __pos;
}


template<class _CharT, class _Traits>
int
basic_filebuf<_CharT, _Traits>::
sync ()
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    // put area active
    if (this->pptr () != 0) {
        // flush the buffer to the file
        if (this->_C_is_eof (overflow (traits_type::eof ())))
            return -1;

        if (this->_C_state & _RWSTD_IOS_STDIO)
            _RW::__rw_fflush (_C_file, this->_C_state);
    }

    // get area active
    if (this->gptr () != 0) {

        // pbacksize may need to be adjusted if it's greater than
        // the available putback area (e.g., after calling putback()
        // at the end of the buffer)
        const _RWSTD_SIZE_T __pbackavail = this->_C_putback_avail ();
        if (__pbackavail < _C_pbacksize)
            _C_pbacksize = __pbackavail;

        _RWSTD_ASSERT (0 != this->_C_bufsize);

        if (_C_pbacksize == this->_C_bufsize)
            _C_pbacksize = this->_C_bufsize - 1;

        typedef _TYPENAME traits_type::state_type _StateT;
        typedef codecvt<char_type, char, _StateT> _Codecvt;

        const _Codecvt &__cvt = _USE_FACET (_Codecvt, this->getloc ());
        int __width = __cvt.encoding ();

        if (__width > 0) {
            // get the number of chars consumed in the buffer
            const off_type __consumed =
                this->gptr () - this->eback () - _C_pbacksize;

            // constant width conversion:
            // adjust the current position/state in the file,
            // taking into account CR/LF conversion on Win32
            _C_cur_pos = _C_beg_pos;
            _C_cur_pos += (__width * __consumed)
                + _C_crlf_intern_count (this->eback () + _C_pbacksize,
                                        this->gptr());
        }
        else {
            // This gets a bit tricky here because we don't know the external
            // file position corresponding to the position in the
            // internal buffer. To figure this out, we'll use the known
            // file position/state corresponding to the start of the buffer
            // (which we have carefully saved in _C_beg_pos) and
            // convert the characters up to the current position in the
            // buffer, counting how many external chars result. We can
            // then use the offset from _C_beg_pos and the state
            // returned from codecvt::out() to construct the current file
            // position

            off_type __ext_chars = 0;   // converted external chars

            char             __xbuf [_RWSTD_DEFAULT_BUFSIZE];
            char*            __xbuf_end  = __xbuf + sizeof __xbuf;
            char*            __to_next   = 0;
            const char_type* __from_next = 0;
            const char_type* __from_end  = this->gptr ();
            _StateT          __state     = _C_beg_pos.state ();
            const char_type* __base      = this->eback () + _C_pbacksize;

            while (__from_next != __from_end) {
                const int __res =
                    __cvt.out (__state, __base, __from_end, __from_next,
                               __xbuf, __xbuf_end, __to_next);

                switch (__res) {
                case codecvt_base::error:
                    return -1;

                case codecvt_base::noconv:
                    __ext_chars += __from_end - __base
                        + _C_crlf_intern_count (__base, __from_end);
                    __from_next = __from_end;   // break out of the loop
                    break;

                default:         // __res = ok or partial
                    // take into account CR/LF conversion on Win32
                    __ext_chars += __to_next - __xbuf
                        + _C_crlf_extern_count (__xbuf, __to_next);
                }
                // repeat with next chunk
                __base = __from_next;
            }

            _C_cur_pos  = _C_beg_pos;
            _C_cur_pos += __ext_chars;
            _C_cur_pos.state (__state);
        }

        // seek within the external file to the position
        // corresponding to the future beginning of the buffer
        const off_type __off =
            _RW::__rw_fseek (_C_file, this->_C_state,
                             _C_cur_pos, ios_base::beg);

        if (-1L == __off)
            return -1;

        traits_type::move (this->eback (), this->gptr () - _C_pbacksize,
                           _C_pbacksize);

        this->setg (this->eback (), this->eback () + _C_pbacksize,
                    this->eback () + _C_pbacksize);
    }

    _C_beg_pos = _C_cur_pos;

    this->setp (0, 0);

    return 0;
}


template<class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::
_C_open (int __fd, void *__file, char_type *__buf, streamsize __n)
{
    if (is_open () || !__file && -1 == __fd || !setbuf (__buf, __n))
        return 0;

    if (__file) {
        _RWSTD_ASSERT (-1 == __fd);

        _C_file = __file;

        this->_C_state |= this->_C_stdio;
    }
    else {
        _RWSTD_ASSERT (!__file);

        _C_file = _RW::__rw_fdopen (__fd);

        if (!_C_file)
            return 0;

        this->_C_state &= ~this->_C_stdio;
    }

    this->_C_state |= _RW::__rw_fmode (_C_file, this->_C_state);

    this->setg (0, 0, 0);
    this->setp (0, 0);

    _C_cur_pos = _C_beg_pos = pos_type ();

    return this;
}


//  write out an unshift sequence if not in initial shift state
template<class _CharT, class _Traits>
bool
basic_filebuf<_CharT, _Traits>::
_C_unshift ()
{
    typedef _TYPENAME traits_type::state_type _StateT;
    typedef codecvt<char_type, char, _StateT> _Codecvt;

    const _Codecvt &__cvt = _USE_FACET (_Codecvt, this->getloc ());

    // unshifting isn't necessary if encoding isn't state dependent
    // or if the state is equivalent to initial state (determined
    // by codecvt::unshift())
    if (__cvt.encoding () >= 0)
        return true;

    // buf to hold unshift sequence - assumes that the shift
    // sequence will be less than 64 chars (we can't safely
    // use dynamic allocation because this function could be
    // called as a result of memory allocation exception)

    char  __useq [64];
    char* __useq_end = 0;

    _StateT __state = _C_cur_pos.state ();

    const int __res =
        __cvt.unshift (__state, __useq, __useq + sizeof __useq, __useq_end);

    const _RWSTD_STREAMSIZE __nbytes = __useq_end - __useq;

    // in the unlikely event that the buffer isn't big enough, assert
    _RWSTD_ASSERT (__res != codecvt_base::partial);

    if (__res == codecvt_base::error)
        return false;

    if (__res == codecvt_base::noconv)
        return true;

    const off_type __nwrote =
        _RW::__rw_fwrite (_C_file, this->_C_state, __useq, __nbytes);

    if (__nwrote < 0)
        return false;

    _C_cur_pos += __nwrote;     // CR/LF conversion not an issue here

    return __nwrote == __nbytes;
}


}   // namespace std
