| 1 | // Locale support (codecvt) -*- C++ -*- | 
| 2 |  | 
| 3 | // Copyright (C) 2000-2019 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 |    *  @brief  Primary class template codecvt. | 
| 268 |    *  @ingroup locales | 
| 269 |    * | 
| 270 |    *  NB: Generic, mostly useless implementation. | 
| 271 |    * | 
| 272 |   */ | 
| 273 |    template<typename _InternT, typename _ExternT, typename _StateT> | 
| 274 |     class codecvt | 
| 275 |     : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> | 
| 276 |     { | 
| 277 |     public: | 
| 278 |       // Types: | 
| 279 |       typedef codecvt_base::result	result; | 
| 280 |       typedef _InternT			intern_type; | 
| 281 |       typedef _ExternT			extern_type; | 
| 282 |       typedef _StateT			state_type; | 
| 283 |  | 
| 284 |     protected: | 
| 285 |       __c_locale			_M_c_locale_codecvt; | 
| 286 |  | 
| 287 |     public: | 
| 288 |       static locale::id			id; | 
| 289 |  | 
| 290 |       explicit | 
| 291 |       codecvt(size_t __refs = 0) | 
| 292 |       : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs), | 
| 293 | 	_M_c_locale_codecvt(0) | 
| 294 |       { } | 
| 295 |  | 
| 296 |       explicit | 
| 297 |       codecvt(__c_locale __cloc, size_t __refs = 0); | 
| 298 |  | 
| 299 |     protected: | 
| 300 |       virtual | 
| 301 |       ~codecvt() { } | 
| 302 |  | 
| 303 |       virtual result | 
| 304 |       do_out(state_type& __state, const intern_type* __from, | 
| 305 | 	     const intern_type* __from_end, const intern_type*& __from_next, | 
| 306 | 	     extern_type* __to, extern_type* __to_end, | 
| 307 | 	     extern_type*& __to_next) const; | 
| 308 |  | 
| 309 |       virtual result | 
| 310 |       do_unshift(state_type& __state, extern_type* __to, | 
| 311 | 		 extern_type* __to_end, extern_type*& __to_next) const; | 
| 312 |  | 
| 313 |       virtual result | 
| 314 |       do_in(state_type& __state, const extern_type* __from, | 
| 315 | 	    const extern_type* __from_end, const extern_type*& __from_next, | 
| 316 | 	    intern_type* __to, intern_type* __to_end, | 
| 317 | 	    intern_type*& __to_next) const; | 
| 318 |  | 
| 319 |       virtual int | 
| 320 |       do_encoding() const throw(); | 
| 321 |  | 
| 322 |       virtual bool | 
| 323 |       do_always_noconv() const throw(); | 
| 324 |  | 
| 325 |       virtual int | 
| 326 |       do_length(state_type&, const extern_type* __from, | 
| 327 | 		const extern_type* __end, size_t __max) const; | 
| 328 |  | 
| 329 |       virtual int | 
| 330 |       do_max_length() const throw(); | 
| 331 |     }; | 
| 332 |  | 
| 333 |   template<typename _InternT, typename _ExternT, typename _StateT> | 
| 334 |     locale::id codecvt<_InternT, _ExternT, _StateT>::id; | 
| 335 |  | 
| 336 |   /// class codecvt<char, char, mbstate_t> specialization. | 
| 337 |   template<> | 
| 338 |     class codecvt<char, char, mbstate_t> | 
| 339 |     : public __codecvt_abstract_base<char, char, mbstate_t> | 
| 340 |     { | 
| 341 |       friend class messages<char>; | 
| 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 |   /** @brief  Class codecvt<wchar_t, char, mbstate_t> specialization. | 
| 397 |    * | 
| 398 |    *  Converts between narrow and wide characters in the native character set | 
| 399 |    */ | 
| 400 |   template<> | 
| 401 |     class codecvt<wchar_t, char, mbstate_t> | 
| 402 |     : public __codecvt_abstract_base<wchar_t, char, mbstate_t> | 
| 403 |     { | 
| 404 |       friend class messages<wchar_t>; | 
| 405 |  | 
| 406 |     public: | 
| 407 |       // Types: | 
| 408 |       typedef wchar_t			intern_type; | 
| 409 |       typedef char			extern_type; | 
| 410 |       typedef mbstate_t			state_type; | 
| 411 |  | 
| 412 |     protected: | 
| 413 |       __c_locale			_M_c_locale_codecvt; | 
| 414 |  | 
| 415 |     public: | 
| 416 |       static locale::id			id; | 
| 417 |  | 
| 418 |       explicit | 
| 419 |       codecvt(size_t __refs = 0); | 
| 420 |  | 
| 421 |       explicit | 
| 422 |       codecvt(__c_locale __cloc, size_t __refs = 0); | 
| 423 |  | 
| 424 |     protected: | 
| 425 |       virtual | 
| 426 |       ~codecvt(); | 
| 427 |  | 
| 428 |       virtual result | 
| 429 |       do_out(state_type& __state, const intern_type* __from, | 
| 430 | 	     const intern_type* __from_end, const intern_type*& __from_next, | 
| 431 | 	     extern_type* __to, extern_type* __to_end, | 
| 432 | 	     extern_type*& __to_next) const; | 
| 433 |  | 
| 434 |       virtual result | 
| 435 |       do_unshift(state_type& __state, | 
| 436 | 		 extern_type* __to, extern_type* __to_end, | 
| 437 | 		 extern_type*& __to_next) const; | 
| 438 |  | 
| 439 |       virtual result | 
| 440 |       do_in(state_type& __state, | 
| 441 | 	     const extern_type* __from, const extern_type* __from_end, | 
| 442 | 	     const extern_type*& __from_next, | 
| 443 | 	     intern_type* __to, intern_type* __to_end, | 
| 444 | 	     intern_type*& __to_next) const; | 
| 445 |  | 
| 446 |       virtual | 
| 447 |       int do_encoding() const throw(); | 
| 448 |  | 
| 449 |       virtual | 
| 450 |       bool do_always_noconv() const throw(); | 
| 451 |  | 
| 452 |       virtual | 
| 453 |       int do_length(state_type&, const extern_type* __from, | 
| 454 | 		    const extern_type* __end, size_t __max) const; | 
| 455 |  | 
| 456 |       virtual int | 
| 457 |       do_max_length() const throw(); | 
| 458 |     }; | 
| 459 | #endif //_GLIBCXX_USE_WCHAR_T | 
| 460 |  | 
| 461 | #if __cplusplus >= 201103L | 
| 462 |   /** @brief  Class codecvt<char16_t, char, mbstate_t> specialization. | 
| 463 |    * | 
| 464 |    *  Converts between UTF-16 and UTF-8. | 
| 465 |    */ | 
| 466 |   template<> | 
| 467 |     class codecvt<char16_t, char, mbstate_t> | 
| 468 |     : public __codecvt_abstract_base<char16_t, char, mbstate_t> | 
| 469 |     { | 
| 470 |     public: | 
| 471 |       // Types: | 
| 472 |       typedef char16_t			intern_type; | 
| 473 |       typedef char			extern_type; | 
| 474 |       typedef mbstate_t			state_type; | 
| 475 |  | 
| 476 |     public: | 
| 477 |       static locale::id			id; | 
| 478 |  | 
| 479 |       explicit | 
| 480 |       codecvt(size_t __refs = 0) | 
| 481 |       : __codecvt_abstract_base<char16_t, char, mbstate_t>(__refs) { } | 
| 482 |  | 
| 483 |     protected: | 
| 484 |       virtual | 
| 485 |       ~codecvt(); | 
| 486 |  | 
| 487 |       virtual result | 
| 488 |       do_out(state_type& __state, const intern_type* __from, | 
| 489 | 	     const intern_type* __from_end, const intern_type*& __from_next, | 
| 490 | 	     extern_type* __to, extern_type* __to_end, | 
| 491 | 	     extern_type*& __to_next) const; | 
| 492 |  | 
| 493 |       virtual result | 
| 494 |       do_unshift(state_type& __state, | 
| 495 | 		 extern_type* __to, extern_type* __to_end, | 
| 496 | 		 extern_type*& __to_next) const; | 
| 497 |  | 
| 498 |       virtual result | 
| 499 |       do_in(state_type& __state, | 
| 500 | 	     const extern_type* __from, const extern_type* __from_end, | 
| 501 | 	     const extern_type*& __from_next, | 
| 502 | 	     intern_type* __to, intern_type* __to_end, | 
| 503 | 	     intern_type*& __to_next) const; | 
| 504 |  | 
| 505 |       virtual | 
| 506 |       int do_encoding() const throw(); | 
| 507 |  | 
| 508 |       virtual | 
| 509 |       bool do_always_noconv() const throw(); | 
| 510 |  | 
| 511 |       virtual | 
| 512 |       int do_length(state_type&, const extern_type* __from, | 
| 513 | 		    const extern_type* __end, size_t __max) const; | 
| 514 |  | 
| 515 |       virtual int | 
| 516 |       do_max_length() const throw(); | 
| 517 |     }; | 
| 518 |  | 
| 519 |   /** @brief  Class codecvt<char32_t, char, mbstate_t> specialization. | 
| 520 |    * | 
| 521 |    *  Converts between UTF-32 and UTF-8. | 
| 522 |    */ | 
| 523 |   template<> | 
| 524 |     class codecvt<char32_t, char, mbstate_t> | 
| 525 |     : public __codecvt_abstract_base<char32_t, char, mbstate_t> | 
| 526 |     { | 
| 527 |     public: | 
| 528 |       // Types: | 
| 529 |       typedef char32_t			intern_type; | 
| 530 |       typedef char			extern_type; | 
| 531 |       typedef mbstate_t			state_type; | 
| 532 |  | 
| 533 |     public: | 
| 534 |       static locale::id			id; | 
| 535 |  | 
| 536 |       explicit | 
| 537 |       codecvt(size_t __refs = 0) | 
| 538 |       : __codecvt_abstract_base<char32_t, char, mbstate_t>(__refs) { } | 
| 539 |  | 
| 540 |     protected: | 
| 541 |       virtual | 
| 542 |       ~codecvt(); | 
| 543 |  | 
| 544 |       virtual result | 
| 545 |       do_out(state_type& __state, const intern_type* __from, | 
| 546 | 	     const intern_type* __from_end, const intern_type*& __from_next, | 
| 547 | 	     extern_type* __to, extern_type* __to_end, | 
| 548 | 	     extern_type*& __to_next) const; | 
| 549 |  | 
| 550 |       virtual result | 
| 551 |       do_unshift(state_type& __state, | 
| 552 | 		 extern_type* __to, extern_type* __to_end, | 
| 553 | 		 extern_type*& __to_next) const; | 
| 554 |  | 
| 555 |       virtual result | 
| 556 |       do_in(state_type& __state, | 
| 557 | 	     const extern_type* __from, const extern_type* __from_end, | 
| 558 | 	     const extern_type*& __from_next, | 
| 559 | 	     intern_type* __to, intern_type* __to_end, | 
| 560 | 	     intern_type*& __to_next) const; | 
| 561 |  | 
| 562 |       virtual | 
| 563 |       int do_encoding() const throw(); | 
| 564 |  | 
| 565 |       virtual | 
| 566 |       bool do_always_noconv() const throw(); | 
| 567 |  | 
| 568 |       virtual | 
| 569 |       int do_length(state_type&, const extern_type* __from, | 
| 570 | 		    const extern_type* __end, size_t __max) const; | 
| 571 |  | 
| 572 |       virtual int | 
| 573 |       do_max_length() const throw(); | 
| 574 |     }; | 
| 575 |  | 
| 576 | #ifdef _GLIBCXX_USE_CHAR8_T | 
| 577 |   /** @brief  Class codecvt<char16_t, char8_t, mbstate_t> specialization. | 
| 578 |    * | 
| 579 |    *  Converts between UTF-16 and UTF-8. | 
| 580 |    */ | 
| 581 |   template<> | 
| 582 |     class codecvt<char16_t, char8_t, mbstate_t> | 
| 583 |     : public __codecvt_abstract_base<char16_t, char8_t, mbstate_t> | 
| 584 |     { | 
| 585 |     public: | 
| 586 |       // Types: | 
| 587 |       typedef char16_t			intern_type; | 
| 588 |       typedef char8_t			extern_type; | 
| 589 |       typedef mbstate_t			state_type; | 
| 590 |  | 
| 591 |     public: | 
| 592 |       static locale::id			id; | 
| 593 |  | 
| 594 |       explicit | 
| 595 |       codecvt(size_t __refs = 0) | 
| 596 |       : __codecvt_abstract_base<char16_t, char8_t, mbstate_t>(__refs) { } | 
| 597 |  | 
| 598 |     protected: | 
| 599 |       virtual | 
| 600 |       ~codecvt(); | 
| 601 |  | 
| 602 |       virtual result | 
| 603 |       do_out(state_type& __state, const intern_type* __from, | 
| 604 | 	     const intern_type* __from_end, const intern_type*& __from_next, | 
| 605 | 	     extern_type* __to, extern_type* __to_end, | 
| 606 | 	     extern_type*& __to_next) const; | 
| 607 |  | 
| 608 |       virtual result | 
| 609 |       do_unshift(state_type& __state, | 
| 610 | 		 extern_type* __to, extern_type* __to_end, | 
| 611 | 		 extern_type*& __to_next) const; | 
| 612 |  | 
| 613 |       virtual result | 
| 614 |       do_in(state_type& __state, | 
| 615 | 	     const extern_type* __from, const extern_type* __from_end, | 
| 616 | 	     const extern_type*& __from_next, | 
| 617 | 	     intern_type* __to, intern_type* __to_end, | 
| 618 | 	     intern_type*& __to_next) const; | 
| 619 |  | 
| 620 |       virtual | 
| 621 |       int do_encoding() const throw(); | 
| 622 |  | 
| 623 |       virtual | 
| 624 |       bool do_always_noconv() const throw(); | 
| 625 |  | 
| 626 |       virtual | 
| 627 |       int do_length(state_type&, const extern_type* __from, | 
| 628 | 		    const extern_type* __end, size_t __max) const; | 
| 629 |  | 
| 630 |       virtual int | 
| 631 |       do_max_length() const throw(); | 
| 632 |     }; | 
| 633 |  | 
| 634 |   /** @brief  Class codecvt<char32_t, char8_t, mbstate_t> specialization. | 
| 635 |    * | 
| 636 |    *  Converts between UTF-32 and UTF-8. | 
| 637 |    */ | 
| 638 |   template<> | 
| 639 |     class codecvt<char32_t, char8_t, mbstate_t> | 
| 640 |     : public __codecvt_abstract_base<char32_t, char8_t, mbstate_t> | 
| 641 |     { | 
| 642 |     public: | 
| 643 |       // Types: | 
| 644 |       typedef char32_t			intern_type; | 
| 645 |       typedef char8_t			extern_type; | 
| 646 |       typedef mbstate_t			state_type; | 
| 647 |  | 
| 648 |     public: | 
| 649 |       static locale::id			id; | 
| 650 |  | 
| 651 |       explicit | 
| 652 |       codecvt(size_t __refs = 0) | 
| 653 |       : __codecvt_abstract_base<char32_t, char8_t, mbstate_t>(__refs) { } | 
| 654 |  | 
| 655 |     protected: | 
| 656 |       virtual | 
| 657 |       ~codecvt(); | 
| 658 |  | 
| 659 |       virtual result | 
| 660 |       do_out(state_type& __state, const intern_type* __from, | 
| 661 | 	     const intern_type* __from_end, const intern_type*& __from_next, | 
| 662 | 	     extern_type* __to, extern_type* __to_end, | 
| 663 | 	     extern_type*& __to_next) const; | 
| 664 |  | 
| 665 |       virtual result | 
| 666 |       do_unshift(state_type& __state, | 
| 667 | 		 extern_type* __to, extern_type* __to_end, | 
| 668 | 		 extern_type*& __to_next) const; | 
| 669 |  | 
| 670 |       virtual result | 
| 671 |       do_in(state_type& __state, | 
| 672 | 	     const extern_type* __from, const extern_type* __from_end, | 
| 673 | 	     const extern_type*& __from_next, | 
| 674 | 	     intern_type* __to, intern_type* __to_end, | 
| 675 | 	     intern_type*& __to_next) const; | 
| 676 |  | 
| 677 |       virtual | 
| 678 |       int do_encoding() const throw(); | 
| 679 |  | 
| 680 |       virtual | 
| 681 |       bool do_always_noconv() const throw(); | 
| 682 |  | 
| 683 |       virtual | 
| 684 |       int do_length(state_type&, const extern_type* __from, | 
| 685 | 		    const extern_type* __end, size_t __max) const; | 
| 686 |  | 
| 687 |       virtual int | 
| 688 |       do_max_length() const throw(); | 
| 689 |     }; | 
| 690 | #endif // _GLIBCXX_USE_CHAR8_T | 
| 691 |  | 
| 692 | #endif // C++11 | 
| 693 |  | 
| 694 |   /// class codecvt_byname [22.2.1.6]. | 
| 695 |   template<typename _InternT, typename _ExternT, typename _StateT> | 
| 696 |     class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> | 
| 697 |     { | 
| 698 |     public: | 
| 699 |       explicit | 
| 700 |       codecvt_byname(const char* __s, size_t __refs = 0) | 
| 701 |       : codecvt<_InternT, _ExternT, _StateT>(__refs) | 
| 702 |       { | 
| 703 | 	if (__builtin_strcmp(__s, "C" ) != 0 | 
| 704 | 	    && __builtin_strcmp(__s, "POSIX" ) != 0) | 
| 705 | 	  { | 
| 706 | 	    this->_S_destroy_c_locale(this->_M_c_locale_codecvt); | 
| 707 | 	    this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); | 
| 708 | 	  } | 
| 709 |       } | 
| 710 |  | 
| 711 | #if __cplusplus >= 201103L | 
| 712 |       explicit | 
| 713 |       codecvt_byname(const string& __s, size_t __refs = 0) | 
| 714 |       : codecvt_byname(__s.c_str(), __refs) { } | 
| 715 | #endif | 
| 716 |  | 
| 717 |     protected: | 
| 718 |       virtual | 
| 719 |       ~codecvt_byname() { } | 
| 720 |     }; | 
| 721 |  | 
| 722 | #if __cplusplus >= 201103L | 
| 723 |   template<> | 
| 724 |     class codecvt_byname<char16_t, char, mbstate_t> | 
| 725 |     : public codecvt<char16_t, char, mbstate_t> | 
| 726 |     { | 
| 727 |     public: | 
| 728 |       explicit | 
| 729 |       codecvt_byname(const char*, size_t __refs = 0) | 
| 730 |       : codecvt<char16_t, char, mbstate_t>(__refs) { } | 
| 731 |  | 
| 732 |       explicit | 
| 733 |       codecvt_byname(const string& __s, size_t __refs = 0) | 
| 734 |       : codecvt_byname(__s.c_str(), __refs) { } | 
| 735 |  | 
| 736 |     protected: | 
| 737 |       virtual | 
| 738 |       ~codecvt_byname() { } | 
| 739 |     }; | 
| 740 |  | 
| 741 |   template<> | 
| 742 |     class codecvt_byname<char32_t, char, mbstate_t> | 
| 743 |     : public codecvt<char32_t, char, mbstate_t> | 
| 744 |     { | 
| 745 |     public: | 
| 746 |       explicit | 
| 747 |       codecvt_byname(const char*, size_t __refs = 0) | 
| 748 |       : codecvt<char32_t, char, mbstate_t>(__refs) { } | 
| 749 |  | 
| 750 |       explicit | 
| 751 |       codecvt_byname(const string& __s, size_t __refs = 0) | 
| 752 |       : codecvt_byname(__s.c_str(), __refs) { } | 
| 753 |  | 
| 754 |     protected: | 
| 755 |       virtual | 
| 756 |       ~codecvt_byname() { } | 
| 757 |     }; | 
| 758 |  | 
| 759 | #if defined(_GLIBCXX_USE_CHAR8_T) | 
| 760 |   template<> | 
| 761 |     class codecvt_byname<char16_t, char8_t, mbstate_t> | 
| 762 |     : public codecvt<char16_t, char8_t, mbstate_t> | 
| 763 |     { | 
| 764 |     public: | 
| 765 |       explicit | 
| 766 |       codecvt_byname(const char* __s, size_t __refs = 0) | 
| 767 |       : codecvt<char16_t, char8_t, mbstate_t>(__refs) { } | 
| 768 |  | 
| 769 |       explicit | 
| 770 |       codecvt_byname(const string& __s, size_t __refs = 0) | 
| 771 |       : codecvt_byname(__s.c_str(), __refs) { } | 
| 772 |  | 
| 773 |     protected: | 
| 774 |       virtual | 
| 775 |       ~codecvt_byname() { } | 
| 776 |     }; | 
| 777 |  | 
| 778 |   template<> | 
| 779 |     class codecvt_byname<char32_t, char8_t, mbstate_t> | 
| 780 |     : public codecvt<char32_t, char8_t, mbstate_t> | 
| 781 |     { | 
| 782 |     public: | 
| 783 |       explicit | 
| 784 |       codecvt_byname(const char* __s, size_t __refs = 0) | 
| 785 |       : codecvt<char32_t, char8_t, mbstate_t>(__refs) { } | 
| 786 |  | 
| 787 |       explicit | 
| 788 |       codecvt_byname(const string& __s, size_t __refs = 0) | 
| 789 |       : codecvt_byname(__s.c_str(), __refs) { } | 
| 790 |  | 
| 791 |     protected: | 
| 792 |       virtual | 
| 793 |       ~codecvt_byname() { } | 
| 794 |     }; | 
| 795 | #endif | 
| 796 |  | 
| 797 | #endif // C++11 | 
| 798 |  | 
| 799 |   // Inhibit implicit instantiations for required instantiations, | 
| 800 |   // which are defined via explicit instantiations elsewhere. | 
| 801 | #if _GLIBCXX_EXTERN_TEMPLATE | 
| 802 |   extern template class codecvt_byname<char, char, mbstate_t>; | 
| 803 |  | 
| 804 |   extern template | 
| 805 |     const codecvt<char, char, mbstate_t>& | 
| 806 |     use_facet<codecvt<char, char, mbstate_t> >(const locale&); | 
| 807 |  | 
| 808 |   extern template | 
| 809 |     bool | 
| 810 |     has_facet<codecvt<char, char, mbstate_t> >(const locale&); | 
| 811 |  | 
| 812 | #ifdef _GLIBCXX_USE_WCHAR_T | 
| 813 |   extern template class codecvt_byname<wchar_t, char, mbstate_t>; | 
| 814 |  | 
| 815 |   extern template | 
| 816 |     const codecvt<wchar_t, char, mbstate_t>& | 
| 817 |     use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); | 
| 818 |  | 
| 819 |   extern template | 
| 820 |     bool | 
| 821 |     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); | 
| 822 | #endif | 
| 823 |  | 
| 824 | #if __cplusplus >= 201103L | 
| 825 |   extern template class codecvt_byname<char16_t, char, mbstate_t>; | 
| 826 |   extern template class codecvt_byname<char32_t, char, mbstate_t>; | 
| 827 |  | 
| 828 | #if defined(_GLIBCXX_USE_CHAR8_T) | 
| 829 |   extern template class codecvt_byname<char16_t, char8_t, mbstate_t>; | 
| 830 |   extern template class codecvt_byname<char32_t, char8_t, mbstate_t>; | 
| 831 | #endif | 
| 832 |  | 
| 833 | #endif | 
| 834 |  | 
| 835 | #endif | 
| 836 |  | 
| 837 | _GLIBCXX_END_NAMESPACE_VERSION | 
| 838 | } // namespace std | 
| 839 |  | 
| 840 | #endif // _CODECVT_H | 
| 841 |  |