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