浏览器探究——webkit部分——解析HTML(2)解码和HTMLTokenizer的处理

浏览器探究——webkit部分——解析HTML(2)解码和HTMLTokenizer的处理

接解析HTML起源篇

起源篇提到数据的处理会调用到如下的两个函数处

DocumentParser::appendBytes

DocumentParser::finish

一个是解析过程中的,一个是解析完成的。而解析开始时,就是起源篇讲的Document,RenderView,DocumentParser的创建,注意当前是html文件,所以创建的是HTMLDocument和HTMLDocumentParser。

测试页面:

<html>

<body>

<p>First name: </p>

<input type="text"name="fname" />

Last name: <input type="text"name="lname" />

</body>

</html>

DocumentParser::appendBytes

首先回顾一下调用到该函数的调用栈

#0 WebCore::DecodedDataDocumentParser::appendBytes

#1WebCore::DocumentWriter::addData

#2WebCore::DocumentLoader::commitData

#3android::FrameLoaderClientAndroid::committedLoad

#4WebCore::DocumentLoader::commitLoad

#5WebCore::DocumentLoader::receivedData

#6WebCore::MainResourceLoader::addData

#7WebCore::ResourceLoader::didReceiveData

#8WebCore::MainResourceLoader::didReceiveData

#9WebCore::ResourceLoader::didReceiveData

#10android::WebUrlLoaderClient::didReceiveData

注意DocumentParser本身并没有实现appendBytes方法,这里调用的是其祖先类DecodedDataDocumentParser的appendBytes。

该函数有参数DocumentWriter,即DocumentWriter调用该函数时把自己作为参数传入了。

首先利用DocumentWriter创建一个TextResourceDecoder,使用函数为DocumentWriter::createDecoderIfNeed。根据名字可见,如果需要才创建,那么什么时候是需要呢?先看下创建的TextResourceDecoder是由谁维护的,在DocumentWriter中有成员RefPtr<TextResourceDecoder> m_decoder;在DocumentWriter构造时并没有创建该TextResourceDecoder的实例,只有在执行DocumentWriter::createDecoderIfNeed时,如果m_decoder为空,则创建一个实例,如果非空,则直接返回。所以这里的IfNeed就指DocumentWriter::m_decoder是否为空了。

解码

TextResourceDecoder

当前第一次执行到这里,所以DocumentWriter::m_decoder为空,需要创建一个TextResourceDecoder,创建时会传入MimeType,TextEncoding等信息。创建的TextResourceDecoder会赋值给DocumentWriter::m_decoder。之后又做了些设置Encoding的操作。

再之后把这个新创建的TextResourceDecoder又设置给了Document(通过Frame找到Document)。看下Document的成员,也有一个RefPtr<TextResourceDecoder> m_decoder;这里把新创建的TextResourceDecoder又赋值给了Document::decoder。最后将创建的TextResourceDecoder返回,完成了DocumentWriter::createDecoderIfNeed。
回到DocumentParser::appendBytes。调用TextResourceDecoder::decode。

TextResourceDecoder::decode

当前是HTML页面,所以这里只看下对HTML的处理情况。

这里先调用了TextResourceDecoder::checkForHeadCharset,该函数是个检查HTML头信息中是否有编码的信息,一般HTML的页面中如果指定了编码信息,那么编码信息会放在<head>标签中。该函数就是做这样的检查的。

该函数中有个重要的操作是把收到的字符串转存到TextResourceDecoder:: m_buffer中。

每次新收到的字符串数据都会追加到这个TextResourceDecoder:: m_buffer中,用于TextResourceDecoder的处理。

之后会创建一个HTMLMetaCharsetParser,并赋值给TextResourceDecoder::m_charsetParser通过HTMLMetaCharsetParser::checkForMetaCharset方法来执行对编码的检测,如果检测到,则把获取到的编码TextEncoding类型设置给TextResourceDecoder。

在TextResourceDecoder中有成员TextEncoding m_encoding;和EncodingSource m_source;分别记录了Encodeing具体的类型和来源。

这个过程的调用栈情况:

#0WebCore::TextResourceD

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值