`
fortaotao
  • 浏览: 46565 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

XMLPULL源码解读记录

    博客分类:
  • XMPP
阅读更多

XMPP协议的JAVA实现,采用XMLPULL协议是比较好的实现策略,下了源码,记录下,不定时更新。

 

一、核心处理流程:

1、pc策略(pc是MXParser类中定义的一个字符数组char[],个人理解翻译为Processed Character处理过的字符)

MXParser实现中通过Reader读到的字符会全部原封不动存储在buf这个字符数组中。在某次next()逻辑中,比如某tag中的文本数据解析过程中,存在CDATA数据或Reference数据时,需要将解析后的字符存储到pc这个字符数组中,如果这种数据在本次next()解析过程中出现多次,即在处理新的CDATA数据或Reference数据时,发现hadCharData为true,需要进行joinPC合并,并将needMerging置为false。pc在每次next()的起始处是被从头覆写的,pcStart和pcEnd会归0.

 

2、nextToken()

a、进行xml头解析parseProlog()

包括BOM、<?xml version='1.0' encoding='UTF-8' standalone='yes'?>和根元素的解析

b、循环进行根元素中的元素分析

b.1、遇到"<"字符,发现已经有字符数据,退出,返回TEXT事件;没有字符数据,则more()下一个字符进行分支判定,分支包括/(是否标签结尾)、!(是否注释!-或CDATA![)、?(PI解析,存在疑问)、合法元素起始字符(正常走parseStartTag()且return该方法返回事件,存在疑问)、其它字符抛异常。

b.1.1、/(是否标签结尾)

 

 

b.2、遇到"&"字符,发现已经有字符数据,退出,返回TEXT事件;没有字符数据,则进行reference解析

 

3、next()

与nextToken()流程基本相同,只是遇到特定字符时,不会中断返回附加事件,流程更简单,这也是只用讲解nextToken()实现逻辑的原因。

XmlPullParser里共定义了5类核心事件,即next()和nextToken()都会关注的事件:

int START_DOCUMENT = 0;

int END_DOCUMENT = 1;

int START_TAG = 2;

int END_TAG = 3;

int TEXT = 4;

6类附加事件,即仅nextToken()会关注的事件。

int CDSECT = 5;

int ENTITY_REF = 6;

int IGNORABLE_WHITESPACE = 7;

int PROCESSING_INSTRUCTION = 8;

int COMMENT = 9;

int DOCDECL = 10;

 

4、buf维护策略

a、每次通过Reader最多读取的内容块大小为READ_CHUNK_SIZE 8K。

b、JVM剩余内存超1000000,则buf定义为char[READ_CHUNK_SIZE],否则为char[256]。

c、设定了95%的容量使用限制,当buf填充超过这个限制,要进行压缩或扩容处理。

压缩就是把未处理的buf部分直接从buf0位进行覆盖;扩容就是直接两倍buf长度,并把未处理的buf部分直接从buf0位进行覆盖。

选择压缩还是扩容,取决于下面的因素:

*如果是xml声明部分处理过程中,禁止压缩(理由没想通)

*如果待分析的buf内容全部在超出限制部分,则适宜于压缩

*如果待分析的buf内容起始位置尚未达到buf的一半,且小于限制,则适宜于扩张

d、超出使用限制,进行扩容或压缩后,很多变量需要重新设值。

*bufStart归0,因为待解析buf内容现在都是从0开始。

*bufEnd也要随bufStart缩减bufStart长度值。

*pos也要随bufStart缩减bufStart长度值。

*posStart、posEnd同上。

*bufAbsoluteStart要准确记录这次缩减,从0调整为bufStart。后续如果再次调整,要再加bufStart。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics