开发语言:C++
功能描述:
Unicode内码转换器。用于UTF-8、UTF-16(UCS2)、UTF-32(UCS4)之间的编码转换。
下载地址:
V1.0 2010年03月12日
- 完成正式版本。
源代码:
UnicodeConverter.h
/* ----------------------------------------------------------
文件名称:UnicodeConverter.h
作者:秦建辉
MSN:splashcn@msn.com
当前版本:V1.0
历史版本:
V1.0 2010年03月12日
完成正式版本。
功能描述:
Unicode内码转换器。用于utf-8、utf-16(UCS2)、utf-32(UCS4)之间的编码转换
------------------------------------------------------------ */
#pragma once
#include <windows.h>
#include <stdio.h>
#include <ostream>
using namespace std;
class CUnicodeConverter
{
/* -------------------------------------------------------------
内码转换
------------------------------------------------------------- */
public:
/*
功能:将UCS4编码转换成UTF8编码
参数:
dwUCS4:要转换的UCS4编码
pbUTF8:用于存储转换后的UTF8编码。设为NULL,可以获取长度信息(字节数)
返回值:
0:无效的UCS4编码
1-6:UTF8编码的有效长度
*/
static INT UCS4_To_UTF8( DWORD dwUCS4, BYTE* pbUTF8 );
/*
功能:将UTF8编码转换成UCS4编码
参数:
pbUTF8:要转换的UTF8编码
dwUCS4:存储转换后的UCS4编码
返回值:
0:参数错误或无效的UTF8编码
1-6:UTF8编码的有效长度
*/
static INT UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 );
/*
功能:将UCS4编码转换成UTF16编码
参数:
dwUCS4:要转换的UCS4编码
pwUTF16:用于存储转换后的UTF16编码。设为NULL,可以获取长度信息(字符数)
返回值:
0:无效的UCS4编码
1:转换成1个UTF16编码
2:转换成2个UTF16编码
*/
static INT UCS4_To_UTF16( DWORD dwUCS4, WORD* pwUTF16 );
/*
功能:将UTF16编码转换成UCS4编码
参数:
pwUTF16:需要转换的UTF16编码
dwUCS4:存储转换后的UCS4编码
返回值:
0:参数错误或无效的UTF16编码
1:1个UTF16编码被转换
2:2个UTF16编码被转换
*/
static INT UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 );
/*
功能:将UTF8字符串转换成UTF16字符串
参数:
pbszUTF8Str:需要转换的UTF8字符串
pwszUTF16Str:存储转换后的UTF16字符串。设为NULL,可以获取所需长度信息(字符数)
返回值:
0:转换失败
>0:UTF16字符串长度
*/
static INT UTF8Str_To_UTF16Str( const BYTE* pbszUTF8Str, WORD* pwszUTF16Str );
/*
功能:将UTF16字符串转换成UTF8字符串
参数:
pwszUTF16Str:需要转换的UTF16字符串
pbszUTF8Str:存储转换后的UTF8字符串。设为NULL,可以获取所需长度信息(字节数)
返回值:
0:转换失败
>0:UTF8字符串长度(不包括NULL字符)
*/
static INT UTF16Str_To_UTF8Str( const WORD* pwszUTF16Str, BYTE* pbszUTF8Str );
/* -------------------------------------------------------------
C文件写入操作
------------------------------------------------------------- */
public:
/*
功能:向文件中写入UTF8编码
返回值:
写入的字节数
*/
static UINT Print_UTF8_By_UCS4( FILE* out, DWORD dwUCS4 );
/*
功能:向文件中写入UTF16编码
返回值:
写入的字节数
*/
static UINT Print_UTF16_By_UCS4( FILE* out, DWORD dwUCS4, BOOL isBigEndian = FALSE );
/*
功能:将UTF16字符串以UTF8编码输出到文件中
返回值:
写入的字节数
*/
static UINT Print_UTF8Str_By_UTF16Str( FILE* out, const WORD* pwszUTF16Str );
/*
功能:将UTF8字符串以UTF16编码输出到文件中
返回值:
写入的字节数
*/
static UINT Print_UTF16Str_By_UTF8Str( FILE* out, const BYTE* pbszUTF8Str, BOOL isBigEndian = FALSE );
/*
功能:向文件中输出UTF8编码字节序标记
返回值:
写入的字节数
*/
static UINT Print_UTF8_BOM( FILE* out );
/*
功能:向文件中输出UTF16编码字节序标记
返回值:
写入的字节数
*/
static UINT Print_UTF16_BOM( FILE* out, BOOL isBigEndian = FALSE );
/* -------------------------------------------------------------
C++流输出操作
------------------------------------------------------------- */
public:
/*
功能:向流中写入UTF8编码
返回值:
写入的字节数
*/
static UINT Print_UTF8_By_UCS4( ostream& os, DWORD dwUCS4 );
/*
功能:向流中写入UTF16编码
返回值:
写入的字节数
*/
static UINT Print_UTF16_By_UCS4( ostream& os, DWORD dwUCS4, BOOL isBigEndian = FALSE );
/*
功能:将UTF16字符串以UTF8编码输出到流中
返回值:
写入的字节数
*/
static UINT Print_UTF8Str_By_UTF16Str( ostream& os, const WORD* pwszUTF16Str );
/*
功能:将UTF8字符串以UTF16编码输出到流中
返回值:
写入的字节数
*/
static UINT Print_UTF16Str_By_UTF8Str( ostream& os, const BYTE* pbszUTF8Str, BOOL isBigEndian = FALSE );
/*
功能:向流中输出UTF8编码字节序标记
返回值:
写入的字节数
*/
static UINT Print_UTF8_BOM( ostream& os );
/*
功能:向流中输出UTF16编码字节序标记
返回值:
写入的字节数
*/
static UINT Print_UTF16_BOM( ostream& os, BOOL isBigEndian = FALSE );
};
/* ------------------------------
END
------------------------------ */
UnicodeConverter.cpp
#include "UnicodeConverter.h"
/* -------------------------------------------------------------
内码转换
------------------------------------------------------------- */
// 转换UCS4编码到UTF8编码
INT CUnicodeConverter::UCS4_To_UTF8( DWORD dwUCS4, BYTE* pbUTF8 )
{
const BYTE abPrefix[] = {0, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
const DWORD adwCodeUp[] = {
0x80, // U+00000000 ~ U+0000007F
0x800, // U+00000080 ~ U+000007FF
0x10000, // U+00000800 ~ U+0000FFFF
0x200000, // U+00010000 ~ U+001FFFFF
0x4000000, // U+00200000 ~ U+03FFFFFF
0x80000000 // U+04000000 ~ U+7FFFFFFF
};
INT i, iLen;
// 根据UCS4编码范围确定对应的UTF-8编码字节数
iLen = sizeof(adwCodeUp) / sizeof(DWORD);
for( i = 0; i < iLen; i++ )
{
if( dwUCS4 < adwCodeUp[i] )
{
break;
}
}
if( i == iLen )return 0; // 无效的UCS4编码
iLen = i + 1; // UTF-8编码字节数
if( pbUTF8 != NULL )
{ // 转换为UTF-8编码
for( ; i > 0; i-- )
{
pbUTF8[i] = static_cast<BYTE>((dwUCS4 & 0x3F) | 0x80);
dwUCS4 >>= 6;
}
pbUTF8[0] = static_cast<BYTE>(dwUCS4 | abPrefix[iLen - 1]);
}
return iLen;
}
// 转换UTF8编码到UCS4编码
INT CUnicodeConverter::UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 )
{
INT i, iLen;
BYTE b;
if( pbUTF8 == NULL )
{ // 参数错误
return 0;
}
b = *pbUTF8++;
if( b < 0x80 )
{
dwUCS4 = b;
return 1;
}
if( b < 0xC0 || b > 0xFD )
{ // 非法UTF8
return 0;
}
if( b < 0xE0 )
{
dwUCS4 = b & 0x1F;
iLen = 2;
}
else if( b < 0xF0 )
{
dwUCS4 = b & 0x0F;
iLen = 3;
}
else if( b < 0xF8 )
{
dwUCS4 = b & 7;
iLen = 4;
}
else if( b < 0xFC )
{
dwUCS4 = b & 3;
iLen = 5;
}
else
{
dwUCS4 = b & 1;
iLen = 6;
}
for( i = 1; i < iLen; i++ )
{
b = *pbUTF8++;
if( b < 0x80 || b > 0xBF )
{ // 非法UTF8
break;
}
dwUCS4 = (dwUCS4 << 6) + (b & 0x3F);
}
if( i < iLen )
{ // 非法UTF8
return 0;
}
else
{
return iLen;
}
}
// 转换UCS4编码到UCS2编码
INT CUnicodeConverter::UCS4_To_UTF16( DWORD dwUCS4, WORD* pwUTF16 )
{
if( dwUCS4 <= 0xFFFF )
{
if( pwUTF16 != NULL )
{
*pwUTF16 = static_cast<WORD>(dwUCS4);
}
return 1;
}
else if( dwUCS4 <= 0xEFFFF )
{
if( pwUTF16 != NULL )
{
pwUTF16[0] = static_cast<WORD>( 0xD800 + (dwUCS4 >> 10) - 0x40 ); // 高10位
pwUTF16[1] = static_cast<WORD>( 0xDC00 + (dwUCS4 & 0x03FF) ); // 低10位
}
return 2;
}
else
{
return 0;
}
}
// 转换UCS2编码到UCS4编码
INT CUnicodeConverter::UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 )
{
WORD w1, w2;
if( pwUTF16 == NULL )
{ // 参数错误
return 0;
}
w1 = pwUTF16[0];
if( w1 >= 0xD800 && w1 <= 0xDFFF )
{ // 编码在替代区域(Surrogate Area)
if( w1 < 0xDC00 )
{
w2 = pwUTF16[1];
if( w2 >= 0xDC00 && w2 <= 0xDFFF )
{
dwUCS4 = (w2 & 0x03FF) + (((w1 & 0x03FF) + 0x40) << 10);
return 2;
}
}
return 0; // 非法UTF16编码
}
else
{
dwUCS4 = w1;
return 1;
}
}
// 转换UTF8字符串到UTF16字符串
INT CUnicodeConverter::UTF8Str_To_UTF16Str( const BYTE* pbszUTF8Str, WORD* pwszUTF16Str )
{
INT iNum, iLen;
DWORD dwUCS4;
if( pbszUTF8Str == NULL )
{ // 参数错误
return 0;
}
iNum = 0; // 统计有效字符个数
while( *pbszUTF8Str )
{ // UTF8编码转换为UCS4编码
iLen = UTF8_To_UCS4( pbszUTF8Str, dwUCS4 );
if( iLen == 0 )
{ // 非法的UTF8编码
return 0;
}
pbszUTF8Str += iLen;
// UCS4编码转换为UTF16编码
iLen = UCS4_To_UTF16( dwUCS4, pwszUTF16Str );
if( iLen == 0 )
{
return 0;
}
if( pwszUTF16Str != NULL )
{
pwszUTF16Str += iLen;
}
iNum += iLen;
}
if( pwszUTF16Str != NULL )
{
*pwszUTF16Str = 0; // 写入字符串结束标记
}
return iNum;
}
// 转换UTF16字符串到UTF8字符串
INT CUnicodeConverter::UTF16Str_To_UTF8Str( const WORD* pwszUTF16Str, BYTE* pbszUTF8Str )
{
INT iNum, iLen;
DWORD dwUCS4;
if( pwszUTF16Str == NULL )
{ // 参数错误
return 0;
}
iNum = 0;
while( *pwszUTF16Str )
{ // UTF16编码转换为UCS4编码
iLen = UTF16_To_UCS4( pwszUTF16Str, dwUCS4 );
if( iLen == 0 )
{ // 非法的UTF16编码
return 0;
}
pwszUTF16Str += iLen;
// UCS4编码转换为UTF8编码
iLen = UCS4_To_UTF8( dwUCS4, pbszUTF8Str );
if( iLen == 0 )
{
return 0;
}
if( pbszUTF8Str != NULL )
{
pbszUTF8Str += iLen;
}
iNum += iLen;
}
if( pbszUTF8Str != NULL )
{
*pbszUTF8Str = 0; // 写入字符串结束标记
}
return iNum;
}
/* -------------------------------------------------------------
C文件写入操作
------------------------------------------------------------- */
// 向文件中输出UTF8编码
UINT CUnicodeConverter::Print_UTF8_By_UCS4( FILE* out, DWORD dwUCS4 )
{
INT iLen;
BYTE abUTF8[8];
if( out == NULL )
{
return 0;
}
iLen = UCS4_To_UTF8( dwUCS4, abUTF8 );
if( iLen == 0 )return 0;
fwrite( abUTF8, 1, iLen, out );
return iLen;
}
// 向文件中输出UTF16编码
UINT CUnicodeConverter::Print_UTF16_By_UCS4( FILE* out, DWORD dwUCS4, BOOL isBigEndian )
{
INT i, iLen;
WORD wCode, awUTF16[2];
if( out == NULL )
{
return 0;
}
iLen = UCS4_To_UTF16( dwUCS4, awUTF16 );
if( iLen == 0 )return 0;
for( i = 0; i < iLen; i++ )
{
wCode = awUTF16[i];
if( isBigEndian )
{
fputc( wCode >> 8, out ); // 输出高位
fputc( wCode & 0xFF, out ); // 输出低位
}
else
{
fputc( wCode & 0xFF, out ); // 输出低位
fputc( wCode >> 8, out ); // 输出高位
}
}
return (iLen << 1);
}
// 将UTF16字符串以UTF8编码输出到文件中
UINT CUnicodeConverter::Print_UTF8Str_By_UTF16Str( FILE* out, const WORD* pwszUTF16Str )
{
INT iCount, iLen;
DWORD dwUCS4;
if( (out == NULL) || (pwszUTF16Str == NULL) )
{
return 0;
}
iCount = 0;
while( *pwszUTF16Str )
{ // 将UTF16编码转换成UCS4编码
iLen = UTF16_To_UCS4( pwszUTF16Str, dwUCS4 );
if( iLen == 0 )
{
break;
}
pwszUTF16Str += iLen;
// 向文件中输出UTF8编码
iCount += Print_UTF8_By_UCS4( out, dwUCS4 );
}
return iCount; // 输出的字节数
}
// 将UTF8字符串以UTF16编码输出到文件中
UINT CUnicodeConverter::Print_UTF16Str_By_UTF8Str( FILE* out, const BYTE* pbszUTF8Str, BOOL isBigEndian )
{
INT iCount, iLen;
DWORD dwUCS4;
if( (out == NULL) || (pbszUTF8Str == NULL) )
{
return 0;
}
iCount = 0;
while( *pbszUTF8Str )
{ // 将UTF16编码转换成UCS4编码
iLen = UTF8_To_UCS4( pbszUTF8Str, dwUCS4 );
if( iLen == 0 )
{
break;
}
pbszUTF8Str += iLen;
// 向文件中输出UTF8编码
iCount += Print_UTF16_By_UCS4( out, dwUCS4, isBigEndian );
}
return iCount; // 输出的字节数
}
// 向文件中输出UTF8字节序标记
UINT CUnicodeConverter::Print_UTF8_BOM( FILE* out )
{
if( out == NULL )
{
return 0;
}
fputc( 0xEF, out );
fputc( 0xBB, out );
fputc( 0xBF, out );
return 3;
}
// 向文件中输出UTF16字节序标记
UINT CUnicodeConverter::Print_UTF16_BOM( FILE* out, BOOL isBigEndian )
{
if( out == NULL )
{
return 0;
}
if( isBigEndian )
{
fputc( 0xFE, out );
fputc( 0xFF, out );
}
else
{
fputc( 0xFF, out );
fputc( 0xFE, out );
}
return 2;
}
/* -------------------------------------------------------------
C++流输出操作
------------------------------------------------------------- */
// 向流中输出UTF8编码
UINT CUnicodeConverter::Print_UTF8_By_UCS4( ostream& os, DWORD dwUCS4 )
{
INT iLen;
BYTE abUTF8[8];
if( !os )return 0;
iLen = UCS4_To_UTF8( dwUCS4, abUTF8 );
if( iLen == 0 )return 0;
os.write( reinterpret_cast<CHAR*>(abUTF8), iLen );
return iLen;
}
// 向流中输出UTF16编码
UINT CUnicodeConverter::Print_UTF16_By_UCS4( ostream& os, DWORD dwUCS4, BOOL isBigEndian )
{
INT i, iLen;
WORD wCode, awUTF16[2];
if( !os )return 0;
iLen = UCS4_To_UTF16( dwUCS4, awUTF16 );
if( iLen == 0 )return 0;
for( i = 0; i < iLen; i++ )
{
wCode = awUTF16[i];
if( isBigEndian )
{
os.put( wCode >> 8 ); // 输出高位
os.put( wCode & 0xFF ); // 输出低位
}
else
{
os.put( wCode & 0xFF ); // 输出低位
os.put( wCode >> 8 ); // 输出高位
}
}
return (iLen << 1);
}
// 将UTF16字符串以UTF8编码输出到流中
UINT CUnicodeConverter::Print_UTF8Str_By_UTF16Str( ostream& os, const WORD* pwszUTF16Str )
{
INT iCount, iLen;
DWORD dwUCS4;
if( !os || (pwszUTF16Str == NULL) )return 0;
iCount = 0;
while( *pwszUTF16Str )
{ // 将UTF16编码转换成UCS4编码
iLen = UTF16_To_UCS4( pwszUTF16Str, dwUCS4 );
if( iLen == 0 )
{
break;
}
pwszUTF16Str += iLen;
// 向流中输出UTF8编码
iCount += Print_UTF8_By_UCS4( os, dwUCS4 );
}
return iCount; // 输出的字节数
}
// 将UTF8字符串以UTF16编码输出到流中
UINT CUnicodeConverter::Print_UTF16Str_By_UTF8Str( ostream& os, const BYTE* pbszUTF8Str, BOOL isBigEndian )
{
INT iCount, iLen;
DWORD dwUCS4;
if( !os || (pbszUTF8Str == NULL) )return 0;
iCount = 0;
while( *pbszUTF8Str )
{ // 将UTF16编码转换成UCS4编码
iLen = UTF8_To_UCS4( pbszUTF8Str, dwUCS4 );
if( iLen == 0 )
{
break;
}
pbszUTF8Str += iLen;
// 向流中输出UTF8编码
iCount += Print_UTF16_By_UCS4( os, dwUCS4, isBigEndian );
}
return iCount; // 输出的字节数
}
// 向流中输出UTF8字节序标记
UINT CUnicodeConverter::Print_UTF8_BOM( ostream& os )
{
if( !os )return 0;
os.put( 0xEF );
os.put( 0xBB );
os.put( 0xBF );
return 3;
}
// 向流中输出UTF16字节序标记
UINT CUnicodeConverter::Print_UTF16_BOM( ostream& os, BOOL isBigEndian )
{
if( !os )return 0;
if( isBigEndian )
{
os.put( 0xFE );
os.put( 0xFF );
}
else
{
os.put( 0xFF );
os.put( 0xFE );
}
return 2;
}
/* ------------------------------
END
------------------------------ */