linux应用程序_1_文本浏览器_2_encoding_1_encoding_manager
所有支持的编码格式都由encoding_manager统一管理
一、抽象一个编码结构体
二、向下提供接口
1、添加能够支持的字库信息
2、注册编码结构体
三、向上提供接口
所有编码初始化
根据文本编码格式,选择一个编码结构体
抽象结构体的依据:
1、不同编码文件的首部标识符长度、标识符内容是不一样
ascii :没有
utf-8 :0xEF, 0xBB, 0xBF
utf-16le :0xFF, 0xFE,
utf-16be:0xFE, 0xFF,
2、结构体应知道自己是否支持当前打开的文本
3、结构体要有一个链表,列出自己可以使用的字库
4、结构体要有获取字符的能力
5、结构体应该有自己的名字、用以区分同类的其他结构体
6、结构体应该有一个链表,与同类的其他结构体建立联系
因此抽象出结构体:
typedef struct EncodingOpr{
char *pcName;
int iHeadLen;
PT_FontOpr ptFontOprSupportHead;
int (*IsSuppot)(char *pcBufHead);
int (*GetCode)(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pudwCode);
struct EncodingOpr *ptNext;
}T_EncodingOpr, *PT_EncodingOpr;
注册:
依据打开文件的头部标识符判断是否支持该编码,若支持,将其添加到链尾
int RegisterEncoding(PT_EncodingOpr ptEncodingOpr)
{
PT_EncodingOpr ptEncodingOprTmp;
if(!g_ptEncodingOpr)
{
g_ptEncodingOpr = ptEncodingOpr;
g_ptEncodingOpr->ptNext = NULL;
}
else
{
ptEncodingOprTmp = g_ptEncodingOpr;
while(ptEncodingOprTmp->ptNext)
{
ptEncodingOprTmp = ptEncodingOprTmp->ptNext;
}
ptEncodingOprTmp->ptNext = ptEncodingOpr;
ptEncodingOpr->ptNext = NULL;
}
return 0;
}
添加支持字库:
初始化时,将文件编码所支持的字库结构体加入编码结构体的字库链表中
int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)
{
PT_FontOpr ptFontOprNew;
if(!ptEncodingOpr || !ptFontOpr)
{
DBG_PRINT("Error at %s,%d, EncodingOpr(%s),FontOpr(%s)\r\n", __FILE__, __LINE__, ptEncodingOpr->pcName, ptFontOpr->pcName);
return -1;
}
else
{
ptFontOprNew = malloc(sizeof(T_FontOpr));
if (!ptFontOprNew)
{
return -1;
}
else
{
memcpy(ptFontOprNew, ptFontOpr, sizeof(T_FontOpr));
ptFontOprNew->ptNext = ptEncodingOpr->ptFontOprSupportHead;
ptEncodingOpr->ptFontOprSupportHead = ptFontOprNew;
return 0;
}
}
}
删除无法使用的字库:
根据实际情况(可能没有字库文件),将编码结构体中的一些字库链表节点删除
int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)
{
PT_FontOpr ptTmp;
PT_FontOpr ptPre;
if (!ptEncodingOpr || !ptFontOpr)
{
return -1;
}
ptTmp = ptEncodingOpr->ptFontOprSupportHead;
if (strcmp(ptTmp->pcName, ptFontOpr->pcName) == 0)
{
ptEncodingOpr->ptFontOprSupportHead = ptTmp->ptNext;
free(ptTmp);
return 0;
}
ptPre = ptEncodingOpr->ptFontOprSupportHead;
ptTmp = ptPre->ptNext;
while (ptTmp)
{
if (strcmp(ptTmp->pcName, ptFontOpr->pcName) == 0)
{
ptPre->ptNext = ptTmp->ptNext;
DBG_PRINT("Del the font %s \r\n",ptTmp->pcName);
free(ptTmp);
return 0;
}
else
{
ptPre = ptTmp;
ptTmp = ptTmp->ptNext;
}
}
return -1;
}
选中编码:
解析文件头部的标识符,选中编码
PT_EncodingOpr SelectEncodingOpr(unsigned char *pucBufHead)
{
PT_EncodingOpr ptEncodingOprTmp = g_ptEncodingOpr;
while(ptEncodingOprTmp)
{
if(ptEncodingOprTmp->IsSuppot((char *)pucBufHead))
{
DBG_PRINT("select encoding : %s\r\n",ptEncodingOprTmp->pcName);
return ptEncodingOprTmp;
}
ptEncodingOprTmp = ptEncodingOprTmp->ptNext;
}
return NULL;
}
初始化:
调用各编码的初始化函数
int EncodingsInit(void)
{
int iError;
iError = AsciiEncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = Utf8EncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = Utf16leEncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = Utf16beEncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
return 0;
}
完整代码:
encoding_manager.h
#ifndef __ENCODING_MANAGER_H
#define __ENCODING_MANAGER_H
#include <fonts_manager.h>
typedef struct EncodingOpr{
char *pcName;
int iHeadLen;
PT_FontOpr ptFontOprSupportHead;
int (*IsSuppot)(char *pcBufHead);
int (*GetCode)(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pudwCode);
struct EncodingOpr *ptNext;
}T_EncodingOpr, *PT_EncodingOpr;
int AsciiEncodingInit(void);
int Utf8EncodingInit(void);
int Utf16leEncodingInit(void);
int Utf16beEncodingInit(void);
int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr);
int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr);
int RegisterEncoding(PT_EncodingOpr ptEncodingOpr);
PT_EncodingOpr SelectEncodingOpr(unsigned char *pucBufHead);
int EncodingsInit(void);
void ShowSupportEncoding(void);
void ShowEncodingSupportFont(PT_EncodingOpr ptEncodingOpr);
#endif
encoding_manager.c
#include <config.h>
#include <encoding_manager.h>
#include <fonts_manager.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
PT_EncodingOpr g_ptEncodingOpr;
int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)
{
PT_FontOpr ptFontOprNew;
if(!ptEncodingOpr || !ptFontOpr)
{
DBG_PRINT("Error at %s,%d, EncodingOpr(%s),FontOpr(%s)\r\n", __FILE__, __LINE__, ptEncodingOpr->pcName, ptFontOpr->pcName);
return -1;
}
else
{
ptFontOprNew = malloc(sizeof(T_FontOpr));
if (!ptFontOprNew)
{
return -1;
}
else
{
memcpy(ptFontOprNew, ptFontOpr, sizeof(T_FontOpr));
ptFontOprNew->ptNext = ptEncodingOpr->ptFontOprSupportHead;
ptEncodingOpr->ptFontOprSupportHead = ptFontOprNew;
return 0;
}
}
}
int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr)
{
PT_FontOpr ptTmp;
PT_FontOpr ptPre;
if (!ptEncodingOpr || !ptFontOpr)
{
return -1;
}
ptTmp = ptEncodingOpr->ptFontOprSupportHead;
if (strcmp(ptTmp->pcName, ptFontOpr->pcName) == 0)
{
ptEncodingOpr->ptFontOprSupportHead = ptTmp->ptNext;
free(ptTmp);
return 0;
}
ptPre = ptEncodingOpr->ptFontOprSupportHead;
ptTmp = ptPre->ptNext;
while (ptTmp)
{
if (strcmp(ptTmp->pcName, ptFontOpr->pcName) == 0)
{
ptPre->ptNext = ptTmp->ptNext;
DBG_PRINT("Del the font %s \r\n",ptTmp->pcName);
free(ptTmp);
return 0;
}
else
{
ptPre = ptTmp;
ptTmp = ptTmp->ptNext;
}
}
return -1;
}
int RegisterEncoding(PT_EncodingOpr ptEncodingOpr)
{
PT_EncodingOpr ptEncodingOprTmp;
if(!g_ptEncodingOpr)
{
g_ptEncodingOpr = ptEncodingOpr;
g_ptEncodingOpr->ptNext = NULL;
}
else
{
ptEncodingOprTmp = g_ptEncodingOpr;
while(ptEncodingOprTmp->ptNext)
{
ptEncodingOprTmp = ptEncodingOprTmp->ptNext;
}
ptEncodingOprTmp->ptNext = ptEncodingOpr;
ptEncodingOpr->ptNext = NULL;
}
return 0;
}
PT_EncodingOpr SelectEncodingOpr(unsigned char *pucBufHead)
{
PT_EncodingOpr ptEncodingOprTmp = g_ptEncodingOpr;
while(ptEncodingOprTmp)
{
if(ptEncodingOprTmp->IsSuppot((char *)pucBufHead))
{
DBG_PRINT("select encoding : %s\r\n",ptEncodingOprTmp->pcName);
return ptEncodingOprTmp;
}
ptEncodingOprTmp = ptEncodingOprTmp->ptNext;
}
return NULL;
}
int EncodingsInit(void)
{
int iError;
iError = AsciiEncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = Utf8EncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = Utf16leEncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = Utf16beEncodingInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
return 0;
}
void ShowSupportEncoding(void)
{
int iCnt = 0;
PT_EncodingOpr ptEncodingOprTmp = g_ptEncodingOpr;
printf("\r\n");
printf("supported encoding:\r\n");
while(ptEncodingOprTmp)
{
printf("%02d : %s\r\n",++iCnt,ptEncodingOprTmp->pcName);
ptEncodingOprTmp = ptEncodingOprTmp->ptNext;
}
}