Chinaunix首页 | 论坛 | 博客
  • 博客访问: 299478
  • 博文数量: 76
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 715
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-20 20:38
文章分类
文章存档

2016年(20)

2015年(56)

分类: 嵌入式

2015-08-23 16:48:22

Utf-8.c

15年8月22日15:47:31

这段代码比较短,就直接在代码里面添加注释了~~~

#include <config.h>

#include <encoding_manager.h>

#include <string.h>


static int isUtf8Coding(unsigned char *pucBufHead);

static int Utf8GetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode);


static T_EncodingOpr g_tUtf8EncodingOpr = {

.name = "utf-8",

.iHeadLen = 3,

.isSupport = isUtf8Coding,

.GetCodeFrmBuf = Utf8GetCodeFrmBuf,

};


static int isUtf8Coding(unsigned char *pucBufHead)

{

const char aStrUtf8[] = {0xEF, 0xBB, 0xBF, 0};

if (strncmp((const char*)pucBufHead, aStrUtf8, 3) == 0)

{

/* UTF-8 */

return 1;

}

else

{

return 0;

}

}

/* 直接将文件内存的前几位与0xEF, 0xBB, 0xBF作比较,相同的话就是用utf-8编码方式。*/

/* 函数成功返回1,失败返回0 */


/* 获得前导为1的位的个数

* 比如二进制数 11001111 的前导12

* 11100001 的前导13

*/

static int GetPreOneBits(unsigned char ucVal)

{

int i;

int j = 0;

for (i = 7; i >= 0; i--)

{

if (!(ucVal & (1<<i)))

break;

else

j++;

}

return j; /* 函数的返回值就是有j位前导1 */

}


static int Utf8GetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode)

{

#if 0

对于UTF-8编码中的任意字节B,如果B的第一位为0,则BASCII码,并且B独立的表示一个字符;

如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;

如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;

如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;

如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示;


因此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符;

根据前二位,可判断该字节是否为一个字符编码的第一个字节;

根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;

根据前五位(如果前四位为1),可判断编码是否有错误或数据传输过程中是否有错误。

#endif


int i;

int iNum;

unsigned char ucVal;

unsigned int dwSum = 0;


if (pucBufStart >= pucBufEnd)

{

/* 文件结束 */

return 0;

}

/* pucBufStartpucBufEnd都是在main函数刚打开文件的时候计算好的参数 */


ucVal = pucBufStart[0];

iNum = GetPreOneBits(pucBufStart[0]);


if ((pucBufStart + iNum) > pucBufEnd)

{

/* 文件结束 */

return 0;

}


if (iNum == 0)

{

/* ASCII */

*pdwCode = pucBufStart[0];

return 1;

}

else

{

ucVal = ucVal << iNum;

ucVal = ucVal >> iNum;

dwSum += ucVal;

for (i = 1; i < iNum; i++)

{

ucVal = pucBufStart[i] & 0x3f;

dwSum = dwSum << 6;

dwSum += ucVal;

}

*pdwCode = dwSum;

return iNum;

}

}


int Utf8EncodingInit(void)

{

AddFontOprForEncoding(&g_tUtf8EncodingOpr, GetFontOpr("freetype"));

AddFontOprForEncoding(&g_tUtf8EncodingOpr, GetFontOpr("ascii"));

return RegisterEncodingOpr(&g_tUtf8EncodingOpr);

}

/* 最后注意这个 Utf8EncodingInit函数,它不只是把 g_tUtf8EncodingOpr这个结构体注册到链表

* 中,它先将 freetypeascii这两个字体添加到g_tUtf8EncodingOpr结构体的

* ptFontOprSupportedHead链表中,然后再注册,说明对于utf-8编码方式的文件,可以用这两种字

* 体来解析。

*/


阅读(1670) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~