#include "util_encode_conv.h"#if defined(WINDOWS_IMPL) /**Windows*/#include <windows.h>#elif defined(LINUX_IMPL) /**Linux*/#include <cstdlib>#include <iconv.h>#endif#include <cstring>#include <string>namespace util {#if defined(WINDOWS_IMPL)static std::string __ws2s(const wchar_t *pwszText, UINT uCodePage){// 空指针输入if(pwszText == NULL) return "";// 无法计算需要的长度.int nNeedSize = WideCharToMultiByte(uCodePage, 0, pwszText, -1, NULL, 0, NULL, NULL);if( 0 == nNeedSize ) return "";// 分配空间,转换.char *pRet = new char[nNeedSize + 1]; // 虽然返回WideCharToMultiByte的长度是包含 null 字符的长度, 还是多+一个字符.memset(pRet, 0, nNeedSize + 1);std::string strRet("");if ( 0 != WideCharToMultiByte(uCodePage, 0, pwszText, -1, pRet, nNeedSize, NULL, NULL) ){strRet = pRet;}delete []pRet;return strRet;}static std::wstring __s2ws(const char* pszText, UINT uCodePage){// 空指针if( pszText == NULL ) return L"";// 计算长度int nNeedSize = MultiByteToWideChar(uCodePage, 0, pszText, -1, NULL, 0);if( 0 == nNeedSize ) return L"";// 分配空间,转换std::wstring strRet(L"");wchar_t *pRet = new wchar_t[nNeedSize + 1];memset(pRet, 0, (nNeedSize + 1) * sizeof(wchar_t));if( 0 != MultiByteToWideChar(uCodePage, 0, pszText, -1, pRet, nNeedSize) ){strRet = pRet;}delete []pRet;return strRet;}#elif defined(LINUX_IMPL)static std::string __ws2s(const wchar_t *pwszText, const char *szCode){if (NULL == pwszText || wcslen(pwszText) == 0)return "";unsigned len = wcslen(pwszText) * 4 + 1;setlocale(LC_CTYPE, szCode);char *p = new char[len];wcstombs(p, pwszText, len);std::string str(p);delete[] p;return str;}static std::wstring __s2ws(const char* pszText, const char *szCode){if (NULL == pszText || strlen(pszText) == 0)return L"";unsigned len = strlen(pszText) + 1;setlocale(LC_CTYPE, szCode);wchar_t *p = new wchar_t[len];mbstowcs(p, pszText, len);std::wstring w_str(p);delete[] p;return w_str;}#endifstd::string EncodeConvert::WtoA(const std::wstring &strText){#if defined(WINDOWS_IMPL)return __ws2s(strText.c_str(), CP_ACP);#elif defined(LINUX_IMPL)return __ws2s(strText.c_str(), "zh_CN.GBK");#endif}std::string EncodeConvert::WtoA(const wchar_t *pwszText){#if defined(WINDOWS_IMPL)return __ws2s(pwszText, CP_ACP);#elif defined(LINUX_IMPL)return __ws2s(pwszText, "zh_CN.GBK");#endif}std::wstring EncodeConvert::AtoW(const std::string &strText){#if defined(WINDOWS_IMPL)return __s2ws(strText.c_str(), CP_ACP);#elif defined(LINUX_IMPL)return __s2ws(strText.c_str(), "zh_CN.GBK");#endif}std::wstring EncodeConvert::AtoW(const char* pszText){#if defined(WINDOWS_IMPL)return __s2ws(pszText, CP_ACP);#elif defined(LINUX_IMPL)return __s2ws(pszText, "zh_CN.GBK");#endif}std::string EncodeConvert::WtoUTF8(const std::wstring &strText){#if defined(WINDOWS_IMPL)return __ws2s(strText.c_str(), CP_UTF8);#elif defined(LINUX_IMPL)return __ws2s(strText.c_str(), "zh_CN.UTF-8");#endif}std::string EncodeConvert::WtoUTF8(const wchar_t *pwszText){#if defined(WINDOWS_IMPL)return __ws2s(pwszText, CP_UTF8);#elif defined(LINUX_IMPL)return __ws2s(pwszText, "zh_CN.UTF-8");#endif}std::wstring EncodeConvert::UTF8toW(const std::string &strText){#if defined(WINDOWS_IMPL)return __s2ws(strText.c_str(), CP_UTF8);#elif defined(LINUX_IMPL)return __s2ws(strText.c_str(), "zh_CN.UTF-8");#endif}std::wstring EncodeConvert::UTF8toW(const char* pszText){#if defined(WINDOWS_IMPL)return __s2ws(pszText, CP_UTF8);#elif defined(LINUX_IMPL)return __s2ws(pszText, "zh_CN.UTF-8");#endif}std::string EncodeConvert::UTF8toA(const std::string &src){#if defined(WINDOWS_IMPL)return WtoA(UTF8toW(src));#elif defined(LINUX_IMPL)iconv_t cd = iconv_open("gb2312", "utf-8");char *csrc = (char*)src.c_str();size_t clen = src.size();size_t dlen = clen * 4;char *cdst = (char*)malloc(dlen);memset(cdst, 0 , dlen);char *cend = cdst;iconv(cd, &csrc, &clen, &cend, &dlen);std::string ret(cdst);free(cdst);iconv_close(cd);return ret;#endif}std::string EncodeConvert::UTF8toA(const char *src){#if defined(WINDOWS_IMPL)return WtoA(UTF8toW(src));#elif defined(LINUX_IMPL)iconv_t cd = iconv_open("gb2312", "utf-8");char *csrc = (char*)src;size_t clen = strlen(src);size_t dlen = clen * 4;char *cdst = (char*)malloc(dlen);memset(cdst, 0 , dlen);char *cend = cdst;iconv(cd, &csrc, &clen, &cend, &dlen);std::string ret(cdst);free(cdst);iconv_close(cd);return ret;#endif}std::string EncodeConvert::AtoUTF8(const std::string &src){#if defined(WINDOWS_IMPL)return WtoUTF8(AtoW(src));#elif defined(LINUX_IMPL)char *csrc = (char*)src.c_str();size_t clen = src.size();size_t dlen = clen * 4;char *cdst = (char*)malloc(dlen);memset(cdst, 0 , dlen);char *cend = cdst;iconv_t cd = iconv_open("utf-8", "gb2312");size_t c = iconv(cd, &csrc, &clen, &cend, &dlen);std::string ret(cdst);iconv_close(cd);free(cdst);return ret;#endif}std::string EncodeConvert::AtoUTF8(const char* src){#if defined(WINDOWS_IMPL)return WtoUTF8(AtoW(src));#elif defined(LINUX_IMPL)iconv_t cd = iconv_open("utf-8", "gb2312");char *csrc = (char*)src;size_t clen = strlen(src);size_t dlen = clen * 4;char *cdst = (char*)malloc(dlen);memset(cdst, 0 , dlen);char *cend = cdst;iconv(cd, &csrc, &clen, &cend, &dlen);std::string ret(cdst);free(cdst);iconv_close(cd);return ret;#endif}/*UTF-8 编码最多可以有6个字节1字节 0xxxxxxx2字节 110xxxxx 10xxxxxx3字节 1110xxxx 10xxxxxx 10xxxxxx4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx*/// 返回值说明:// 0 -> 输入字符串符合UTF-8编码规则// -1 -> 检测到非法的UTF-8编码首字节// -2 -> 检测到非法的UTF-8字节编码的后续字节.int EncodeConvert::IsTextUTF8(const char* pszSrc){const unsigned char* puszSrc = (const unsigned char*)pszSrc; // 一定要无符号的,有符号的比较就不正确了.// 看看有没有BOM表示 EF BB BFif( puszSrc[0] != 0 && puszSrc[0] == 0xEF &&puszSrc[1] != 0 && puszSrc[1] == 0xBB &&puszSrc[2] != 0 && puszSrc[2] == 0xBF){return 0;}// 如果没有 BOM标识bool bIsNextByte = false;int nBytes = 0; // 记录一个字符的UTF8编码已经占用了几个字节.const unsigned char* pCur = (const unsigned char*)pszSrc; // 指针游标用无符号字符型. 因为高位为1, 如果用 char 型, 会变为负数,不利于编程时候的比较操作.while( pCur[0] != 0 ){if(!bIsNextByte){bIsNextByte = true;if ( (pCur[0] >> 7) == 0) { bIsNextByte = false; nBytes = 1; bIsNextByte = false; } // 最高位为0, ANSI 兼容的.else if ((pCur[0] >> 5) == 0x06) { nBytes = 2; } // 右移5位后是 110 -> 2字节编码的UTF8字符的首字节else if ((pCur[0] >> 4) == 0x0E) { nBytes = 3; } // 右移4位后是 1110 -> 3字节编码的UTF8字符的首字节else if ((pCur[0] >> 3) == 0x1E) { nBytes = 4; } // 右移3位后是 11110 -> 4字节编码的UTF8字符的首字节else if ((pCur[0] >> 2) == 0x3E) { nBytes = 5; } // 右移2位后是 111110 -> 5字节编码的UTF8字符的首字节else if ((pCur[0] >> 1) == 0x7E) { nBytes = 6; } // 右移1位后是 1111110 -> 6字节编码的UTF8字符的首字节else{nBytes = -1; // 非法的UTF8字符编码的首字节break;}}else{if ((pCur[0] >> 6) == 0x02) // 首先,后续字节必须以 10xxx 开头{nBytes--;if (nBytes == 1) bIsNextByte = false; // 当 nBytes = 1时, 说明下一个字节应该是首字节.}else{nBytes = -2;break;}}// 下跳一个字符pCur++;}if( nBytes == 1) return 0;else return nBytes;}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。