/***************************************************************************
 *
 * codecvt.cpp - definition of codecvt<char, char, mbstate_t> members
 *
 * $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 1994-2007 Rogue Wave Software, Inc.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC

#include <rw/_defs.h>


// working around a Compaq C++ bug (see PR #26778)
#if __DECCXX_VER >= 60300000 && __DECCXX_VER < 60400000

#  include <stdarg.h>
_USING (std::va_list);

// override autoconfigured macro whose value is incorrect
// if <unistd.h> is #included before <iconv.h>
#  include <unistd.h>
#  define _RWSTD_NO_ICONV_CONST_CHAR

#endif   // Compaq C++ 6.3

#include <limits.h>
#include <locale.h>
#include <string.h>   // for memcmp()
#include <errno.h>
#include <wchar.h>    // for mbsinit()

#if    defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x540 \
    && (defined (__SunOS_5_8) || defined (__SunOS_5_9))
   // working around SunOS/SunPro header dependencies (see PR #26255)
#  undef _TIME_T
#endif   // SunPro <= 5.4 && SunOS 5.{8,9}

#include <loc/_codecvt.h>
#include <loc/_locale.h>
#include <loc/_localedef.h>

#include "setlocale.h"
#include "use_facet.h"


// _RWSTD_MBSTATE_T macro might expand to char* (on AIX)
typedef _RWSTD_MBSTATE_T StateT;


_RWSTD_NAMESPACE (__rw) {

static inline int
__rw_mbsinit (const StateT *ps)
{
#ifndef _RWSTD_NO_MBSINIT

    return ::mbsinit (ps);

#else   // if defined (_RWSTD_NO_MBSINIT)

    // commented out to work around an HP aCC 1.21 bug
    /* static */ const StateT state = StateT ();
    return !ps || 0 == memcmp (ps, &state, sizeof state);

#endif   // _RWSTD_NO_MBSINIT

}


}   // namespace __rw


_RWSTD_NAMESPACE (std) {


_RW::__rw_facet_id codecvt<char, char, _RWSTD_MBSTATE_T>::id;


codecvt<char, char, _RWSTD_MBSTATE_T>::
codecvt (size_t refs /* = 0 */) _THROWS (())
    : _RW::__rw_facet (refs), _C_always_noconv (-1)
{
    // empty
}


// outlined to avoid generating a vtable in each translation unit
// that uses the class
/* virtual */ codecvt<char, char, _RWSTD_MBSTATE_T>::
~codecvt ()   // nothrow
{
    // no-op
}


/* virtual */ codecvt_base::result
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_out (state_type         &state,
        const intern_type  *from,
        const intern_type  *from_end,
        const intern_type *&from_next,
        extern_type        *to,
        extern_type        *to_end,
        extern_type       *&to_next) const
{
    // verify that both ranges are valid
    _RWSTD_ASSERT (from <= from_end);
    _RWSTD_ASSERT (to <= to_end);
    _RWSTD_ASSERT ((from && from_end) || (!from && !from_end));
    _RWSTD_ASSERT ((to && to_end) || (!to && !to_end));

    // next pointers must always be set before returning, even on error
    from_next = from;
    to_next   = to;

#ifdef _RWSTDDEBUG

    // verify that the conversion state is valid
    const int mbstate_valid = _RW::__rw_mbsinit (&state);

    _RWSTD_ASSERT (0 != mbstate_valid);

#else   // if !defined (_RWSTDDEBUG)

    _RWSTD_UNUSED (state);

#endif   // _RWSTDDEBUG

    // be prepared to handle an overridden do_always_noconv()
    // that returns false (highly unlikely but possible)
    if (always_noconv ())
        return noconv;

    const size_t nfrom = from_end - from;
    const size_t nto   = to_end - to;

    const size_t nconv = nfrom < nto ? nfrom : nto;

    // use memmove() in case ranges overlap
    memmove (to, from, nconv);

    from_next += nconv;
    to_next   += nconv;

    // Table 53, and lwg issue 382: do_out() returns partial
    // if not all source characters could be converted (e.g.,
    // because the destination range is full)
    return nto < nfrom ? partial : ok;
}


/* virtual */ codecvt_base::result
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_in (state_type         &state,
       const extern_type  *from,
       const extern_type  *from_end,
       const extern_type *&from_next,
       intern_type        *to,
       intern_type        *to_end,
       intern_type       *&to_next) const
{
    // verify that both ranges are valid
    _RWSTD_ASSERT (from <= from_end);
    _RWSTD_ASSERT (to   <= to_end);
    _RWSTD_ASSERT ((from && from_end) || (!from && !from_end));
    _RWSTD_ASSERT ((to && to_end) || (!to && !to_end));

    typedef codecvt<char, char, _RWSTD_MBSTATE_T> This;

    // call do_out() above (avoid calling overridden do_out(), if any)
    return This::do_out (state,
                         from, from_end, from_next,
                         to, to_end, to_next);
}


/* virtual */ codecvt_base::result
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_unshift (state_type   &state,
            extern_type  *to,
            extern_type  *to_end,
            extern_type *&to_next) const
{
    // verify that the range is valid
    _RWSTD_ASSERT (to <= to_end);
    _RWSTD_ASSERT ((to && to_end) || (!to && !to_end));

    _RWSTD_UNUSED (to_end);

    // next pointer must always be set before returning, even on error
    to_next = to;

    const int mbstate_valid = _RW::__rw_mbsinit (&state);
    _RWSTD_ASSERT (mbstate_valid);

    return mbstate_valid ? noconv : error;
}


/* virtual */ int 
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_encoding () const _THROWS (())
{
    return 1;   // 1 external char converts to a single internal char
}


/* virtual */ bool
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_always_noconv () const _THROWS (())
{
    return true;   // conversion never necessary
}


// signature follows lwg issue 75
/* virtual */ int
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_length (state_type        &state,
           const extern_type *from,
           const extern_type *from_end,
           size_t             imax) const
{
    // 22.2.1.5.2, p9 - preconditions
    _RWSTD_ASSERT (from <= from_end);

    // verify that the range is valid
    _RWSTD_ASSERT ((from && from_end) || (!from && !from_end));

    const int mbstate_valid = _RW::__rw_mbsinit (&state);
    _RWSTD_ASSERT (mbstate_valid);

    if (!mbstate_valid)
        return 0;

    // 22.2.1.5.2, p10
    const size_t len = from_end - from;
    return int (len < imax ? len : imax);
}


/* virtual */ int
codecvt<char, char, _RWSTD_MBSTATE_T>::
do_max_length () const _THROWS (())
{
    return 1;   // 22.2.1.5.2, p11
}


codecvt_byname<char, char, _RWSTD_MBSTATE_T>::
codecvt_byname (const char *name, size_t ref)
    : codecvt <intern_type, extern_type, state_type> (ref)
{
    _C_set_name (name, _C_namebuf, sizeof _C_namebuf);
}


// outlined to avoid generating a vtable in each translation unit
// that uses the class
/* virtual */ codecvt_byname<char, char, _RWSTD_MBSTATE_T>::
~codecvt_byname ()   // nothrow
{
    // no-op
}


}   // namespace std

#define TARGS_C   <char, char, _RWSTD_MBSTATE_T>

_RWSTD_DEFINE_FACET_FACTORY (static, codecvt, TARGS_C, codecvt);
_RWSTD_SPECIALIZE_USE_FACET (codecvt);

