Webcore中文本资源编解码

Webcore中文本资源编解码

 

dlmu2001

 

本文描述的文本资源编解码,针对的是字符串编解码,如 UTF-8,GB2312 ,而非传输编解码(如 gzip )。

    关于字符串编码的理论知识,如果你还不了解,可以参考 http://baike.baidu.com/view/1204863.htm

    我们以一个最简单的网页为例,假设服务器上有一个纯链接的页面,没有任何派生资源( image css sound subframe javascript 等)。服务器传送给我们的页面,他们字符串编码是各种各样的,常见的有 utf8 gb2312 。如果我们用 utf8 的解码方式去解 gb2312 的网页,那么网页显示出来的就是乱码。所以, webcore 里面,需要首先找出服务器提供的网页的字符串编码格式,然后调用对应的解码接口进行解码,输出 webcore 的其它模块接受的 unicode 方式的文本( String 类)。

    那如何来确定网页的字符串编码呢,一般有如下几种方式

1 )父亲节点继承过来的 charset 属性,比如 Iframe 里面的 charset ,如果不指定,则一般继承自原生页面(当然,前提是 subframe 和原生页面的 domain 是一样的)

2 HTTP 响应头部中包含了 charset 字段

3 )如果有外部的 css ,也可能由外部 css 来指定 charset

4 HTML head 元素里面的 meta 标签指定了字符串编码,如
<head><meta http-equiv="Content-Type" content="text/html;charset=gb2312">

5 )如果是 XML 页面, XML 头部中指定了 charset ,如
      <?xml version="1.0" encoding="UTF-8"?>

对一个浏览器来说,可能还会支持用户直接指定字符串编码方式,自动识别。

 

   WebCore 中同字符串解码处理相关的文件主要是   TextResourceDecoder.h/TextResourceDecoder.cpp ,TextCodec.h/TextCodec.cpp,  以及不同平台的字符串解码的 porting (如 TextCodecICU.cpp,TextCodecQt   .cpp,TextCodecUTF16.cpp 等),这里以 TextCodecICU porting 为例来理解。

  

   WebCore 中通过 DocumentWriter 类维护了一个 TextResourceDecoder 类的指针 m_decoder ,以此来实现对文本资源的解码功能的调用和控制。  

   当网络有数据到来的时候,会调用 DocumentWriter.cpp createDecoderIfNeeded 函数,这里可以看到一个 TextResourceDecoder 的创建,首先考虑的是设置中是否允许自动识别,其后是 HTTP  响应的 header 中是否有 charset 头部( m_decoding ),如果此处调用了 TextResourceDecoder 类的 setEncoding 方法设置了编码方式,则之后就不需要再去检查 HTML 中的 meta 标签等。

   在创建了 decoder 以后,就可以对数据进行解码了, DecodedDataDocumentParser 类的 appendBytes 函数调用了 TextResourceDecoder decode 方法,对到来的数据进行解码,由于数据是分段到了,所以分段解码。如果数据来齐了,或者中断了,则调用 TextResourceDecoder flush 函数来结束解码流程。

 

TextResourceDecoder 类主要实现两个功能,一个是 charset 的获取,包括 meta charset 的获取, xml charset 的获取, charset 的自动识别( KanjiCode 类)。另外一个是解码组件的调用和维护。

解码组件的维护是通过成员变量 m_codec 来完成的。在开始 decode 的时候,调用 newTextCodec 接口,根据 charset 类型,来创建一个解码组件,然后调用解码组件的 decode 方法完成解码(该方法通过 TextCodec 类进行了封装,通过 TextCodecICU 等类进行了实现)。解码完成以后,则将 m_codec 释放( clear )。需要注意的是,在 TextResourceDecoder 类的 flush 接口中,需要先进行 decode ,才进行 clear ,以免丢失数据。

 

最后说一下 TextEncodingRegistry.cpp 这个文件,从名字也可以看出来,它用来负责解码控件的注册和管理,相当于一个容器,来匹配编码方式和对应的解码组件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值