// -*- C++ -*-
/***************************************************************************
 *
 * codecvt - Declarations for the Standard Library code conversion facet
 *
 ***************************************************************************
 *    
 *  Copyright 2000 Compaq Computer Corporation
 *
 *  COMPAQ Registered in U.S. Patent and Trademark Office.
 *
 *  Confidential computer software. Valid license from Compaq required for
 *  possession, use or copying. Consistent with FAR 12.211 and 12.212,
 *  Commercial Computer Software, Computer Software Documentation, and
 *  Technical Data for Commercial Items are licensed to the U.S. Government
 *  under vendor's standard commercial license.
 *
 ****************************************************************************
 *
 * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
 * ALL RIGHTS RESERVED
 *
 * The software and information contained herein are proprietary to, and
 * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
 * intends to preserve as trade secrets such software and information.
 * This software is furnished pursuant to a written license agreement and
 * may be used, copied, transmitted, and stored only in accordance with
 * the terms of such license and with the inclusion of the above copyright
 * notice.  This software and information or any other copies thereof may
 * not be provided or otherwise made available to any other person.
 *
 * Notwithstanding any other lease or license that may pertain to, or
 * accompany the delivery of, this computer software and information, the
 * rights of the Government regarding its use, reproduction and disclosure
 * are as set forth in Section 52.227-19 of the FARS Computer
 * Software-Restricted Rights clause.
 * 
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7013.
 * Contractor/Manufacturer is Rogue Wave Software, Inc.,
 * P.O. Box 2328, Corvallis, Oregon 97339.
 *
 * This computer software and information is distributed with "restricted
 * rights."  Use, duplication or disclosure is subject to restrictions as
 * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
 * Computer Software-Restricted Rights (April 1985)."  If the Clause at
 * 18-52.227-74 "Rights in Data General" is specified in the contract,
 * then the "Alternate III" clause applies.
 *
 **************************************************************************/

#ifndef __STD_CODECVT__
#define __STD_CODECVT__

#ifndef __STD_RWLOCALE__
#include <rwlocale>
#endif

#ifndef __STD_LIMITS
#include <limits>
#endif

#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __save
#      pragma __environment __cxx_header_defaults
#   endif
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#pragma __extern_prefix __save
#pragma __extern_prefix "CXXL$" 
#endif

#ifndef _RWSTD_NO_NAMESPACE
namespace std {
#endif

class _RWSTDExport codecvt_base {
 public:
  enum result { ok, partial, error, noconv };
};

// ------------------------------------------------------
// Codeset conversion facet -- codecvt<fromT,toT,stateT>.
// ------------------------------------------------------

_RWSTD_TEMPLATE
class _RWSTDExport codecvt<char,char,mbstate_t>:
    public locale::facet, public codecvt_base
{
 public:
  typedef char      extern_type;   
  typedef char      intern_type;
  typedef mbstate_t state_type;

  _EXPLICIT codecvt (size_t refs=0):
      locale::facet(refs,locale::_RWrw_ctype_category) { }

  result out (mbstate_t& state,
      const char* from, const char* from_end, const char*& from_next,
      char* to, char* to_limit, char*& to_next) const
    { return do_out(state,from,from_end,from_next,to,to_limit,to_next); }

  result unshift (mbstate_t& state,
      char* to, char* to_limit, char*& to_next) const
    { return do_unshift(state,to,to_limit,to_next); }

  result in(mbstate_t& state,
      const char* from, const char* from_end, const char*& from_next,
      char* to, char* to_limit, char*& to_next) const
    { return do_in(state,from,from_end,from_next,to,to_limit,to_next); }

  int encoding() const _RWSTD_THROW_SPEC_NULL
    { return do_encoding(); }

  bool always_noconv() const _RWSTD_THROW_SPEC_NULL
    { return do_always_noconv(); }

  int length (const mbstate_t& state, const char* from, const char* end,
      size_t max) const { return do_length(state,from,end,max); }

  int max_length() const _RWSTD_THROW_SPEC_NULL
    { return do_max_length(); }

#ifndef _MSC_VER
  static locale::id _RWSTDExport id;
#else
  static locale::id id;
#endif

  // Rogue Wave extension:
  typedef string internal_string_type;
  typedef string external_string_type;
  internal_string_type in (const external_string_type &s) const { return s; }
  external_string_type out (const internal_string_type &s) const { return s; }

  // Implementation:
  enum { _RWfacet_cat = locale::_RWrw_ctype_category, _RWok_implicit = 1 };

 protected:
  virtual ~codecvt();

  virtual result do_out(mbstate_t& state,
    const char* from, const char* from_end, const char*& from_next,
          char* to, char* to_limit, char*& to_next) const;

  virtual result do_in(mbstate_t& state,
    const char* from, const char* from_end, const char*& from_next,
          char* to, char* to_limit, char*& to_next) const;

  virtual result do_unshift(mbstate_t& state,
          char* to, char* to_limit, char*& to_next) const;

  virtual int do_encoding() const _RWSTD_THROW_SPEC_NULL;

  virtual bool do_always_noconv() const _RWSTD_THROW_SPEC_NULL;

  virtual int do_length (const mbstate_t&, const char* from, const char* end,
      size_t max) const;

  virtual int do_max_length() const _RWSTD_THROW_SPEC_NULL;

 private:
  #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  locale::id &_RWget_id (void) const { return id; }
  #endif
};

#ifndef _RWSTD_NO_WIDE_CHAR
_RWSTD_TEMPLATE
class _RWSTDExport codecvt<wchar_t,char,mbstate_t>:
    public locale::facet, public codecvt_base
{
 public:
  typedef wchar_t intern_type;
  typedef char    extern_type;
  typedef mbstate_t state_type;

  _EXPLICIT codecvt (size_t refs=0):
      locale::facet(refs,locale::_RWrw_ctype_category) { }

  result out (mbstate_t& state,
      const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
      char* to, char* to_limit, char*& to_next) const
    { return do_out(state,from,from_end,from_next,to,to_limit,to_next); }

  result unshift (mbstate_t& state,
      char* to, char* to_limit, char*& to_next) const
    { return do_unshift(state,to,to_limit,to_next); }

  result in (mbstate_t& state,
      const char* from, const char* from_end, const char*& from_next,
      wchar_t* to, wchar_t* to_limit, wchar_t*& to_next) const
    { return do_in(state,from,from_end,from_next,to,to_limit,to_next); }

  int encoding() const _RWSTD_THROW_SPEC_NULL
    { return do_encoding(); }

  bool always_noconv() const _RWSTD_THROW_SPEC_NULL
    { return do_always_noconv(); }

  int length (const mbstate_t& state, const char* from, const char* end,
      size_t max) const
    { return do_length(state,from,end,max); }

  int max_length() const _RWSTD_THROW_SPEC_NULL
    { return do_max_length(); }

#ifndef _MSC_VER
  static locale::id _RWSTDExport id;
#else
  static locale::id id;
#endif

  // Rogue Wave extension:
  typedef string external_string_type;
  typedef wstring internal_string_type;
  internal_string_type in (const external_string_type &s) const;
  external_string_type out (const internal_string_type &s) const;

  // Implementation:
  enum { _RWfacet_cat = locale::_RWrw_ctype_category, _RWok_implicit = 1 };

 protected:
  virtual ~codecvt();

  virtual result do_out (mbstate_t& state,
    const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
          char* to, char* to_limit, char*& to_next) const;

  virtual result do_in (mbstate_t& state,
    const char* from, const char* from_end, const char*& from_next,
          wchar_t* to, wchar_t* to_limit, wchar_t*& to_next) const;

  virtual result do_unshift (mbstate_t& state,
          char* to, char* to_limit, char*& to_next) const;

  virtual bool do_always_noconv() const _RWSTD_THROW_SPEC_NULL;

  virtual int do_encoding() const _RWSTD_THROW_SPEC_NULL;

  virtual int do_length (const mbstate_t&, const char* from,
      const char* end, size_t max) const;

  virtual int do_max_length() const _RWSTD_THROW_SPEC_NULL;

 private:
  #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  locale::id &_RWget_id (void) const { return id; }
  #endif
};

#endif // _RWSTD_NO_WIDE_CHAR

template <class internT, class externT, class stateT>
class codecvt: public locale::facet, public codecvt_base {
 public:
  typedef internT intern_type;
  typedef externT extern_type;
  typedef stateT state_type;

  _EXPLICIT codecvt (size_t refs=0): locale::facet(refs) { }

  result out (stateT& state,
      const internT* from, const internT* from_end, const internT*& from_next,
      externT* to, externT* to_limit, externT*& to_next) const
    { return do_out(state,from,from_end,from_next,to,to_limit,to_next); }

  result unshift (stateT& state,
      externT* to, externT* to_limit, externT*& to_next) const
    { return do_unshift(state,to,to_limit,to_next); }

  result in (stateT& state,
      const externT* from, const externT* from_end, const externT*& from_next,
      internT* to, internT* to_limit, internT*& to_next) const
    { return do_in(state,from,from_end,from_next,to,to_limit,to_next); }

  bool always_noconv() const _RWSTD_THROW_SPEC_NULL
    { return do_always_noconv(); }

  int encoding() const _RWSTD_THROW_SPEC_NULL
    { return do_encoding(); }

  int length (const stateT& state, const externT* from, const externT* end,
      size_t max) const
    { return do_length(state,from,end,max); }

  int max_length() const _RWSTD_THROW_SPEC_NULL
    { return do_max_length(); }

  static locale::id id;

  // Rogue Wave extension:
  typedef basic_string<externT,char_traits<externT>,allocator<externT> >
      external_string_type;
  typedef basic_string<internT,char_traits<internT>,allocator<internT> >
      internal_string_type;
  internal_string_type in (const external_string_type &s) const;
  external_string_type out (const internal_string_type &s) const;

  // Implementation:
  enum { _RWfacet_cat = locale::_RWrw_ctype_category, _RWok_implicit = 1 };

 protected:
  virtual ~codecvt();

  virtual result do_out (stateT& state,
    const internT* from, const internT* from_end, const internT*& from_next,
          externT* to, externT* to_limit, externT*& to_next) const;

  virtual result do_in (stateT& state,
    const externT* from, const externT* from_end, const externT*& from_next,
          internT* to, internT* to_limit, internT*& to_next) const;

  virtual result do_unshift (stateT& state,
          externT* to, externT* to_limit, externT*& to_next) const;

  virtual int do_encoding() const _RWSTD_THROW_SPEC_NULL;

  virtual bool do_always_noconv() const _RWSTD_THROW_SPEC_NULL;

  virtual int do_length (const stateT&, const externT* from, const externT* end,
      size_t max) const;

  virtual int do_max_length() const _RWSTD_THROW_SPEC_NULL;

 private:
  #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  locale::id &_RWget_id (void) const { return id; }
  #endif
};

template <class internT, class externT, class stateT>
class codecvt_byname: public codecvt<internT,externT,stateT> {
 public:
  
  typedef internT intern_type;
  typedef externT extern_type;
  typedef stateT state_type; 

  _EXPLICIT codecvt_byname (const char*, size_t refs=0);

 protected:
  virtual ~codecvt_byname();

  virtual codecvt_base::result do_out (stateT&, 
          const internT*, const internT*, const internT*&,
          externT*, externT*, externT*&) const;

  virtual codecvt_base::result do_in (stateT&,
    const externT*, const externT*, const externT*&,
          internT*, internT*, internT*&) const;

  virtual codecvt_base::result do_unshift (stateT&,
          externT*, externT*, externT*&) const;

  virtual int do_encoding () const _RWSTD_THROW_SPEC_NULL;

  virtual bool do_always_noconv () const _RWSTD_THROW_SPEC_NULL;

// Virtual member functions inherited from codecvt<,,>:
// virtual int do_length (const stateT &state, const externT* from,
//     const externT* end, size_t max) const;
// virtual int do_max_length() const _RWSTD_THROW_SPEC_NULL;
};

#if defined(__DECCXX) && !defined(__DECFIXCXXL646)

#ifndef _RWSTD_NO_WIDE_CHAR
template <>
class _RWSTDExport codecvt_byname<wchar_t,char,mbstate_t> : public codecvt<wchar_t,char,mbstate_t> {

 private:
  _LocaleManager* _LocaleManagerPtr;

 public:
  
  _EXPLICIT codecvt_byname (const char*, size_t refs=0);

 protected:
  virtual ~codecvt_byname();

  virtual codecvt_base::result do_out(mbstate_t&, 
          const wchar_t*, const wchar_t*, const wchar_t*&,
          char*, char*, char*&) const;

  virtual codecvt_base::result do_in(mbstate_t&,
          const char*, const char*, const char*&,
          wchar_t*, wchar_t*, wchar_t*&) const;

  virtual bool do_always_noconv () const _RWSTD_THROW_SPEC_NULL;

  virtual int do_encoding() const _RWSTD_THROW_SPEC_NULL;

  virtual int do_length (const mbstate_t&, const char*,
          const char*, size_t) const;

  virtual int do_max_length() const _RWSTD_THROW_SPEC_NULL;
};

#endif // __RWSTD_NO_WIDE_CHAR

#endif

#ifndef _RWSTD_NO_NAMESPACE
}
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#   pragma __extern_prefix __restore
#endif

#ifdef _RWSTD_COMPILE_INSTANTIATE
#include <codecvt.cc>
#endif

#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __restore
#   endif
#endif

#endif // __STD_CODECVT__

