ANSIToMultiByteUTF8的跨平台实现
2010年9月27日
15:53
//2010-09-27 转载请注明出处
//从reactOS的IntWideCharToMultiByteUTF8源码移植,模仿windows的实现方式
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Added: 2010/9/27 13:09 viki
//comments: 增加跨平台的UTF8转换函数,目前去掉了iconv转换中的一些出错处理
// 待补充和完善。
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//此函数迁移自ReactOS的源码,模拟windows中IntWideCharToMultiByteUTF8的实现
int QtUtility::WideCharToMultiByteUTF8(constwchar_t* WideCharString, int WideCharCount,
char* MultiByteString, int MultiByteCount)
{
/* Check the parameters. */
if (WideCharString == NULL ||
(MultiByteString == NULL &&MultiByteCount > 0) ||
(void*)WideCharString == (void*)MultiByteString||
MultiByteCount < 0)
{
//SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Determine the input string length. */
if (WideCharCount < 0)
{
WideCharCount = (int)wcslen(WideCharString) +1;
}
int TempLength;
wchar_t Char;
/* Does caller query for output buffer size? */
if (MultiByteCount == 0)
{
for (TempLength = 0; WideCharCount;
WideCharCount--, WideCharString++)
{
TempLength++;
if (*WideCharString >= 0x80)
{
TempLength++;
if (*WideCharString >= 0x800)
TempLength++;
if (*WideCharString >= 0x10000)
TempLength++;
}
}
return TempLength;
}
for (TempLength = MultiByteCount;WideCharCount; WideCharCount--, WideCharString++)
{
Char = *WideCharString;
//U+00000000 – U+0000007F 0xxxxxxx
if (Char < 0x80) /*0x800-0x7f: 1 bytes */ /* ASCII */
{
if (!TempLength)
{
//SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
TempLength--;
*MultiByteString++ = (char)Char;
continue;
}
//U+00000080 – U+000007FF 110xxxxx 10xxxxxx
if (Char < 0x800) /*0x80-0x7ff: 2 bytes */
{
if (TempLength < 2)
{
//SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
MultiByteString[1] = 0x80 | (Char & 0x3f);Char >>= 6;
MultiByteString[0] = 0xc0 | Char;
MultiByteString += 2;
TempLength -= 2;
continue;
}
//U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
if (Char < 0x10000) /* 0x800-0xffff: 3bytes */
{
if (TempLength < 3)
{
//SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
MultiByteString[2] = 0x80 | (Char & 0x3f);Char >>= 6;
MultiByteString[1] = 0x80 | (Char & 0x3f);Char >>= 6;
MultiByteString[0] = 0xe0 | Char;
MultiByteString += 3;
TempLength -= 3;
continue;
}
//现今Unicode编码最多到U+0010FFFD的增补私用B区
//U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx10xxxxxx
if (Char < 0x200000) /*0x10000-0x1fffff: 4 bytes */
{
if (TempLength < 4)
{
//SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
MultiByteString[3] = 0x80 | (Char & 0x3f);Char >>= 6;
MultiByteString[2] = 0x80 | (Char & 0x3f);Char >>= 6;
MultiByteString[1] = 0x80 | (Char & 0x3f);Char >>= 6;
MultiByteString[0] = 0xf0 | Char;
MultiByteString += 4;
TempLength -= 4;
continue;
}
U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx10xxxxxx 10xxxxxx
//if (Char < 0x4000000) /*0x200000-0x3ffffff: 5 bytes */
//{
// if(TempLength < 5)
// {
// //SetLastError(ERROR_INSUFFICIENT_BUFFER);
// break;
// }
// MultiByteString[4]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[3]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[2]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[1]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[0]= 0xf8 | Char;
// MultiByteString+= 5;
// TempLength-= 5;
// continue;
//}
U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx10xxxxxx 10xxxxxx 10xxxxxx
//if (Char < 0x4000000) /*0x4000000-0x8fffffff: 6 bytes */
//{
// if(TempLength < 6)
// {
// //SetLastError(ERROR_INSUFFICIENT_BUFFER);
// break;
// }
// MultiByteString[5]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[4]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[3]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[2]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[1]= 0x80 | (Char & 0x3f); Char >>= 6;
// MultiByteString[0]= 0xfc | Char;
// MultiByteString+= 6;
// TempLength-= 6;
// continue;
//}
}
return MultiByteCount - TempLength;
}
int QtUtility::ANSIToMultiByteUTF8(constchar* ANSIString, int ANSICharCount, char* UTF8String, int UTF8Count)
{
if (ANSIString == NULL ||
(UTF8String == NULL && UTF8Count >0) ||
(void*)ANSIString == (void*)UTF8String)
{
//SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Determine the input string length. */
if (ANSICharCount < 0)
{
ANSICharCount = (int)strlen(ANSIString) + 1;
}
//设置区域
#ifndef WIN32
setlocale(LC_CTYPE,"zh_CN.gb2312");
#else
setlocale(LC_CTYPE,"");
#endif
int iwcslen = (int)mbstowcs(NULL, (constchar*)ANSIString, 0) + 1;
if (iwcslen <= 1)
{
#ifndef WIN32
setlocale(LC_CTYPE, "");
#endif
return 0;
}
wchar_t* pWcsBuffer = new wchar_t[iwcslen];
if (pWcsBuffer == NULL)
{
#ifndef WIN32
setlocale(LC_CTYPE, "");
#endif
return 0;
}
int nret = (int)mbstowcs(pWcsBuffer,(const char*)ANSIString, iwcslen);
if (nret <= 0)
{
#ifndef WIN32
setlocale(LC_CTYPE, "");
#endif
delete[] pWcsBuffer;
return 0;
}
//pWcsBuffer[iwcslen] = 0x00;
nret = WideCharToMultiByteUTF8(pWcsBuffer,(int)wcslen(pWcsBuffer), UTF8String, UTF8Count);
if (UTF8String != NULL && UTF8Count> 0 && nret > 0)
{
UTF8String[UTF8Count] = 0x00;
}
delete[] pWcsBuffer;
#ifndef WIN32
setlocale(LC_CTYPE, "");
#endif
return nret;
}
已使用 Microsoft OneNote 2010 创建
一个用于存放所有笔记和信息的位置