// -*- C++ -*-
/***************************************************************************
 *
 * fstream.cc - Definition for the Standard Library file streams
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Copyright 2005-2006 The Apache Software Foundation or its licensors,
 * as applicable.
 *
 * Copyright 1994-2006 Rogue Wave Software.
 *
 * Licensed 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.
 * 
 **************************************************************************/

_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 */)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

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

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

    // write out any unshift sequence if necessary
    // (applies to multibyte, state dependent encodings only)
    if (this->_C_out_last () && !_C_unshift ())
        return 0;   // failure

    if (__close_file && _RW::__rw_fclose (_C_file, this->_C_state))
        return 0;   // failure

    _C_file    = 0;
    _C_cur_pos = _C_beg_pos = pos_type (off_type (-1));

    return this;
}


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) {
            __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
