📄 wyiconv.cpp
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2003*/#define WYLIB_SOURCE#include "wyiconv.h"const char WyIConv::class_name[]="WyIConv";const ::iconv_t WyIConv::_DefaultICD=(::iconv_t)(-1); // see iconv_open(3)WyIConv::WyIConv() WY__TSPC() : _icd(_DefaultICD){};WyIConv::WyIConv(const char* tocode, const char* fromcode) : _icd(::iconv_open(tocode,fromcode)){ if(_icd==(::iconv_t)(-1)) { WY_THROW( Reply(errno) ); }};WyIConv::~WyIConv(){ if(_icd!=_DefaultICD) { const ::iconv_t tmpfd( _icd ); _icd=_DefaultICD; ::iconv_close(tmpfd); }};WyRet WyIConv::reset(void){ if(_icd!=_DefaultICD) { const ::iconv_t tmpfd( _icd ); _icd=_DefaultICD; if(::iconv_close(tmpfd)!=0) { WY_RETURN(errno); } } return(Ok);};WyRet WyIConv::reset(const char* tocode, const char* fromcode){ const ::iconv_t tmpfd(::iconv_open(tocode,fromcode)); if(tmpfd==(::iconv_t)(-1)) { WY_RETURN( errno ); } try { this->reset(); } catch(...) { ::iconv_close(tmpfd); throw; }; _icd=tmpfd; return(Ok);};WyRet WyIConv::iconv(void){ if(::iconv(_icd,NULL,NULL,NULL,NULL)==(size_t)(-1)) { WY_RETURN(errno); } return(Ok);};WyRet WyIConv::iconv(WyStr& outbuf){ outbuf.reset(); WyRet r; char* out_ptr( &outbuf[0] ); size_t out_lft( outbuf._capacity() ); for(;;) { const size_t v=::iconv(_icd,NULL,NULL, &out_ptr,&out_lft); if(v==(size_t)(-1)) { if(errno==E2BIG) { // note: iconv(..) does not return Wym_E2BIG, instead the reply // from WyStr::_reserve if((r=outbuf._reserve(outbuf._capacity()<<1))!=Ok) { // FBIG/NOMEM outbuf.reset(); WY_RETURN(r); } out_ptr=&outbuf[0]; out_lft=outbuf._capacity(); continue; } else { outbuf.reset(); WY_RETURN(errno); // not likely to occur from the manual } } else { #ifdef WY_DEBUG if(outbuf._capacity()<(size_t)(out_ptr-outbuf.begin())) { WY_TERMINATE(""); } #endif outbuf._setsize(out_ptr-outbuf.begin()); // won't fail return(Ok); } }; // UNREACHABLE};WyRet WyIConv::iconv(WyCSeg& in_range, WyStr& out_buf,size_t& n_reversible){ n_reversible=0; if(in_range.is_overlap(out_buf.cseg())) { WY_RETURN( Wym_ELOOP ); } out_buf.reset(); const char* in_ptr( in_range.begin() ); size_t in_lft( in_range.size() ); char* out_ptr( &out_buf[0] ); size_t out_lft( out_buf._capacity() ); WyRet r; for(;;) { const size_t v( ::iconv(_icd,(char**)&in_ptr,&in_lft, &out_ptr,&out_lft) ); if(v==(size_t)(-1)) { in_range.reset(in_ptr,in_lft); out_buf._setsize(out_ptr-out_buf.begin()); // won't fail if(errno==E2BIG) { // note: this member does not return Wym_E2BIG, instead the reply // from WyStr::_reserve if((r=out_buf._reserve(out_buf._capacity()<<1))!=Ok) { // FBIG/NOMEM WY_RETURN(r); } out_ptr=&out_buf[out_buf.size()]; out_lft=out_buf._capacity()-out_buf.size(); continue; } else { WY_RETURN(errno); } } else { n_reversible+=v; #ifdef WY_DEBUG if(in_lft!=(size_t)(in_range.end()-in_ptr)) { WY_TERMINATE(""); // ::iconv result not as expected } #endif in_range.reset(in_ptr,in_lft); #ifdef WY_DEBUG if(out_buf._capacity()<(size_t)(out_ptr-out_buf.begin())) { WY_TERMINATE(""); // ::iconv result not as expected } #endif out_buf._setsize(out_ptr-out_buf.begin()); // won't fail return(Ok); } }; // UNREACHABLE};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -