Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Locale support (codecvt) -*- C++ -*-
  2.  
  3. // Copyright (C) 2000-2013 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 3, 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. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file bits/codecvt.h
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{locale}
  28.  */
  29.  
  30. //
  31. // ISO C++ 14882: 22.2.1.5 Template class codecvt
  32. //
  33.  
  34. // Written by Benjamin Kosnik <bkoz@redhat.com>
  35.  
  36. #ifndef _CODECVT_H
  37. #define _CODECVT_H 1
  38.  
  39. #pragma GCC system_header
  40.  
  41. namespace std _GLIBCXX_VISIBILITY(default)
  42. {
  43. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  44.  
  45.   /// Empty base class for codecvt facet [22.2.1.5].
  46.   class codecvt_base
  47.   {
  48.   public:
  49.     enum result
  50.     {
  51.       ok,
  52.       partial,
  53.       error,
  54.       noconv
  55.     };
  56.   };
  57.  
  58.   /**
  59.    *  @brief  Common base for codecvt functions.
  60.    *
  61.    *  This template class provides implementations of the public functions
  62.    *  that forward to the protected virtual functions.
  63.    *
  64.    *  This template also provides abstract stubs for the protected virtual
  65.    *  functions.
  66.   */
  67.   template<typename _InternT, typename _ExternT, typename _StateT>
  68.     class __codecvt_abstract_base
  69.     : public locale::facet, public codecvt_base
  70.     {
  71.     public:
  72.       // Types:
  73.       typedef codecvt_base::result      result;
  74.       typedef _InternT                  intern_type;
  75.       typedef _ExternT                  extern_type;
  76.       typedef _StateT                   state_type;
  77.  
  78.       // 22.2.1.5.1 codecvt members
  79.       /**
  80.        *  @brief  Convert from internal to external character set.
  81.        *
  82.        *  Converts input string of intern_type to output string of
  83.        *  extern_type.  This is analogous to wcsrtombs.  It does this by
  84.        *  calling codecvt::do_out.
  85.        *
  86.        *  The source and destination character sets are determined by the
  87.        *  facet's locale, internal and external types.
  88.        *
  89.        *  The characters in [from,from_end) are converted and written to
  90.        *  [to,to_end).  from_next and to_next are set to point to the
  91.        *  character following the last successfully converted character,
  92.        *  respectively.  If the result needed no conversion, from_next and
  93.        *  to_next are not affected.
  94.        *
  95.        *  The @a state argument should be initialized if the input is at the
  96.        *  beginning and carried from a previous call if continuing
  97.        *  conversion.  There are no guarantees about how @a state is used.
  98.        *
  99.        *  The result returned is a member of codecvt_base::result.  If
  100.        *  all the input is converted, returns codecvt_base::ok.  If no
  101.        *  conversion is necessary, returns codecvt_base::noconv.  If
  102.        *  the input ends early or there is insufficient space in the
  103.        *  output, returns codecvt_base::partial.  Otherwise the
  104.        *  conversion failed and codecvt_base::error is returned.
  105.        *
  106.        *  @param  __state  Persistent conversion state data.
  107.        *  @param  __from  Start of input.
  108.        *  @param  __from_end  End of input.
  109.        *  @param  __from_next  Returns start of unconverted data.
  110.        *  @param  __to  Start of output buffer.
  111.        *  @param  __to_end  End of output buffer.
  112.        *  @param  __to_next  Returns start of unused output area.
  113.        *  @return  codecvt_base::result.
  114.       */
  115.       result
  116.       out(state_type& __state, const intern_type* __from,
  117.           const intern_type* __from_end, const intern_type*& __from_next,
  118.           extern_type* __to, extern_type* __to_end,
  119.           extern_type*& __to_next) const
  120.       {
  121.         return this->do_out(__state, __from, __from_end, __from_next,
  122.                             __to, __to_end, __to_next);
  123.       }
  124.  
  125.       /**
  126.        *  @brief  Reset conversion state.
  127.        *
  128.        *  Writes characters to output that would restore @a state to initial
  129.        *  conditions.  The idea is that if a partial conversion occurs, then
  130.        *  the converting the characters written by this function would leave
  131.        *  the state in initial conditions, rather than partial conversion
  132.        *  state.  It does this by calling codecvt::do_unshift().
  133.        *
  134.        *  For example, if 4 external characters always converted to 1 internal
  135.        *  character, and input to in() had 6 external characters with state
  136.        *  saved, this function would write two characters to the output and
  137.        *  set the state to initialized conditions.
  138.        *
  139.        *  The source and destination character sets are determined by the
  140.        *  facet's locale, internal and external types.
  141.        *
  142.        *  The result returned is a member of codecvt_base::result.  If the
  143.        *  state could be reset and data written, returns codecvt_base::ok.  If
  144.        *  no conversion is necessary, returns codecvt_base::noconv.  If the
  145.        *  output has insufficient space, returns codecvt_base::partial.
  146.        *  Otherwise the reset failed and codecvt_base::error is returned.
  147.        *
  148.        *  @param  __state  Persistent conversion state data.
  149.        *  @param  __to  Start of output buffer.
  150.        *  @param  __to_end  End of output buffer.
  151.        *  @param  __to_next  Returns start of unused output area.
  152.        *  @return  codecvt_base::result.
  153.       */
  154.       result
  155.       unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
  156.               extern_type*& __to_next) const
  157.       { return this->do_unshift(__state, __to,__to_end,__to_next); }
  158.  
  159.       /**
  160.        *  @brief  Convert from external to internal character set.
  161.        *
  162.        *  Converts input string of extern_type to output string of
  163.        *  intern_type.  This is analogous to mbsrtowcs.  It does this by
  164.        *  calling codecvt::do_in.
  165.        *
  166.        *  The source and destination character sets are determined by the
  167.        *  facet's locale, internal and external types.
  168.        *
  169.        *  The characters in [from,from_end) are converted and written to
  170.        *  [to,to_end).  from_next and to_next are set to point to the
  171.        *  character following the last successfully converted character,
  172.        *  respectively.  If the result needed no conversion, from_next and
  173.        *  to_next are not affected.
  174.        *
  175.        *  The @a state argument should be initialized if the input is at the
  176.        *  beginning and carried from a previous call if continuing
  177.        *  conversion.  There are no guarantees about how @a state is used.
  178.        *
  179.        *  The result returned is a member of codecvt_base::result.  If
  180.        *  all the input is converted, returns codecvt_base::ok.  If no
  181.        *  conversion is necessary, returns codecvt_base::noconv.  If
  182.        *  the input ends early or there is insufficient space in the
  183.        *  output, returns codecvt_base::partial.  Otherwise the
  184.        *  conversion failed and codecvt_base::error is returned.
  185.        *
  186.        *  @param  __state  Persistent conversion state data.
  187.        *  @param  __from  Start of input.
  188.        *  @param  __from_end  End of input.
  189.        *  @param  __from_next  Returns start of unconverted data.
  190.        *  @param  __to  Start of output buffer.
  191.        *  @param  __to_end  End of output buffer.
  192.        *  @param  __to_next  Returns start of unused output area.
  193.        *  @return  codecvt_base::result.
  194.       */
  195.       result
  196.       in(state_type& __state, const extern_type* __from,
  197.          const extern_type* __from_end, const extern_type*& __from_next,
  198.          intern_type* __to, intern_type* __to_end,
  199.          intern_type*& __to_next) const
  200.       {
  201.         return this->do_in(__state, __from, __from_end, __from_next,
  202.                            __to, __to_end, __to_next);
  203.       }
  204.  
  205.       int
  206.       encoding() const throw()
  207.       { return this->do_encoding(); }
  208.  
  209.       bool
  210.       always_noconv() const throw()
  211.       { return this->do_always_noconv(); }
  212.  
  213.       int
  214.       length(state_type& __state, const extern_type* __from,
  215.              const extern_type* __end, size_t __max) const
  216.       { return this->do_length(__state, __from, __end, __max); }
  217.  
  218.       int
  219.       max_length() const throw()
  220.       { return this->do_max_length(); }
  221.  
  222.     protected:
  223.       explicit
  224.       __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
  225.  
  226.       virtual
  227.       ~__codecvt_abstract_base() { }
  228.  
  229.       /**
  230.        *  @brief  Convert from internal to external character set.
  231.        *
  232.        *  Converts input string of intern_type to output string of
  233.        *  extern_type.  This function is a hook for derived classes to change
  234.        *  the value returned.  @see out for more information.
  235.       */
  236.       virtual result
  237.       do_out(state_type& __state, const intern_type* __from,
  238.              const intern_type* __from_end, const intern_type*& __from_next,
  239.              extern_type* __to, extern_type* __to_end,
  240.              extern_type*& __to_next) const = 0;
  241.  
  242.       virtual result
  243.       do_unshift(state_type& __state, extern_type* __to,
  244.                  extern_type* __to_end, extern_type*& __to_next) const = 0;
  245.  
  246.       virtual result
  247.       do_in(state_type& __state, const extern_type* __from,
  248.             const extern_type* __from_end, const extern_type*& __from_next,
  249.             intern_type* __to, intern_type* __to_end,
  250.             intern_type*& __to_next) const = 0;
  251.  
  252.       virtual int
  253.       do_encoding() const throw() = 0;
  254.  
  255.       virtual bool
  256.       do_always_noconv() const throw() = 0;
  257.  
  258.       virtual int
  259.       do_length(state_type&, const extern_type* __from,
  260.                 const extern_type* __end, size_t __max) const = 0;
  261.  
  262.       virtual int
  263.       do_max_length() const throw() = 0;
  264.     };
  265.  
  266.  
  267.  
  268.   /**
  269.    *  @brief  Primary class template codecvt.
  270.    *  @ingroup locales
  271.    *
  272.    *  NB: Generic, mostly useless implementation.
  273.    *
  274.   */
  275.    template<typename _InternT, typename _ExternT, typename _StateT>
  276.     class codecvt
  277.     : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
  278.     {
  279.     public:
  280.       // Types:
  281.       typedef codecvt_base::result      result;
  282.       typedef _InternT                  intern_type;
  283.       typedef _ExternT                  extern_type;
  284.       typedef _StateT                   state_type;
  285.  
  286.     protected:
  287.       __c_locale                        _M_c_locale_codecvt;
  288.  
  289.     public:
  290.       static locale::id                 id;
  291.  
  292.       explicit
  293.       codecvt(size_t __refs = 0)
  294.       : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs),
  295.         _M_c_locale_codecvt(0)
  296.       { }
  297.  
  298.       explicit
  299.       codecvt(__c_locale __cloc, size_t __refs = 0);
  300.  
  301.     protected:
  302.       virtual
  303.       ~codecvt() { }
  304.  
  305.       virtual result
  306.       do_out(state_type& __state, const intern_type* __from,
  307.              const intern_type* __from_end, const intern_type*& __from_next,
  308.              extern_type* __to, extern_type* __to_end,
  309.              extern_type*& __to_next) const;
  310.  
  311.       virtual result
  312.       do_unshift(state_type& __state, extern_type* __to,
  313.                  extern_type* __to_end, extern_type*& __to_next) const;
  314.  
  315.       virtual result
  316.       do_in(state_type& __state, const extern_type* __from,
  317.             const extern_type* __from_end, const extern_type*& __from_next,
  318.             intern_type* __to, intern_type* __to_end,
  319.             intern_type*& __to_next) const;
  320.  
  321.       virtual int
  322.       do_encoding() const throw();
  323.  
  324.       virtual bool
  325.       do_always_noconv() const throw();
  326.  
  327.       virtual int
  328.       do_length(state_type&, const extern_type* __from,
  329.                 const extern_type* __end, size_t __max) const;
  330.  
  331.       virtual int
  332.       do_max_length() const throw();
  333.     };
  334.  
  335.   template<typename _InternT, typename _ExternT, typename _StateT>
  336.     locale::id codecvt<_InternT, _ExternT, _StateT>::id;
  337.  
  338.   /// class codecvt<char, char, mbstate_t> specialization.
  339.   template<>
  340.     class codecvt<char, char, mbstate_t>
  341.     : public __codecvt_abstract_base<char, char, mbstate_t>
  342.     {
  343.     public:
  344.       // Types:
  345.       typedef char                      intern_type;
  346.       typedef char                      extern_type;
  347.       typedef mbstate_t                 state_type;
  348.  
  349.     protected:
  350.       __c_locale                        _M_c_locale_codecvt;
  351.  
  352.     public:
  353.       static locale::id id;
  354.  
  355.       explicit
  356.       codecvt(size_t __refs = 0);
  357.  
  358.       explicit
  359.       codecvt(__c_locale __cloc, size_t __refs = 0);
  360.  
  361.     protected:
  362.       virtual
  363.       ~codecvt();
  364.  
  365.       virtual result
  366.       do_out(state_type& __state, const intern_type* __from,
  367.              const intern_type* __from_end, const intern_type*& __from_next,
  368.              extern_type* __to, extern_type* __to_end,
  369.              extern_type*& __to_next) const;
  370.  
  371.       virtual result
  372.       do_unshift(state_type& __state, extern_type* __to,
  373.                  extern_type* __to_end, extern_type*& __to_next) const;
  374.  
  375.       virtual result
  376.       do_in(state_type& __state, const extern_type* __from,
  377.             const extern_type* __from_end, const extern_type*& __from_next,
  378.             intern_type* __to, intern_type* __to_end,
  379.             intern_type*& __to_next) const;
  380.  
  381.       virtual int
  382.       do_encoding() const throw();
  383.  
  384.       virtual bool
  385.       do_always_noconv() const throw();
  386.  
  387.       virtual int
  388.       do_length(state_type&, const extern_type* __from,
  389.                 const extern_type* __end, size_t __max) const;
  390.  
  391.       virtual int
  392.       do_max_length() const throw();
  393.   };
  394.  
  395. #ifdef _GLIBCXX_USE_WCHAR_T
  396.   /// class codecvt<wchar_t, char, mbstate_t> specialization.
  397.   template<>
  398.     class codecvt<wchar_t, char, mbstate_t>
  399.     : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
  400.     {
  401.     public:
  402.       // Types:
  403.       typedef wchar_t                   intern_type;
  404.       typedef char                      extern_type;
  405.       typedef mbstate_t                 state_type;
  406.  
  407.     protected:
  408.       __c_locale                        _M_c_locale_codecvt;
  409.  
  410.     public:
  411.       static locale::id                 id;
  412.  
  413.       explicit
  414.       codecvt(size_t __refs = 0);
  415.  
  416.       explicit
  417.       codecvt(__c_locale __cloc, size_t __refs = 0);
  418.  
  419.     protected:
  420.       virtual
  421.       ~codecvt();
  422.  
  423.       virtual result
  424.       do_out(state_type& __state, const intern_type* __from,
  425.              const intern_type* __from_end, const intern_type*& __from_next,
  426.              extern_type* __to, extern_type* __to_end,
  427.              extern_type*& __to_next) const;
  428.  
  429.       virtual result
  430.       do_unshift(state_type& __state,
  431.                  extern_type* __to, extern_type* __to_end,
  432.                  extern_type*& __to_next) const;
  433.  
  434.       virtual result
  435.       do_in(state_type& __state,
  436.              const extern_type* __from, const extern_type* __from_end,
  437.              const extern_type*& __from_next,
  438.              intern_type* __to, intern_type* __to_end,
  439.              intern_type*& __to_next) const;
  440.  
  441.       virtual
  442.       int do_encoding() const throw();
  443.  
  444.       virtual
  445.       bool do_always_noconv() const throw();
  446.  
  447.       virtual
  448.       int do_length(state_type&, const extern_type* __from,
  449.                     const extern_type* __end, size_t __max) const;
  450.  
  451.       virtual int
  452.       do_max_length() const throw();
  453.     };
  454. #endif //_GLIBCXX_USE_WCHAR_T
  455.  
  456.   /// class codecvt_byname [22.2.1.6].
  457.   template<typename _InternT, typename _ExternT, typename _StateT>
  458.     class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
  459.     {
  460.     public:
  461.       explicit
  462.       codecvt_byname(const char* __s, size_t __refs = 0)
  463.       : codecvt<_InternT, _ExternT, _StateT>(__refs)
  464.       {
  465.         if (__builtin_strcmp(__s, "C") != 0
  466.             && __builtin_strcmp(__s, "POSIX") != 0)
  467.           {
  468.             this->_S_destroy_c_locale(this->_M_c_locale_codecvt);
  469.             this->_S_create_c_locale(this->_M_c_locale_codecvt, __s);
  470.           }
  471.       }
  472.  
  473.     protected:
  474.       virtual
  475.       ~codecvt_byname() { }
  476.     };
  477.  
  478.   // Inhibit implicit instantiations for required instantiations,
  479.   // which are defined via explicit instantiations elsewhere.
  480. #if _GLIBCXX_EXTERN_TEMPLATE
  481.   extern template class codecvt_byname<char, char, mbstate_t>;
  482.  
  483.   extern template
  484.     const codecvt<char, char, mbstate_t>&
  485.     use_facet<codecvt<char, char, mbstate_t> >(const locale&);
  486.  
  487.   extern template
  488.     bool
  489.     has_facet<codecvt<char, char, mbstate_t> >(const locale&);
  490.  
  491. #ifdef _GLIBCXX_USE_WCHAR_T
  492.   extern template class codecvt_byname<wchar_t, char, mbstate_t>;
  493.  
  494.   extern template
  495.     const codecvt<wchar_t, char, mbstate_t>&
  496.     use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
  497.  
  498.   extern template
  499.     bool
  500.     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
  501. #endif
  502. #endif
  503.  
  504. _GLIBCXX_END_NAMESPACE_VERSION
  505. } // namespace std
  506.  
  507. #endif // _CODECVT_H
  508.