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
00039
00040 #define _GLIBCXX_USE___ENC_TRAITS 1
00041
00042
00043
00044
00045
00046 class __enc_traits
00047 {
00048 public:
00049
00050
00051
00052 typedef iconv_t __desc_type;
00053
00054 protected:
00055
00056
00057 static const int _S_max_size = 32;
00058
00059 char _M_int_enc[_S_max_size];
00060
00061 char _M_ext_enc[_S_max_size];
00062
00063
00064 __desc_type _M_in_desc;
00065
00066 __desc_type _M_out_desc;
00067
00068
00069 int _M_ext_bom;
00070
00071
00072 int _M_int_bom;
00073
00074 public:
00075 explicit __enc_traits()
00076 : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0)
00077 {
00078 memset(_M_int_enc, 0, _S_max_size);
00079 memset(_M_ext_enc, 0, _S_max_size);
00080 }
00081
00082 explicit __enc_traits(const char* __int, const char* __ext,
00083 int __ibom = 0, int __ebom = 0)
00084 : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(__ebom), _M_int_bom(__ibom)
00085 {
00086 strncpy(_M_int_enc, __int, _S_max_size);
00087 strncpy(_M_ext_enc, __ext, _S_max_size);
00088 _M_init();
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 __enc_traits(const __enc_traits& __obj): _M_in_desc(0), _M_out_desc(0)
00100 {
00101 strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size);
00102 strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size);
00103 _M_ext_bom = __obj._M_ext_bom;
00104 _M_int_bom = __obj._M_int_bom;
00105 _M_destroy();
00106 _M_init();
00107 }
00108
00109
00110 __enc_traits&
00111 operator=(const __enc_traits& __obj)
00112 {
00113 strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size);
00114 strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size);
00115 _M_ext_bom = __obj._M_ext_bom;
00116 _M_int_bom = __obj._M_int_bom;
00117 _M_destroy();
00118 _M_init();
00119 return *this;
00120 }
00121
00122 ~__enc_traits()
00123 { _M_destroy(); }
00124
00125 void
00126 _M_init()
00127 {
00128 const __desc_type __err = reinterpret_cast<iconv_t>(-1);
00129 if (!_M_in_desc)
00130 {
00131 _M_in_desc = iconv_open(_M_int_enc, _M_ext_enc);
00132 if (_M_in_desc == __err)
00133 __throw_runtime_error(__N("__enc_traits::_M_init "
00134 "creating iconv input descriptor failed"));
00135 }
00136 if (!_M_out_desc)
00137 {
00138 _M_out_desc = iconv_open(_M_ext_enc, _M_int_enc);
00139 if (_M_out_desc == __err)
00140 __throw_runtime_error(__N("__enc_traits::_M_init "
00141 "creating iconv output descriptor failed"));
00142 }
00143 }
00144
00145 void
00146 _M_destroy()
00147 {
00148 const __desc_type __err = reinterpret_cast<iconv_t>(-1);
00149 if (_M_in_desc && _M_in_desc != __err)
00150 {
00151 iconv_close(_M_in_desc);
00152 _M_in_desc = 0;
00153 }
00154 if (_M_out_desc && _M_out_desc != __err)
00155 {
00156 iconv_close(_M_out_desc);
00157 _M_out_desc = 0;
00158 }
00159 }
00160
00161 bool
00162 _M_good()
00163 {
00164 const __desc_type __err = reinterpret_cast<iconv_t>(-1);
00165 bool __test = _M_in_desc && _M_in_desc != __err;
00166 __test &= _M_out_desc && _M_out_desc != __err;
00167 return __test;
00168 }
00169
00170 const __desc_type*
00171 _M_get_in_descriptor()
00172 { return &_M_in_desc; }
00173
00174 const __desc_type*
00175 _M_get_out_descriptor()
00176 { return &_M_out_desc; }
00177
00178 int
00179 _M_get_external_bom()
00180 { return _M_ext_bom; }
00181
00182 int
00183 _M_get_internal_bom()
00184 { return _M_int_bom; }
00185
00186 const char*
00187 _M_get_internal_enc()
00188 { return _M_int_enc; }
00189
00190 const char*
00191 _M_get_external_enc()
00192 { return _M_ext_enc; }
00193 };
00194
00195
00196
00197
00198 template<typename _InternT, typename _ExternT>
00199 class codecvt<_InternT, _ExternT, __enc_traits>
00200 : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits>
00201 {
00202 public:
00203
00204 typedef codecvt_base::result result;
00205 typedef _InternT intern_type;
00206 typedef _ExternT extern_type;
00207 typedef __enc_traits state_type;
00208 typedef __enc_traits::__desc_type __desc_type;
00209 typedef __enc_traits __enc_type;
00210
00211
00212 static locale::id id;
00213
00214 explicit
00215 codecvt(size_t __refs = 0)
00216 : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
00217 { }
00218
00219 explicit
00220 codecvt(__enc_type* __enc, size_t __refs = 0)
00221 : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
00222 { }
00223
00224 protected:
00225 virtual
00226 ~codecvt() { }
00227
00228 virtual result
00229 do_out(state_type& __state, const intern_type* __from,
00230 const intern_type* __from_end, const intern_type*& __from_next,
00231 extern_type* __to, extern_type* __to_end,
00232 extern_type*& __to_next) const;
00233
00234 virtual result
00235 do_unshift(state_type& __state, extern_type* __to,
00236 extern_type* __to_end, extern_type*& __to_next) const;
00237
00238 virtual result
00239 do_in(state_type& __state, const extern_type* __from,
00240 const extern_type* __from_end, const extern_type*& __from_next,
00241 intern_type* __to, intern_type* __to_end,
00242 intern_type*& __to_next) const;
00243
00244 virtual int
00245 do_encoding() const throw();
00246
00247 virtual bool
00248 do_always_noconv() const throw();
00249
00250 virtual int
00251 do_length(state_type&, const extern_type* __from,
00252 const extern_type* __end, size_t __max) const;
00253
00254 virtual int
00255 do_max_length() const throw();
00256 };
00257
00258 template<typename _InternT, typename _ExternT>
00259 locale::id
00260 codecvt<_InternT, _ExternT, __enc_traits>::id;
00261
00262
00263
00264
00265
00266 template<typename _T>
00267 inline size_t
00268 __iconv_adaptor(size_t(*__func)(iconv_t, _T, size_t*, char**, size_t*),
00269 iconv_t __cd, char** __inbuf, size_t* __inbytes,
00270 char** __outbuf, size_t* __outbytes)
00271 { return __func(__cd, (_T)__inbuf, __inbytes, __outbuf, __outbytes); }
00272
00273 template<typename _InternT, typename _ExternT>
00274 codecvt_base::result
00275 codecvt<_InternT, _ExternT, __enc_traits>::
00276 do_out(state_type& __state, const intern_type* __from,
00277 const intern_type* __from_end, const intern_type*& __from_next,
00278 extern_type* __to, extern_type* __to_end,
00279 extern_type*& __to_next) const
00280 {
00281 result __ret = codecvt_base::error;
00282 if (__state._M_good())
00283 {
00284 const __desc_type* __desc = __state._M_get_out_descriptor();
00285 const size_t __fmultiple = sizeof(intern_type);
00286 size_t __fbytes = __fmultiple * (__from_end - __from);
00287 const size_t __tmultiple = sizeof(extern_type);
00288 size_t __tbytes = __tmultiple * (__to_end - __to);
00289
00290
00291
00292 char* __cto = reinterpret_cast<char*>(__to);
00293 char* __cfrom;
00294 size_t __conv;
00295
00296
00297
00298
00299
00300
00301 int __int_bom = __state._M_get_internal_bom();
00302 if (__int_bom)
00303 {
00304 size_t __size = __from_end - __from;
00305 intern_type* __cfixed = static_cast<intern_type*>
00306 (__builtin_alloca(sizeof(intern_type) * (__size + 1)));
00307 __cfixed[0] = static_cast<intern_type>(__int_bom);
00308 char_traits<intern_type>::copy(__cfixed + 1, __from, __size);
00309 __cfrom = reinterpret_cast<char*>(__cfixed);
00310 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00311 &__fbytes, &__cto, &__tbytes);
00312 }
00313 else
00314 {
00315 intern_type* __cfixed = const_cast<intern_type*>(__from);
00316 __cfrom = reinterpret_cast<char*>(__cfixed);
00317 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, &__fbytes,
00318 &__cto, &__tbytes);
00319 }
00320
00321 if (__conv != size_t(-1))
00322 {
00323 __from_next = reinterpret_cast<const intern_type*>(__cfrom);
00324 __to_next = reinterpret_cast<extern_type*>(__cto);
00325 __ret = codecvt_base::ok;
00326 }
00327 else
00328 {
00329 if (__fbytes < __fmultiple * (__from_end - __from))
00330 {
00331 __from_next = reinterpret_cast<const intern_type*>(__cfrom);
00332 __to_next = reinterpret_cast<extern_type*>(__cto);
00333 __ret = codecvt_base::partial;
00334 }
00335 else
00336 __ret = codecvt_base::error;
00337 }
00338 }
00339 return __ret;
00340 }
00341
00342 template<typename _InternT, typename _ExternT>
00343 codecvt_base::result
00344 codecvt<_InternT, _ExternT, __enc_traits>::
00345 do_unshift(state_type& __state, extern_type* __to,
00346 extern_type* __to_end, extern_type*& __to_next) const
00347 {
00348 result __ret = codecvt_base::error;
00349 if (__state._M_good())
00350 {
00351 const __desc_type* __desc = __state._M_get_in_descriptor();
00352 const size_t __tmultiple = sizeof(intern_type);
00353 size_t __tlen = __tmultiple * (__to_end - __to);
00354
00355
00356
00357 char* __cto = reinterpret_cast<char*>(__to);
00358 size_t __conv = __iconv_adaptor(iconv,*__desc, NULL, NULL,
00359 &__cto, &__tlen);
00360
00361 if (__conv != size_t(-1))
00362 {
00363 __to_next = reinterpret_cast<extern_type*>(__cto);
00364 if (__tlen == __tmultiple * (__to_end - __to))
00365 __ret = codecvt_base::noconv;
00366 else if (__tlen == 0)
00367 __ret = codecvt_base::ok;
00368 else
00369 __ret = codecvt_base::partial;
00370 }
00371 else
00372 __ret = codecvt_base::error;
00373 }
00374 return __ret;
00375 }
00376
00377 template<typename _InternT, typename _ExternT>
00378 codecvt_base::result
00379 codecvt<_InternT, _ExternT, __enc_traits>::
00380 do_in(state_type& __state, const extern_type* __from,
00381 const extern_type* __from_end, const extern_type*& __from_next,
00382 intern_type* __to, intern_type* __to_end,
00383 intern_type*& __to_next) const
00384 {
00385 result __ret = codecvt_base::error;
00386 if (__state._M_good())
00387 {
00388 const __desc_type* __desc = __state._M_get_in_descriptor();
00389 const size_t __fmultiple = sizeof(extern_type);
00390 size_t __flen = __fmultiple * (__from_end - __from);
00391 const size_t __tmultiple = sizeof(intern_type);
00392 size_t __tlen = __tmultiple * (__to_end - __to);
00393
00394
00395
00396 char* __cto = reinterpret_cast<char*>(__to);
00397 char* __cfrom;
00398 size_t __conv;
00399
00400
00401
00402
00403
00404
00405 int __ext_bom = __state._M_get_external_bom();
00406 if (__ext_bom)
00407 {
00408 size_t __size = __from_end - __from;
00409 extern_type* __cfixed = static_cast<extern_type*>
00410 (__builtin_alloca(sizeof(extern_type) * (__size + 1)));
00411 __cfixed[0] = static_cast<extern_type>(__ext_bom);
00412 char_traits<extern_type>::copy(__cfixed + 1, __from, __size);
00413 __cfrom = reinterpret_cast<char*>(__cfixed);
00414 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00415 &__flen, &__cto, &__tlen);
00416 }
00417 else
00418 {
00419 extern_type* __cfixed = const_cast<extern_type*>(__from);
00420 __cfrom = reinterpret_cast<char*>(__cfixed);
00421 __conv = __iconv_adaptor(iconv, *__desc, &__cfrom,
00422 &__flen, &__cto, &__tlen);
00423 }
00424
00425
00426 if (__conv != size_t(-1))
00427 {
00428 __from_next = reinterpret_cast<const extern_type*>(__cfrom);
00429 __to_next = reinterpret_cast<intern_type*>(__cto);
00430 __ret = codecvt_base::ok;
00431 }
00432 else
00433 {
00434 if (__flen < static_cast<size_t>(__from_end - __from))
00435 {
00436 __from_next = reinterpret_cast<const extern_type*>(__cfrom);
00437 __to_next = reinterpret_cast<intern_type*>(__cto);
00438 __ret = codecvt_base::partial;
00439 }
00440 else
00441 __ret = codecvt_base::error;
00442 }
00443 }
00444 return __ret;
00445 }
00446
00447 template<typename _InternT, typename _ExternT>
00448 int
00449 codecvt<_InternT, _ExternT, __enc_traits>::
00450 do_encoding() const throw()
00451 {
00452 int __ret = 0;
00453 if (sizeof(_ExternT) <= sizeof(_InternT))
00454 __ret = sizeof(_InternT)/sizeof(_ExternT);
00455 return __ret;
00456 }
00457
00458 template<typename _InternT, typename _ExternT>
00459 bool
00460 codecvt<_InternT, _ExternT, __enc_traits>::
00461 do_always_noconv() const throw()
00462 { return false; }
00463
00464 template<typename _InternT, typename _ExternT>
00465 int
00466 codecvt<_InternT, _ExternT, __enc_traits>::
00467 do_length(state_type&, const extern_type* __from,
00468 const extern_type* __end, size_t __max) const
00469 { return std::min(__max, static_cast<size_t>(__end - __from)); }
00470
00471
00472
00473 template<typename _InternT, typename _ExternT>
00474 int
00475 codecvt<_InternT, _ExternT, __enc_traits>::
00476 do_max_length() const throw()
00477 { return 1; }
00478