libstdc++

codecvt.h
Go to the documentation of this file.
1 // Locale support (codecvt) -*- C++ -*-
2
3 // Copyright (C) 2000-2013 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
268 /**
269 * @brief Primary class template codecvt.
270 * @ingroup locales
271 *
272 * NB: Generic, mostly useless implementation.
273 *
274 */
275 template<typename _InternT, typename _ExternT, typename _StateT>
276 class codecvt
277 : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
278 {
279 public:
280 // Types:
281 typedef codecvt_base::result result;
282 typedef _InternT intern_type;
283 typedef _ExternT extern_type;
284 typedef _StateT state_type;
285
286 protected:
287 __c_locale _M_c_locale_codecvt;
288
289 public:
290 static locale::id id;
291
292 explicit
293 codecvt(size_t __refs = 0)
294 : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs),
295 _M_c_locale_codecvt(0)
296 { }
297
298 explicit
299 codecvt(__c_locale __cloc, size_t __refs = 0);
300
301 protected:
302 virtual
303 ~codecvt() { }
304
305 virtual result
306 do_out(state_type& __state, const intern_type* __from,
307 const intern_type* __from_end, const intern_type*& __from_next,
308 extern_type* __to, extern_type* __to_end,
309 extern_type*& __to_next) const;
310
311 virtual result
312 do_unshift(state_type& __state, extern_type* __to,
313 extern_type* __to_end, extern_type*& __to_next) const;
314
315 virtual result
316 do_in(state_type& __state, const extern_type* __from,
317 const extern_type* __from_end, const extern_type*& __from_next,
318 intern_type* __to, intern_type* __to_end,
319 intern_type*& __to_next) const;
320
321 virtual int
322 do_encoding() const throw();
323
324 virtual bool
325 do_always_noconv() const throw();
326
327 virtual int
328 do_length(state_type&, const extern_type* __from,
329 const extern_type* __end, size_t __max) const;
330
331 virtual int
332 do_max_length() const throw();
333 };
334
335 template<typename _InternT, typename _ExternT, typename _StateT>
336 locale::id codecvt<_InternT, _ExternT, _StateT>::id;
337
338 /// class codecvt<char, char, mbstate_t> specialization.
339 template<>
340 class codecvt<char, char, mbstate_t>
341 : public __codecvt_abstract_base<char, char, mbstate_t>
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 /// class codecvt<wchar_t, char, mbstate_t> specialization.
397 template<>
398 class codecvt<wchar_t, char, mbstate_t>
399 : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
400 {
401 public:
402 // Types:
403 typedef wchar_t intern_type;
404 typedef char extern_type;
405 typedef mbstate_t state_type;
406
407 protected:
408 __c_locale _M_c_locale_codecvt;
409
410 public:
411 static locale::id id;
412
413 explicit
414 codecvt(size_t __refs = 0);
415
416 explicit
417 codecvt(__c_locale __cloc, size_t __refs = 0);
418
419 protected:
420 virtual
421 ~codecvt();
422
423 virtual result
424 do_out(state_type& __state, const intern_type* __from,
425 const intern_type* __from_end, const intern_type*& __from_next,
426 extern_type* __to, extern_type* __to_end,
427 extern_type*& __to_next) const;
428
429 virtual result
430 do_unshift(state_type& __state,
431 extern_type* __to, extern_type* __to_end,
432 extern_type*& __to_next) const;
433
434 virtual result
435 do_in(state_type& __state,
436 const extern_type* __from, const extern_type* __from_end,
437 const extern_type*& __from_next,
438 intern_type* __to, intern_type* __to_end,
439 intern_type*& __to_next) const;
440
441 virtual
442 int do_encoding() const throw();
443
444 virtual
445 bool do_always_noconv() const throw();
446
447 virtual
448 int do_length(state_type&, const extern_type* __from,
449 const extern_type* __end, size_t __max) const;
450
451 virtual int
452 do_max_length() const throw();
453 };
454 #endif //_GLIBCXX_USE_WCHAR_T
455
456 /// class codecvt_byname [22.2.1.6].
457 template<typename _InternT, typename _ExternT, typename _StateT>
458 class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
459 {
460 public:
461 explicit
462 codecvt_byname(const char* __s, size_t __refs = 0)
463 : codecvt<_InternT, _ExternT, _StateT>(__refs)
464 {
465 if (__builtin_strcmp(__s, "C") != 0
466 && __builtin_strcmp(__s, "POSIX") != 0)
467 {
468 this->_S_destroy_c_locale(this->_M_c_locale_codecvt);
469 this->_S_create_c_locale(this->_M_c_locale_codecvt, __s);
470 }
471 }
472
473 protected:
474 virtual
475 ~codecvt_byname() { }
476 };
477
478 // Inhibit implicit instantiations for required instantiations,
479 // which are defined via explicit instantiations elsewhere.
480 #if _GLIBCXX_EXTERN_TEMPLATE
481 extern template class codecvt_byname<char, char, mbstate_t>;
482
483 extern template
484 const codecvt<char, char, mbstate_t>&
485 use_facet<codecvt<char, char, mbstate_t> >(const locale&);
486
487 extern template
488 bool
489 has_facet<codecvt<char, char, mbstate_t> >(const locale&);
490
491 #ifdef _GLIBCXX_USE_WCHAR_T
492 extern template class codecvt_byname<wchar_t, char, mbstate_t>;
493
494 extern template
495 const codecvt<wchar_t, char, mbstate_t>&
496 use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
497
498 extern template
499 bool
500 has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
501 #endif
502 #endif
503
504 _GLIBCXX_END_NAMESPACE_VERSION
505 } // namespace std
506
507 #endif // _CODECVT_H