Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | // Locale support (codecvt) -*- C++ -*- |
2 | |||
3 | // Copyright (C) 2000, 2001 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 2, 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 | // You should have received a copy of the GNU General Public License along |
||
17 | // with this library; see the file COPYING. If not, write to the Free |
||
18 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
||
19 | // USA. |
||
20 | |||
21 | // As a special exception, you may use this file as part of a free software |
||
22 | // library without restriction. Specifically, if other files instantiate |
||
23 | // templates or use macros or inline functions from this file, or you compile |
||
24 | // this file and link it with other files to produce an executable, this |
||
25 | // file does not by itself cause the resulting executable to be covered by |
||
26 | // the GNU General Public License. This exception does not however |
||
27 | // invalidate any other reasons why the executable file might be covered by |
||
28 | // the GNU General Public License. |
||
29 | |||
30 | // |
||
31 | // ISO C++ 14882: 22.2.1.5 Template class codecvt |
||
32 | // |
||
33 | |||
34 | // Warning: this file is not meant for user inclusion. Use |
||
35 | |||
36 | // Written by Benjamin Kosnik |
||
37 | |||
38 | #ifndef _CPP_BITS_CODECVT_H |
||
39 | #define _CPP_BITS_CODECVT_H 1 |
||
40 | |||
41 | #pragma GCC system_header |
||
42 | |||
43 | // XXX |
||
44 | // __enc_traits may need to move up the locale header hierarchy, |
||
45 | // depending on if ctype ends up using it. |
||
46 | |||
47 | #ifdef _GLIBCPP_USE_WCHAR_T |
||
48 | // Extensions to use icov for dealing with character encodings, |
||
49 | // including conversions and comparisons between various character |
||
50 | // sets. This object encapsulates data that may need to be shared between |
||
51 | // char_traits, codecvt and ctype. |
||
52 | |||
53 | #if _GLIBCPP_USE_SHADOW_HEADERS |
||
54 | using _C_legacy::CODESET; |
||
55 | #endif |
||
56 | |||
57 | class __enc_traits |
||
58 | { |
||
59 | public: |
||
60 | // Types: |
||
61 | // NB: A conversion descriptor subsumes and enhances the |
||
62 | // functionality of a simple state type such as mbstate_t. |
||
63 | typedef iconv_t __desc_type; |
||
64 | |||
65 | protected: |
||
66 | // Data Members: |
||
67 | // Max size of charset encoding name |
||
68 | static const int _S_max_size = 32; |
||
69 | // Name of internal character set encoding. |
||
70 | char _M_int_enc[_S_max_size]; |
||
71 | // Name of external character set encoding. |
||
72 | char _M_ext_enc[_S_max_size]; |
||
73 | |||
74 | // Conversion descriptor between external encoding to internal encoding. |
||
75 | __desc_type _M_in_desc; |
||
76 | // Conversion descriptor between internal encoding to external encoding. |
||
77 | __desc_type _M_out_desc; |
||
78 | |||
79 | // Details the byte-order marker for the external encoding, if necessary. |
||
80 | int _M_ext_bom; |
||
81 | |||
82 | // Details the byte-order marker for the internal encoding, if necessary. |
||
83 | int _M_int_bom; |
||
84 | |||
85 | public: |
||
86 | __enc_traits() |
||
87 | : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0) |
||
88 | { |
||
89 | // __intc_end = whatever we are using internally, which is |
||
90 | // UCS4 (linux) |
||
91 | // UCS2 == UNICODE (microsoft, java, aix, whatever...) |
||
92 | // XXX Currently don't know how to get this data from target system... |
||
93 | strcpy(_M_int_enc, "UCS4"); |
||
94 | |||
95 | // __extc_end = external codeset in current locale |
||
96 | strcpy(_M_ext_enc, nl_langinfo(CODESET)); |
||
97 | } |
||
98 | |||
99 | __enc_traits(const char* __int, const char* __ext, int __ibom = 0, |
||
100 | int __ebom = 0) |
||
101 | : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0) |
||
102 | { |
||
103 | strncpy(_M_int_enc, __int, _S_max_size); |
||
104 | strncpy(_M_ext_enc, __ext, _S_max_size); |
||
105 | } |
||
106 | |||
107 | // 21.1.2 traits typedefs |
||
108 | // p4 |
||
109 | // typedef STATE_T state_type |
||
110 | // requires: state_type shall meet the requirements of |
||
111 | // CopyConstructible types (20.1.3) |
||
112 | __enc_traits(const __enc_traits& __obj) |
||
113 | { |
||
114 | strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size); |
||
115 | strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size); |
||
116 | _M_ext_bom = __obj._M_ext_bom; |
||
117 | _M_int_bom = __obj._M_int_bom; |
||
118 | } |
||
119 | |||
120 | ~__enc_traits() |
||
121 | { |
||
122 | iconv_close(_M_in_desc); |
||
123 | iconv_close(_M_out_desc); |
||
124 | } |
||
125 | |||
126 | // Initializes |
||
127 | void |
||
128 | _M_init() |
||
129 | { |
||
130 | _M_in_desc = iconv_open(_M_int_enc, _M_ext_enc); |
||
131 | _M_out_desc = iconv_open(_M_ext_enc, _M_int_enc); |
||
132 | if (_M_out_desc == iconv_t(-1) || _M_in_desc == iconv_t(-1)) |
||
133 | { |
||
134 | // XXX Extended error checking. |
||
135 | } |
||
136 | } |
||
137 | |||
138 | bool |
||
139 | _M_good() |
||
140 | { |
||
141 | return _M_out_desc && _M_in_desc |
||
142 | && _M_out_desc != iconv_t(-1) && _M_in_desc != iconv_t(-1); |
||
143 | } |
||
144 | |||
145 | const __desc_type* |
||
146 | _M_get_in_descriptor() |
||
147 | { return &_M_in_desc; } |
||
148 | |||
149 | const __desc_type* |
||
150 | _M_get_out_descriptor() |
||
151 | { return &_M_out_desc; } |
||
152 | |||
153 | const char* |
||
154 | _M_get_internal_enc() |
||
155 | { return _M_int_enc; } |
||
156 | |||
157 | const char* |
||
158 | _M_get_external_enc() |
||
159 | { return _M_ext_enc; } |
||
160 | |||
161 | int |
||
162 | _M_get_external_bom() |
||
163 | { return _M_ext_bom; } |
||
164 | |||
165 | int |
||
166 | _M_get_internal_bom() |
||
167 | { return _M_int_bom; } |
||
168 | }; |
||
169 | #endif //_GLIBCPP_USE_WCHAR_T |
||
170 | |||
171 | |||
172 | // 22.2.1.5 Template class codecvt |
||
173 | class codecvt_base |
||
174 | { |
||
175 | public: |
||
176 | enum result |
||
177 | { |
||
178 | ok, |
||
179 | partial, |
||
180 | error, |
||
181 | noconv |
||
182 | }; |
||
183 | }; |
||
184 | |||
185 | // Template class __codecvt_abstract_base |
||
186 | // NB: An abstract base class that fills in the public inlines, so |
||
187 | // that the specializations don't have to re-copy the public |
||
188 | // interface. |
||
189 | template |
||
190 | class __codecvt_abstract_base |
||
191 | : public locale::facet, public codecvt_base |
||
192 | { |
||
193 | public: |
||
194 | // Types: |
||
195 | typedef codecvt_base::result result; |
||
196 | typedef _InternT intern_type; |
||
197 | typedef _ExternT extern_type; |
||
198 | typedef _StateT state_type; |
||
199 | |||
200 | // 22.2.1.5.1 codecvt members |
||
201 | result |
||
202 | out(state_type& __state, const intern_type* __from, |
||
203 | const intern_type* __from_end, const intern_type*& __from_next, |
||
204 | extern_type* __to, extern_type* __to_end, |
||
205 | extern_type*& __to_next) const |
||
206 | { |
||
207 | return this->do_out(__state, __from, __from_end, __from_next, |
||
208 | __to, __to_end, __to_next); |
||
209 | } |
||
210 | |||
211 | result |
||
212 | unshift(state_type& __state, extern_type* __to, extern_type* __to_end, |
||
213 | extern_type*& __to_next) const |
||
214 | { return this->do_unshift(__state, __to,__to_end,__to_next); } |
||
215 | |||
216 | result |
||
217 | in(state_type& __state, const extern_type* __from, |
||
218 | const extern_type* __from_end, const extern_type*& __from_next, |
||
219 | intern_type* __to, intern_type* __to_end, |
||
220 | intern_type*& __to_next) const |
||
221 | { |
||
222 | return this->do_in(__state, __from, __from_end, __from_next, |
||
223 | __to, __to_end, __to_next); |
||
224 | } |
||
225 | |||
226 | int |
||
227 | encoding() const throw() |
||
228 | { return this->do_encoding(); } |
||
229 | |||
230 | bool |
||
231 | always_noconv() const throw() |
||
232 | { return this->do_always_noconv(); } |
||
233 | |||
234 | int |
||
235 | length(const state_type& __state, const extern_type* __from, |
||
236 | const extern_type* __end, size_t __max) const |
||
237 | { return this->do_length(__state, __from, __end, __max); } |
||
238 | |||
239 | int |
||
240 | max_length() const throw() |
||
241 | { return this->do_max_length(); } |
||
242 | |||
243 | protected: |
||
244 | explicit |
||
245 | __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } |
||
246 | |||
247 | virtual |
||
248 | ~__codecvt_abstract_base() { } |
||
249 | |||
250 | virtual result |
||
251 | do_out(state_type& __state, const intern_type* __from, |
||
252 | const intern_type* __from_end, const intern_type*& __from_next, |
||
253 | extern_type* __to, extern_type* __to_end, |
||
254 | extern_type*& __to_next) const = 0; |
||
255 | |||
256 | virtual result |
||
257 | do_unshift(state_type& __state, extern_type* __to, |
||
258 | extern_type* __to_end, extern_type*& __to_next) const = 0; |
||
259 | |||
260 | virtual result |
||
261 | do_in(state_type& __state, const extern_type* __from, |
||
262 | const extern_type* __from_end, const extern_type*& __from_next, |
||
263 | intern_type* __to, intern_type* __to_end, |
||
264 | intern_type*& __to_next) const = 0; |
||
265 | |||
266 | virtual int |
||
267 | do_encoding() const throw() = 0; |
||
268 | |||
269 | virtual bool |
||
270 | do_always_noconv() const throw() = 0; |
||
271 | |||
272 | virtual int |
||
273 | do_length(const state_type&, const extern_type* __from, |
||
274 | const extern_type* __end, size_t __max) const = 0; |
||
275 | |||
276 | virtual int |
||
277 | do_max_length() const throw() = 0; |
||
278 | }; |
||
279 | |||
280 | // 22.2.1.5 Template class codecvt |
||
281 | // NB: Generic, mostly useless implementation. |
||
282 | template |
||
283 | class codecvt |
||
284 | : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> |
||
285 | { |
||
286 | public: |
||
287 | // Types: |
||
288 | typedef codecvt_base::result result; |
||
289 | typedef _InternT intern_type; |
||
290 | typedef _ExternT extern_type; |
||
291 | typedef _StateT state_type; |
||
292 | |||
293 | // Data Members: |
||
294 | static locale::id id; |
||
295 | |||
296 | explicit |
||
297 | codecvt(size_t __refs = 0) |
||
298 | : __codecvt_abstract_base<_InternT,_ExternT,_StateT> (__refs) { } |
||
299 | |||
300 | protected: |
||
301 | virtual |
||
302 | ~codecvt() { } |
||
303 | }; |
||
304 | |||
305 | template |
||
306 | locale::id codecvt<_InternT, _ExternT, _StateT>::id; |
||
307 | |||
308 | #ifdef _GLIBCPP_USE_WCHAR_T |
||
309 | // partial specialization |
||
310 | // This specialization takes advantage of iconv to provide code |
||
311 | // conversions between a large number of character encodings. |
||
312 | template |
||
313 | class codecvt<_InternT, _ExternT, __enc_traits> |
||
314 | : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits> |
||
315 | { |
||
316 | public: |
||
317 | // Types: |
||
318 | typedef codecvt_base::result result; |
||
319 | typedef _InternT intern_type; |
||
320 | typedef _ExternT extern_type; |
||
321 | typedef __enc_traits state_type; |
||
322 | typedef __enc_traits::__desc_type __desc_type; |
||
323 | typedef __enc_traits __enc_type; |
||
324 | |||
325 | // Data Members: |
||
326 | static locale::id id; |
||
327 | |||
328 | explicit |
||
329 | codecvt(size_t __refs = 0) |
||
330 | : __codecvt_abstract_base |
||
331 | { } |
||
332 | |||
333 | explicit |
||
334 | codecvt(__enc_type* __enc, size_t __refs = 0) |
||
335 | : __codecvt_abstract_base |
||
336 | { } |
||
337 | |||
338 | protected: |
||
339 | virtual |
||
340 | ~codecvt() { } |
||
341 | |||
342 | virtual result |
||
343 | do_out(state_type& __state, const intern_type* __from, |
||
344 | const intern_type* __from_end, const intern_type*& __from_next, |
||
345 | extern_type* __to, extern_type* __to_end, |
||
346 | extern_type*& __to_next) const; |
||
347 | |||
348 | virtual result |
||
349 | do_unshift(state_type& __state, extern_type* __to, |
||
350 | extern_type* __to_end, extern_type*& __to_next) const; |
||
351 | |||
352 | virtual result |
||
353 | do_in(state_type& __state, const extern_type* __from, |
||
354 | const extern_type* __from_end, const extern_type*& __from_next, |
||
355 | intern_type* __to, intern_type* __to_end, |
||
356 | intern_type*& __to_next) const; |
||
357 | |||
358 | virtual int |
||
359 | do_encoding() const throw(); |
||
360 | |||
361 | virtual bool |
||
362 | do_always_noconv() const throw(); |
||
363 | |||
364 | virtual int |
||
365 | do_length(const state_type&, const extern_type* __from, |
||
366 | const extern_type* __end, size_t __max) const; |
||
367 | |||
368 | virtual int |
||
369 | do_max_length() const throw(); |
||
370 | }; |
||
371 | |||
372 | template |
||
373 | locale::id |
||
374 | codecvt<_InternT, _ExternT, __enc_traits>::id; |
||
375 | |||
376 | // This adaptor works around the signature problems of the second |
||
377 | // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 |
||
378 | // uses 'char**', which is what the standard is (apparently) due to use |
||
379 | // in the future. Using this adaptor, g++ will do the work for us. |
||
380 | template |
||
381 | inline size_t |
||
382 | __iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t*, char**, size_t*), |
||
383 | iconv_t cd, char** inbuf, size_t* inbytesleft, |
||
384 | char** outbuf, size_t* outbytesleft) |
||
385 | { |
||
386 | return iconv_func(cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft); |
||
387 | } |
||
388 | |||
389 | template |
||
390 | codecvt_base::result |
||
391 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
392 | do_out(state_type& __state, const intern_type* __from, |
||
393 | const intern_type* __from_end, const intern_type*& __from_next, |
||
394 | extern_type* __to, extern_type* __to_end, |
||
395 | extern_type*& __to_next) const |
||
396 | { |
||
397 | result __ret = error; |
||
398 | if (__state._M_good()) |
||
399 | { |
||
400 | typedef state_type::__desc_type __desc_type; |
||
401 | const __desc_type* __desc = __state._M_get_out_descriptor(); |
||
402 | const size_t __fmultiple = sizeof(intern_type) / sizeof(char); |
||
403 | size_t __flen = __fmultiple * (__from_end - __from); |
||
404 | const size_t __tmultiple = sizeof(extern_type) / sizeof(char); |
||
405 | size_t __tlen = __tmultiple * (__to_end - __to); |
||
406 | |||
407 | // Argument list for iconv specifies a byte sequence. Thus, |
||
408 | // all to/from arrays must be brutally casted to char*. |
||
409 | char* __cto = reinterpret_cast |
||
410 | char* __cfrom; |
||
411 | size_t __conv; |
||
412 | |||
413 | // Some encodings need a byte order marker as the first item |
||
414 | // in the byte stream, to designate endian-ness. The default |
||
415 | // value for the byte order marker is NULL, so if this is |
||
416 | // the case, it's not necessary and we can just go on our |
||
417 | // merry way. |
||
418 | int __int_bom = __state._M_get_internal_bom(); |
||
419 | if (__int_bom) |
||
420 | { |
||
421 | size_t __size = __from_end - __from; |
||
422 | intern_type* __cfixed = static_cast |
||
423 | __cfixed[0] = static_cast |
||
424 | char_traits |
||
425 | __cfrom = reinterpret_cast |
||
426 | __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, |
||
427 | &__flen, &__cto, &__tlen); |
||
428 | } |
||
429 | else |
||
430 | { |
||
431 | intern_type* __cfixed = const_cast |
||
432 | __cfrom = reinterpret_cast |
||
433 | __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, |
||
434 | &__flen, &__cto, &__tlen); |
||
435 | } |
||
436 | |||
437 | if (__conv != size_t(-1)) |
||
438 | { |
||
439 | __from_next = reinterpret_cast |
||
440 | __to_next = reinterpret_cast |
||
441 | __ret = ok; |
||
442 | } |
||
443 | else |
||
444 | { |
||
445 | if (__flen < static_cast |
||
446 | { |
||
447 | __from_next = reinterpret_cast |
||
448 | __to_next = reinterpret_cast |
||
449 | __ret = partial; |
||
450 | } |
||
451 | else |
||
452 | __ret = error; |
||
453 | } |
||
454 | } |
||
455 | return __ret; |
||
456 | } |
||
457 | |||
458 | template |
||
459 | codecvt_base::result |
||
460 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
461 | do_unshift(state_type& __state, extern_type* __to, |
||
462 | extern_type* __to_end, extern_type*& __to_next) const |
||
463 | { |
||
464 | result __ret = error; |
||
465 | if (__state._M_good()) |
||
466 | { |
||
467 | typedef state_type::__desc_type __desc_type; |
||
468 | const __desc_type* __desc = __state._M_get_in_descriptor(); |
||
469 | const size_t __tmultiple = sizeof(intern_type) / sizeof(char); |
||
470 | size_t __tlen = __tmultiple * (__to_end - __to); |
||
471 | |||
472 | // Argument list for iconv specifies a byte sequence. Thus, |
||
473 | // all to/from arrays must be brutally casted to char*. |
||
474 | char* __cto = reinterpret_cast |
||
475 | size_t __conv = __iconv_adaptor(iconv,*__desc, NULL, NULL, |
||
476 | &__cto, &__tlen); |
||
477 | |||
478 | if (__conv != size_t(-1)) |
||
479 | { |
||
480 | __to_next = reinterpret_cast |
||
481 | if (__tlen == __tmultiple * (__to_end - __to)) |
||
482 | __ret = noconv; |
||
483 | else if (__tlen == 0) |
||
484 | __ret = ok; |
||
485 | else |
||
486 | __ret = partial; |
||
487 | } |
||
488 | else |
||
489 | __ret = error; |
||
490 | } |
||
491 | return __ret; |
||
492 | } |
||
493 | |||
494 | template |
||
495 | codecvt_base::result |
||
496 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
497 | do_in(state_type& __state, const extern_type* __from, |
||
498 | const extern_type* __from_end, const extern_type*& __from_next, |
||
499 | intern_type* __to, intern_type* __to_end, |
||
500 | intern_type*& __to_next) const |
||
501 | { |
||
502 | result __ret = error; |
||
503 | if (__state._M_good()) |
||
504 | { |
||
505 | typedef state_type::__desc_type __desc_type; |
||
506 | const __desc_type* __desc = __state._M_get_in_descriptor(); |
||
507 | const size_t __fmultiple = sizeof(extern_type) / sizeof(char); |
||
508 | size_t __flen = __fmultiple * (__from_end - __from); |
||
509 | const size_t __tmultiple = sizeof(intern_type) / sizeof(char); |
||
510 | size_t __tlen = __tmultiple * (__to_end - __to); |
||
511 | |||
512 | // Argument list for iconv specifies a byte sequence. Thus, |
||
513 | // all to/from arrays must be brutally casted to char*. |
||
514 | char* __cto = reinterpret_cast |
||
515 | char* __cfrom; |
||
516 | size_t __conv; |
||
517 | |||
518 | // Some encodings need a byte order marker as the first item |
||
519 | // in the byte stream, to designate endian-ness. The default |
||
520 | // value for the byte order marker is NULL, so if this is |
||
521 | // the case, it's not necessary and we can just go on our |
||
522 | // merry way. |
||
523 | int __ext_bom = __state._M_get_external_bom(); |
||
524 | if (__ext_bom) |
||
525 | { |
||
526 | size_t __size = __from_end - __from; |
||
527 | extern_type* __cfixed = static_cast |
||
528 | __cfixed[0] = static_cast |
||
529 | char_traits |
||
530 | __cfrom = reinterpret_cast |
||
531 | __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, |
||
532 | &__flen, &__cto, &__tlen); |
||
533 | } |
||
534 | else |
||
535 | { |
||
536 | extern_type* __cfixed = const_cast |
||
537 | __cfrom = reinterpret_cast |
||
538 | __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, |
||
539 | &__flen, &__cto, &__tlen); |
||
540 | } |
||
541 | |||
542 | |||
543 | if (__conv != size_t(-1)) |
||
544 | { |
||
545 | __from_next = reinterpret_cast |
||
546 | __to_next = reinterpret_cast |
||
547 | __ret = ok; |
||
548 | } |
||
549 | else |
||
550 | { |
||
551 | if (__flen < static_cast |
||
552 | { |
||
553 | __from_next = reinterpret_cast |
||
554 | __to_next = reinterpret_cast |
||
555 | __ret = partial; |
||
556 | } |
||
557 | else |
||
558 | __ret = error; |
||
559 | } |
||
560 | } |
||
561 | return __ret; |
||
562 | } |
||
563 | |||
564 | template |
||
565 | int |
||
566 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
567 | do_encoding() const throw() |
||
568 | { return 0; } |
||
569 | |||
570 | template |
||
571 | bool |
||
572 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
573 | do_always_noconv() const throw() |
||
574 | { return false; } |
||
575 | |||
576 | template |
||
577 | int |
||
578 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
579 | do_length(const state_type&, const extern_type* __from, |
||
580 | const extern_type* __end, size_t __max) const |
||
581 | { return min(__max, static_cast |
||
582 | |||
583 | #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS |
||
584 | // 74. Garbled text for codecvt::do_max_length |
||
585 | template |
||
586 | int |
||
587 | codecvt<_InternT, _ExternT, __enc_traits>:: |
||
588 | do_max_length() const throw() |
||
589 | { return 1; } |
||
590 | #endif |
||
591 | #endif /* _GLIBCPP_USE_WCHAR_T */ |
||
592 | |||
593 | // codecvt |
||
594 | template<> |
||
595 | class codecvt |
||
596 | : public __codecvt_abstract_base |
||
597 | { |
||
598 | public: |
||
599 | // Types: |
||
600 | typedef char intern_type; |
||
601 | typedef char extern_type; |
||
602 | typedef mbstate_t state_type; |
||
603 | |||
604 | // Data Members: |
||
605 | static locale::id id; |
||
606 | |||
607 | explicit |
||
608 | codecvt(size_t __refs = 0); |
||
609 | |||
610 | protected: |
||
611 | virtual |
||
612 | ~codecvt(); |
||
613 | |||
614 | virtual result |
||
615 | do_out(state_type& __state, const intern_type* __from, |
||
616 | const intern_type* __from_end, const intern_type*& __from_next, |
||
617 | extern_type* __to, extern_type* __to_end, |
||
618 | extern_type*& __to_next) const; |
||
619 | |||
620 | virtual result |
||
621 | do_unshift(state_type& __state, extern_type* __to, |
||
622 | extern_type* __to_end, extern_type*& __to_next) const; |
||
623 | |||
624 | virtual result |
||
625 | do_in(state_type& __state, const extern_type* __from, |
||
626 | const extern_type* __from_end, const extern_type*& __from_next, |
||
627 | intern_type* __to, intern_type* __to_end, |
||
628 | intern_type*& __to_next) const; |
||
629 | |||
630 | virtual int |
||
631 | do_encoding() const throw(); |
||
632 | |||
633 | virtual bool |
||
634 | do_always_noconv() const throw(); |
||
635 | |||
636 | virtual int |
||
637 | do_length(const state_type&, const extern_type* __from, |
||
638 | const extern_type* __end, size_t __max) const; |
||
639 | |||
640 | virtual int |
||
641 | do_max_length() const throw(); |
||
642 | }; |
||
643 | |||
644 | #ifdef _GLIBCPP_USE_WCHAR_T |
||
645 | // codecvt |
||
646 | template<> |
||
647 | class codecvt |
||
648 | : public __codecvt_abstract_base |
||
649 | { |
||
650 | public: |
||
651 | // Types: |
||
652 | typedef wchar_t intern_type; |
||
653 | typedef char extern_type; |
||
654 | typedef mbstate_t state_type; |
||
655 | |||
656 | // Data Members: |
||
657 | static locale::id id; |
||
658 | |||
659 | explicit |
||
660 | codecvt(size_t __refs = 0); |
||
661 | |||
662 | protected: |
||
663 | virtual |
||
664 | ~codecvt(); |
||
665 | |||
666 | virtual result |
||
667 | do_out(state_type& __state, const intern_type* __from, |
||
668 | const intern_type* __from_end, const intern_type*& __from_next, |
||
669 | extern_type* __to, extern_type* __to_end, |
||
670 | extern_type*& __to_next) const; |
||
671 | |||
672 | virtual result |
||
673 | do_unshift(state_type& __state, |
||
674 | extern_type* __to, extern_type* __to_end, |
||
675 | extern_type*& __to_next) const; |
||
676 | |||
677 | virtual result |
||
678 | do_in(state_type& __state, |
||
679 | const extern_type* __from, const extern_type* __from_end, |
||
680 | const extern_type*& __from_next, |
||
681 | intern_type* __to, intern_type* __to_end, |
||
682 | intern_type*& __to_next) const; |
||
683 | |||
684 | virtual |
||
685 | int do_encoding() const throw(); |
||
686 | |||
687 | virtual |
||
688 | bool do_always_noconv() const throw(); |
||
689 | |||
690 | virtual |
||
691 | int do_length(const state_type&, const extern_type* __from, |
||
692 | const extern_type* __end, size_t __max) const; |
||
693 | |||
694 | virtual int |
||
695 | do_max_length() const throw(); |
||
696 | }; |
||
697 | #endif //_GLIBCPP_USE_WCHAR_T |
||
698 | |||
699 | // 22.2.1.6 Template class codecvt_byname |
||
700 | template |
||
701 | class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> |
||
702 | { |
||
703 | public: |
||
704 | explicit |
||
705 | codecvt_byname(const char*, size_t __refs = 0) |
||
706 | : codecvt<_InternT, _ExternT, _StateT>(__refs) { } |
||
707 | protected: |
||
708 | virtual |
||
709 | ~codecvt_byname() { } |
||
710 | }; |
||
711 | |||
712 | #endif // _CPP_BITS_CODECVT_H |
||
713 | |||
714 | // Local Variables: |
||
715 | // mode:c++ |
||
716 | // End:>>>> |
||
717 |