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

2016年(20)

2015年(56)

分类: 嵌入式

2015-08-23 16:43:38

encoding_manager.c

15年8月22日15:30:38

#include <config.h>

#include <encoding_manager.h>

#include <string.h>

#include <stdlib.h>


static PT_EncodingOpr g_ptEncodingOprHead;


int RegisterEncodingOpr(PT_EncodingOpr ptEncodingOpr)

{

PT_EncodingOpr ptTmp;


if (!g_ptEncodingOprHead)

{

g_ptEncodingOprHead = ptEncodingOpr;

ptEncodingOpr->ptNext = NULL;

}

else

{

ptTmp = g_ptEncodingOprHead;

while (ptTmp->ptNext)

{

ptTmp = ptTmp->ptNext;

}

ptTmp->ptNext = ptEncodingOpr;

ptEncodingOpr->ptNext = NULL;

}


return 0;

}




void ShowEncodingOpr(void)

{

int i = 0;

PT_EncodingOpr ptTmp = g_ptEncodingOprHead;


while (ptTmp)

{

printf("%02d %s\n", i++, ptTmp->name);

ptTmp = ptTmp->ptNext;

}

}


PT_EncodingOpr SelectEncodingOprForFile(unsigned char *pucFileBufHead)

{

PT_EncodingOpr ptTmp = g_ptEncodingOprHead;


while (ptTmp)

{

if (ptTmp->isSupport(pucFileBufHead))

return ptTmp;

else

ptTmp = ptTmp->ptNext;

}

return NULL;

}



int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)

{

PT_FontOpr ptFontOprCpy;

if (!ptEncodingOpr || !ptFontOpr)

{

return -1;

}

else

{

ptFontOprCpy = malloc(sizeof(T_FontOpr));

if (!ptFontOprCpy)

{

return -1;

}

else

{

memcpy(ptFontOprCpy, ptFontOpr, sizeof(T_FontOpr));

ptFontOprCpy->ptNext = ptEncodingOpr->ptFontOprSupportedHead;

ptEncodingOpr->ptFontOprSupportedHead = ptFontOprCpy;

return 0;

}

}

}


int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)

{

PT_FontOpr ptTmp;

PT_FontOpr ptPre;

if (!ptEncodingOpr || !ptFontOpr)

{

return -1;

}

else

{

ptTmp = ptEncodingOpr->ptFontOprSupportedHead;

if (strcmp(ptTmp->name, ptFontOpr->name) == 0)

{

/* 删除头节点 */

ptEncodingOpr->ptFontOprSupportedHead = ptTmp->ptNext;

free(ptTmp);

return 0;

}


ptPre = ptEncodingOpr->ptFontOprSupportedHead;

ptTmp = ptPre->ptNext;

while (ptTmp)

{

if (strcmp(ptTmp->name, ptFontOpr->name) == 0)

{

/* 从链表中取出,释放 */

ptPre->ptNext = ptTmp->ptNext;

free(ptTmp);

return 0;

}

else

{

ptPre = ptTmp;

ptTmp = ptTmp->ptNext;

}

}


return -1;

}

}


int EncodingInit(void)

{

int iError;


iError = AsciiEncodingInit();

if (iError)

{

DBG_PRINTF("AsciiEncodingInit error!\n");

return -1;

}


iError = Utf16leEncodingInit();

if (iError)

{

DBG_PRINTF("Utf16leEncodingInit error!\n");

return -1;

}

iError = Utf16beEncodingInit();

if (iError)

{

DBG_PRINTF("Utf16beEncodingInit error!\n");

return -1;

}

iError = Utf8EncodingInit();

if (iError)

{

DBG_PRINTF("Utf8EncodingInit error!\n");

return -1;

}


return 0;

}

encoding_manager.h

#ifndef _ENCODING_MANAGER_H

#define _ENCODING_MANAGER_H


#include <fonts_manager.h>

#include <disp_manager.h>


typedef struct EncodingOpr {

char *name;

int iHeadLen;

PT_FontOpr ptFontOprSupportedHead;

int (*isSupport)(unsigned char *pucBufHead);

int (*GetCodeFrmBuf)(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode);

struct EncodingOpr *ptNext;

}T_EncodingOpr, *PT_EncodingOpr;


int RegisterEncodingOpr(PT_EncodingOpr ptEncodingOpr);

void ShowEncodingOpr(void);

PT_DispOpr GetDispOpr(char *pcName);

PT_EncodingOpr SelectEncodingOprForFile(unsigned char *pucFileBufHead);

int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr);

int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr);

int EncodingInit(void);

int AsciiEncodingInit(void);

int Utf16beEncodingInit(void);

int Utf16leEncodingInit(void);

int Utf8EncodingInit(void);


#endif /* _ENCODING_MANAGER_H */


先讲解encoding_manager.h

主要是这个 EncodingOpr结构体:

typedef struct EncodingOpr {

char *name; /* 名字,根据名字找到对应的结构体 */

int iHeadLen; /* 前导1的长度,后面具体分析。 */

PT_FontOpr ptFontOprSupportedHead;

int (*isSupport)(unsigned char *pucBufHead);

int (*GetCodeFrmBuf)(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode);

struct EncodingOpr *ptNext;

}T_EncodingOpr, *PT_EncodingOpr;

1)这个结构体挺复杂的,首先,显示一个字符的步骤是:1.得到这个字符的编码2.根据这个编码选择用哪个字体来解析3.显示。 所以,对应每一种编码格式,都有一个它自己的EncodingOpr结构体,每个编码格式里面都有它相对应可以解析这个编码的字体,而这个字体可能不止是一个,我们把这些字体放在EncodingOpr结构体里面的 ptFontOprSupportedHead链表中。所以这是 EncodingOpr结构体中 ptFontOprSupportedHead的由来。

2isSupport函数,对于一个字符,是否可以用utf-8(或其他编码)来解析呢?我们在每种编码方式里面添加了这个函数,这样,通过调用这个函数,就可以知道是否可以用这个编码方式来解码。(3GetCodeFrmBuf函数,从一个文件(已经映射到内存中了)中取出编码值,对于utf-8的编码,它的编码值是以0xEF0xBB0xBF来开头的,对于utf-16le的编码,它的编码值是以0xFF, 0xFE来开头的,我们想要获取真正的字符编码值,需要将这个前导位去掉,来取出真正的编码,这个函数就是这个作用。


下面分析encoding_manager.c文件:

1)首先,还是先定义一个g_ptEncodingOprHead链表头,

static PT_EncodingOpr g_ptEncodingOprHead;


int RegisterEncodingOpr(PT_EncodingOpr ptEncodingOpr)

{

PT_EncodingOpr ptTmp;


if (!g_ptEncodingOprHead)

{

g_ptEncodingOprHead = ptEncodingOpr;

ptEncodingOpr->ptNext = NULL;

}

else

{

ptTmp = g_ptEncodingOprHead;

while (ptTmp->ptNext)

{

ptTmp = ptTmp->ptNext;

}

ptTmp->ptNext = ptEncodingOpr;

ptEncodingOpr->ptNext = NULL;

}


return 0;

}

/* ptEncodingOpr这个结构体添加到 g_ptEncodingOprHead链表中,到最后,这个链表中含有

* utf-8utf-16beutf-16leascii这几种编码方式的结构体。

*/

2ShowEncodingOpr()函数,取出链表中每一项的名字,打印出来。

3)为文件选择编码方式函数:

PT_EncodingOpr SelectEncodingOprForFile(unsigned char *pucFileBufHead)

{

PT_EncodingOpr ptTmp = g_ptEncodingOprHead;


while (ptTmp)

{

if (ptTmp->isSupport(pucFileBufHead))

return ptTmp;

/*其中isSupport函数返回1代表支持*/

else

ptTmp = ptTmp->ptNext;

}

return NULL;

}

/* 这个函数从 g_ptEncodingOprHead链表中遍历每一项,选择支持文件的编码方式,从main.c中可以

* 看出来,程序首先将utf-8, utf-16be, utf-16le, asci等几种编码方式进行注册,即添加进

* g_ptEncodingOprHead这个链表中,当打开一个文件的时候,调用这个

* SelectEncodingOprForFile函数来选择其中一个支持的编码方式。

*/

4AddFontOprForEncoding函数:(之前已经说过,每个编码方式都可以用一种或多种字体来解析,这些字体就放在编码对应的ptEncodingOpr结构体里面的ptFontOprSupportedHead链表中)

int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)

{

PT_FontOpr ptFontOprCpy;

if (!ptEncodingOpr || !ptFontOpr)

{

return -1;

}

/* 如果这两项中有一项为空,则返回-1. */

else

{

ptFontOprCpy = malloc(sizeof(T_FontOpr));

if (!ptFontOprCpy)

{

return -1;

}

/* 分配内存,如果没成功,返回-1*/

else

{

memcpy(ptFontOprCpy, ptFontOpr, sizeof(T_FontOpr));

ptFontOprCpy->ptNext = ptEncodingOpr->ptFontOprSupportedHead;

ptEncodingOpr->ptFontOprSupportedHead = ptFontOprCpy;

/* 这三句代码不是很理解,1)首先将 ptFontOpr拷贝到 ptFontOprCpy分配的内存中,这时候

* ptFontOprCpy里面就是ptFontOpr结构体2)将ptFontOprCpyptNext指向原来的链表头3)再

* 将整个ptFontOprCpy结构体赋值给链表头,形成一个新的链表头,也就是说ptFontOprCpy是新的链

* 表头,它的ptNext指向原来的链表头,相当与在链表头前面加了一项。 */

return 0;

}

}

}

5DelFontOprFrmEncoding函数:

int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)

{

PT_FontOpr ptTmp;

PT_FontOpr ptPre;

if (!ptEncodingOpr || !ptFontOpr) /* 如果这两项任意一项为空就返回-1 */

{

return -1;

}

else

{

ptTmp = ptEncodingOpr->ptFontOprSupportedHead;

if (strcmp(ptTmp->name, ptFontOpr->name) == 0)

{

/* 删除头节点 */

ptEncodingOpr->ptFontOprSupportedHead = ptTmp->ptNext;

free(ptTmp);

return 0;

}


ptPre = ptEncodingOpr->ptFontOprSupportedHead;

ptTmp = ptPre->ptNext;

while (ptTmp)

{

if (strcmp(ptTmp->name, ptFontOpr->name) == 0)

{

/* 从链表中取出,释放 */

ptPre->ptNext = ptTmp->ptNext;

free(ptTmp);

return 0;

}

else

{

ptPre = ptTmp;

ptTmp = ptTmp->ptNext;

}

}


return -1;

}

}

这个函数是上一个函数的反函数,主要是理解里面的链表操作。

6EncodingInit函数:在里面注册了ascii, utf16le, utf16be, utf8这几种编码方式。


阅读(1498) | 评论(0) | 转发(0) |
0

上一篇:电子书-Draw.c

下一篇:电子书-fb.c

给主人留下些什么吧!~~