]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // Locale support (codecvt) -*- C++ -*- |
2 | ||
8d9254fc | 3 | // Copyright (C) 2000-2020 Free Software Foundation, Inc. |
725dc051 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
725dc051 BK |
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 | ||
748086b7 JJ |
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. | |
725dc051 | 19 | |
748086b7 JJ |
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/>. | |
725dc051 | 24 | |
143c27b0 BK |
25 | /** @file bits/codecvt.h |
26 | * This is an internal header file, included by other library headers. | |
f910786b | 27 | * Do not attempt to use it directly. @headername{locale} |
143c27b0 BK |
28 | */ |
29 | ||
725dc051 BK |
30 | // |
31 | // ISO C++ 14882: 22.2.1.5 Template class codecvt | |
32 | // | |
33 | ||
825bd0e1 | 34 | // Written by Benjamin Kosnik <bkoz@redhat.com> |
725dc051 | 35 | |
3d7c150e BK |
36 | #ifndef _CODECVT_H |
37 | #define _CODECVT_H 1 | |
725dc051 | 38 | |
b0a85b86 GDR |
39 | #pragma GCC system_header |
40 | ||
12ffa228 BK |
41 | namespace std _GLIBCXX_VISIBILITY(default) |
42 | { | |
43 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
78a53887 | 44 | |
939759fc | 45 | /// Empty base class for codecvt facet [22.2.1.5]. |
725dc051 BK |
46 | class codecvt_base |
47 | { | |
48 | public: | |
49 | enum result | |
50 | { | |
51 | ok, | |
52 | partial, | |
53 | error, | |
54 | noconv | |
55 | }; | |
56 | }; | |
57 | ||
ffcec5c8 | 58 | /** |
00aca6e8 | 59 | * @brief Common base for codecvt functions. |
ffcec5c8 JQ |
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 | */ | |
725dc051 | 67 | template<typename _InternT, typename _ExternT, typename _StateT> |
ed6814f7 | 68 | class __codecvt_abstract_base |
725dc051 BK |
69 | : public locale::facet, public codecvt_base |
70 | { | |
71 | public: | |
72 | // Types: | |
38cca750 | 73 | typedef codecvt_base::result result; |
ed6814f7 BI |
74 | typedef _InternT intern_type; |
75 | typedef _ExternT extern_type; | |
76 | typedef _StateT state_type; | |
77 | ||
725dc051 | 78 | // 22.2.1.5.1 codecvt members |
ffcec5c8 JQ |
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 | * | |
28dac70a | 95 | * The @a state argument should be initialized if the input is at the |
ffcec5c8 JQ |
96 | * beginning and carried from a previous call if continuing |
97 | * conversion. There are no guarantees about how @a state is used. | |
98 | * | |
6309eefc BK |
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. | |
ffcec5c8 | 105 | * |
93c66bc6 BK |
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. | |
ffcec5c8 JQ |
113 | * @return codecvt_base::result. |
114 | */ | |
725dc051 | 115 | result |
ed6814f7 | 116 | out(state_type& __state, const intern_type* __from, |
725dc051 | 117 | const intern_type* __from_end, const intern_type*& __from_next, |
ed6814f7 | 118 | extern_type* __to, extern_type* __to_end, |
725dc051 | 119 | extern_type*& __to_next) const |
ed6814f7 BI |
120 | { |
121 | return this->do_out(__state, __from, __from_end, __from_next, | |
122 | __to, __to_end, __to_next); | |
725dc051 BK |
123 | } |
124 | ||
ffcec5c8 JQ |
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 | * | |
93c66bc6 BK |
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. | |
ffcec5c8 JQ |
152 | * @return codecvt_base::result. |
153 | */ | |
725dc051 BK |
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 | ||
ffcec5c8 JQ |
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 | * | |
28dac70a | 175 | * The @a state argument should be initialized if the input is at the |
ffcec5c8 JQ |
176 | * beginning and carried from a previous call if continuing |
177 | * conversion. There are no guarantees about how @a state is used. | |
178 | * | |
6309eefc BK |
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. | |
ffcec5c8 | 185 | * |
93c66bc6 BK |
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. | |
ffcec5c8 JQ |
193 | * @return codecvt_base::result. |
194 | */ | |
725dc051 | 195 | result |
ed6814f7 | 196 | in(state_type& __state, const extern_type* __from, |
725dc051 | 197 | const extern_type* __from_end, const extern_type*& __from_next, |
ed6814f7 | 198 | intern_type* __to, intern_type* __to_end, |
725dc051 | 199 | intern_type*& __to_next) const |
ed6814f7 | 200 | { |
725dc051 | 201 | return this->do_in(__state, __from, __from_end, __from_next, |
ed6814f7 | 202 | __to, __to_end, __to_next); |
725dc051 BK |
203 | } |
204 | ||
ed6814f7 | 205 | int |
725dc051 BK |
206 | encoding() const throw() |
207 | { return this->do_encoding(); } | |
208 | ||
ed6814f7 | 209 | bool |
725dc051 BK |
210 | always_noconv() const throw() |
211 | { return this->do_always_noconv(); } | |
212 | ||
213 | int | |
e61c8e23 | 214 | length(state_type& __state, const extern_type* __from, |
725dc051 BK |
215 | const extern_type* __end, size_t __max) const |
216 | { return this->do_length(__state, __from, __end, __max); } | |
217 | ||
ed6814f7 | 218 | int |
725dc051 BK |
219 | max_length() const throw() |
220 | { return this->do_max_length(); } | |
221 | ||
222 | protected: | |
ed6814f7 | 223 | explicit |
725dc051 BK |
224 | __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } |
225 | ||
ed6814f7 | 226 | virtual |
725dc051 BK |
227 | ~__codecvt_abstract_base() { } |
228 | ||
ffcec5c8 JQ |
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 | */ | |
725dc051 | 236 | virtual result |
ed6814f7 | 237 | do_out(state_type& __state, const intern_type* __from, |
725dc051 BK |
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 | |
ed6814f7 | 243 | do_unshift(state_type& __state, extern_type* __to, |
725dc051 | 244 | extern_type* __to_end, extern_type*& __to_next) const = 0; |
ed6814f7 | 245 | |
725dc051 | 246 | virtual result |
ed6814f7 BI |
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, | |
725dc051 | 250 | intern_type*& __to_next) const = 0; |
ed6814f7 BI |
251 | |
252 | virtual int | |
725dc051 BK |
253 | do_encoding() const throw() = 0; |
254 | ||
ed6814f7 | 255 | virtual bool |
725dc051 BK |
256 | do_always_noconv() const throw() = 0; |
257 | ||
ed6814f7 BI |
258 | virtual int |
259 | do_length(state_type&, const extern_type* __from, | |
725dc051 BK |
260 | const extern_type* __end, size_t __max) const = 0; |
261 | ||
ed6814f7 | 262 | virtual int |
725dc051 BK |
263 | do_max_length() const throw() = 0; |
264 | }; | |
265 | ||
0eb95b0d BK |
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> | |
ed6814f7 | 274 | class codecvt |
725dc051 BK |
275 | : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> |
276 | { | |
ed6814f7 | 277 | public: |
725dc051 | 278 | // Types: |
38cca750 | 279 | typedef codecvt_base::result result; |
ed6814f7 BI |
280 | typedef _InternT intern_type; |
281 | typedef _ExternT extern_type; | |
282 | typedef _StateT state_type; | |
725dc051 | 283 | |
38cca750 BK |
284 | protected: |
285 | __c_locale _M_c_locale_codecvt; | |
286 | ||
287 | public: | |
ed6814f7 | 288 | static locale::id id; |
725dc051 | 289 | |
ed6814f7 BI |
290 | explicit |
291 | codecvt(size_t __refs = 0) | |
b78eebe4 PC |
292 | : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs), |
293 | _M_c_locale_codecvt(0) | |
294 | { } | |
38cca750 | 295 | |
ed6814f7 | 296 | explicit |
38cca750 | 297 | codecvt(__c_locale __cloc, size_t __refs = 0); |
725dc051 BK |
298 | |
299 | protected: | |
ed6814f7 | 300 | virtual |
725dc051 | 301 | ~codecvt() { } |
c7e2dba5 BK |
302 | |
303 | virtual result | |
ed6814f7 | 304 | do_out(state_type& __state, const intern_type* __from, |
c7e2dba5 BK |
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 | |
ed6814f7 | 310 | do_unshift(state_type& __state, extern_type* __to, |
c7e2dba5 | 311 | extern_type* __to_end, extern_type*& __to_next) const; |
ed6814f7 | 312 | |
c7e2dba5 | 313 | virtual result |
ed6814f7 BI |
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, | |
c7e2dba5 | 317 | intern_type*& __to_next) const; |
ed6814f7 BI |
318 | |
319 | virtual int | |
c7e2dba5 BK |
320 | do_encoding() const throw(); |
321 | ||
ed6814f7 | 322 | virtual bool |
c7e2dba5 BK |
323 | do_always_noconv() const throw(); |
324 | ||
ed6814f7 BI |
325 | virtual int |
326 | do_length(state_type&, const extern_type* __from, | |
c7e2dba5 BK |
327 | const extern_type* __end, size_t __max) const; |
328 | ||
ed6814f7 | 329 | virtual int |
c7e2dba5 | 330 | do_max_length() const throw(); |
725dc051 BK |
331 | }; |
332 | ||
333 | template<typename _InternT, typename _ExternT, typename _StateT> | |
334 | locale::id codecvt<_InternT, _ExternT, _StateT>::id; | |
335 | ||
939759fc | 336 | /// class codecvt<char, char, mbstate_t> specialization. |
725dc051 | 337 | template<> |
ed6814f7 | 338 | class codecvt<char, char, mbstate_t> |
725dc051 BK |
339 | : public __codecvt_abstract_base<char, char, mbstate_t> |
340 | { | |
d31008d7 FD |
341 | friend class messages<char>; |
342 | ||
ed6814f7 | 343 | public: |
725dc051 | 344 | // Types: |
ed6814f7 BI |
345 | typedef char intern_type; |
346 | typedef char extern_type; | |
347 | typedef mbstate_t state_type; | |
38cca750 BK |
348 | |
349 | protected: | |
350 | __c_locale _M_c_locale_codecvt; | |
725dc051 | 351 | |
38cca750 | 352 | public: |
725dc051 BK |
353 | static locale::id id; |
354 | ||
ed6814f7 | 355 | explicit |
725dc051 BK |
356 | codecvt(size_t __refs = 0); |
357 | ||
ed6814f7 | 358 | explicit |
38cca750 | 359 | codecvt(__c_locale __cloc, size_t __refs = 0); |
c6b5df53 | 360 | |
725dc051 | 361 | protected: |
ed6814f7 | 362 | virtual |
725dc051 BK |
363 | ~codecvt(); |
364 | ||
365 | virtual result | |
ed6814f7 | 366 | do_out(state_type& __state, const intern_type* __from, |
725dc051 BK |
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 | |
ed6814f7 | 372 | do_unshift(state_type& __state, extern_type* __to, |
725dc051 BK |
373 | extern_type* __to_end, extern_type*& __to_next) const; |
374 | ||
375 | virtual result | |
ed6814f7 | 376 | do_in(state_type& __state, const extern_type* __from, |
725dc051 | 377 | const extern_type* __from_end, const extern_type*& __from_next, |
ed6814f7 | 378 | intern_type* __to, intern_type* __to_end, |
725dc051 BK |
379 | intern_type*& __to_next) const; |
380 | ||
ed6814f7 | 381 | virtual int |
725dc051 BK |
382 | do_encoding() const throw(); |
383 | ||
ed6814f7 | 384 | virtual bool |
725dc051 BK |
385 | do_always_noconv() const throw(); |
386 | ||
ed6814f7 BI |
387 | virtual int |
388 | do_length(state_type&, const extern_type* __from, | |
725dc051 BK |
389 | const extern_type* __end, size_t __max) const; |
390 | ||
ed6814f7 | 391 | virtual int |
725dc051 BK |
392 | do_max_length() const throw(); |
393 | }; | |
394 | ||
3d7c150e | 395 | #ifdef _GLIBCXX_USE_WCHAR_T |
bb93f35d JW |
396 | /** @brief Class codecvt<wchar_t, char, mbstate_t> specialization. |
397 | * | |
398 | * Converts between narrow and wide characters in the native character set | |
399 | */ | |
725dc051 | 400 | template<> |
ed6814f7 | 401 | class codecvt<wchar_t, char, mbstate_t> |
725dc051 BK |
402 | : public __codecvt_abstract_base<wchar_t, char, mbstate_t> |
403 | { | |
d31008d7 FD |
404 | friend class messages<wchar_t>; |
405 | ||
725dc051 BK |
406 | public: |
407 | // Types: | |
ed6814f7 BI |
408 | typedef wchar_t intern_type; |
409 | typedef char extern_type; | |
410 | typedef mbstate_t state_type; | |
725dc051 | 411 | |
38cca750 BK |
412 | protected: |
413 | __c_locale _M_c_locale_codecvt; | |
414 | ||
415 | public: | |
ed6814f7 | 416 | static locale::id id; |
725dc051 | 417 | |
ed6814f7 | 418 | explicit |
725dc051 BK |
419 | codecvt(size_t __refs = 0); |
420 | ||
ed6814f7 | 421 | explicit |
c6b5df53 PC |
422 | codecvt(__c_locale __cloc, size_t __refs = 0); |
423 | ||
725dc051 | 424 | protected: |
ed6814f7 | 425 | virtual |
725dc051 BK |
426 | ~codecvt(); |
427 | ||
428 | virtual result | |
ed6814f7 | 429 | do_out(state_type& __state, const intern_type* __from, |
725dc051 BK |
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 | ||
ed6814f7 | 446 | virtual |
725dc051 BK |
447 | int do_encoding() const throw(); |
448 | ||
ed6814f7 | 449 | virtual |
725dc051 BK |
450 | bool do_always_noconv() const throw(); |
451 | ||
ed6814f7 | 452 | virtual |
e61c8e23 | 453 | int do_length(state_type&, const extern_type* __from, |
725dc051 BK |
454 | const extern_type* __end, size_t __max) const; |
455 | ||
ed6814f7 | 456 | virtual int |
725dc051 BK |
457 | do_max_length() const throw(); |
458 | }; | |
3d7c150e | 459 | #endif //_GLIBCXX_USE_WCHAR_T |
725dc051 | 460 | |
bb93f35d | 461 | #if __cplusplus >= 201103L |
bb93f35d JW |
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 | ||
c124af93 TH |
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 | ||
bb93f35d JW |
692 | #endif // C++11 |
693 | ||
939759fc | 694 | /// class codecvt_byname [22.2.1.6]. |
725dc051 BK |
695 | template<typename _InternT, typename _ExternT, typename _StateT> |
696 | class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> | |
697 | { | |
698 | public: | |
ed6814f7 BI |
699 | explicit |
700 | codecvt_byname(const char* __s, size_t __refs = 0) | |
c6b5df53 | 701 | : codecvt<_InternT, _ExternT, _StateT>(__refs) |
ed6814f7 | 702 | { |
538075fe PC |
703 | if (__builtin_strcmp(__s, "C") != 0 |
704 | && __builtin_strcmp(__s, "POSIX") != 0) | |
bf5fe473 | 705 | { |
563ae04f BK |
706 | this->_S_destroy_c_locale(this->_M_c_locale_codecvt); |
707 | this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); | |
bf5fe473 | 708 | } |
c6b5df53 PC |
709 | } |
710 | ||
71a16cd8 JW |
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 | ||
612c9c70 | 722 | #if __cplusplus >= 201103L |
71a16cd8 JW |
723 | template<> |
724 | class codecvt_byname<char16_t, char, mbstate_t> | |
725 | : public codecvt<char16_t, char, mbstate_t> | |
726 | { | |
727 | public: | |
728 | explicit | |
9ed83a33 | 729 | codecvt_byname(const char*, size_t __refs = 0) |
71a16cd8 JW |
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 | ||
725dc051 | 736 | protected: |
ed6814f7 | 737 | virtual |
725dc051 BK |
738 | ~codecvt_byname() { } |
739 | }; | |
725dc051 | 740 | |
71a16cd8 JW |
741 | template<> |
742 | class codecvt_byname<char32_t, char, mbstate_t> | |
743 | : public codecvt<char32_t, char, mbstate_t> | |
744 | { | |
745 | public: | |
746 | explicit | |
9ed83a33 | 747 | codecvt_byname(const char*, size_t __refs = 0) |
71a16cd8 JW |
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 | }; | |
c124af93 TH |
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 | ||
612c9c70 | 797 | #endif // C++11 |
71a16cd8 | 798 | |
84b31797 PC |
799 | // Inhibit implicit instantiations for required instantiations, |
800 | // which are defined via explicit instantiations elsewhere. | |
84b31797 PC |
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 | |
71a16cd8 | 823 | |
612c9c70 | 824 | #if __cplusplus >= 201103L |
71a16cd8 JW |
825 | extern template class codecvt_byname<char16_t, char, mbstate_t>; |
826 | extern template class codecvt_byname<char32_t, char, mbstate_t>; | |
c124af93 TH |
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 | ||
71a16cd8 JW |
833 | #endif |
834 | ||
84b31797 PC |
835 | #endif |
836 | ||
12ffa228 | 837 | _GLIBCXX_END_NAMESPACE_VERSION |
ed4f96af | 838 | } // namespace std |
78a53887 | 839 | |
3d7c150e | 840 | #endif // _CODECVT_H |