Subversion Repositories Kolibri OS

Rev

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(__refs)
331
      { }
332
 
333
      explicit
334
      codecvt(__enc_type* __enc, size_t __refs = 0)
335
      : __codecvt_abstract_base(__refs)
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(__to);
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(__builtin_alloca(sizeof(intern_type) * (__size + 1)));
423
	      __cfixed[0] = static_cast(__int_bom);
424
	      char_traits::copy(__cfixed + 1, __from, __size);
425
	      __cfrom = reinterpret_cast(__cfixed);
426
	      __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
427
                                        &__flen, &__cto, &__tlen);
428
	    }
429
	  else
430
	    {
431
	      intern_type* __cfixed = const_cast(__from);
432
	      __cfrom = reinterpret_cast(__cfixed);
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(__cfrom);
440
	      __to_next = reinterpret_cast(__cto);
441
	      __ret = ok;
442
	    }
443
	  else
444
	    {
445
	      if (__flen < static_cast(__from_end - __from))
446
		{
447
		  __from_next = reinterpret_cast(__cfrom);
448
		  __to_next = reinterpret_cast(__cto);
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(__to);
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(__cto);
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(__to);
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(__builtin_alloca(sizeof(extern_type) * (__size + 1)));
528
	      __cfixed[0] = static_cast(__ext_bom);
529
	      char_traits::copy(__cfixed + 1, __from, __size);
530
	      __cfrom = reinterpret_cast(__cfixed);
531
	      __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
532
                                       &__flen, &__cto, &__tlen);
533
	    }
534
	  else
535
	    {
536
	      extern_type* __cfixed = const_cast(__from);
537
	      __cfrom = reinterpret_cast(__cfixed);
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(__cfrom);
546
	      __to_next = reinterpret_cast(__cto);
547
	      __ret = ok;
548
	    }
549
	  else
550
	    {
551
	      if (__flen < static_cast(__from_end - __from))
552
		{
553
		  __from_next = reinterpret_cast(__cfrom);
554
		  __to_next = reinterpret_cast(__cto);
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(__end - __from)); }
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 required specialization
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 required specialization
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