// Locale support (codecvt) -*- C++ -*-

// Copyright (C) 2000-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

//
// ISO C++ 14882: 22.2.1.5 Template class codecvt
//

// Written by Benjamin Kosnik <bkoz@redhat.com>

/** @file ext/codecvt_specializations.h
 *  This file is a GNU extension to the Standard C++ Library.
 */

#ifndef _EXT_CODECVT_SPECIALIZATIONS_H
#define _EXT_CODECVT_SPECIALIZATIONS_H 1

#include <bits/c++config.h>
#include <locale>
#include <iconv.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /// Extension to use iconv for dealing with character encodings.
  // This includes conversions and comparisons between various character
  // sets.  This object encapsulates data that may need to be shared between
  // char_traits, codecvt and ctype.
  class encoding_state
  {
  public:
    // Types: 
    // NB: A conversion descriptor subsumes and enhances the
    // functionality of a simple state type such as mbstate_t.
    typedef iconv_t	descriptor_type;
    
  protected:
    // Name of internal character set encoding.
    std::string	       	_M_int_enc;

    // Name of external character set encoding.
    std::string  	_M_ext_enc;

    // Conversion descriptor between external encoding to internal encoding.
    descriptor_type	_M_in_desc;

    // Conversion descriptor between internal encoding to external encoding.
    descriptor_type	_M_out_desc;

    // The byte-order marker for the external encoding, if necessary.
    int			_M_ext_bom;

    // The byte-order marker for the internal encoding, if necessary.
    int			_M_int_bom;

    // Number of external bytes needed to construct one complete
    // character in the internal encoding.
    // NB: -1 indicates variable, or stateful, encodings.
    int 		_M_bytes;

  public:
    explicit 
    encoding_state() 
    : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0), _M_bytes(0)
    { }

    explicit 
    encoding_state(const char* __int, const char* __ext, 
		   int __ibom = 0, int __ebom = 0, int __bytes = 1)
    : _M_int_enc(__int), _M_ext_enc(__ext), _M_in_desc(0), _M_out_desc(0), 
      _M_ext_bom(__ebom), _M_int_bom(__ibom), _M_bytes(__bytes)
    { init(); }

    // 21.1.2 traits typedefs
    // p4
    // typedef STATE_T state_type
    // requires: state_type shall meet the requirements of
    // CopyConstructible types (20.1.3)
    // NB: This does not preserve the actual state of the conversion
    // descriptor member, but it does duplicate the encoding
    // information.
    encoding_state(const encoding_state& __obj) : _M_in_desc(0), _M_out_desc(0)
    { construct(__obj); }

    // Need assignment operator as well.
    encoding_state&
    operator=(const encoding_state& __obj)
    {
      construct(__obj);
      return *this;
    }

    ~encoding_state()
    { destroy(); } 

    bool
    good() const throw()
    { 
      const descriptor_type __err = (iconv_t)(-1);
      bool __test = _M_in_desc && _M_in_desc != __err; 
      __test &=  _M_out_desc && _M_out_desc != __err;
      return __test;
    }
    
    int
    character_ratio() const
    { return _M_bytes; }

    const std::string
    internal_encoding() const
    { return _M_int_enc; }

    int 
    internal_bom() const
    { return _M_int_bom; }

    const std::string
    external_encoding() const
    { return _M_ext_enc; }

    int 
    external_bom() const
    { return _M_ext_bom; }

    const descriptor_type&
    in_descriptor() const
    { return _M_in_desc; }

    const descriptor_type&
    out_descriptor() const
    { return _M_out_desc; }

  protected:
    void
    init()
    {
      const descriptor_type __err = (iconv_t)(-1);
      const bool __have_encodings = _M_int_enc.size() && _M_ext_enc.size();
      if (!_M_in_desc && __have_encodings)
	{
	  _M_in_desc = iconv_open(_M_int_enc.c_str(), _M_ext_enc.c_str());
	  if (_M_in_desc == __err)
	    std::__throw_runtime_error(__N("encoding_state::_M_init "
				    "creating iconv input descriptor failed"));
	}
      if (!_M_out_desc && __have_encodings)
	{
	  _M_out_desc = iconv_open(_M_ext_enc.c_str(), _M_int_enc.c_str());
	  if (_M_out_desc == __err)
	    std::__throw_runtime_error(__N("encoding_state::_M_init "
				  "creating iconv output descriptor failed"));
	}
    }

    void
    construct(const encoding_state& __obj)
    {
      destroy();
      _M_int_enc = __obj._M_int_enc;
      _M_ext_enc = __obj._M_ext_enc;
      _M_ext_bom = __obj._M_ext_bom;
      _M_int_bom = __obj._M_int_bom;
      _M_bytes = __obj._M_bytes;
      init();
    }

    void
    destroy() throw()
    {
      const descriptor_type __err = (iconv_t)(-1);
      if (_M_in_desc && _M_in_desc != __err) 
	{
	  iconv_close(_M_in_desc);
	  _M_in_desc = 0;
	}
      if (_M_out_desc && _M_out_desc != __err) 
	{
	  iconv_close(_M_out_desc);
	  _M_out_desc = 0;
	}
    }
  };

  /// encoding_char_traits
  // Custom traits type with encoding_state for the state type, and the
  // associated fpos<encoding_state> for the position type, all other
  // bits equivalent to the required char_traits instantiations.
  template<typename _CharT>
    struct encoding_char_traits : public std::char_traits<_CharT>
    {
      typedef encoding_state				state_type;
      typedef typename std::fpos<state_type>		pos_type;
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace


namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  using __gnu_cxx::encoding_state;

  /// codecvt<InternT, _ExternT, encoding_state> specialization.
  // This partial specialization takes advantage of iconv to provide
  // code conversions between a large number of character encodings.
  template<typename _InternT, typename _ExternT>
    class codecvt<_InternT, _ExternT, encoding_state>
    : public __codecvt_abstract_base<_InternT, _ExternT, encoding_state>
    {
    public:      
      // Types:
      typedef codecvt_base::result			result;
      typedef _InternT 					intern_type;
      typedef _ExternT 					extern_type;
      typedef __gnu_cxx::encoding_state 		state_type;
      typedef state_type::descriptor_type 		descriptor_type;

      // Data Members:
      static locale::id 		id;

      explicit 
      codecvt(size_t __refs = 0)
      : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
      { }

      explicit 
      codecvt(state_type& __enc, size_t __refs = 0)
      : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
      { }

     protected:
      virtual 
      ~codecvt() { }

      virtual result
      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;

      virtual result
      do_unshift(state_type& __state, extern_type* __to, 
		 extern_type* __to_end, extern_type*& __to_next) const;

      virtual result
      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;

      virtual int 
      do_encoding() const throw();

      virtual bool 
      do_always_noconv() const throw();

      virtual int 
      do_length(state_type&, const extern_type* __from, 
		const extern_type* __end, size_t __max) const;

      virtual int 
      do_max_length() const throw();
    };

  template<typename _InternT, typename _ExternT>
    locale::id 
    codecvt<_InternT, _ExternT, encoding_state>::id;

  // This adaptor works around the signature problems of the second
  // argument to iconv():  SUSv2 and others use 'const char**', but glibc 2.2
  // uses 'char**', which matches the POSIX 1003.1-2001 standard.
  // Using this adaptor, g++ will do the work for us.
  template<typename _Tp>
    inline size_t
    __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*),
                    iconv_t __cd, char** __inbuf, size_t* __inbytes,
                    char** __outbuf, size_t* __outbytes)
    { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); }

  template<typename _InternT, typename _ExternT>
    codecvt_base::result
    codecvt<_InternT, _ExternT, encoding_state>::
    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
    {
      result __ret = codecvt_base::error;
      if (__state.good())
	{
	  const descriptor_type& __desc = __state.out_descriptor();
	  const size_t __fmultiple = sizeof(intern_type);
	  size_t __fbytes = __fmultiple * (__from_end - __from);
	  const size_t __tmultiple = sizeof(extern_type);
	  size_t __tbytes = __tmultiple * (__to_end - __to); 
	  
	  // Argument list for iconv specifies a byte sequence. Thus,
	  // all to/from arrays must be brutally casted to char*.
	  char* __cto = reinterpret_cast<char*>(__to);
	  char* __cfrom;
	  size_t __conv;

	  // Some encodings need a byte order marker as the first item
	  // in the byte stream, to designate endian-ness. The default
	  // value for the byte order marker is NULL, so if this is
	  // the case, it's not necessary and we can just go on our
	  // merry way.
	  int __int_bom = __state.internal_bom();
	  if (__int_bom)
	    {	  
	      size_t __size = __from_end - __from;
	      intern_type* __cfixed = static_cast<intern_type*>
		(__builtin_alloca(sizeof(intern_type) * (__size + 1)));
	      __cfixed[0] = static_cast<intern_type>(__int_bom);
	      char_traits<intern_type>::copy(__cfixed + 1, __from, __size);
	      __cfrom = reinterpret_cast<char*>(__cfixed);
	      __conv = __iconv_adaptor(iconv, __desc, &__cfrom,
                                        &__fbytes, &__cto, &__tbytes); 
	    }
	  else
	    {
	      intern_type* __cfixed = const_cast<intern_type*>(__from);
	      __cfrom = reinterpret_cast<char*>(__cfixed);
	      __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, 
				       &__cto, &__tbytes); 
	    }

	  if (__conv != size_t(-1))
	    {
	      __from_next = reinterpret_cast<const intern_type*>(__cfrom);
	      __to_next = reinterpret_cast<extern_type*>(__cto);
	      __ret = codecvt_base::ok;
	    }
	  else 
	    {
	      if (__fbytes < __fmultiple * (__from_end - __from))
		{
		  __from_next = reinterpret_cast<const intern_type*>(__cfrom);
		  __to_next = reinterpret_cast<extern_type*>(__cto);
		  __ret = codecvt_base::partial;
		}
	      else
		__ret = codecvt_base::error;
	    }
	}
      return __ret; 
    }

  template<typename _InternT, typename _ExternT>
    codecvt_base::result
    codecvt<_InternT, _ExternT, encoding_state>::
    do_unshift(state_type& __state, extern_type* __to, 
	       extern_type* __to_end, extern_type*& __to_next) const
    {
      result __ret = codecvt_base::error;
      if (__state.good())
	{
	  const descriptor_type& __desc = __state.in_descriptor();
	  const size_t __tmultiple = sizeof(intern_type);
	  size_t __tlen = __tmultiple * (__to_end - __to); 
	  
	  // Argument list for iconv specifies a byte sequence. Thus,
	  // all to/from arrays must be brutally casted to char*.
	  char* __cto = reinterpret_cast<char*>(__to);
	  size_t __conv = __iconv_adaptor(iconv,__desc, 0, 0,
                                          &__cto, &__tlen); 
	  
	  if (__conv != size_t(-1))
	    {
	      __to_next = reinterpret_cast<extern_type*>(__cto);
	      if (__tlen == __tmultiple * (__to_end - __to))
		__ret = codecvt_base::noconv;
	      else if (__tlen == 0)
		__ret = codecvt_base::ok;
	      else
		__ret = codecvt_base::partial;
	    }
	  else 
	    __ret = codecvt_base::error;
	}
      return __ret; 
    }
   
  template<typename _InternT, typename _ExternT>
    codecvt_base::result
    codecvt<_InternT, _ExternT, encoding_state>::
    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
    { 
      result __ret = codecvt_base::error;
      if (__state.good())
	{
	  const descriptor_type& __desc = __state.in_descriptor();
	  const size_t __fmultiple = sizeof(extern_type);
	  size_t __flen = __fmultiple * (__from_end - __from);
	  const size_t __tmultiple = sizeof(intern_type);
	  size_t __tlen = __tmultiple * (__to_end - __to); 
	  
	  // Argument list for iconv specifies a byte sequence. Thus,
	  // all to/from arrays must be brutally casted to char*.
	  char* __cto = reinterpret_cast<char*>(__to);
	  char* __cfrom;
	  size_t __conv;

	  // Some encodings need a byte order marker as the first item
	  // in the byte stream, to designate endian-ness. The default
	  // value for the byte order marker is NULL, so if this is
	  // the case, it's not necessary and we can just go on our
	  // merry way.
	  int __ext_bom = __state.external_bom();
	  if (__ext_bom)
	    {	  
	      size_t __size = __from_end - __from;
	      extern_type* __cfixed =  static_cast<extern_type*>
		(__builtin_alloca(sizeof(extern_type) * (__size + 1)));
	      __cfixed[0] = static_cast<extern_type>(__ext_bom);
	      char_traits<extern_type>::copy(__cfixed + 1, __from, __size);
	      __cfrom = reinterpret_cast<char*>(__cfixed);
	      __conv = __iconv_adaptor(iconv, __desc, &__cfrom,
                                       &__flen, &__cto, &__tlen); 
	    }
	  else
	    {
	      extern_type* __cfixed = const_cast<extern_type*>(__from);
	      __cfrom = reinterpret_cast<char*>(__cfixed);
	      __conv = __iconv_adaptor(iconv, __desc, &__cfrom,
                                       &__flen, &__cto, &__tlen); 
	    }

	  
	  if (__conv != size_t(-1))
	    {
	      __from_next = reinterpret_cast<const extern_type*>(__cfrom);
	      __to_next = reinterpret_cast<intern_type*>(__cto);
	      __ret = codecvt_base::ok;
	    }
	  else 
	    {
	      if (__flen < static_cast<size_t>(__from_end - __from))
		{
		  __from_next = reinterpret_cast<const extern_type*>(__cfrom);
		  __to_next = reinterpret_cast<intern_type*>(__cto);
		  __ret = codecvt_base::partial;
		}
	      else
		__ret = codecvt_base::error;
	    }
	}
      return __ret; 
    }
  
  template<typename _InternT, typename _ExternT>
    int 
    codecvt<_InternT, _ExternT, encoding_state>::
    do_encoding() const throw()
    {
      int __ret = 0;
      if (sizeof(_ExternT) <= sizeof(_InternT))
	__ret = sizeof(_InternT) / sizeof(_ExternT);
      return __ret; 
    }
  
  template<typename _InternT, typename _ExternT>
    bool 
    codecvt<_InternT, _ExternT, encoding_state>::
    do_always_noconv() const throw()
    { return false; }
  
  template<typename _InternT, typename _ExternT>
    int 
    codecvt<_InternT, _ExternT, encoding_state>::
    do_length(state_type&, const extern_type* __from, 
	      const extern_type* __end, size_t __max) const
    { return std::min(__max, static_cast<size_t>(__end - __from)); }

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 74.  Garbled text for codecvt::do_max_length
  template<typename _InternT, typename _ExternT>
    int 
    codecvt<_InternT, _ExternT, encoding_state>::
    do_max_length() const throw()
    { return 1; }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif
