Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Locale support (codecvt) -*- C++ -*-
  2.  
  3. // Copyright (C) 2000, 2001 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 2, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. //
  31. // ISO C++ 14882: 22.2.1.5 Template class codecvt
  32. //
  33.  
  34. // Warning: this file is not meant for user inclusion.  Use <locale>.
  35.  
  36. // Written by Benjamin Kosnik <bkoz@cygnus.com>
  37.  
  38. #ifndef _CPP_BITS_CODECVT_H
  39. #define _CPP_BITS_CODECVT_H     1
  40.  
  41. #pragma GCC system_header
  42.  
  43.   // XXX
  44.   // __enc_traits may need to move up the locale header hierarchy,
  45.   // depending on if ctype ends up using it.
  46.  
  47. #ifdef _GLIBCPP_USE_WCHAR_T
  48.   // Extensions to use icov for dealing with character encodings,
  49.   // including conversions and comparisons between various character
  50.   // sets.  This object encapsulates data that may need to be shared between
  51.   // char_traits, codecvt and ctype.
  52.  
  53. #if _GLIBCPP_USE_SHADOW_HEADERS
  54.   using _C_legacy::CODESET;
  55. #endif
  56.  
  57.   class __enc_traits
  58.   {
  59.   public:
  60.     // Types:
  61.     // NB: A conversion descriptor subsumes and enhances the
  62.     // functionality of a simple state type such as mbstate_t.
  63.     typedef iconv_t     __desc_type;
  64.    
  65.   protected:
  66.     // Data Members:
  67.     // Max size of charset encoding name
  68.     static const int    _S_max_size = 32;
  69.     // Name of internal character set encoding.
  70.     char                _M_int_enc[_S_max_size];
  71.     // Name of external character set encoding.
  72.     char                _M_ext_enc[_S_max_size];
  73.  
  74.     // Conversion descriptor between external encoding to internal encoding.
  75.     __desc_type         _M_in_desc;
  76.     // Conversion descriptor between internal encoding to external encoding.
  77.     __desc_type         _M_out_desc;
  78.  
  79.     // Details the byte-order marker for the external encoding, if necessary.
  80.     int                 _M_ext_bom;
  81.  
  82.     // Details the byte-order marker for the internal encoding, if necessary.
  83.     int                 _M_int_bom;
  84.  
  85.   public:
  86.     __enc_traits()
  87.     : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0)
  88.     {
  89.       // __intc_end = whatever we are using internally, which is
  90.       // UCS4 (linux)
  91.       // UCS2 == UNICODE  (microsoft, java, aix, whatever...)
  92.       // XXX Currently don't know how to get this data from target system...
  93.       strcpy(_M_int_enc, "UCS4");
  94.  
  95.       // __extc_end = external codeset in current locale
  96.       strcpy(_M_ext_enc, nl_langinfo(CODESET));
  97.     }
  98.  
  99.     __enc_traits(const char* __int, const char* __ext, int __ibom = 0,
  100.                  int __ebom = 0)
  101.     : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0)
  102.     {
  103.       strncpy(_M_int_enc, __int, _S_max_size);
  104.       strncpy(_M_ext_enc, __ext, _S_max_size);
  105.     }
  106.  
  107.     // 21.1.2 traits typedefs
  108.     // p4
  109.     // typedef STATE_T state_type
  110.     // requires: state_type shall meet the requirements of
  111.     // CopyConstructible types (20.1.3)
  112.     __enc_traits(const __enc_traits& __obj)
  113.     {
  114.       strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size);
  115.       strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size);
  116.       _M_ext_bom = __obj._M_ext_bom;
  117.       _M_int_bom = __obj._M_int_bom;
  118.     }
  119.  
  120.     ~__enc_traits()
  121.     {
  122.       iconv_close(_M_in_desc);
  123.       iconv_close(_M_out_desc);
  124.     }
  125.  
  126.     // Initializes
  127.     void
  128.     _M_init()
  129.     {
  130.       _M_in_desc = iconv_open(_M_int_enc, _M_ext_enc);
  131.       _M_out_desc = iconv_open(_M_ext_enc, _M_int_enc);
  132.       if (_M_out_desc == iconv_t(-1) || _M_in_desc == iconv_t(-1))
  133.         {
  134.           // XXX Extended error checking.
  135.         }
  136.     }
  137.  
  138.     bool
  139.     _M_good()
  140.     {
  141.       return _M_out_desc && _M_in_desc
  142.              && _M_out_desc != iconv_t(-1) && _M_in_desc != iconv_t(-1);
  143.     }
  144.  
  145.     const __desc_type*
  146.     _M_get_in_descriptor()
  147.     { return &_M_in_desc; }
  148.  
  149.     const __desc_type*
  150.     _M_get_out_descriptor()
  151.     { return &_M_out_desc; }
  152.  
  153.    const char*
  154.     _M_get_internal_enc()
  155.     { return _M_int_enc; }
  156.  
  157.     const char*
  158.     _M_get_external_enc()
  159.     { return _M_ext_enc; }
  160.  
  161.     int
  162.     _M_get_external_bom()
  163.     { return _M_ext_bom; }
  164.  
  165.     int
  166.     _M_get_internal_bom()
  167.     { return _M_int_bom; }
  168.   };
  169. #endif //_GLIBCPP_USE_WCHAR_T
  170.  
  171.  
  172.   //  22.2.1.5  Template class codecvt
  173.   class codecvt_base
  174.   {
  175.   public:
  176.     enum result
  177.     {
  178.       ok,
  179.       partial,
  180.       error,
  181.       noconv
  182.     };
  183.   };
  184.  
  185.   // Template class __codecvt_abstract_base
  186.   // NB: An abstract base class that fills in the public inlines, so
  187.   // that the specializations don't have to re-copy the public
  188.   // interface.
  189.   template<typename _InternT, typename _ExternT, typename _StateT>
  190.     class __codecvt_abstract_base
  191.     : public locale::facet, public codecvt_base
  192.     {
  193.     public:
  194.       // Types:
  195.       typedef codecvt_base::result                      result;
  196.       typedef _InternT                                  intern_type;
  197.       typedef _ExternT                                  extern_type;
  198.       typedef _StateT                                   state_type;
  199.      
  200.       // 22.2.1.5.1 codecvt members
  201.       result
  202.       out(state_type& __state, const intern_type* __from,
  203.           const intern_type* __from_end, const intern_type*& __from_next,
  204.           extern_type* __to, extern_type* __to_end,
  205.           extern_type*& __to_next) const
  206.       {
  207.         return this->do_out(__state, __from, __from_end, __from_next,
  208.                             __to, __to_end, __to_next);
  209.       }
  210.  
  211.       result
  212.       unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
  213.               extern_type*& __to_next) const
  214.       { return this->do_unshift(__state, __to,__to_end,__to_next); }
  215.  
  216.       result
  217.       in(state_type& __state, const extern_type* __from,
  218.          const extern_type* __from_end, const extern_type*& __from_next,
  219.          intern_type* __to, intern_type* __to_end,
  220.          intern_type*& __to_next) const
  221.       {
  222.         return this->do_in(__state, __from, __from_end, __from_next,
  223.                            __to, __to_end, __to_next);
  224.       }
  225.  
  226.       int
  227.       encoding() const throw()
  228.       { return this->do_encoding(); }
  229.  
  230.       bool
  231.       always_noconv() const throw()
  232.       { return this->do_always_noconv(); }
  233.  
  234.       int
  235.       length(const state_type& __state, const extern_type* __from,
  236.              const extern_type* __end, size_t __max) const
  237.       { return this->do_length(__state, __from, __end, __max); }
  238.  
  239.       int
  240.       max_length() const throw()
  241.       { return this->do_max_length(); }
  242.  
  243.     protected:
  244.       explicit
  245.       __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
  246.  
  247.       virtual
  248.       ~__codecvt_abstract_base() { }
  249.  
  250.       virtual result
  251.       do_out(state_type& __state, const intern_type* __from,
  252.              const intern_type* __from_end, const intern_type*& __from_next,
  253.              extern_type* __to, extern_type* __to_end,
  254.              extern_type*& __to_next) const = 0;
  255.  
  256.       virtual result
  257.       do_unshift(state_type& __state, extern_type* __to,
  258.                  extern_type* __to_end, extern_type*& __to_next) const = 0;
  259.      
  260.       virtual result
  261.       do_in(state_type& __state, const extern_type* __from,
  262.             const extern_type* __from_end, const extern_type*& __from_next,
  263.             intern_type* __to, intern_type* __to_end,
  264.             intern_type*& __to_next) const = 0;
  265.      
  266.       virtual int
  267.       do_encoding() const throw() = 0;
  268.  
  269.       virtual bool
  270.       do_always_noconv() const throw() = 0;
  271.  
  272.       virtual int
  273.       do_length(const state_type&, const extern_type* __from,
  274.                 const extern_type* __end, size_t __max) const = 0;
  275.  
  276.       virtual int
  277.       do_max_length() const throw() = 0;
  278.     };
  279.  
  280.   // 22.2.1.5 Template class codecvt
  281.   // NB: Generic, mostly useless implementation.
  282.   template<typename _InternT, typename _ExternT, typename _StateT>
  283.     class codecvt
  284.     : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
  285.     {
  286.     public:      
  287.       // Types:
  288.       typedef codecvt_base::result                      result;
  289.       typedef _InternT intern_type;
  290.       typedef _ExternT extern_type;
  291.       typedef _StateT  state_type;
  292.  
  293.       // Data Members:
  294.       static locale::id id;
  295.  
  296.       explicit
  297.       codecvt(size_t __refs = 0)
  298.       : __codecvt_abstract_base<_InternT,_ExternT,_StateT> (__refs) { }
  299.  
  300.     protected:
  301.       virtual
  302.       ~codecvt() { }
  303.     };
  304.  
  305.   template<typename _InternT, typename _ExternT, typename _StateT>
  306.     locale::id codecvt<_InternT, _ExternT, _StateT>::id;
  307.  
  308. #ifdef _GLIBCPP_USE_WCHAR_T
  309.   // partial specialization
  310.   // This specialization takes advantage of iconv to provide code
  311.   // conversions between a large number of character encodings.
  312.   template<typename _InternT, typename _ExternT>
  313.     class codecvt<_InternT, _ExternT, __enc_traits>
  314.     : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits>
  315.     {
  316.     public:      
  317.       // Types:
  318.       typedef codecvt_base::result                      result;
  319.       typedef _InternT                                  intern_type;
  320.       typedef _ExternT                                  extern_type;
  321.       typedef __enc_traits                              state_type;
  322.       typedef __enc_traits::__desc_type                 __desc_type;
  323.       typedef __enc_traits                              __enc_type;
  324.  
  325.       // Data Members:
  326.       static locale::id                 id;
  327.  
  328.       explicit
  329.       codecvt(size_t __refs = 0)
  330.       : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
  331.       { }
  332.  
  333.       explicit
  334.       codecvt(__enc_type* __enc, size_t __refs = 0)
  335.       : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
  336.       { }
  337.  
  338.     protected:
  339.       virtual
  340.       ~codecvt() { }
  341.  
  342.       virtual result
  343.       do_out(state_type& __state, const intern_type* __from,
  344.              const intern_type* __from_end, const intern_type*& __from_next,
  345.              extern_type* __to, extern_type* __to_end,
  346.              extern_type*& __to_next) const;
  347.  
  348.       virtual result
  349.       do_unshift(state_type& __state, extern_type* __to,
  350.                  extern_type* __to_end, extern_type*& __to_next) const;
  351.  
  352.       virtual result
  353.       do_in(state_type& __state, const extern_type* __from,
  354.             const extern_type* __from_end, const extern_type*& __from_next,
  355.             intern_type* __to, intern_type* __to_end,
  356.             intern_type*& __to_next) const;
  357.  
  358.       virtual int
  359.       do_encoding() const throw();
  360.  
  361.       virtual bool
  362.       do_always_noconv() const throw();
  363.  
  364.       virtual int
  365.       do_length(const state_type&, const extern_type* __from,
  366.                 const extern_type* __end, size_t __max) const;
  367.  
  368.       virtual int
  369.       do_max_length() const throw();
  370.     };
  371.  
  372.   template<typename _InternT, typename _ExternT>
  373.     locale::id
  374.     codecvt<_InternT, _ExternT, __enc_traits>::id;
  375.  
  376.   // This adaptor works around the signature problems of the second
  377.   // argument to iconv():  SUSv2 and others use 'const char**', but glibc 2.2
  378.   // uses 'char**', which is what the standard is (apparently) due to use
  379.   // in the future.  Using this adaptor, g++ will do the work for us.
  380.   template<typename _T>
  381.     inline size_t
  382.     __iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t*, char**, size_t*),
  383.                     iconv_t cd, char** inbuf, size_t* inbytesleft,
  384.                     char** outbuf, size_t* outbytesleft)
  385.     {
  386.       return iconv_func(cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft);
  387.     }
  388.  
  389.   template<typename _InternT, typename _ExternT>
  390.     codecvt_base::result
  391.     codecvt<_InternT, _ExternT, __enc_traits>::
  392.     do_out(state_type& __state, const intern_type* __from,
  393.            const intern_type* __from_end, const intern_type*& __from_next,
  394.            extern_type* __to, extern_type* __to_end,
  395.            extern_type*& __to_next) const
  396.     {
  397.       result __ret = error;
  398.       if (__state._M_good())
  399.         {
  400.           typedef state_type::__desc_type       __desc_type;
  401.           const __desc_type* __desc = __state._M_get_out_descriptor();
  402.           const size_t __fmultiple = sizeof(intern_type) / sizeof(char);
  403.           size_t __flen = __fmultiple * (__from_end - __from);
  404.           const size_t __tmultiple = sizeof(extern_type) / sizeof(char);
  405.           size_t __tlen = __tmultiple * (__to_end - __to);
  406.          
  407.           // Argument list for iconv specifies a byte sequence. Thus,
  408.           // all to/from arrays must be brutally casted to char*.
  409.           char* __cto = reinterpret_cast<char*>(__to);
  410.           char* __cfrom;
  411.           size_t __conv;
  412.  
  413.           // Some encodings need a byte order marker as the first item
  414.           // in the byte stream, to designate endian-ness. The default
  415.           // value for the byte order marker is NULL, so if this is
  416.           // the case, it's not necessary and we can just go on our
  417.           // merry way.
  418.           int __int_bom = __state._M_get_internal_bom();
  419.           if (__int_bom)
  420.             {    
  421.               size_t __size = __from_end - __from;
  422.               intern_type* __cfixed = static_cast<intern_type*>(__builtin_alloca(sizeof(intern_type) * (__size + 1)));
  423.               __cfixed[0] = static_cast<intern_type>(__int_bom);
  424.               char_traits<intern_type>::copy(__cfixed + 1, __from, __size);
  425.               __cfrom = reinterpret_cast<char*>(__cfixed);
  426.               __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
  427.                                         &__flen, &__cto, &__tlen);
  428.             }
  429.           else
  430.             {
  431.               intern_type* __cfixed = const_cast<intern_type*>(__from);
  432.               __cfrom = reinterpret_cast<char*>(__cfixed);
  433.               __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
  434.                                        &__flen, &__cto, &__tlen);
  435.             }
  436.  
  437.           if (__conv != size_t(-1))
  438.             {
  439.               __from_next = reinterpret_cast<const intern_type*>(__cfrom);
  440.               __to_next = reinterpret_cast<extern_type*>(__cto);
  441.               __ret = ok;
  442.             }
  443.           else
  444.             {
  445.               if (__flen < static_cast<size_t>(__from_end - __from))
  446.                 {
  447.                   __from_next = reinterpret_cast<const intern_type*>(__cfrom);
  448.                   __to_next = reinterpret_cast<extern_type*>(__cto);
  449.                   __ret = partial;
  450.                 }
  451.               else
  452.                 __ret = error;
  453.             }
  454.         }
  455.       return __ret;
  456.     }
  457.  
  458.   template<typename _InternT, typename _ExternT>
  459.     codecvt_base::result
  460.     codecvt<_InternT, _ExternT, __enc_traits>::
  461.     do_unshift(state_type& __state, extern_type* __to,
  462.                extern_type* __to_end, extern_type*& __to_next) const
  463.     {
  464.       result __ret = error;
  465.       if (__state._M_good())
  466.         {
  467.           typedef state_type::__desc_type       __desc_type;
  468.           const __desc_type* __desc = __state._M_get_in_descriptor();
  469.           const size_t __tmultiple = sizeof(intern_type) / sizeof(char);
  470.           size_t __tlen = __tmultiple * (__to_end - __to);
  471.          
  472.           // Argument list for iconv specifies a byte sequence. Thus,
  473.           // all to/from arrays must be brutally casted to char*.
  474.           char* __cto = reinterpret_cast<char*>(__to);
  475.           size_t __conv = __iconv_adaptor(iconv,*__desc, NULL, NULL,
  476.                                           &__cto, &__tlen);
  477.          
  478.           if (__conv != size_t(-1))
  479.             {
  480.               __to_next = reinterpret_cast<extern_type*>(__cto);
  481.               if (__tlen == __tmultiple * (__to_end - __to))
  482.                 __ret = noconv;
  483.               else if (__tlen == 0)
  484.                 __ret = ok;
  485.               else
  486.                 __ret = partial;
  487.             }
  488.           else
  489.             __ret = error;
  490.         }
  491.       return __ret;
  492.     }
  493.    
  494.   template<typename _InternT, typename _ExternT>
  495.     codecvt_base::result
  496.     codecvt<_InternT, _ExternT, __enc_traits>::
  497.     do_in(state_type& __state, const extern_type* __from,
  498.           const extern_type* __from_end, const extern_type*& __from_next,
  499.           intern_type* __to, intern_type* __to_end,
  500.           intern_type*& __to_next) const
  501.     {
  502.       result __ret = error;
  503.       if (__state._M_good())
  504.         {
  505.           typedef state_type::__desc_type       __desc_type;
  506.           const __desc_type* __desc = __state._M_get_in_descriptor();
  507.           const size_t __fmultiple = sizeof(extern_type) / sizeof(char);
  508.           size_t __flen = __fmultiple * (__from_end - __from);
  509.           const size_t __tmultiple = sizeof(intern_type) / sizeof(char);
  510.           size_t __tlen = __tmultiple * (__to_end - __to);
  511.          
  512.           // Argument list for iconv specifies a byte sequence. Thus,
  513.           // all to/from arrays must be brutally casted to char*.
  514.           char* __cto = reinterpret_cast<char*>(__to);
  515.           char* __cfrom;
  516.           size_t __conv;
  517.  
  518.           // Some encodings need a byte order marker as the first item
  519.           // in the byte stream, to designate endian-ness. The default
  520.           // value for the byte order marker is NULL, so if this is
  521.           // the case, it's not necessary and we can just go on our
  522.           // merry way.
  523.           int __ext_bom = __state._M_get_external_bom();
  524.           if (__ext_bom)
  525.             {    
  526.               size_t __size = __from_end - __from;
  527.               extern_type* __cfixed =  static_cast<extern_type*>(__builtin_alloca(sizeof(extern_type) * (__size + 1)));
  528.               __cfixed[0] = static_cast<extern_type>(__ext_bom);
  529.               char_traits<extern_type>::copy(__cfixed + 1, __from, __size);
  530.               __cfrom = reinterpret_cast<char*>(__cfixed);
  531.               __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
  532.                                        &__flen, &__cto, &__tlen);
  533.             }
  534.           else
  535.             {
  536.               extern_type* __cfixed = const_cast<extern_type*>(__from);
  537.               __cfrom = reinterpret_cast<char*>(__cfixed);
  538.               __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
  539.                                        &__flen, &__cto, &__tlen);
  540.             }
  541.  
  542.          
  543.           if (__conv != size_t(-1))
  544.             {
  545.               __from_next = reinterpret_cast<const extern_type*>(__cfrom);
  546.               __to_next = reinterpret_cast<intern_type*>(__cto);
  547.               __ret = ok;
  548.             }
  549.           else
  550.             {
  551.               if (__flen < static_cast<size_t>(__from_end - __from))
  552.                 {
  553.                   __from_next = reinterpret_cast<const extern_type*>(__cfrom);
  554.                   __to_next = reinterpret_cast<intern_type*>(__cto);
  555.                   __ret = partial;
  556.                 }
  557.               else
  558.                 __ret = error;
  559.             }
  560.         }
  561.       return __ret;
  562.     }
  563.  
  564.   template<typename _InternT, typename _ExternT>
  565.     int
  566.     codecvt<_InternT, _ExternT, __enc_traits>::
  567.     do_encoding() const throw()
  568.     { return 0; }
  569.  
  570.   template<typename _InternT, typename _ExternT>
  571.     bool
  572.     codecvt<_InternT, _ExternT, __enc_traits>::
  573.     do_always_noconv() const throw()
  574.     { return false; }
  575.  
  576.   template<typename _InternT, typename _ExternT>
  577.     int
  578.     codecvt<_InternT, _ExternT, __enc_traits>::
  579.     do_length(const state_type&, const extern_type* __from,
  580.               const extern_type* __end, size_t __max) const
  581.     { return min(__max, static_cast<size_t>(__end - __from)); }
  582.  
  583. #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
  584. // 74.  Garbled text for codecvt::do_max_length
  585.   template<typename _InternT, typename _ExternT>
  586.     int
  587.     codecvt<_InternT, _ExternT, __enc_traits>::
  588.     do_max_length() const throw()
  589.     { return 1; }
  590. #endif
  591. #endif /* _GLIBCPP_USE_WCHAR_T */
  592.  
  593.   // codecvt<char, char, mbstate_t> required specialization
  594.   template<>
  595.     class codecvt<char, char, mbstate_t>
  596.     : public __codecvt_abstract_base<char, char, mbstate_t>
  597.     {
  598.     public:      
  599.       // Types:
  600.       typedef char      intern_type;
  601.       typedef char      extern_type;
  602.       typedef mbstate_t state_type;
  603.  
  604.       // Data Members:
  605.       static locale::id id;
  606.  
  607.       explicit
  608.       codecvt(size_t __refs = 0);
  609.  
  610.     protected:
  611.       virtual
  612.       ~codecvt();
  613.  
  614.       virtual result
  615.       do_out(state_type& __state, const intern_type* __from,
  616.              const intern_type* __from_end, const intern_type*& __from_next,
  617.              extern_type* __to, extern_type* __to_end,
  618.              extern_type*& __to_next) const;
  619.  
  620.       virtual result
  621.       do_unshift(state_type& __state, extern_type* __to,
  622.                  extern_type* __to_end, extern_type*& __to_next) const;
  623.  
  624.       virtual result
  625.       do_in(state_type& __state, const extern_type* __from,
  626.             const extern_type* __from_end, const extern_type*& __from_next,
  627.             intern_type* __to, intern_type* __to_end,
  628.             intern_type*& __to_next) const;
  629.  
  630.       virtual int
  631.       do_encoding() const throw();
  632.  
  633.       virtual bool
  634.       do_always_noconv() const throw();
  635.  
  636.       virtual int
  637.       do_length(const state_type&, const extern_type* __from,
  638.                 const extern_type* __end, size_t __max) const;
  639.  
  640.       virtual int
  641.       do_max_length() const throw();
  642.   };
  643.  
  644. #ifdef _GLIBCPP_USE_WCHAR_T
  645.   // codecvt<wchar_t, char, mbstate_t> required specialization
  646.   template<>
  647.     class codecvt<wchar_t, char, mbstate_t>
  648.     : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
  649.     {
  650.     public:
  651.       // Types:
  652.       typedef wchar_t   intern_type;
  653.       typedef char      extern_type;
  654.       typedef mbstate_t state_type;
  655.  
  656.       // Data Members:
  657.       static locale::id id;
  658.  
  659.       explicit
  660.       codecvt(size_t __refs = 0);
  661.  
  662.     protected:
  663.       virtual
  664.       ~codecvt();
  665.  
  666.       virtual result
  667.       do_out(state_type& __state, const intern_type* __from,
  668.              const intern_type* __from_end, const intern_type*& __from_next,
  669.              extern_type* __to, extern_type* __to_end,
  670.              extern_type*& __to_next) const;
  671.  
  672.       virtual result
  673.       do_unshift(state_type& __state,
  674.                  extern_type* __to, extern_type* __to_end,
  675.                  extern_type*& __to_next) const;
  676.  
  677.       virtual result
  678.       do_in(state_type& __state,
  679.              const extern_type* __from, const extern_type* __from_end,
  680.              const extern_type*& __from_next,
  681.              intern_type* __to, intern_type* __to_end,
  682.              intern_type*& __to_next) const;
  683.  
  684.       virtual
  685.       int do_encoding() const throw();
  686.  
  687.       virtual
  688.       bool do_always_noconv() const throw();
  689.  
  690.       virtual
  691.       int do_length(const state_type&, const extern_type* __from,
  692.                     const extern_type* __end, size_t __max) const;
  693.  
  694.       virtual int
  695.       do_max_length() const throw();
  696.     };
  697. #endif //_GLIBCPP_USE_WCHAR_T
  698.  
  699.   // 22.2.1.6  Template class codecvt_byname
  700.   template<typename _InternT, typename _ExternT, typename _StateT>
  701.     class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
  702.     {
  703.     public:
  704.       explicit
  705.       codecvt_byname(const char*, size_t __refs = 0)
  706.       : codecvt<_InternT, _ExternT, _StateT>(__refs) { }
  707.     protected:
  708.       virtual
  709.       ~codecvt_byname() { }
  710.     };
  711.  
  712. #endif // _CPP_BITS_CODECVT_H
  713.  
  714. // Local Variables:
  715. // mode:c++
  716. // End:
  717.  
  718.