/**
* @file StrCode.h
* @brief 声明并实现字符串编码转换类 CStrCode
*
* 本类提供6个静态函数,实现GBK、Unicode、UTF-8编码之间的任意转换
*
* @version 1.1
* @author gale
* @date 2007-03-14
*
* Copyright (c) 2007, 5nx.com
* All rights reserved.
*/
#pragma once
#ifdef _UNICODE
#define UTF8ToTCHAR CStrCode::UTF8ToUnicode
#define TCHARToUTF8 CStrCode::UnicodeToUTF8
#define UnicodeToTCHAR
#else
#define UTF8ToTCHAR CStrCode::UTF8ToGBK
#define TCHARToUTF8 CStrCode::GBKToUTF8
#define UnicodeToTCHAR CStrCode::UnicodeToGBK
#endif
/**
* @brief 字符串编码转换类
*
* 本类提供6个静态函数,实现GBK、Unicode、UTF-8编码之间的任意转换
*/
class CStrCode
{
public:
/**
* @brief GBK → Unicode
*
* GBK编码字符串转换成Unicode编码字符串
*
* @param lpGBK 要转换的源字符串
* @param lpUnicode 转换后的目的字符串缓冲区
* @return 如果参数lpUnicode=NULL,返回转换需要的目的缓冲区大小(字符单位),\n
* 否则,返回转换后字符串的字符数
*/
static int GBKToUnicode( LPCSTR lpGBK, LPWSTR lpUnicode = NULL )
{
// 如果源字符串无效,退出
if ( ::strlen( lpGBK ) <= 0 )
{
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nUnicodeLen = ::MultiByteToWideChar( CP_ACP, 0, lpGBK, -1, NULL, 0 );
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpUnicode == NULL )
{
return nUnicodeLen;
}
// 转换字符串
nUnicodeLen = ::MultiByteToWideChar( CP_ACP,
0,
lpGBK,
static_cast<int>( ::strlen( lpGBK ) ),
lpUnicode,
nUnicodeLen );
// 字符串结尾添加“0”结束符
*( lpUnicode + nUnicodeLen ) = 0;
// 返回实际转换的目的字符串字符数
return nUnicodeLen;
}
/**
* @brief Unicode → GBK
*
* Unicode编码字符串转换成GBK编码字符串
*
* @param lpUnicode 要转换的源字符串
* @param lpGBK 转换后的目的字符串缓冲区
* @return 如果参数lpGBK=NULL,返回转换需要的目的缓冲区大小(字符单位),\n
* 否则,返回转换后字符串的字符数
*/
static int UnicodeToGBK( LPCWSTR lpUnicode, LPSTR lpGBK = NULL )
{
// 如果源字符串无效,退出
if ( ::wcslen( lpUnicode ) <= 0 )
{
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nGBKLen = WideCharToMultiByte( CP_ACP, 0, lpUnicode, -1, NULL, 0, NULL, NULL );
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpGBK == NULL )
{
return nGBKLen;
}
// 转换字符串
nGBKLen = ::WideCharToMultiByte( CP_ACP,
0,
lpUnicode,
static_cast<int>( ::wcslen( lpUnicode ) ),
lpGBK,
nGBKLen,
NULL,
NULL );
// 字符串结尾添加“0”结束符
*( lpGBK + nGBKLen ) = 0;
// 返回实际转换的目的字符串字符数
return nGBKLen;
}
/**
* @brief UTF-8 → Unicode
*
* UTF-8编码字符串转换成Unicode编码字符串
*
* @param lpUTF8 要转换的源字符串
* @param lpUnicode 转换后的目的字符串缓冲区
* @return 如果参数lpUnicode=NULL,返回转换需要的目的缓冲区大小(字符单位),\n
* 否则,返回转换后字符串的字符数
*/
static int UTF8ToUnicode( LPCSTR lpUTF8, LPWSTR lpUnicode = NULL )
{
// 如果源字符串无效,退出
if ( ::strlen( lpUTF8 ) <= 0 )
{
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nUnicodeLen = ::MultiByteToWideChar( CP_UTF8, 0, lpUTF8, -1, NULL, 0 );
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpUnicode == NULL )
{
return nUnicodeLen;
}
// 转换字符串
nUnicodeLen = ::MultiByteToWideChar( CP_UTF8,
0,
lpUTF8,
static_cast<int>( ::strlen( lpUTF8 ) ),
lpUnicode,
nUnicodeLen );
// 字符串结尾添加“0”结束符
*( lpUnicode + nUnicodeLen ) = 0;
// 返回实际转换的目的字符串字符数
return nUnicodeLen;
}
/**
* @brief Unicode → UTF-8
*
* Unicode编码字符串转换成UTF-8编码字符串
*
* @param lpUnicode 要转换的源字符串
* @param lpUTF8 转换后的目的字符串缓冲区
* @return 如果参数lpUTF8=NULL,返回转换需要的目的缓冲区大小(字符单位),\n
* 否则,返回转换后字符串的字符数
*/
static int UnicodeToUTF8( LPCWSTR lpUnicode, LPSTR lpUTF8 = NULL )
{
// 如果源字符串无效,退出
if ( ::wcslen( lpUnicode ) <= 0 )
{
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nUTF8Len = WideCharToMultiByte( CP_UTF8, 0, lpUnicode, -1, NULL, 0, NULL, NULL );
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpUTF8 == NULL )
{
return nUTF8Len;
}
// 转换字符串
nUTF8Len = ::WideCharToMultiByte( CP_UTF8,
0,
lpUnicode,
static_cast<int>( ::wcslen( lpUnicode ) ),
lpUTF8,
nUTF8Len,
NULL,
NULL );
// 字符串结尾添加“0”结束符
*( lpUTF8 + nUTF8Len ) = 0;
// 返回实际转换的目的字符串字符数
return nUTF8Len;
}
/**
* @brief lpGBK → lpUTF-8
*
* GBK编码字符串转换成UTF-8编码字符串
*
* @param lpGBK 要转换的源字符串
* @param lpUTF8 转换后的目的字符串缓冲区
* @return 如果参数lpUTF8=NULL,返回转换需要的目的缓冲区大小(字符单位),\n
* 否则,返回转换后字符串的字符数
*/
static int GBKToUTF8( LPCSTR lpGBK, LPSTR lpUTF8 = NULL )
{
// 如果源字符串无效,退出
if ( ::strlen( lpGBK ) <= 0 )
{
return 0;
}
// 计算转换成中间编码字符串需要的缓冲区大小
int nUnicodeLen = GBKToUnicode( lpGBK );
// 申请临时缓冲区(中间编码字符串)
WCHAR * pUnicode = new WCHAR[ nUnicodeLen ];
// 转换成中间编码字符串(Unicode)
if ( GBKToUnicode( lpGBK, pUnicode ) == 0 )
{
delete [] pUnicode;
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nUTF8Len = UnicodeToUTF8( pUnicode );
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpUTF8 == NULL )
{
delete [] pUnicode;
return nUTF8Len;
}
// 转换字符串
nUTF8Len = UnicodeToUTF8( pUnicode, lpUTF8 );
// 删除临时缓冲区(中间编码字符串)
delete [] pUnicode;
// 返回实际转换的目的字符串字符数
return nUTF8Len;
}
/**
* @brief lpUTF-8 → lpGBK
*
* UTF-8编码字符串转换成GBK编码字符串
*
* @param lpUTF8 要转换的源字符串
* @param lpGBK 转换后的目的字符串缓冲区
* @return 如果参数lpGBK=NULL,返回转换需要的目的缓冲区大小(字符单位),\n
* 否则,返回转换后字符串的字符数
*/
static int UTF8ToGBK( LPCSTR lpUTF8, LPSTR lpGBK = NULL )
{
// 如果源字符串无效,退出
if ( ::strlen( lpUTF8 ) <= 0 )
{
return 0;
}
// 计算转换成中间编码字符串需要的缓冲区大小
int nUnicodeLen = UTF8ToUnicode( lpUTF8 );
// 申请临时缓冲区(中间编码字符串)
WCHAR * pUnicode = new WCHAR[ nUnicodeLen ];
// 转换成中间编码字符串(Unicode)
if ( UTF8ToUnicode( lpUTF8, pUnicode ) == 0 )
{
delete [] pUnicode;
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nGBKLen = UnicodeToGBK( pUnicode );
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpGBK == NULL )
{
delete [] pUnicode;
return nGBKLen;
}
// 转换字符串
nGBKLen = UnicodeToGBK( pUnicode, lpGBK );
// 删除临时缓冲区(中间编码字符串)
delete [] pUnicode;
// 返回实际转换的目的字符串字符数
return nGBKLen;
}
static int UTF8ToUTF8Text( LPCSTR lpUTF8, LPSTR lpUTF8Text = NULL )
{
int nUTF8Len = ::strlen( lpUTF8 );
// 如果源字符串无效,退出
if ( nUTF8Len <= 0 )
{
return 0;
}
// 计算转换需要的目的字符串缓冲区大小
int nUTF8TextLen = nUTF8Len * 3 + 1;
// 如果第2个参数是缺省值( NULL ),则直接返回需要的目的字符串缓冲区大小
if ( lpUTF8Text == NULL )
{
return nUTF8TextLen;
}
// 转换字符串
for ( int i = 0; i < nUTF8Len ; i ++ )
{
lpUTF8Text[ i * 3 ] = '%';
lpUTF8Text[ i * 3 + 1 ] =
ConvertHexToChar( static_cast<BYTE>( ( lpUTF8[ i ] >> 4 ) & 0x0f ) );
lpUTF8Text[ i * 3 + 2 ] =
ConvertHexToChar( static_cast<BYTE>( lpUTF8[ i ] & 0x0f ) );
}
// 字符串结尾添加“0”结束符
lpUTF8Text[ i * 3 ] = '\0';