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