免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1453 | 回复: 0
打印 上一主题 下一主题

FreeBSD的Libc中GB18030的代码初探 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-02-09 11:07 |只看该作者 |倒序浏览

在“/usr/src/lib/libc/locale/gb18030.c”中实现了以下几个函数:

static size_t _GB18030_mbrtowc(wchar_t *, const char *,size_t, mbstate_t *);
static int _GB18030_mbsinit(const mbstate_t *);

static size_t _GB18030_wcrtomb(char *, wchar_t,mbstate_t *);



定义了一个结构体:

typedef struct {
     int    count;
     u_char bytes[4];
} _GB18030State;



在以前的日志当中提到过GB18030.c文件中的“_GB18030_init(_RuneLocale *rl)”函数,其中主要的功用就是把系统进行“宽字节多字节”的函数指针指向上面的那三个函数,用以根据locale加载对应的处理函数


1、_GB18030_mbsinit() 函数:

主要代码:

_GB18030_mbsinit(const mbstate_t *ps)
{
    return (ps == NULL || ((const _GB18030State *)ps)->count == 0);
}
很明显,这个函数所作的初始化就是设置_GB18030State的count成员为零,先可以把count理解成一个计数器,用来记录转换的字数!



2、_GB18030_mbrtowc() 函数:

主要代码:

_GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s,size_t n, mbstate_t * __restrict ps)

/* pws:指向宽字符的指针,s:指向多字节字符的指针*/
{
     _GB18030State *gs;
     wchar_t wch;
     int ch, len, ocount;
     size_t ncopy;
     
     gs = (_GB18030State *)ps;
     if (gs->count count > sizeof(gs->bytes)) {
         errno = EINVAL;
         return ((size_t)-1);
     }

     if (s == NULL) {
         s = "";
         n = 1;
         pwc = NULL;
     }

     /*确定多字节字符的宽度*/
     ncopy = MIN(MIN(n, MB_CUR_MAX), sizeof(gs->bytes) - gs->count);
     memcpy(gs->bytes + gs->count, s, ncopy);
     ocount = gs->count;
     gs->count += ncopy;
     s = (char *)gs->bytes;
     n = gs->count;

     /* Incomplete multibyte sequence */
     if (n == 0)
        return ((size_t)-2);


/* Single byte:  [00-7f]
  * Two byte:  [81-fe][40-7e,80-fe]
  * Four byte:  [81-fe][30-39][81-fe][30-39]
  */
     ch = (unsigned char)*s++;
     /* 单字节 */
     if (ch = 0x81 && ch = 0x40 && ch = 0x80 && ch



         else if (ch >= 0x30 && ch  0xfe)
                goto ilseq;
           wch = (wch  0x39)
               goto ilseq;
           wch = (wch


     else
           goto ilseq;
} else
     goto ilseq;


/* 最后的处理 */
if (pwc != NULL)
  *pwc = wch;
gs->count = 0;
return (wch == L'\0' ? 0 : len - ocount);

/* 错误处理 */

ilseq:
errno = EILSEQ;
return ((size_t)-1);



}  函数结束




由上面的代码可以看出,对于GB18030编码的多字节到宽字节的转换,如果符合编码要求的话,就是把四个字节的数据,依次存到一个whar_t的字符当中:

mbchar:    byte1    byte2     byte3    byte4
wchar:     byte1|byte2|byte3|byte4





本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12258/showart_72789.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP