#include "stdafx.h" #include "iconv.h" #include "iconv_impl.h" #ifdef USE_STATIC_ICONV // 使用静态库; // mt #if defined(_MT) && !defined(_DLL) #ifdef _DEBUG// mtd; #pragma comment(lib,"./lib/libiconv_mtd.lib") #else // mt; #pragma comment(lib,"./lib/libiconv_mt.lib") #endif #endif // md; #if defined(_MT) && defined(_DLL) #ifdef _DEBUG // mdd; #pragma comment(lib,"./lib/libiconv_mdd.lib") #else // md; #pragma comment(lib,"./lib/libiconv_md.lib") #endif #endif #else // 使用dll的静态连接; // mt #if defined(_MT) && !defined(_DLL) #ifdef _DEBUG// mtd; #pragma comment(lib,"./dll/libiconv_mtd.lib") #else // mt; #pragma comment(lib,"./dll/libiconv_mt.lib") #endif #endif // md; #if defined(_MT) && defined(_DLL) #ifdef _DEBUG // mdd; #pragma comment(lib,"./dll/libiconv_mdd.lib") #else // md; #pragma comment(lib,"./dll/libiconv_md.lib") #endif #endif #endif /************************************************************************/ /* 函数:[1/22/2018 Home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ std::string convert2(const char *from, const char* to, const char* inbuf, const size_t &inbufsize) { int iconv_ret = 0; // 打开字符集转换; iconv_t hIconv = iconv_open(to, from); if (-1 == (int)hIconv) return "";//打开失败,可能不支持的字符集 size_t insize = inbufsize; std::string strout; // 循环利用; size_t outsize = 512; // 513多一位用做字符结束符; char out[513] = { 0 }; while (insize > 0) { outsize = 512; memset(out, 0, outsize); // out地址保存不变,以便重复使用; char *p = out; // 开始转换; iconv_ret = iconv(hIconv, (const char**)(&inbuf), &insize, &p, &outsize); if (((iconv_ret == (size_t)-1) && (E2BIG == errno)) || (iconv_ret != (size_t)-1)) { // out和p地址不同, p-out指针相减得到长度; //strout.append(out, p - out); strout.insert(strout.size(), out, p - out); } } //关闭字符集转换 iconv_close(hIconv); return strout; } std::string convert(const char *from, const char* to, const char* inbuf, const size_t &inbufsize) { int iconv_ret = 0; // 打开字符集转换; iconv_t hIconv = iconv_open(to, from); if (-1 == (int)hIconv) return "";//打开失败,可能不支持的字符集 int status = 0; int times = (inbufsize / 512) + 1; // 预计可转换的次数; iconv(hIconv, NULL, NULL, NULL, NULL); size_t insize = inbufsize; std::string strout = ""; // 循环利用; size_t outsize = 512; // 513多一位用做字符结束符; char out[513] = { 0 }; while (insize > 0) { outsize = 512; memset(out, 0, outsize); // out地址保存不变,以便重复使用; char *p = out; // 开始转换; //times--; iconv_ret = iconv(hIconv, (const char**)(&inbuf), &insize, &p, &outsize); if (out != p) { int saved_errno = errno; strout.insert(strout.size(), out, p - out); errno = saved_errno; } if (iconv_ret == (size_t)(-1)) { if (errno == EILSEQ) {// 输入中遇到无效的多字节序列; int one = 1; // 非法序列丢弃并继续; iconvctl(hIconv, ICONV_SET_DISCARD_ILSEQ, &one); status = -3; } else if (errno == EINVAL) {// 输入中遇到了一个不完整的多字节序列; if (inbufsize == 0) { status = -4; goto done; } else { break; } } else if (errno == E2BIG) {// *outbuf没有足够的空间; status = -5; //goto done; } else { status = -6; goto done; } } /*if (((iconv_ret == (size_t)-1) && (E2BIG == errno)) || (iconv_ret != (size_t)-1)) { // out和p地址不同, p-out指针相减得到长度; //strout.append(out, p - out); strout.insert(strout.size(), out, p - out); }*/ } done: //关闭字符集转换 iconv_close(hIconv); return strout; } /************************************************************************/ /* 函数:[7/26/2016 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ TString EnCode_UTF8URL(const TCHAR* pText) { if (pText == NULL || pText[0] == '\0') return _T(""); std::string tt = ""; std::string dd = ""; //ASCII2UTF8(pText, tt); #ifdef UNICODE tt = convert("UCS-2LE", "UTF-8", (char*)pText, _tcslen(pText) * sizeof(TCHAR)); #else tt = convert("ASCII", "UTF-8", pText, strlen(pText)); #endif size_t len = tt.length(); for (size_t i = 0; i < len; i++) { if (isalnum((BYTE)tt.at(i))) { char tempbuff[2] = { 0 }; sprintf_s(tempbuff, "%c", (BYTE)tt.at(i)); dd.append(tempbuff); } else if (isspace((BYTE)tt.at(i))) { dd.append("+"); } else { char tempbuff[4]; sprintf_s(tempbuff, "%%%X%X", ((BYTE)tt.at(i)) >> 4, ((BYTE)tt.at(i)) % 16); dd.append(tempbuff); } } #ifdef UNICODE //tt = convert("ASCII", "UCS-2LE", dd.c_str(), dd.size()); //TString result; //result.append((TCHAR*)tt.c_str(), dd.size()); //return result; // 将以上4行代码,简化成一行; return TString().append((TCHAR*)convert("ASCII", "UCS-2LE", dd.c_str(), dd.size()).c_str(), dd.size()); #else return dd; #endif } void EnCode_UTF8URL(const TCHAR* pText, TString& strResult) { std::string tt = ""; //ASCII2UTF8(pText, tt); #ifdef UNICODE std::string result = ""; tt = convert("UCS-2LE", "UTF-8", (char*)pText, _tcslen(pText) * sizeof(TCHAR)); #else tt = convert("ASCII", "UTF-8", pText, strlen(pText)); #endif size_t len = tt.length(); for (size_t i = 0; i < len; i++) { if (isalnum((BYTE)tt.at(i))) { char tempbuff[2] = { 0 }; sprintf_s(tempbuff, "%c", (BYTE)tt.at(i)); #ifdef UNICODE result.append(tempbuff); #else strResult.append(tempbuff); #endif } else if (isspace((BYTE)tt.at(i))) { #ifdef UNICODE result.append("+"); #else strResult.append("+"); #endif } else { char tempbuff[4]; sprintf_s(tempbuff, "%%%X%X", ((BYTE)tt.at(i)) >> 4, ((BYTE)tt.at(i)) % 16); #ifdef UNICODE result.append(tempbuff); #else strResult.append(tempbuff); #endif } } #ifdef UNICODE //tt = convert("ASCII", "UCS-2LE", dd.c_str(), dd.size()); //TString result; //result.append((TCHAR*)tt.c_str(), dd.size()); // 将以上代码,简化成一行; strResult.append((TCHAR*)convert("ASCII", "UCS-2LE", result.c_str(), result.size()).c_str(), result.size()); #endif }