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