📄 x2gb.c
字号:
/* convertCode.cpp : Defines the entry point for the console application. */
/***************************************************************************
* Copyright (c) 2008, .......
* All rights reserved.
*
* 文件名称:convertCode.c
* 文件标识:
* 摘 要:汉字内码转换处理函数
* @main()
* @Utf16TOGb18030()
* @Utf8TOGb18030()
* @Big5TOGb18030()
* @Utf16TOBig5()
* @Utf8TOBig5()
* @Gb18030TOBig5()
* @SearchCodeTable()
* 当前版本:1.0
* 作 者:CZ
* 完成日期:
*
* 修改与优化处理:
**************************************************************************/
typedef unsigned int U32;
typedef unsigned short int U16;
typedef unsigned char U8;
typedef signed int S32;
typedef short signed int S16;
typedef signed char S8;
typedef struct utf16_gb
{
U16 unicode;
U16 gb;
} UTF16_GB_4B;
/*********************************************************
文件内部使用的宏
均为编码转换开关,
命名规则: _源码类型_目标嘛类型,其中GB表示GB18030码,如_GB_BIG5表示将GB18030编码转换为BIG5码
取值规则: 需要相应编码转换时将对应的宏定义为1,反之为0
*****************************************************/
#define _UTF16_GB 1
#define _UTF8_GB 1
#define _BIG5_GB 1
#define _A02 1
#define _BIG_ENDIAN 0
#define _LITTLE_ENDIAN 1
#define CONVERT_OK 0
#define CONVERT_ERROR 1
#define INPUTCODE_ERROR 2
#define INPUTLEN_ERROR 3
#if (_UTF16_GB || _UTF8_GB)
/* ".\tools1\UTF16_GB_2B_H.h" 里定义: U16 TB_UTF16_GB[][256] */
/* ".\tools1\UTF16_GB_4B_H.h"里定义:UTF16_GB_4B TB_UTF16_GB_4B[] */
/* 以下地址值需查字库说明得到 */
#if (_LITTLE_ENDIAN)
U16 * TB_UTF16_GB = (U16 *)0x280000;
UTF16_GB_4B * TB_UTF16_GB_4B = (UTF16_GB_4B *)0x2dfc00;
#elif (_BIG_ENDIAN)
U16 * TB_UTF16_GB = (U16 *)0x2A0000;
UTF16_GB_4B * TB_UTF16_GB_4B = (UTF16_GB_4B *)0x2e6210;
#endif
#endif
#if (_BIG5_GB)
/* U16 *TB_BIG5_GB[256]= (U16 **)0x2c0000; 编译不通过,只好将TB_BIG5_GB改为一维数组,通过高维*256达到二维定位效果 */
U16 *TB_BIG5_GB = (U16 *)0x2c0000; /* 这个值需查字库说明得到 */
#endif
U16 SearchCodeTable(U16 unicodeKey);
S8 Utf16TOGb18030(U16* pu16InputCode, U8* pu8OutputCode, U8* pu8OutputLen);
S8 Utf8TOGb18030(U8* pu8InputCode, U8 u8InputLen, U8* pu8OutputCode, U8* pu8OutputLen);
S8 Big5TOGb18030(U8* pu8InputCode, U8 u8InputLen, U8* pu8OutputCode, U8* pu8OutputLen);
#if (_UTF16_GB )
/***************************************************************************
* 函数名称: Utf16TOGb18030
* 作者 : CZ
* 函数功能 : 将Utf16编码的字符转换为GB18030编码
* 接口描述:
*
* 输入参数:
* pu16InputCode - 输入的Utf16编码字符的存储地址
* pu8OutputCode - 供存放输出的GB18030编码字符的首地址
* pu8OutputLen - 供存放输出的GB18030编码字符字节数的地址
* 返回参数:CONVERT_OK - 转换成功 CONVERT_ERROR - 转换失败
* 转换成功时,输出的字符存放在pu8OutputCode,长度存放在pu8OutputLen
*
* 影响的参数:无
*
*
* 补充说明:
* 结果转换通过查表(即TB_UTF16_GB)得到,但节约空间起见,此表只输出前2字节结果
* 对于有4字节的汉字,再通过SearchCodeTable查表TB_UTF16_GB_4B得到后面2字节.
* TB_UTF16_GB分成2种格式,即ROM格式和RAM格式,均为
*****************************************************************************/
S8 Utf16TOGb18030(U16* pu16InputCode, U8* pu8OutputCode, U8* pu8OutputLen)
{
U16 u16InData,u16SeekResult,u16OutData;
U8 u8DataH,u8DataL;
/* 取得输入的UTF16数据,并分成高低位 */
u16InData = *(pu16InputCode);
u8DataH = u16InData >> 8;
u8DataL = u16InData & 0xff;
/* 读出转换表结果 */
/* u16OutData = TB_UTF16_GB[u8DataH][u8DataL]; 将TB_BIG5_GB改为一维数组,通过高维*256达到二维定位效果 */
u16OutData = TB_UTF16_GB[u8DataH*256 + u8DataL];
/* 单字节以及无对应结果的情况判断 */
if (u16OutData <= 0xff)
{
if ((u16OutData == 0)&&(u16InData != 0))
{ /* 无对应结果 */
* pu8OutputLen = 0;
return CONVERT_ERROR;
}
else
{ /* 单字节结果 */
* pu8OutputLen = 1;
pu8OutputCode[0] = (U8)u16OutData;
return CONVERT_OK;
}
}
/* 4字节的情况判断 ,在CJK统一汉字扩充A 3400-4DB5 */
/* 但是,有80个字符,对应GB码位是0xFE50-FEA0。Unicode将其中52字收录到“CJK统一汉字扩充A”
所以,这80个字符需排除出 4字节的情况判断
*/
if((u16InData >= 0x3400 )&&(u16InData <= 0x4db5)&&((u16OutData < 0xFE50 )||(u16OutData > 0xFEA0 )) )
{
u16SeekResult = SearchCodeTable(u16InData);
if (u16SeekResult > 0)
{
* pu8OutputLen = 4;
pu8OutputCode[0] = u16OutData >> 8;
pu8OutputCode[1] = u16OutData & 0xff;
pu8OutputCode[2] = u16SeekResult >> 8;
pu8OutputCode[3] = u16SeekResult & 0xff;
return CONVERT_OK;
}
else
{/* 无对应结果 */
* pu8OutputLen = 0;
return CONVERT_ERROR;
}
}
/* 余下的为2字节的情况 */
* pu8OutputLen = 2;
pu8OutputCode[0] = u16OutData >> 8;
pu8OutputCode[1] = u16OutData & 0xff;
return CONVERT_OK;
}
#endif
#if (_UTF16_GB || _UTF8_GB )
/***************************************************************************
* 函数名称: SearchCodeTable
* 作者 : CZ
* 函数功能 : 查表返回UTF16字符中对应4字节GB18030部分的后两字节
* 接口描述:
*
* 输入参数:
* unicodeKey - 输入的Utf16编码字符
*
* 返回参数:
* 查表成功时 返回的两字节查询结果以BigEndian格式合成一个非零的U16数
* 即所查询的GB18030编码第3字节对应返回值的高8位,第4字节对应低8位
* 查表失败时,返回值为0
*
* 影响的参数:无
*
*
* 补充说明: 使用两分法查找
*****************************************************************************/
U16 SearchCodeTable(U16 unicodeKey)
{
int first = 0;
int end = 6529; /* = sizeof(TB_UTF16_GB_4B)/sizeof(UTF16_GB_4B) - 1; */
int mid = 0;
while (first <= end)
{
mid = (first + end) / 2;
if (TB_UTF16_GB_4B[mid].unicode == unicodeKey)
{
return TB_UTF16_GB_4B[mid].gb;
}
else if (TB_UTF16_GB_4B[mid].unicode > unicodeKey)
{
end = mid - 1;
}
else
{
first = mid + 1;
}
}
return 0;
}
#endif
#if (_UTF8_GB)
/***************************************************************************
* 函数名称: Utf8TOGb18030
* 作者 : CZ
* 函数功能 : 将Utf8编码的字符转换为GB18030编码
* 接口描述:
*
* 输入参数:
* pu8InputCode - 输入的Utf8编码字符的存储地址
* u8InputLen - 输入的Utf8编码字符的长度
* pu8OutputCode - 供存放输出的GB18030编码字符的首地址
* pu8OutputLen - 供存放输出的GB18030编码字符字节数的地址
* 返回参数:CONVERT_OK - 转换成功 CONVERT_ERROR - 转换失败
* 转换成功时,输出的字符存放在pu8OutputCode,长度存放在pu8OutputLen
*
* 影响的参数:无
*
*
* 补充说明:
* 算法是先将Utf8编码字符转换为Utf16编码,然后类似Utf16TOGb18030()
*****************************************************************************/
S8 Utf8TOGb18030(U8* pu8InputCode, U8 u8InputLen, U8* pu8OutputCode, U8* pu8OutputLen)
{
U16 u16InData,u16SeekResult,u16OutData;
U8 u8DataH,u8DataL;
/* 将Utf8编码字符转换为Utf16 */
switch(u8InputLen)
{
case 1: /* */
u8DataH = 0;
u8DataL = pu8InputCode[0] ;
u16InData = (U16)u8DataL;
if(u8DataL > 0x7f)
{
* pu8OutputLen = 0;
return INPUTCODE_ERROR;
}
else
{
* pu8OutputLen = 1;
pu8OutputCode[0] = u8DataL;
return CONVERT_OK;
}
break;
case 2:
u8DataH = (pu8InputCode[0] & 0x1f) >> 2;
u8DataL = ((pu8InputCode[0] & 0x3) << 6) + (pu8InputCode[1] & 0x3f);
u16InData = (u8DataH << 8) + u8DataL;
break;
case 3:
u8DataH = ((pu8InputCode[0] & 0x0F) << 4) | ((pu8InputCode[1] >> 2) & 0x0F);
u8DataL = ((pu8InputCode[1] & 0x03) << 6) + (pu8InputCode[2] & 0x3F);
u16InData = (u8DataH << 8) + u8DataL;
break;
default:
* pu8OutputLen = 0;
return INPUTLEN_ERROR;
}
/* 读出转换表结果 */
/* u16OutData = TB_UTF16_GB[u8DataH][u8DataL]; 将TB_BIG5_GB改为一维数组,通过高维*256达到二维定位效果 */
u16OutData = TB_UTF16_GB[u8DataH*256 + u8DataL];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -