00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _CPP_BITS_CODECVT_H
00039 #define _CPP_BITS_CODECVT_H 1
00040
00041 #pragma GCC system_header
00042
00043
00044
00045
00046
00047 #ifdef _GLIBCPP_USE_WCHAR_T
00048
00049
00050
00051
00052
00053 #if _GLIBCPP_USE_SHADOW_HEADERS
00054 using _C_legacy::CODESET;
00055 #endif
00056
00057 class __enc_traits
00058 {
00059 public:
00060
00061
00062
00063 typedef iconv_t __desc_type;
00064
00065 protected:
00066
00067
00068 static const int _S_max_size = 32;
00069
00070 char _M_int_enc[_S_max_size];
00071
00072 char _M_ext_enc[_S_max_size];
00073
00074
00075 __desc_type _M_in_desc;
00076
00077 __desc_type _M_out_desc;
00078
00079
00080 int _M_ext_bom;
00081
00082
00083 int _M_int_bom;
00084
00085 public:
00086 __enc_traits()
00087 : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0)
00088 {
00089
00090
00091
00092
00093 strcpy(_M_int_enc, "UCS4");
00094
00095
00096 strcpy(_M_ext_enc, nl_langinfo(CODESET));
00097 }
00098
00099 __enc_traits(const char* __int, const char* __ext, int __ibom = 0,
00100 int __ebom = 0)
00101 : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0)
00102 {
00103 strncpy(_M_int_enc, __int, _S_max_size);
00104 strncpy(_M_ext_enc, __ext, _S_max_size);
00105 }
00106
00107
00108
00109
00110
00111
00112 __enc_traits(const __enc_traits& __obj)
00113 {
00114 strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size);
00115 strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size);
00116 _M_ext_bom = __obj._M_ext_bom;
00117 _M_int_bom = __obj._M_int_bom;
00118 }
00119
00120 ~__enc_traits()
00121 {
00122 iconv_close(_M_in_desc);
00123 iconv_close(_M_out_desc);
00124 }
00125
00126
00127 void
00128 _M_init()
00129 {
00130 _M_in_desc = iconv_open(_M_int_enc, _M_ext_enc);
00131 _M_out_desc = iconv_open(_M_ext_enc, _M_int_enc);
00132 if (_M_out_desc == iconv_t(-1) || _M_in_desc == iconv_t(-1))
00133 {
00134
00135 }
00136 }
00137
00138 bool
00139 _M_good()
00140 {
00141 return _M_out_desc && _M_in_desc
00142 && _M_out_desc != iconv_t(-1) && _M_in_desc != iconv_t(-1);
00143 }
00144
00145 const __desc_type*
00146 _M_get_in_descriptor()
00147 { return &_M_in_desc; }
00148
00149 const __desc_type*
00150 _M_get_out_descriptor()
00151 { return &_M_out_desc; }
00152
00153 const char*
00154 _M_get_internal_enc()
00155 { return _M_int_enc; }
00156
00157 const char*
00158 _M_get_external_enc()
00159 { return _M_ext_enc; }
00160
00161 int
00162 _M_get_external_bom()
00163 { return _M_ext_bom; }
00164
00165 int
00166 _M_get_internal_bom()
00167 { return _M_int_bom; }
00168 };
00169 #endif //_GLIBCPP_USE_WCHAR_T
00170
00171
00172
00173 class codecvt_base
00174 {
00175 public:
00176 enum result
00177 {
00178 ok,
00179 partial,
00180 error,
00181 noconv
00182 };
00183 };
00184
00185
00186
00187
00188
00189 template<typename _InternT, typename _ExternT, typename _StateT>
00190 class __codecvt_abstract_base
00191 : public locale::facet, public codecvt_base
00192 {
00193 public:
00194
00195 typedef codecvt_base::result result;
00196 typedef _InternT intern_type;
00197 typedef _ExternT extern_type;
00198 typedef _StateT state_type;
00199
00200
00201 result
00202 out(state_type& __state, const intern_type* __from,
00203 const intern_type* __from_end, const intern_type*& __from_next,
00204 extern_type* __to, extern_type* __to_end,
00205 extern_type*& __to_next) const
00206 {
00207 return this->do_out(__state, __from, __from_end, __from_next,
00208 __to, __to_end, __to_next);
00209 }
00210
00211 result
00212 unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
00213 extern_type*& __to_next) const
00214 { return this->do_unshift(__state, __to,__to_end,__to_next); }
00215
00216 result
00217 in(state_type& __state, const extern_type* __from,
00218 const extern_type* __from_end, const extern_type*& __from_next,
00219 intern_type* __to, intern_type* __to_end,
00220 intern_type*& __to_next) const
00221 {
00222 return this->do_in(__state, __from, __from_end, __from_next,
00223 __to, __to_end, __to_next);
00224 }
00225
00226 int
00227 encoding() const throw()
00228 { return this->do_encoding(); }
00229
00230 bool
00231 always_noconv() const throw()
00232 { return this->do_always_noconv(); }
00233
00234 int
00235 length(const state_type& __state, const extern_type* __from,
00236 const extern_type* __end, size_t __max) const
00237 { return this->do_length(__state, __from, __end, __max); }
00238
00239 int
00240 max_length() const throw()
00241 { return this->do_max_length(); }
00242
00243 protected:
00244 explicit
00245 __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
00246
00247 virtual
00248 ~__codecvt_abstract_base() { }
00249
00250 virtual result
00251 do_out(state_type& __state, const intern_type* __from,
00252 const intern_type* __from_end, const intern_type*& __from_next,
00253 extern_type* __to, extern_type* __to_end,
00254 extern_type*& __to_next) const = 0;
00255
00256 virtual result
00257 do_unshift(state_type& __state, extern_type* __to,
00258 extern_type* __to_end, extern_type*& __to_next) const = 0;
00259
00260 virtual result
00261 do_in(state_type& __state, const extern_type* __from,
00262 const extern_type* __from_end, const extern_type*& __from_next,
00263 intern_type* __to, intern_type* __to_end,
00264 intern_type*& __to_next) const = 0;
00265
00266 virtual int
00267 do_encoding() const throw() = 0;
00268
00269 virtual bool
00270 do_always_noconv() const throw() = 0;
00271
00272 virtual int
00273 do_length(const state_type&, const extern_type* __from,
00274 const extern_type* __end, size_t __max) const = 0;
00275
00276 virtual int
00277 do_max_length() const throw() = 0;
00278 };
00279
00280
00281
00282 template<typename _InternT, typename _ExternT, typename _StateT>
00283 class codecvt
00284 : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
00285 {
00286 public:
00287
00288 typedef codecvt_base::result result;
00289 typedef _InternT intern_type;
00290 typedef _ExternT extern_type;
00291 typedef _StateT state_type;
00292
00293
00294 static locale::id id;
00295
00296 explicit
00297 codecvt(size_t __refs = 0)
00298 : __codecvt_abstract_base<_InternT,_ExternT,_StateT> (__refs) { }
00299
00300 protected:
00301 virtual
00302 ~codecvt() { }
00303 };
00304
00305 template<typename _InternT, typename _ExternT, typename _StateT>
00306 locale::id codecvt<_InternT, _ExternT, _StateT>::id;
00307
00308 #ifdef _GLIBCPP_USE_WCHAR_T
00309
00310
00311
00312 template<typename _InternT, typename _ExternT>
00313 class codecvt<_InternT, _ExternT, __enc_traits>
00314 : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits>
00315 {
00316 public:
00317
00318 typedef codecvt_base::result result;
00319 typedef _InternT intern_type;
00320 typedef _ExternT extern_type;
00321 typedef __enc_traits state_type;
00322 typedef __enc_traits::__desc_type __desc_type;
00323 typedef __enc_traits __enc_type;
00324
00325
00326 static locale::id id;
00327
00328 explicit
00329 codecvt(size_t __refs = 0)
00330 : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
00331 { }
00332
00333 explicit
00334 codecvt(__enc_type* __enc, size_t __refs = 0)
00335 : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
00336 { }
00337
00338 protected:
00339 virtual
00340 ~codecvt() { }
00341
00342 virtual result
00343 do_out(state_type& __state, const intern_type* __from,
00344 const intern_type* __from_end, const intern_type*& __from_next,
00345 extern_type* __to, extern_type* __to_end,
00346 extern_type*& __to_next) const;
00347
00348 virtual result
00349 do_unshift(state_type& __state, extern_type* __to,
00350 extern_type* __to_end, extern_type*& __to_next) const;
00351
00352 virtual result
00353 do_in(state_type& __state, const extern_type* __from,
00354 const extern_type* __from_end, const extern_type*& __from_next,
00355 intern_type* __to, intern_type* __to_end,
00356 intern_type*& __to_next) const;
00357
00358 virtual int
00359 do_encoding() const throw();
00360
00361 virtual bool
00362 do_always_noconv() const throw();
00363
00364 virtual int
00365 do_length(const state_type&, const extern_type* __from,
00366 const extern_type* __end, size_t __max) const;
00367
00368 virtual int
00369 do_max_length() const throw();
00370 };
00371
00372 template<typename _InternT, typename _ExternT>
00373 locale::id
00374 codecvt<_InternT, _ExternT, __enc_traits>::id;
00375
00376
00377
00378
00379
00380 template<typename _T>
00381 inline size_t
00382 __iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t*, char**, size_t*),
00383 iconv_t cd, char** inbuf, size_t* inbytesleft,
00384 char** outbuf, size_t* outbytesleft)
00385 {
00386 return iconv_func(cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft);
00387 }
00388
00389 template<typename _InternT, typename _ExternT>
00390 codecvt_base::result
00391
00392 codecvt<_InternT, _ExternT, __enc_traits>:: do_out(state_type& __state, const intern_type* __from,
00393 const intern_type* __from_end, const intern_type*& __from_next,
00394 extern_type* __to, extern_type* __to_end,
00395 extern_type*& __to_next) const
00396 {
00397 result __ret = codecvt::error;
00398 if (__state._M_good())
00399 {
00400 typedef state_type::__desc_type __desc_type;
00401 const __desc_type* __desc = __state._M_get_out_descriptor();
00402 const size_t __fmultiple = sizeof(intern_type) / sizeof(char);
00403 size_t __flen = __fmultiple * (__from_end - __from);
00404 const size_t __tmultiple = sizeof(extern_type) / sizeof(char);
00405 size_t __tlen = __tmultiple * (__to_end - __to);
00406
00407
00408
00409 char* __cto = reinterpret_cast<char*>(__to);
00410 char* __cfrom;
00411 size_t __conv;
00412
00413
00414
00415
00416
00417
00418 int __int_bom = __state._M_get_internal_bom();
00419 if (__int_bom)
00420 {
00421 size_t __size = __from_end - __from;
00422 intern_type* __cfixed = static_cast<intern_type*>(__builtin_alloca(sizeof(intern_type) * (__size + 1)));
00423 __cfixed[0] = static_cast<intern_type>(__int_bom);
00424 char_traits<intern_type>::copy(__cfixed + 1, __from, __size);
00425 __cfrom = reinterpret_cast<char*>(__cfixed);
00426 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00427 &__flen, &__cto, &__tlen);
00428 }
00429 else
00430 {
00431 intern_type* __cfixed = const_cast<intern_type*>(__from);
00432 __cfrom = reinterpret_cast<char*>(__cfixed);
00433 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00434 &__flen, &__cto, &__tlen);
00435 }
00436
00437 if (__conv != size_t(-1))
00438 {
00439 __from_next = reinterpret_cast<const intern_type*>(__cfrom);
00440 __to_next = reinterpret_cast<extern_type*>(__cto);
00441 __ret = codecvt::ok;
00442 }
00443 else
00444 {
00445 if (__flen < static_cast<size_t>(__from_end - __from))
00446 {
00447 __from_next = reinterpret_cast<const intern_type*>(__cfrom);
00448 __to_next = reinterpret_cast<extern_type*>(__cto);
00449 __ret = codecvt::partial;
00450 }
00451 else
00452 __ret = codecvt::error;
00453 }
00454 }
00455 return __ret;
00456 }
00457
00458 template<typename _InternT, typename _ExternT>
00459 codecvt_base::result
00460
00461 codecvt<_InternT, _ExternT, __enc_traits>:: do_unshift(state_type& __state, extern_type* __to,
00462 extern_type* __to_end, extern_type*& __to_next) const
00463 {
00464 result __ret = codecvt::error;
00465 if (__state._M_good())
00466 {
00467 typedef state_type::__desc_type __desc_type;
00468 const __desc_type* __desc = __state._M_get_in_descriptor();
00469 const size_t __tmultiple = sizeof(intern_type) / sizeof(char);
00470 size_t __tlen = __tmultiple * (__to_end - __to);
00471
00472
00473
00474 char* __cto = reinterpret_cast<char*>(__to);
00475 size_t __conv = __iconv_adaptor(iconv,*__desc, NULL, NULL,
00476 &__cto, &__tlen);
00477
00478 if (__conv != size_t(-1))
00479 {
00480 __to_next = reinterpret_cast<extern_type*>(__cto);
00481 if (__tlen == __tmultiple * (__to_end - __to))
00482 __ret = codecvt::noconv;
00483 else if (__tlen == 0)
00484 __ret = codecvt::ok;
00485 else
00486 __ret = codecvt::partial;
00487 }
00488 else
00489 __ret = codecvt::error;
00490 }
00491 return __ret;
00492 }
00493
00494 template<typename _InternT, typename _ExternT>
00495 codecvt_base::result
00496
00497 codecvt<_InternT, _ExternT, __enc_traits>:: do_in(state_type& __state, const extern_type* __from,
00498 const extern_type* __from_end, const extern_type*& __from_next,
00499 intern_type* __to, intern_type* __to_end,
00500 intern_type*& __to_next) const
00501 {
00502 result __ret = codecvt::error;
00503 if (__state._M_good())
00504 {
00505 typedef state_type::__desc_type __desc_type;
00506 const __desc_type* __desc = __state._M_get_in_descriptor();
00507 const size_t __fmultiple = sizeof(extern_type) / sizeof(char);
00508 size_t __flen = __fmultiple * (__from_end - __from);
00509 const size_t __tmultiple = sizeof(intern_type) / sizeof(char);
00510 size_t __tlen = __tmultiple * (__to_end - __to);
00511
00512
00513
00514 char* __cto = reinterpret_cast<char*>(__to);
00515 char* __cfrom;
00516 size_t __conv;
00517
00518
00519
00520
00521
00522
00523 int __ext_bom = __state._M_get_external_bom();
00524 if (__ext_bom)
00525 {
00526 size_t __size = __from_end - __from;
00527 extern_type* __cfixed = static_cast<extern_type*>(__builtin_alloca(sizeof(extern_type) * (__size + 1)));
00528 __cfixed[0] = static_cast<extern_type>(__ext_bom);
00529 char_traits<extern_type>::copy(__cfixed + 1, __from, __size);
00530 __cfrom = reinterpret_cast<char*>(__cfixed);
00531 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00532 &__flen, &__cto, &__tlen);
00533 }
00534 else
00535 {
00536 extern_type* __cfixed = const_cast<extern_type*>(__from);
00537 __cfrom = reinterpret_cast<char*>(__cfixed);
00538 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00539 &__flen, &__cto, &__tlen);
00540 }
00541
00542
00543 if (__conv != size_t(-1))
00544 {
00545 __from_next = reinterpret_cast<const extern_type*>(__cfrom);
00546 __to_next = reinterpret_cast<intern_type*>(__cto);
00547 __ret = codecvt::ok;
00548 }
00549 else
00550 {
00551 if (__flen < static_cast<size_t>(__from_end - __from))
00552 {
00553 __from_next = reinterpret_cast<const extern_type*>(__cfrom);
00554 __to_next = reinterpret_cast<intern_type*>(__cto);
00555 __ret = codecvt::partial;
00556 }
00557 else
00558 __ret = codecvt::error;
00559 }
00560 }
00561 return __ret;
00562 }
00563
00564 template<typename _InternT, typename _ExternT>
00565 int
00566
00567 codecvt<_InternT, _ExternT, __enc_traits>:: do_encoding() const throw()
00568 { return 0; }
00569
00570 template<typename _InternT, typename _ExternT>
00571 bool
00572
00573 codecvt<_InternT, _ExternT, __enc_traits>:: do_always_noconv() const throw()
00574 { return false; }
00575
00576 template<typename _InternT, typename _ExternT>
00577 int
00578
00579 codecvt<_InternT, _ExternT, __enc_traits>:: do_length(const state_type&, const extern_type* __from,
00580 const extern_type* __end, size_t __max) const
00581 { return min(__max, static_cast<size_t>(__end - __from)); }
00582
00583 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00584
00585 template<typename _InternT, typename _ExternT>
00586 int
00587
00588 codecvt<_InternT, _ExternT, __enc_traits>:: do_max_length() const throw()
00589 { return 1; }
00590 #endif
00591 #endif
00592
00593
00594 template<>
00595 class codecvt<char, char, mbstate_t>
00596 : public __codecvt_abstract_base<char, char, mbstate_t>
00597 {
00598 public:
00599
00600 typedef char intern_type;
00601 typedef char extern_type;
00602 typedef mbstate_t state_type;
00603
00604
00605 static locale::id id;
00606
00607 explicit
00608 codecvt(size_t __refs = 0);
00609
00610 protected:
00611 virtual
00612 ~codecvt();
00613
00614 virtual result
00615 do_out(state_type& __state, const intern_type* __from,
00616 const intern_type* __from_end, const intern_type*& __from_next,
00617 extern_type* __to, extern_type* __to_end,
00618 extern_type*& __to_next) const;
00619
00620 virtual result
00621 do_unshift(state_type& __state, extern_type* __to,
00622 extern_type* __to_end, extern_type*& __to_next) const;
00623
00624 virtual result
00625 do_in(state_type& __state, const extern_type* __from,
00626 const extern_type* __from_end, const extern_type*& __from_next,
00627 intern_type* __to, intern_type* __to_end,
00628 intern_type*& __to_next) const;
00629
00630 virtual int
00631 do_encoding() const throw();
00632
00633 virtual bool
00634 do_always_noconv() const throw();
00635
00636 virtual int
00637 do_length(const state_type&, const extern_type* __from,
00638 const extern_type* __end, size_t __max) const;
00639
00640 virtual int
00641 do_max_length() const throw();
00642 };
00643
00644 #ifdef _GLIBCPP_USE_WCHAR_T
00645
00646 template<>
00647 class codecvt<wchar_t, char, mbstate_t>
00648 : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
00649 {
00650 public:
00651
00652 typedef wchar_t intern_type;
00653 typedef char extern_type;
00654 typedef mbstate_t state_type;
00655
00656
00657 static locale::id id;
00658
00659 explicit
00660 codecvt(size_t __refs = 0);
00661
00662 protected:
00663 virtual
00664 ~codecvt();
00665
00666 virtual result
00667 do_out(state_type& __state, const intern_type* __from,
00668 const intern_type* __from_end, const intern_type*& __from_next,
00669 extern_type* __to, extern_type* __to_end,
00670 extern_type*& __to_next) const;
00671
00672 virtual result
00673 do_unshift(state_type& __state,
00674 extern_type* __to, extern_type* __to_end,
00675 extern_type*& __to_next) const;
00676
00677 virtual result
00678 do_in(state_type& __state,
00679 const extern_type* __from, const extern_type* __from_end,
00680 const extern_type*& __from_next,
00681 intern_type* __to, intern_type* __to_end,
00682 intern_type*& __to_next) const;
00683
00684 virtual
00685 int do_encoding() const throw();
00686
00687 virtual
00688 bool do_always_noconv() const throw();
00689
00690 virtual
00691 int do_length(const state_type&, const extern_type* __from,
00692 const extern_type* __end, size_t __max) const;
00693
00694 virtual int
00695 do_max_length() const throw();
00696 };
00697 #endif //_GLIBCPP_USE_WCHAR_T
00698
00699
00700 template<typename _InternT, typename _ExternT, typename _StateT>
00701 class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
00702 {
00703 public:
00704 explicit
00705 codecvt_byname(const char*, size_t __refs = 0)
00706 : codecvt<_InternT, _ExternT, _StateT>(__refs) { }
00707 protected:
00708 virtual
00709 ~codecvt_byname() { }
00710 };
00711
00712 #endif // _CPP_BITS_CODECVT_H
00713
00714
00715
00716
00717