197403Sobrien// Locale support (codecvt) -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 4169691Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 31169691Skan/** @file bits/codecvt.h 32169691Skan * This is an internal header file, included by other library headers. 33169691Skan * You should not attempt to use it directly. 34169691Skan */ 35169691Skan 3697403Sobrien// 3797403Sobrien// ISO C++ 14882: 22.2.1.5 Template class codecvt 3897403Sobrien// 3997403Sobrien 40169691Skan// Written by Benjamin Kosnik <bkoz@redhat.com> 4197403Sobrien 42132720Skan#ifndef _CODECVT_H 43132720Skan#define _CODECVT_H 1 4497403Sobrien 4597403Sobrien#pragma GCC system_header 4697403Sobrien 47169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 48169691Skan 49169691Skan /// @brief Empty base class for codecvt facet [22.2.1.5]. 5097403Sobrien class codecvt_base 5197403Sobrien { 5297403Sobrien public: 5397403Sobrien enum result 5497403Sobrien { 5597403Sobrien ok, 5697403Sobrien partial, 5797403Sobrien error, 5897403Sobrien noconv 5997403Sobrien }; 6097403Sobrien }; 6197403Sobrien 62132720Skan /** 63169691Skan * @brief Common base for codecvt functions. 64132720Skan * 65132720Skan * This template class provides implementations of the public functions 66132720Skan * that forward to the protected virtual functions. 67132720Skan * 68132720Skan * This template also provides abstract stubs for the protected virtual 69132720Skan * functions. 70132720Skan */ 7197403Sobrien template<typename _InternT, typename _ExternT, typename _StateT> 72132720Skan class __codecvt_abstract_base 7397403Sobrien : public locale::facet, public codecvt_base 7497403Sobrien { 7597403Sobrien public: 7697403Sobrien // Types: 77103447Skan typedef codecvt_base::result result; 78132720Skan typedef _InternT intern_type; 79132720Skan typedef _ExternT extern_type; 80132720Skan typedef _StateT state_type; 81132720Skan 8297403Sobrien // 22.2.1.5.1 codecvt members 83132720Skan /** 84132720Skan * @brief Convert from internal to external character set. 85132720Skan * 86132720Skan * Converts input string of intern_type to output string of 87132720Skan * extern_type. This is analogous to wcsrtombs. It does this by 88132720Skan * calling codecvt::do_out. 89132720Skan * 90132720Skan * The source and destination character sets are determined by the 91132720Skan * facet's locale, internal and external types. 92132720Skan * 93132720Skan * The characters in [from,from_end) are converted and written to 94132720Skan * [to,to_end). from_next and to_next are set to point to the 95132720Skan * character following the last successfully converted character, 96132720Skan * respectively. If the result needed no conversion, from_next and 97132720Skan * to_next are not affected. 98132720Skan * 99132720Skan * The @a state argument should be intialized if the input is at the 100132720Skan * beginning and carried from a previous call if continuing 101132720Skan * conversion. There are no guarantees about how @a state is used. 102132720Skan * 103169691Skan * The result returned is a member of codecvt_base::result. If 104169691Skan * all the input is converted, returns codecvt_base::ok. If no 105169691Skan * conversion is necessary, returns codecvt_base::noconv. If 106169691Skan * the input ends early or there is insufficient space in the 107169691Skan * output, returns codecvt_base::partial. Otherwise the 108169691Skan * conversion failed and codecvt_base::error is returned. 109132720Skan * 110132720Skan * @param state Persistent conversion state data. 111132720Skan * @param from Start of input. 112132720Skan * @param from_end End of input. 113132720Skan * @param from_next Returns start of unconverted data. 114132720Skan * @param to Start of output buffer. 115132720Skan * @param to_end End of output buffer. 116132720Skan * @param to_next Returns start of unused output area. 117132720Skan * @return codecvt_base::result. 118132720Skan */ 11997403Sobrien result 120132720Skan out(state_type& __state, const intern_type* __from, 12197403Sobrien const intern_type* __from_end, const intern_type*& __from_next, 122132720Skan extern_type* __to, extern_type* __to_end, 12397403Sobrien extern_type*& __to_next) const 124132720Skan { 125132720Skan return this->do_out(__state, __from, __from_end, __from_next, 126132720Skan __to, __to_end, __to_next); 12797403Sobrien } 12897403Sobrien 129132720Skan /** 130132720Skan * @brief Reset conversion state. 131132720Skan * 132132720Skan * Writes characters to output that would restore @a state to initial 133132720Skan * conditions. The idea is that if a partial conversion occurs, then 134132720Skan * the converting the characters written by this function would leave 135132720Skan * the state in initial conditions, rather than partial conversion 136132720Skan * state. It does this by calling codecvt::do_unshift(). 137132720Skan * 138132720Skan * For example, if 4 external characters always converted to 1 internal 139132720Skan * character, and input to in() had 6 external characters with state 140132720Skan * saved, this function would write two characters to the output and 141132720Skan * set the state to initialized conditions. 142132720Skan * 143132720Skan * The source and destination character sets are determined by the 144132720Skan * facet's locale, internal and external types. 145132720Skan * 146132720Skan * The result returned is a member of codecvt_base::result. If the 147132720Skan * state could be reset and data written, returns codecvt_base::ok. If 148132720Skan * no conversion is necessary, returns codecvt_base::noconv. If the 149132720Skan * output has insufficient space, returns codecvt_base::partial. 150132720Skan * Otherwise the reset failed and codecvt_base::error is returned. 151132720Skan * 152132720Skan * @param state Persistent conversion state data. 153132720Skan * @param to Start of output buffer. 154132720Skan * @param to_end End of output buffer. 155132720Skan * @param to_next Returns start of unused output area. 156132720Skan * @return codecvt_base::result. 157132720Skan */ 15897403Sobrien result 15997403Sobrien unshift(state_type& __state, extern_type* __to, extern_type* __to_end, 16097403Sobrien extern_type*& __to_next) const 16197403Sobrien { return this->do_unshift(__state, __to,__to_end,__to_next); } 16297403Sobrien 163132720Skan /** 164132720Skan * @brief Convert from external to internal character set. 165132720Skan * 166132720Skan * Converts input string of extern_type to output string of 167132720Skan * intern_type. This is analogous to mbsrtowcs. It does this by 168132720Skan * calling codecvt::do_in. 169132720Skan * 170132720Skan * The source and destination character sets are determined by the 171132720Skan * facet's locale, internal and external types. 172132720Skan * 173132720Skan * The characters in [from,from_end) are converted and written to 174132720Skan * [to,to_end). from_next and to_next are set to point to the 175132720Skan * character following the last successfully converted character, 176132720Skan * respectively. If the result needed no conversion, from_next and 177132720Skan * to_next are not affected. 178132720Skan * 179132720Skan * The @a state argument should be intialized if the input is at the 180132720Skan * beginning and carried from a previous call if continuing 181132720Skan * conversion. There are no guarantees about how @a state is used. 182132720Skan * 183169691Skan * The result returned is a member of codecvt_base::result. If 184169691Skan * all the input is converted, returns codecvt_base::ok. If no 185169691Skan * conversion is necessary, returns codecvt_base::noconv. If 186169691Skan * the input ends early or there is insufficient space in the 187169691Skan * output, returns codecvt_base::partial. Otherwise the 188169691Skan * conversion failed and codecvt_base::error is returned. 189132720Skan * 190132720Skan * @param state Persistent conversion state data. 191132720Skan * @param from Start of input. 192132720Skan * @param from_end End of input. 193132720Skan * @param from_next Returns start of unconverted data. 194132720Skan * @param to Start of output buffer. 195132720Skan * @param to_end End of output buffer. 196132720Skan * @param to_next Returns start of unused output area. 197132720Skan * @return codecvt_base::result. 198132720Skan */ 19997403Sobrien result 200132720Skan in(state_type& __state, const extern_type* __from, 20197403Sobrien const extern_type* __from_end, const extern_type*& __from_next, 202132720Skan intern_type* __to, intern_type* __to_end, 20397403Sobrien intern_type*& __to_next) const 204132720Skan { 20597403Sobrien return this->do_in(__state, __from, __from_end, __from_next, 206132720Skan __to, __to_end, __to_next); 20797403Sobrien } 20897403Sobrien 209132720Skan int 21097403Sobrien encoding() const throw() 21197403Sobrien { return this->do_encoding(); } 21297403Sobrien 213132720Skan bool 21497403Sobrien always_noconv() const throw() 21597403Sobrien { return this->do_always_noconv(); } 21697403Sobrien 21797403Sobrien int 218132720Skan length(state_type& __state, const extern_type* __from, 21997403Sobrien const extern_type* __end, size_t __max) const 22097403Sobrien { return this->do_length(__state, __from, __end, __max); } 22197403Sobrien 222132720Skan int 22397403Sobrien max_length() const throw() 22497403Sobrien { return this->do_max_length(); } 22597403Sobrien 22697403Sobrien protected: 227132720Skan explicit 22897403Sobrien __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } 22997403Sobrien 230132720Skan virtual 23197403Sobrien ~__codecvt_abstract_base() { } 23297403Sobrien 233132720Skan /** 234132720Skan * @brief Convert from internal to external character set. 235132720Skan * 236132720Skan * Converts input string of intern_type to output string of 237132720Skan * extern_type. This function is a hook for derived classes to change 238132720Skan * the value returned. @see out for more information. 239132720Skan */ 24097403Sobrien virtual result 241132720Skan do_out(state_type& __state, const intern_type* __from, 24297403Sobrien const intern_type* __from_end, const intern_type*& __from_next, 24397403Sobrien extern_type* __to, extern_type* __to_end, 24497403Sobrien extern_type*& __to_next) const = 0; 24597403Sobrien 24697403Sobrien virtual result 247132720Skan do_unshift(state_type& __state, extern_type* __to, 24897403Sobrien extern_type* __to_end, extern_type*& __to_next) const = 0; 249132720Skan 25097403Sobrien virtual result 251132720Skan do_in(state_type& __state, const extern_type* __from, 252132720Skan const extern_type* __from_end, const extern_type*& __from_next, 253132720Skan intern_type* __to, intern_type* __to_end, 25497403Sobrien intern_type*& __to_next) const = 0; 255132720Skan 256132720Skan virtual int 25797403Sobrien do_encoding() const throw() = 0; 25897403Sobrien 259132720Skan virtual bool 26097403Sobrien do_always_noconv() const throw() = 0; 26197403Sobrien 262132720Skan virtual int 263132720Skan do_length(state_type&, const extern_type* __from, 26497403Sobrien const extern_type* __end, size_t __max) const = 0; 26597403Sobrien 266132720Skan virtual int 26797403Sobrien do_max_length() const throw() = 0; 26897403Sobrien }; 26997403Sobrien 270169691Skan /// @brief class codecvt [22.2.1.5]. 271169691Skan /// NB: Generic, mostly useless implementation. 27297403Sobrien template<typename _InternT, typename _ExternT, typename _StateT> 273132720Skan class codecvt 27497403Sobrien : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> 27597403Sobrien { 276132720Skan public: 27797403Sobrien // Types: 278103447Skan typedef codecvt_base::result result; 279132720Skan typedef _InternT intern_type; 280132720Skan typedef _ExternT extern_type; 281132720Skan typedef _StateT state_type; 28297403Sobrien 283132720Skan protected: 284132720Skan __c_locale _M_c_locale_codecvt; 285132720Skan 286103447Skan public: 287132720Skan static locale::id id; 28897403Sobrien 289132720Skan explicit 290132720Skan codecvt(size_t __refs = 0) 291103447Skan : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { } 29297403Sobrien 293132720Skan explicit 294132720Skan codecvt(__c_locale __cloc, size_t __refs = 0); 295132720Skan 29697403Sobrien protected: 297132720Skan virtual 29897403Sobrien ~codecvt() { } 29997403Sobrien 30097403Sobrien virtual result 301132720Skan do_out(state_type& __state, const intern_type* __from, 30297403Sobrien const intern_type* __from_end, const intern_type*& __from_next, 30397403Sobrien extern_type* __to, extern_type* __to_end, 30497403Sobrien extern_type*& __to_next) const; 30597403Sobrien 30697403Sobrien virtual result 307132720Skan do_unshift(state_type& __state, extern_type* __to, 30897403Sobrien extern_type* __to_end, extern_type*& __to_next) const; 309132720Skan 31097403Sobrien virtual result 311132720Skan do_in(state_type& __state, const extern_type* __from, 312132720Skan const extern_type* __from_end, const extern_type*& __from_next, 313132720Skan intern_type* __to, intern_type* __to_end, 31497403Sobrien intern_type*& __to_next) const; 315132720Skan 316132720Skan virtual int 31797403Sobrien do_encoding() const throw(); 31897403Sobrien 319132720Skan virtual bool 32097403Sobrien do_always_noconv() const throw(); 32197403Sobrien 322132720Skan virtual int 323132720Skan do_length(state_type&, const extern_type* __from, 32497403Sobrien const extern_type* __end, size_t __max) const; 32597403Sobrien 326132720Skan virtual int 32797403Sobrien do_max_length() const throw(); 32897403Sobrien }; 32997403Sobrien 33097403Sobrien template<typename _InternT, typename _ExternT, typename _StateT> 33197403Sobrien locale::id codecvt<_InternT, _ExternT, _StateT>::id; 33297403Sobrien 333169691Skan /// @brief class codecvt<char, char, mbstate_t> specialization. 33497403Sobrien template<> 335132720Skan class codecvt<char, char, mbstate_t> 33697403Sobrien : public __codecvt_abstract_base<char, char, mbstate_t> 33797403Sobrien { 338132720Skan public: 33997403Sobrien // Types: 340132720Skan typedef char intern_type; 341132720Skan typedef char extern_type; 342132720Skan typedef mbstate_t state_type; 34397403Sobrien 344132720Skan protected: 345132720Skan __c_locale _M_c_locale_codecvt; 346132720Skan 347103447Skan public: 34897403Sobrien static locale::id id; 34997403Sobrien 350132720Skan explicit 35197403Sobrien codecvt(size_t __refs = 0); 35297403Sobrien 353132720Skan explicit 354132720Skan codecvt(__c_locale __cloc, size_t __refs = 0); 355132720Skan 35697403Sobrien protected: 357132720Skan virtual 35897403Sobrien ~codecvt(); 35997403Sobrien 36097403Sobrien virtual result 361132720Skan do_out(state_type& __state, const intern_type* __from, 36297403Sobrien const intern_type* __from_end, const intern_type*& __from_next, 36397403Sobrien extern_type* __to, extern_type* __to_end, 36497403Sobrien extern_type*& __to_next) const; 36597403Sobrien 36697403Sobrien virtual result 367132720Skan do_unshift(state_type& __state, extern_type* __to, 36897403Sobrien extern_type* __to_end, extern_type*& __to_next) const; 36997403Sobrien 37097403Sobrien virtual result 371132720Skan do_in(state_type& __state, const extern_type* __from, 37297403Sobrien const extern_type* __from_end, const extern_type*& __from_next, 373132720Skan intern_type* __to, intern_type* __to_end, 37497403Sobrien intern_type*& __to_next) const; 37597403Sobrien 376132720Skan virtual int 37797403Sobrien do_encoding() const throw(); 37897403Sobrien 379132720Skan virtual bool 38097403Sobrien do_always_noconv() const throw(); 38197403Sobrien 382132720Skan virtual int 383132720Skan do_length(state_type&, const extern_type* __from, 38497403Sobrien const extern_type* __end, size_t __max) const; 38597403Sobrien 386132720Skan virtual int 38797403Sobrien do_max_length() const throw(); 38897403Sobrien }; 38997403Sobrien 390132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 391169691Skan /// @brief class codecvt<wchar_t, char, mbstate_t> specialization. 39297403Sobrien template<> 393132720Skan class codecvt<wchar_t, char, mbstate_t> 39497403Sobrien : public __codecvt_abstract_base<wchar_t, char, mbstate_t> 39597403Sobrien { 39697403Sobrien public: 39797403Sobrien // Types: 398132720Skan typedef wchar_t intern_type; 399132720Skan typedef char extern_type; 400132720Skan typedef mbstate_t state_type; 40197403Sobrien 402132720Skan protected: 403132720Skan __c_locale _M_c_locale_codecvt; 404132720Skan 405103447Skan public: 406132720Skan static locale::id id; 40797403Sobrien 408132720Skan explicit 40997403Sobrien codecvt(size_t __refs = 0); 41097403Sobrien 411132720Skan explicit 412132720Skan codecvt(__c_locale __cloc, size_t __refs = 0); 413132720Skan 41497403Sobrien protected: 415132720Skan virtual 41697403Sobrien ~codecvt(); 41797403Sobrien 41897403Sobrien virtual result 419132720Skan do_out(state_type& __state, const intern_type* __from, 42097403Sobrien const intern_type* __from_end, const intern_type*& __from_next, 42197403Sobrien extern_type* __to, extern_type* __to_end, 42297403Sobrien extern_type*& __to_next) const; 42397403Sobrien 42497403Sobrien virtual result 42597403Sobrien do_unshift(state_type& __state, 42697403Sobrien extern_type* __to, extern_type* __to_end, 42797403Sobrien extern_type*& __to_next) const; 42897403Sobrien 42997403Sobrien virtual result 43097403Sobrien do_in(state_type& __state, 43197403Sobrien const extern_type* __from, const extern_type* __from_end, 43297403Sobrien const extern_type*& __from_next, 43397403Sobrien intern_type* __to, intern_type* __to_end, 43497403Sobrien intern_type*& __to_next) const; 43597403Sobrien 436132720Skan virtual 43797403Sobrien int do_encoding() const throw(); 43897403Sobrien 439132720Skan virtual 44097403Sobrien bool do_always_noconv() const throw(); 44197403Sobrien 442132720Skan virtual 443132720Skan int do_length(state_type&, const extern_type* __from, 44497403Sobrien const extern_type* __end, size_t __max) const; 44597403Sobrien 446132720Skan virtual int 44797403Sobrien do_max_length() const throw(); 44897403Sobrien }; 449132720Skan#endif //_GLIBCXX_USE_WCHAR_T 45097403Sobrien 451169691Skan /// @brief class codecvt_byname [22.2.1.6]. 45297403Sobrien template<typename _InternT, typename _ExternT, typename _StateT> 45397403Sobrien class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> 45497403Sobrien { 45597403Sobrien public: 456132720Skan explicit 457132720Skan codecvt_byname(const char* __s, size_t __refs = 0) 458132720Skan : codecvt<_InternT, _ExternT, _StateT>(__refs) 459132720Skan { 460132720Skan if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) 461132720Skan { 462132720Skan this->_S_destroy_c_locale(this->_M_c_locale_codecvt); 463132720Skan this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); 464132720Skan } 465132720Skan } 466103447Skan 46797403Sobrien protected: 468132720Skan virtual 46997403Sobrien ~codecvt_byname() { } 47097403Sobrien }; 47197403Sobrien 472169691Skan_GLIBCXX_END_NAMESPACE 47397403Sobrien 474132720Skan#endif // _CODECVT_H 475