ANSIToMultiByteUTF8的跨平台实现

ANSIToMultiByteUTF8的跨平台实现

2010年9月27日

15:53

//2010-09-27 转载请注明出处

//reactOSIntWideCharToMultiByteUTF8源码移植,模仿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 创建
一个用于存放所有笔记和信息的位置



Published by Wiz



posted on 2011-08-31 14:01  windviki  阅读(594)  评论(0编辑  收藏  举报