/*
* Copyright 2007 Stephen Liu
* For license terms, see the file COPYING along with this library.
*/
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <typeinfo>
#include "spxmlparser.hpp"
#include "spxmlreader.hpp"
#include "spxmlutils.hpp"
#include "spxmlstag.hpp"
#include "spxmlevent.hpp"
#include "spxmlcodec.hpp"
//=========================================================
SP_XmlReader :: SP_XmlReader()
{
mBuffer = new SP_XmlStringBuffer();
}
SP_XmlReader :: ~SP_XmlReader()
{
delete mBuffer;
}
void SP_XmlReader :: changeReader(
SP_XmlPullParser * parser, SP_XmlReader * reader )
{
parser->changeReader( reader );
}
SP_XmlReader * SP_XmlReader :: getReader( SP_XmlPullParser * parser, int type )
{
return parser->getReader( type );
}
void SP_XmlReader :: setError( SP_XmlPullParser * parser, const char * error )
{
parser->setError( error );
}
void SP_XmlReader :: reset()
{
mBuffer->clean();
}
//=========================================================
SP_XmlPIReader :: SP_XmlPIReader()
{
}
SP_XmlPIReader :: ~SP_XmlPIReader()
{
}
void SP_XmlPIReader :: read( SP_XmlPullParser * parser, char c )
{
if( '>' == c ) {
changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
} else {
mBuffer->append( c );
}
}
SP_XmlPullEvent * SP_XmlPIReader :: getEvent( SP_XmlPullParser * parser )
{
SP_XmlPullEvent * retEvent = NULL;
if( mBuffer->getSize() > 0 ) {
char * begin = (char*)mBuffer->getBuffer();
for( ; isspace( *begin ); ) begin++;
char * end = begin;
for( ; '\0' != *end && '?' != *end && ( ! isspace( *end ) ); ) end++;
char savedChar = *end;
*end = '\0';
if( 0 == strcasecmp( begin, "xml" ) ) {
*end = savedChar;
retEvent = parseDocDeclEvent( parser, mBuffer );
} else {
SP_XmlPIEvent * piEvent = new SP_XmlPIEvent();
piEvent->setTarget( begin );
*end = savedChar;
begin = end;
for( ; isspace( *begin ); ) begin++;
end = begin;
for( ; '\0' != *end && '?' != *end; ) end++;
piEvent->setData( begin, end - begin );
retEvent = piEvent;
}
}
return retEvent;
}
SP_XmlPullEvent * SP_XmlPIReader :: parseDocDeclEvent( SP_XmlPullParser * parser,
SP_XmlStringBuffer * buffer )
{
SP_XmlDocDeclEvent * retEvent = NULL;
SP_XmlSTagParser tagParser( parser->getEncoding() );
tagParser.append( buffer->getBuffer(), buffer->getSize() );
tagParser.append( " ", 1 );
if( NULL == tagParser.getError() ) {
SP_XmlStartTagEvent * event = tagParser.takeEvent();
const char * version = event->getAttrValue( "version" );
const char * encoding = event->getAttrValue( "encoding" );
const char * standalone = event->getAttrValue( "standalone" );
retEvent = new SP_XmlDocDeclEvent();
retEvent->setVersion( NULL == version ? "" : version );
retEvent->setEncoding( NULL == encoding ? "" : encoding );
if( NULL != standalone ) {
if( 0 == strcasecmp( "no", standalone ) ) {
retEvent->setStandalone( 0 );
} else {
retEvent->setStandalone( 1 );
}
}
delete event;
} else {
setError( parser, tagParser.getError() );
}
return retEvent;
}
//=========================================================
SP_XmlStartTagReader :: SP_XmlStartTagReader()
{
mIsQuot = 0;
}
SP_XmlStartTagReader :: ~SP_XmlStartTagReader()
{
}
void SP_XmlStartTagReader :: read( SP_XmlPullParser * parser, char c )
{
if( '>' == c && 0 == mIsQuot ) {
changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
} else if( '/' == c && 0 == mIsQuot ) {
SP_XmlReader * reader = getReader( parser, SP_XmlReader::eETag );
const char * pos = mBuffer->getBuffer();
for( ; isspace( *pos ); ) pos++;
for( ; 0 == isspace( *pos ) && '\0' != *pos; pos++ ) {
reader->read( parser, *pos );
}
changeReader( parser, reader );
} else if( '<' == c && 0 == mIsQuot ) {
setError( parser, "illegal char" );
} else {
mBuffer->append( c );
if( 0 == mIsQuot ) {
if( '\'' == c ) mIsQuot = 1;
if( '"' == c ) mIsQuot = 2;
} else {
if( 1 == mIsQuot && '\'' == c ) mIsQuot = 0;
if( 2 == mIsQuot && '"' == c ) mIsQuot = 0;
}
}
}
SP_XmlPullEvent * SP_XmlStartTagReader :: getEvent( SP_XmlPullParser * parser )
{
SP_XmlStartTagEvent * retEvent = NULL;
SP_XmlSTagParser tagParser( parser->getEncoding() );
tagParser.append( mBuffer->getBuffer(), mBuffer->getSize() );
tagParser.append( " ", 1 );
if( NULL == tagParser.getError() ) {
retEvent = tagParser.takeEvent();
} else {
setError( parser, tagParser.getError() );
}
return retEvent;
}
void SP_XmlStartTagReader :: reset()
{
SP_XmlReader::reset();
mIsQuot = 0;
}
//=========================================================
SP_XmlEndTagReader :: SP_XmlEndTagReader()
{
}
SP_XmlEndTagReader :: ~SP_XmlEndTagReader()
{
}
void SP_XmlEndTagReader :: read( SP_XmlPullParser * parser, char c )
{
if( '>' == c ) {
changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
} else if( '/' == c ) {
setError( parser, "illegal name char" );
} else {
mBuffer->append( c );
}
}
SP_XmlPullEvent * SP_XmlEndTagReader :: getEvent( SP_XmlPullParser * parser )
{
const char * end = mBuffer->getBuffer() + mBuffer->getSize() - 1;
for( ; end > mBuffer->getBuffer() && isspace( *end ); ) end--;
SP_XmlEndTagEvent * retEvent = new SP_XmlEndTagEvent();
retEvent->setText( mBuffer->getBuffer(), end - mBuffer->getBuffer() + 1 );
return retEvent;
}
//=========================================================
SP_XmlPCDataReader :: SP_XmlPCDataReader()
{
}
SP_XmlPCDataReader :: ~SP_XmlPCDataReader()
{
}
void SP_XmlPCDataReader :: read( SP_XmlPullParser * parser, char c )
{
if( '<' == c ) {
SP_XmlReader * reader = getReader( parser, SP_XmlReader::eLBracket );
reader->read( parser, c );
changeReader( parser, reader );
} else {
mBuffer->append( c );
if (mBuffer->getSize() >= parser->getMaxTextSize())
{
SP_XmlPullEvent * event = getEvent(parser);
if (event != NULL) {
parser->enqueueEvent(event);
mBuffer->clean();
}
}
}
}
SP_XmlPullEvent * SP_XmlPCDataReader :: getEvent( SP_XmlPullParser * parser )
{
SP_XmlCDataEvent * retEvent = NULL;
int ignore = 0;
if( 0 != parser->getIgnoreWhitespace() ) {
ignore = 1;
for( const char * pos = mBuffer->getBuffer(); '\0' != *pos; pos++ ) {
if( !isspace( *pos ) ) {
ignore = 0;
break;
}
}
}
if( 0 == ignore && mBuffer->getSize() > 0 ) {
retEvent = new SP_XmlCDataEvent();
SP_XmlStringBuffer buffer;
SP_XmlStringCodec::decode( parser->getEncoding(), mBuffer->getBuffer(), &buffer );
retEvent->setText( buffer.getBuffer(), buffer.getSize() );
}
return retEvent;
}
//=========================================================
SP_XmlCDataSectionReader :: SP_XmlCDataSectionReader()
{
}
SP_XmlCDataSectionReader :: ~SP_XmlCDataSectionReader()
{
}
void SP_XmlCDataSectionReader :: read( SP_XmlPullParser * parser, char c )
{
if( '>' == c && mBuffer->getSize() > 2 ) {
char last1 = mBuffer->getBuffer()[ mBuffer->getSize() - 1 ];
char last2 = mBuffer->getBuffer()[ mBuffer->getSize() - 2 ];
if( ']' == last1 && ']' == last2 ) {
changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
} else {
mBuffer->append( c );
}
} else {
mBuffer->append( c );
}
}
SP_XmlPullEvent * SP_XmlCDataSectionReader :: getEvent( SP_XmlPullParser * parser )
{
SP_XmlCDataEvent * retEvent = NULL;
int len = mBuffer->getSize();
const char * data = mBuffer->getBuffer();
if( 0 == strncmp( data, "CDATA[", strlen( "CDATA[" ) ) ) {
data += strlen( "CDATA[" );
len -= strlen( "CDATA[" );
}
int ignore = 0;
if( 0 != parser->getIgnoreWhitespace() ) {
ignore = 1;
for( int i = 0; i < len - 2; i++ ) {
if( !isspace( data[i] ) ) {
ignore = 0;
break;
}
}
}
if( 0 == ignore && len > 2 ) {
retEvent = new SP_XmlCDataEvent();
retEvent->setText( data, len - 2 );
}
return retEvent;
}
//=========================================================
小贝德罗
- 粉丝: 89
- 资源: 1万+
最新资源
- 基于Node.js和WebSocket的音频数据流分析音乐节奏展示设计源码
- 基于Surface框架的CURD和后台页面快速搭建设计源码
- 基于Snowflake算法的分布式唯一ID生成器UidGenerator在SpringBoot中的整合与应用设计源码
- 四轴直交机械手工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于Java语言的RabbitMQ精品课程设计源码
- 四合一测试设备(含bom)sw17可编辑工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于SSM框架和JavaScript的教材管理系统设计源码
- 基于JqueryMobile框架的kLink通讯录应用设计源码
- 基于2024暑假鸿蒙应用师资班培训的TeachObject20240715_01设计源码
- 卧式气动膏体灌装机工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于Vue的JavaScript光雨电子书后台源码
- 基于山东大学经验的转专业学生攻略设计源码
- 基于51单片机的蓝牙循迹小车设计源码
- Teaching Small Language Models to Reason 小模型如何在大模型中生效
- 基于Html和Ruby语言的test项目设计源码
- 线材激光焊接裁断机工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈