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