⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x2gb.c

📁 对于通用的嵌入式系统字处理单元,本模块化程序可以快速实现常用汉字编码(GB2312,GB18030,BIG5码,Unicode码)的相互转换,无需库函数.从而实现使用单汉字字库显现多内码.具体参见re
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -