libjingle代码分析(XML解析)

来源:互联网 发布:电气工程绘图软件 编辑:程序博客网 时间:2024/05/19 18:16

ok,我们已经搞清XMPP节是怎么收到的了,也知道收到后XmppEngineImpl:HandleInput会被调用,然后就看到今天的重点:XML解析

HandleInput会调用XmppStanzaParser.Parse() 解析XML,后者调用XmlParser.Parse(),这个函数即调用了expat库函数,根据expat的使用方法,接下来的事都是回调函数干的,可是他们在哪?

我们回去看看这个XmppStanzeParser是个啥东西呢?注意它里面定义了这样一个类

这是适配器模式,将XmppStanzeParser接口转换为XmlParseHandler类型的。显然这些都是回调函数,可是流程是什么样的?我们得看看这个handler的定义。

这家伙是个纯虚基类,然后发现XmlParser就定义在它下面(这是个好习惯,一个接口和使用它的类定义在一起),而XmlParse里面有个成员变量pxph_是XmlParseHandler 类型的。然后再看看这里

看看最下面这4个函数,注释写的“expat callbacks”,表明它们是回调函数的发源地。我们随便挑个函数,就ExpatStartElement去看看,

看最下面的pxph_->StartElement!

所以XmlParse是真正做XML解析工作的,而XmppStanzaParser通过ParserHandler适配成XmlParserHandler接口来接收XmlParser的回调。可是被回调后XmppStanzeParser会怎么办呢?

看看它的4个回调函数,发觉有两个成员变量一直被使用:XmppStanzaParseHandler * psph_和XmlBuilder builder_

XmppStanzaParseHandler又是个纯虚基类,它唯一的派生类定义在XmppEngineImpl中,定义如下

啊哈,似曾相识的感觉,这又是个适配器!将XmppEngineImlp适配成XmppStanzaParseHandler以接收XmppStanzaParser的回调,回调后XmppEngineImpl的IncomingStart, IncomingStanza, IncomingEnd中的某个将被调用,随即开始消息处理

而第二个变量XmlBuilder看看它的函数名就知道,这是用来生成XML回复的,可是回复是怎么发出的?我们找个回复函数,XmppEngineImpl::SendStanza看着比较典型,就它了:

如果还在登陆调用OutgoingStanza,否则是InternalSendStanza,我们看看一般情况,即调用InternalSendStanza,这函数只是调用XmlPrinter把XML输出到output_的流里,没有任何发送啊。回来看看SendStanza函数,它有个Enterexit看着很奇怪,只感觉类似资源自动释放,我们去看看,果然,它的析构函数里有大量代码,它检查是否需要发送数据,如果需要则调用WriteOutput发送。此外还有是否需要关闭连接==,可能是多个函数需要实现这样的功能,所以被封装起来,做成这种形式

 

0 0