libstdc++
|
00001 // Locale support (codecvt) -*- C++ -*- 00002 00003 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 00004 // 2009, 2010, 2011 Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file bits/codecvt.h 00027 * This is an internal header file, included by other library headers. 00028 * Do not attempt to use it directly. @headername{locale} 00029 */ 00030 00031 // 00032 // ISO C++ 14882: 22.2.1.5 Template class codecvt 00033 // 00034 00035 // Written by Benjamin Kosnik <bkoz@redhat.com> 00036 00037 #ifndef _CODECVT_H 00038 #define _CODECVT_H 1 00039 00040 #pragma GCC system_header 00041 00042 namespace std _GLIBCXX_VISIBILITY(default) 00043 { 00044 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00045 00046 /// Empty base class for codecvt facet [22.2.1.5]. 00047 class codecvt_base 00048 { 00049 public: 00050 enum result 00051 { 00052 ok, 00053 partial, 00054 error, 00055 noconv 00056 }; 00057 }; 00058 00059 /** 00060 * @brief Common base for codecvt functions. 00061 * 00062 * This template class provides implementations of the public functions 00063 * that forward to the protected virtual functions. 00064 * 00065 * This template also provides abstract stubs for the protected virtual 00066 * functions. 00067 */ 00068 template<typename _InternT, typename _ExternT, typename _StateT> 00069 class __codecvt_abstract_base 00070 : public locale::facet, public codecvt_base 00071 { 00072 public: 00073 // Types: 00074 typedef codecvt_base::result result; 00075 typedef _InternT intern_type; 00076 typedef _ExternT extern_type; 00077 typedef _StateT state_type; 00078 00079 // 22.2.1.5.1 codecvt members 00080 /** 00081 * @brief Convert from internal to external character set. 00082 * 00083 * Converts input string of intern_type to output string of 00084 * extern_type. This is analogous to wcsrtombs. It does this by 00085 * calling codecvt::do_out. 00086 * 00087 * The source and destination character sets are determined by the 00088 * facet's locale, internal and external types. 00089 * 00090 * The characters in [from,from_end) are converted and written to 00091 * [to,to_end). from_next and to_next are set to point to the 00092 * character following the last successfully converted character, 00093 * respectively. If the result needed no conversion, from_next and 00094 * to_next are not affected. 00095 * 00096 * The @a state argument should be initialized if the input is at the 00097 * beginning and carried from a previous call if continuing 00098 * conversion. There are no guarantees about how @a state is used. 00099 * 00100 * The result returned is a member of codecvt_base::result. If 00101 * all the input is converted, returns codecvt_base::ok. If no 00102 * conversion is necessary, returns codecvt_base::noconv. If 00103 * the input ends early or there is insufficient space in the 00104 * output, returns codecvt_base::partial. Otherwise the 00105 * conversion failed and codecvt_base::error is returned. 00106 * 00107 * @param state Persistent conversion state data. 00108 * @param from Start of input. 00109 * @param from_end End of input. 00110 * @param from_next Returns start of unconverted data. 00111 * @param to Start of output buffer. 00112 * @param to_end End of output buffer. 00113 * @param to_next Returns start of unused output area. 00114 * @return codecvt_base::result. 00115 */ 00116 result 00117 out(state_type& __state, const intern_type* __from, 00118 const intern_type* __from_end, const intern_type*& __from_next, 00119 extern_type* __to, extern_type* __to_end, 00120 extern_type*& __to_next) const 00121 { 00122 return this->do_out(__state, __from, __from_end, __from_next, 00123 __to, __to_end, __to_next); 00124 } 00125 00126 /** 00127 * @brief Reset conversion state. 00128 * 00129 * Writes characters to output that would restore @a state to initial 00130 * conditions. The idea is that if a partial conversion occurs, then 00131 * the converting the characters written by this function would leave 00132 * the state in initial conditions, rather than partial conversion 00133 * state. It does this by calling codecvt::do_unshift(). 00134 * 00135 * For example, if 4 external characters always converted to 1 internal 00136 * character, and input to in() had 6 external characters with state 00137 * saved, this function would write two characters to the output and 00138 * set the state to initialized conditions. 00139 * 00140 * The source and destination character sets are determined by the 00141 * facet's locale, internal and external types. 00142 * 00143 * The result returned is a member of codecvt_base::result. If the 00144 * state could be reset and data written, returns codecvt_base::ok. If 00145 * no conversion is necessary, returns codecvt_base::noconv. If the 00146 * output has insufficient space, returns codecvt_base::partial. 00147 * Otherwise the reset failed and codecvt_base::error is returned. 00148 * 00149 * @param state Persistent conversion state data. 00150 * @param to Start of output buffer. 00151 * @param to_end End of output buffer. 00152 * @param to_next Returns start of unused output area. 00153 * @return codecvt_base::result. 00154 */ 00155 result 00156 unshift(state_type& __state, extern_type* __to, extern_type* __to_end, 00157 extern_type*& __to_next) const 00158 { return this->do_unshift(__state, __to,__to_end,__to_next); } 00159 00160 /** 00161 * @brief Convert from external to internal character set. 00162 * 00163 * Converts input string of extern_type to output string of 00164 * intern_type. This is analogous to mbsrtowcs. It does this by 00165 * calling codecvt::do_in. 00166 * 00167 * The source and destination character sets are determined by the 00168 * facet's locale, internal and external types. 00169 * 00170 * The characters in [from,from_end) are converted and written to 00171 * [to,to_end). from_next and to_next are set to point to the 00172 * character following the last successfully converted character, 00173 * respectively. If the result needed no conversion, from_next and 00174 * to_next are not affected. 00175 * 00176 * The @a state argument should be initialized if the input is at the 00177 * beginning and carried from a previous call if continuing 00178 * conversion. There are no guarantees about how @a state is used. 00179 * 00180 * The result returned is a member of codecvt_base::result. If 00181 * all the input is converted, returns codecvt_base::ok. If no 00182 * conversion is necessary, returns codecvt_base::noconv. If 00183 * the input ends early or there is insufficient space in the 00184 * output, returns codecvt_base::partial. Otherwise the 00185 * conversion failed and codecvt_base::error is returned. 00186 * 00187 * @param state Persistent conversion state data. 00188 * @param from Start of input. 00189 * @param from_end End of input. 00190 * @param from_next Returns start of unconverted data. 00191 * @param to Start of output buffer. 00192 * @param to_end End of output buffer. 00193 * @param to_next Returns start of unused output area. 00194 * @return codecvt_base::result. 00195 */ 00196 result 00197 in(state_type& __state, const extern_type* __from, 00198 const extern_type* __from_end, const extern_type*& __from_next, 00199 intern_type* __to, intern_type* __to_end, 00200 intern_type*& __to_next) const 00201 { 00202 return this->do_in(__state, __from, __from_end, __from_next, 00203 __to, __to_end, __to_next); 00204 } 00205 00206 int 00207 encoding() const throw() 00208 { return this->do_encoding(); } 00209 00210 bool 00211 always_noconv() const throw() 00212 { return this->do_always_noconv(); } 00213 00214 int 00215 length(state_type& __state, const extern_type* __from, 00216 const extern_type* __end, size_t __max) const 00217 { return this->do_length(__state, __from, __end, __max); } 00218 00219 int 00220 max_length() const throw() 00221 { return this->do_max_length(); } 00222 00223 protected: 00224 explicit 00225 __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } 00226 00227 virtual 00228 ~__codecvt_abstract_base() { } 00229 00230 /** 00231 * @brief Convert from internal to external character set. 00232 * 00233 * Converts input string of intern_type to output string of 00234 * extern_type. This function is a hook for derived classes to change 00235 * the value returned. @see out for more information. 00236 */ 00237 virtual result 00238 do_out(state_type& __state, const intern_type* __from, 00239 const intern_type* __from_end, const intern_type*& __from_next, 00240 extern_type* __to, extern_type* __to_end, 00241 extern_type*& __to_next) const = 0; 00242 00243 virtual result 00244 do_unshift(state_type& __state, extern_type* __to, 00245 extern_type* __to_end, extern_type*& __to_next) const = 0; 00246 00247 virtual result 00248 do_in(state_type& __state, const extern_type* __from, 00249 const extern_type* __from_end, const extern_type*& __from_next, 00250 intern_type* __to, intern_type* __to_end, 00251 intern_type*& __to_next) const = 0; 00252 00253 virtual int 00254 do_encoding() const throw() = 0; 00255 00256 virtual bool 00257 do_always_noconv() const throw() = 0; 00258 00259 virtual int 00260 do_length(state_type&, const extern_type* __from, 00261 const extern_type* __end, size_t __max) const = 0; 00262 00263 virtual int 00264 do_max_length() const throw() = 0; 00265 }; 00266 00267 00268 00269 /** 00270 * @brief Primary class template codecvt. 00271 * @ingroup locales 00272 * 00273 * NB: Generic, mostly useless implementation. 00274 * 00275 */ 00276 template<typename _InternT, typename _ExternT, typename _StateT> 00277 class codecvt 00278 : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> 00279 { 00280 public: 00281 // Types: 00282 typedef codecvt_base::result result; 00283 typedef _InternT intern_type; 00284 typedef _ExternT extern_type; 00285 typedef _StateT state_type; 00286 00287 protected: 00288 __c_locale _M_c_locale_codecvt; 00289 00290 public: 00291 static locale::id id; 00292 00293 explicit 00294 codecvt(size_t __refs = 0) 00295 : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { } 00296 00297 explicit 00298 codecvt(__c_locale __cloc, size_t __refs = 0); 00299 00300 protected: 00301 virtual 00302 ~codecvt() { } 00303 00304 virtual result 00305 do_out(state_type& __state, const intern_type* __from, 00306 const intern_type* __from_end, const intern_type*& __from_next, 00307 extern_type* __to, extern_type* __to_end, 00308 extern_type*& __to_next) const; 00309 00310 virtual result 00311 do_unshift(state_type& __state, extern_type* __to, 00312 extern_type* __to_end, extern_type*& __to_next) const; 00313 00314 virtual result 00315 do_in(state_type& __state, const extern_type* __from, 00316 const extern_type* __from_end, const extern_type*& __from_next, 00317 intern_type* __to, intern_type* __to_end, 00318 intern_type*& __to_next) const; 00319 00320 virtual int 00321 do_encoding() const throw(); 00322 00323 virtual bool 00324 do_always_noconv() const throw(); 00325 00326 virtual int 00327 do_length(state_type&, const extern_type* __from, 00328 const extern_type* __end, size_t __max) const; 00329 00330 virtual int 00331 do_max_length() const throw(); 00332 }; 00333 00334 template<typename _InternT, typename _ExternT, typename _StateT> 00335 locale::id codecvt<_InternT, _ExternT, _StateT>::id; 00336 00337 /// class codecvt<char, char, mbstate_t> specialization. 00338 template<> 00339 class codecvt<char, char, mbstate_t> 00340 : public __codecvt_abstract_base<char, char, mbstate_t> 00341 { 00342 public: 00343 // Types: 00344 typedef char intern_type; 00345 typedef char extern_type; 00346 typedef mbstate_t state_type; 00347 00348 protected: 00349 __c_locale _M_c_locale_codecvt; 00350 00351 public: 00352 static locale::id id; 00353 00354 explicit 00355 codecvt(size_t __refs = 0); 00356 00357 explicit 00358 codecvt(__c_locale __cloc, size_t __refs = 0); 00359 00360 protected: 00361 virtual 00362 ~codecvt(); 00363 00364 virtual result 00365 do_out(state_type& __state, const intern_type* __from, 00366 const intern_type* __from_end, const intern_type*& __from_next, 00367 extern_type* __to, extern_type* __to_end, 00368 extern_type*& __to_next) const; 00369 00370 virtual result 00371 do_unshift(state_type& __state, extern_type* __to, 00372 extern_type* __to_end, extern_type*& __to_next) const; 00373 00374 virtual result 00375 do_in(state_type& __state, const extern_type* __from, 00376 const extern_type* __from_end, const extern_type*& __from_next, 00377 intern_type* __to, intern_type* __to_end, 00378 intern_type*& __to_next) const; 00379 00380 virtual int 00381 do_encoding() const throw(); 00382 00383 virtual bool 00384 do_always_noconv() const throw(); 00385 00386 virtual int 00387 do_length(state_type&, const extern_type* __from, 00388 const extern_type* __end, size_t __max) const; 00389 00390 virtual int 00391 do_max_length() const throw(); 00392 }; 00393 00394 #ifdef _GLIBCXX_USE_WCHAR_T 00395 /// class codecvt<wchar_t, char, mbstate_t> specialization. 00396 template<> 00397 class codecvt<wchar_t, char, mbstate_t> 00398 : public __codecvt_abstract_base<wchar_t, char, mbstate_t> 00399 { 00400 public: 00401 // Types: 00402 typedef wchar_t intern_type; 00403 typedef char extern_type; 00404 typedef mbstate_t state_type; 00405 00406 protected: 00407 __c_locale _M_c_locale_codecvt; 00408 00409 public: 00410 static locale::id id; 00411 00412 explicit 00413 codecvt(size_t __refs = 0); 00414 00415 explicit 00416 codecvt(__c_locale __cloc, size_t __refs = 0); 00417 00418 protected: 00419 virtual 00420 ~codecvt(); 00421 00422 virtual result 00423 do_out(state_type& __state, const intern_type* __from, 00424 const intern_type* __from_end, const intern_type*& __from_next, 00425 extern_type* __to, extern_type* __to_end, 00426 extern_type*& __to_next) const; 00427 00428 virtual result 00429 do_unshift(state_type& __state, 00430 extern_type* __to, extern_type* __to_end, 00431 extern_type*& __to_next) const; 00432 00433 virtual result 00434 do_in(state_type& __state, 00435 const extern_type* __from, const extern_type* __from_end, 00436 const extern_type*& __from_next, 00437 intern_type* __to, intern_type* __to_end, 00438 intern_type*& __to_next) const; 00439 00440 virtual 00441 int do_encoding() const throw(); 00442 00443 virtual 00444 bool do_always_noconv() const throw(); 00445 00446 virtual 00447 int do_length(state_type&, const extern_type* __from, 00448 const extern_type* __end, size_t __max) const; 00449 00450 virtual int 00451 do_max_length() const throw(); 00452 }; 00453 #endif //_GLIBCXX_USE_WCHAR_T 00454 00455 /// class codecvt_byname [22.2.1.6]. 00456 template<typename _InternT, typename _ExternT, typename _StateT> 00457 class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> 00458 { 00459 public: 00460 explicit 00461 codecvt_byname(const char* __s, size_t __refs = 0) 00462 : codecvt<_InternT, _ExternT, _StateT>(__refs) 00463 { 00464 if (__builtin_strcmp(__s, "C") != 0 00465 && __builtin_strcmp(__s, "POSIX") != 0) 00466 { 00467 this->_S_destroy_c_locale(this->_M_c_locale_codecvt); 00468 this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); 00469 } 00470 } 00471 00472 protected: 00473 virtual 00474 ~codecvt_byname() { } 00475 }; 00476 00477 // Inhibit implicit instantiations for required instantiations, 00478 // which are defined via explicit instantiations elsewhere. 00479 #if _GLIBCXX_EXTERN_TEMPLATE 00480 extern template class codecvt_byname<char, char, mbstate_t>; 00481 00482 extern template 00483 const codecvt<char, char, mbstate_t>& 00484 use_facet<codecvt<char, char, mbstate_t> >(const locale&); 00485 00486 extern template 00487 bool 00488 has_facet<codecvt<char, char, mbstate_t> >(const locale&); 00489 00490 #ifdef _GLIBCXX_USE_WCHAR_T 00491 extern template class codecvt_byname<wchar_t, char, mbstate_t>; 00492 00493 extern template 00494 const codecvt<wchar_t, char, mbstate_t>& 00495 use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); 00496 00497 extern template 00498 bool 00499 has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); 00500 #endif 00501 #endif 00502 00503 _GLIBCXX_END_NAMESPACE_VERSION 00504 } // namespace std 00505 00506 #endif // _CODECVT_H