Merge from vendor branch GCC:
[dragonfly.git] / contrib / gcc-4.1 / libstdc++-v3 / include / bits / codecvt.h
1 // Locale support (codecvt) -*- C++ -*-
2
3 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
4 //  Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 //
32 // ISO C++ 14882: 22.2.1.5 Template class codecvt
33 //
34
35 // Written by Benjamin Kosnik <bkoz@redhat.com>
36
37 /** @file bits/codecvt.h
38  *  This is an internal header file, included by other library headers.
39  *  You should not attempt to use it directly.
40  */
41
42 #ifndef _CODECVT_H
43 #define _CODECVT_H 1
44
45 #pragma GCC system_header
46
47   /// @brief  Empty base class for codecvt facet [22.2.1.5].
48   class codecvt_base
49   {
50   public:
51     enum result
52     {
53       ok,
54       partial,
55       error,
56       noconv
57     };
58   };
59
60   /**
61    *  @brief  Common base for codecvt functions.
62    *
63    *  This template class provides implementations of the public functions
64    *  that forward to the protected virtual functions.
65    *
66    *  This template also provides abstract stubs for the protected virtual
67    *  functions.
68   */
69   template<typename _InternT, typename _ExternT, typename _StateT>
70     class __codecvt_abstract_base
71     : public locale::facet, public codecvt_base
72     {
73     public:
74       // Types:
75       typedef codecvt_base::result      result;
76       typedef _InternT                  intern_type;
77       typedef _ExternT                  extern_type;
78       typedef _StateT                   state_type;
79
80       // 22.2.1.5.1 codecvt members
81       /**
82        *  @brief  Convert from internal to external character set.
83        *
84        *  Converts input string of intern_type to output string of
85        *  extern_type.  This is analogous to wcsrtombs.  It does this by
86        *  calling codecvt::do_out.
87        *
88        *  The source and destination character sets are determined by the
89        *  facet's locale, internal and external types.
90        *
91        *  The characters in [from,from_end) are converted and written to
92        *  [to,to_end).  from_next and to_next are set to point to the
93        *  character following the last successfully converted character,
94        *  respectively.  If the result needed no conversion, from_next and
95        *  to_next are not affected.
96        *
97        *  The @a state argument should be intialized if the input is at the
98        *  beginning and carried from a previous call if continuing
99        *  conversion.  There are no guarantees about how @a state is used.
100        *
101        *  The result returned is a member of codecvt_base::result.  If
102        *  all the input is converted, returns codecvt_base::ok.  If no
103        *  conversion is necessary, returns codecvt_base::noconv.  If
104        *  the input ends early or there is insufficient space in the
105        *  output, returns codecvt_base::partial.  Otherwise the
106        *  conversion failed and codecvt_base::error is returned.
107        *
108        *  @param  state  Persistent conversion state data.
109        *  @param  from  Start of input.
110        *  @param  from_end  End of input.
111        *  @param  from_next  Returns start of unconverted data.
112        *  @param  to  Start of output buffer.
113        *  @param  to_end  End of output buffer.
114        *  @param  to_next  Returns start of unused output area.
115        *  @return  codecvt_base::result.
116       */
117       result
118       out(state_type& __state, const intern_type* __from,
119           const intern_type* __from_end, const intern_type*& __from_next,
120           extern_type* __to, extern_type* __to_end,
121           extern_type*& __to_next) const
122       {
123         return this->do_out(__state, __from, __from_end, __from_next,
124                             __to, __to_end, __to_next);
125       }
126
127       /**
128        *  @brief  Reset conversion state.
129        *
130        *  Writes characters to output that would restore @a state to initial
131        *  conditions.  The idea is that if a partial conversion occurs, then
132        *  the converting the characters written by this function would leave
133        *  the state in initial conditions, rather than partial conversion
134        *  state.  It does this by calling codecvt::do_unshift().
135        *
136        *  For example, if 4 external characters always converted to 1 internal
137        *  character, and input to in() had 6 external characters with state
138        *  saved, this function would write two characters to the output and
139        *  set the state to initialized conditions.
140        *
141        *  The source and destination character sets are determined by the
142        *  facet's locale, internal and external types.
143        *
144        *  The result returned is a member of codecvt_base::result.  If the
145        *  state could be reset and data written, returns codecvt_base::ok.  If
146        *  no conversion is necessary, returns codecvt_base::noconv.  If the
147        *  output has insufficient space, returns codecvt_base::partial.
148        *  Otherwise the reset failed and codecvt_base::error is returned.
149        *
150        *  @param  state  Persistent conversion state data.
151        *  @param  to  Start of output buffer.
152        *  @param  to_end  End of output buffer.
153        *  @param  to_next  Returns start of unused output area.
154        *  @return  codecvt_base::result.
155       */
156       result
157       unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
158               extern_type*& __to_next) const
159       { return this->do_unshift(__state, __to,__to_end,__to_next); }
160
161       /**
162        *  @brief  Convert from external to internal character set.
163        *
164        *  Converts input string of extern_type to output string of
165        *  intern_type.  This is analogous to mbsrtowcs.  It does this by
166        *  calling codecvt::do_in.
167        *
168        *  The source and destination character sets are determined by the
169        *  facet's locale, internal and external types.
170        *
171        *  The characters in [from,from_end) are converted and written to
172        *  [to,to_end).  from_next and to_next are set to point to the
173        *  character following the last successfully converted character,
174        *  respectively.  If the result needed no conversion, from_next and
175        *  to_next are not affected.
176        *
177        *  The @a state argument should be intialized if the input is at the
178        *  beginning and carried from a previous call if continuing
179        *  conversion.  There are no guarantees about how @a state is used.
180        *
181        *  The result returned is a member of codecvt_base::result.  If
182        *  all the input is converted, returns codecvt_base::ok.  If no
183        *  conversion is necessary, returns codecvt_base::noconv.  If
184        *  the input ends early or there is insufficient space in the
185        *  output, returns codecvt_base::partial.  Otherwise the
186        *  conversion failed and codecvt_base::error is returned.
187        *
188        *  @param  state  Persistent conversion state data.
189        *  @param  from  Start of input.
190        *  @param  from_end  End of input.
191        *  @param  from_next  Returns start of unconverted data.
192        *  @param  to  Start of output buffer.
193        *  @param  to_end  End of output buffer.
194        *  @param  to_next  Returns start of unused output area.
195        *  @return  codecvt_base::result.
196       */
197       result
198       in(state_type& __state, const extern_type* __from,
199          const extern_type* __from_end, const extern_type*& __from_next,
200          intern_type* __to, intern_type* __to_end,
201          intern_type*& __to_next) const
202       {
203         return this->do_in(__state, __from, __from_end, __from_next,
204                            __to, __to_end, __to_next);
205       }
206
207       int
208       encoding() const throw()
209       { return this->do_encoding(); }
210
211       bool
212       always_noconv() const throw()
213       { return this->do_always_noconv(); }
214
215       int
216       length(state_type& __state, const extern_type* __from,
217              const extern_type* __end, size_t __max) const
218       { return this->do_length(__state, __from, __end, __max); }
219
220       int
221       max_length() const throw()
222       { return this->do_max_length(); }
223
224     protected:
225       explicit
226       __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
227
228       virtual
229       ~__codecvt_abstract_base() { }
230
231       /**
232        *  @brief  Convert from internal to external character set.
233        *
234        *  Converts input string of intern_type to output string of
235        *  extern_type.  This function is a hook for derived classes to change
236        *  the value returned.  @see out for more information.
237       */
238       virtual result
239       do_out(state_type& __state, const intern_type* __from,
240              const intern_type* __from_end, const intern_type*& __from_next,
241              extern_type* __to, extern_type* __to_end,
242              extern_type*& __to_next) const = 0;
243
244       virtual result
245       do_unshift(state_type& __state, extern_type* __to,
246                  extern_type* __to_end, extern_type*& __to_next) const = 0;
247
248       virtual result
249       do_in(state_type& __state, const extern_type* __from,
250             const extern_type* __from_end, const extern_type*& __from_next,
251             intern_type* __to, intern_type* __to_end,
252             intern_type*& __to_next) const = 0;
253
254       virtual int
255       do_encoding() const throw() = 0;
256
257       virtual bool
258       do_always_noconv() const throw() = 0;
259
260       virtual int
261       do_length(state_type&, const extern_type* __from,
262                 const extern_type* __end, size_t __max) const = 0;
263
264       virtual int
265       do_max_length() const throw() = 0;
266     };
267
268   /// @brief class codecvt [22.2.1.5].
269   /// NB: Generic, mostly useless implementation.
270   template<typename _InternT, typename _ExternT, typename _StateT>
271     class codecvt
272     : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
273     {
274     public:
275       // Types:
276       typedef codecvt_base::result      result;
277       typedef _InternT                  intern_type;
278       typedef _ExternT                  extern_type;
279       typedef _StateT                   state_type;
280
281     protected:
282       __c_locale                        _M_c_locale_codecvt;
283
284     public:
285       static locale::id                 id;
286
287       explicit
288       codecvt(size_t __refs = 0)
289       : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { }
290
291       explicit
292       codecvt(__c_locale __cloc, size_t __refs = 0);
293
294     protected:
295       virtual
296       ~codecvt() { }
297
298       virtual result
299       do_out(state_type& __state, const intern_type* __from,
300              const intern_type* __from_end, const intern_type*& __from_next,
301              extern_type* __to, extern_type* __to_end,
302              extern_type*& __to_next) const;
303
304       virtual result
305       do_unshift(state_type& __state, extern_type* __to,
306                  extern_type* __to_end, extern_type*& __to_next) const;
307
308       virtual result
309       do_in(state_type& __state, const extern_type* __from,
310             const extern_type* __from_end, const extern_type*& __from_next,
311             intern_type* __to, intern_type* __to_end,
312             intern_type*& __to_next) const;
313
314       virtual int
315       do_encoding() const throw();
316
317       virtual bool
318       do_always_noconv() const throw();
319
320       virtual int
321       do_length(state_type&, const extern_type* __from,
322                 const extern_type* __end, size_t __max) const;
323
324       virtual int
325       do_max_length() const throw();
326     };
327
328   template<typename _InternT, typename _ExternT, typename _StateT>
329     locale::id codecvt<_InternT, _ExternT, _StateT>::id;
330
331   /// @brief class codecvt<char, char, mbstate_t> specialization.
332   template<>
333     class codecvt<char, char, mbstate_t>
334     : public __codecvt_abstract_base<char, char, mbstate_t>
335     {
336     public:
337       // Types:
338       typedef char                      intern_type;
339       typedef char                      extern_type;
340       typedef mbstate_t                 state_type;
341
342     protected:
343       __c_locale                        _M_c_locale_codecvt;
344
345     public:
346       static locale::id id;
347
348       explicit
349       codecvt(size_t __refs = 0);
350
351       explicit
352       codecvt(__c_locale __cloc, size_t __refs = 0);
353
354     protected:
355       virtual
356       ~codecvt();
357
358       virtual result
359       do_out(state_type& __state, const intern_type* __from,
360              const intern_type* __from_end, const intern_type*& __from_next,
361              extern_type* __to, extern_type* __to_end,
362              extern_type*& __to_next) const;
363
364       virtual result
365       do_unshift(state_type& __state, extern_type* __to,
366                  extern_type* __to_end, extern_type*& __to_next) const;
367
368       virtual result
369       do_in(state_type& __state, const extern_type* __from,
370             const extern_type* __from_end, const extern_type*& __from_next,
371             intern_type* __to, intern_type* __to_end,
372             intern_type*& __to_next) const;
373
374       virtual int
375       do_encoding() const throw();
376
377       virtual bool
378       do_always_noconv() const throw();
379
380       virtual int
381       do_length(state_type&, const extern_type* __from,
382                 const extern_type* __end, size_t __max) const;
383
384       virtual int
385       do_max_length() const throw();
386   };
387
388 #ifdef _GLIBCXX_USE_WCHAR_T
389   /// @brief  class codecvt<wchar_t, char, mbstate_t> specialization.
390   template<>
391     class codecvt<wchar_t, char, mbstate_t>
392     : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
393     {
394     public:
395       // Types:
396       typedef wchar_t                   intern_type;
397       typedef char                      extern_type;
398       typedef mbstate_t                 state_type;
399
400     protected:
401       __c_locale                        _M_c_locale_codecvt;
402
403     public:
404       static locale::id                 id;
405
406       explicit
407       codecvt(size_t __refs = 0);
408
409       explicit
410       codecvt(__c_locale __cloc, size_t __refs = 0);
411
412     protected:
413       virtual
414       ~codecvt();
415
416       virtual result
417       do_out(state_type& __state, const intern_type* __from,
418              const intern_type* __from_end, const intern_type*& __from_next,
419              extern_type* __to, extern_type* __to_end,
420              extern_type*& __to_next) const;
421
422       virtual result
423       do_unshift(state_type& __state,
424                  extern_type* __to, extern_type* __to_end,
425                  extern_type*& __to_next) const;
426
427       virtual result
428       do_in(state_type& __state,
429              const extern_type* __from, const extern_type* __from_end,
430              const extern_type*& __from_next,
431              intern_type* __to, intern_type* __to_end,
432              intern_type*& __to_next) const;
433
434       virtual
435       int do_encoding() const throw();
436
437       virtual
438       bool do_always_noconv() const throw();
439
440       virtual
441       int do_length(state_type&, const extern_type* __from,
442                     const extern_type* __end, size_t __max) const;
443
444       virtual int
445       do_max_length() const throw();
446     };
447 #endif //_GLIBCXX_USE_WCHAR_T
448
449   /// @brief class codecvt_byname [22.2.1.6].
450   template<typename _InternT, typename _ExternT, typename _StateT>
451     class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
452     {
453     public:
454       explicit
455       codecvt_byname(const char* __s, size_t __refs = 0)
456       : codecvt<_InternT, _ExternT, _StateT>(__refs)
457       {
458         if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
459           {
460             this->_S_destroy_c_locale(this->_M_c_locale_codecvt);
461             this->_S_create_c_locale(this->_M_c_locale_codecvt, __s);
462           }
463       }
464
465     protected:
466       virtual
467       ~codecvt_byname() { }
468     };
469
470 #endif // _CODECVT_H