Mbed port of the Simple Plain Xml parser. See http://code.google.com/p/spxml/ for more details. This library uses less memory and is much better suited to streaming data than TinyXML (doesn\'t use as much C++ features, and especially works without streams). See http://mbed.org/users/hlipka/notebook/xml-parsing/ for usage examples.

Dependents:   spxmltest_weather VFD_fontx2_weather weather_LCD_display News_LCD_display ... more

Committer:
hlipka
Date:
Wed Nov 24 20:52:14 2010 +0000
Revision:
0:3fa97f2c0505
initial revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hlipka 0:3fa97f2c0505 1 /*
hlipka 0:3fa97f2c0505 2 * Copyright 2007 Stephen Liu
hlipka 0:3fa97f2c0505 3 * LGPL, see http://code.google.com/p/spxml/
hlipka 0:3fa97f2c0505 4 * For license terms, see the file COPYING along with this library.
hlipka 0:3fa97f2c0505 5 */
hlipka 0:3fa97f2c0505 6
hlipka 0:3fa97f2c0505 7 #include <string.h>
hlipka 0:3fa97f2c0505 8 #include <ctype.h>
hlipka 0:3fa97f2c0505 9 #include <stdlib.h>
hlipka 0:3fa97f2c0505 10 #include <typeinfo>
hlipka 0:3fa97f2c0505 11
hlipka 0:3fa97f2c0505 12 #include "spxmlparser.hpp"
hlipka 0:3fa97f2c0505 13 #include "spxmlreader.hpp"
hlipka 0:3fa97f2c0505 14 #include "spxmlutils.hpp"
hlipka 0:3fa97f2c0505 15 #include "spxmlstag.hpp"
hlipka 0:3fa97f2c0505 16 #include "spxmlevent.hpp"
hlipka 0:3fa97f2c0505 17 #include "spxmlcodec.hpp"
hlipka 0:3fa97f2c0505 18
hlipka 0:3fa97f2c0505 19 //=========================================================
hlipka 0:3fa97f2c0505 20
hlipka 0:3fa97f2c0505 21 SP_XmlReader :: SP_XmlReader()
hlipka 0:3fa97f2c0505 22 {
hlipka 0:3fa97f2c0505 23 mBuffer = new SP_XmlStringBuffer();
hlipka 0:3fa97f2c0505 24 }
hlipka 0:3fa97f2c0505 25
hlipka 0:3fa97f2c0505 26 SP_XmlReader :: ~SP_XmlReader()
hlipka 0:3fa97f2c0505 27 {
hlipka 0:3fa97f2c0505 28 delete mBuffer;
hlipka 0:3fa97f2c0505 29 }
hlipka 0:3fa97f2c0505 30
hlipka 0:3fa97f2c0505 31 void SP_XmlReader :: changeReader(
hlipka 0:3fa97f2c0505 32 SP_XmlPullParser * parser, SP_XmlReader * reader )
hlipka 0:3fa97f2c0505 33 {
hlipka 0:3fa97f2c0505 34 parser->changeReader( reader );
hlipka 0:3fa97f2c0505 35 }
hlipka 0:3fa97f2c0505 36
hlipka 0:3fa97f2c0505 37 SP_XmlReader * SP_XmlReader :: getReader( SP_XmlPullParser * parser, int type )
hlipka 0:3fa97f2c0505 38 {
hlipka 0:3fa97f2c0505 39 return parser->getReader( type );
hlipka 0:3fa97f2c0505 40 }
hlipka 0:3fa97f2c0505 41
hlipka 0:3fa97f2c0505 42 void SP_XmlReader :: setError( SP_XmlPullParser * parser, const char * error )
hlipka 0:3fa97f2c0505 43 {
hlipka 0:3fa97f2c0505 44 parser->setError( error );
hlipka 0:3fa97f2c0505 45 }
hlipka 0:3fa97f2c0505 46
hlipka 0:3fa97f2c0505 47 void SP_XmlReader :: reset()
hlipka 0:3fa97f2c0505 48 {
hlipka 0:3fa97f2c0505 49 mBuffer->clean();
hlipka 0:3fa97f2c0505 50 }
hlipka 0:3fa97f2c0505 51
hlipka 0:3fa97f2c0505 52 //=========================================================
hlipka 0:3fa97f2c0505 53
hlipka 0:3fa97f2c0505 54 SP_XmlPIReader :: SP_XmlPIReader()
hlipka 0:3fa97f2c0505 55 {
hlipka 0:3fa97f2c0505 56 }
hlipka 0:3fa97f2c0505 57
hlipka 0:3fa97f2c0505 58 SP_XmlPIReader :: ~SP_XmlPIReader()
hlipka 0:3fa97f2c0505 59 {
hlipka 0:3fa97f2c0505 60 }
hlipka 0:3fa97f2c0505 61
hlipka 0:3fa97f2c0505 62 void SP_XmlPIReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 63 {
hlipka 0:3fa97f2c0505 64 if( '>' == c ) {
hlipka 0:3fa97f2c0505 65 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 66 } else {
hlipka 0:3fa97f2c0505 67 mBuffer->append( c );
hlipka 0:3fa97f2c0505 68 }
hlipka 0:3fa97f2c0505 69 }
hlipka 0:3fa97f2c0505 70
hlipka 0:3fa97f2c0505 71 SP_XmlPullEvent * SP_XmlPIReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 72 {
hlipka 0:3fa97f2c0505 73 SP_XmlPullEvent * retEvent = NULL;
hlipka 0:3fa97f2c0505 74
hlipka 0:3fa97f2c0505 75 if( mBuffer->getSize() > 0 ) {
hlipka 0:3fa97f2c0505 76 char * begin = (char*)mBuffer->getBuffer();
hlipka 0:3fa97f2c0505 77 for( ; isspace( *begin ); ) begin++;
hlipka 0:3fa97f2c0505 78
hlipka 0:3fa97f2c0505 79 char * end = begin;
hlipka 0:3fa97f2c0505 80 for( ; '\0' != *end && '?' != *end && ( ! isspace( *end ) ); ) end++;
hlipka 0:3fa97f2c0505 81
hlipka 0:3fa97f2c0505 82 char savedChar = *end;
hlipka 0:3fa97f2c0505 83 *end = '\0';
hlipka 0:3fa97f2c0505 84
hlipka 0:3fa97f2c0505 85 if( 0 == strcasecmp( begin, "xml" ) ) {
hlipka 0:3fa97f2c0505 86 *end = savedChar;
hlipka 0:3fa97f2c0505 87
hlipka 0:3fa97f2c0505 88 retEvent = parseDocDeclEvent( parser, mBuffer );
hlipka 0:3fa97f2c0505 89 } else {
hlipka 0:3fa97f2c0505 90 SP_XmlPIEvent * piEvent = new SP_XmlPIEvent();
hlipka 0:3fa97f2c0505 91 piEvent->setTarget( begin );
hlipka 0:3fa97f2c0505 92
hlipka 0:3fa97f2c0505 93 *end = savedChar;
hlipka 0:3fa97f2c0505 94
hlipka 0:3fa97f2c0505 95 begin = end;
hlipka 0:3fa97f2c0505 96 for( ; isspace( *begin ); ) begin++;
hlipka 0:3fa97f2c0505 97
hlipka 0:3fa97f2c0505 98 end = begin;
hlipka 0:3fa97f2c0505 99 for( ; '\0' != *end && '?' != *end; ) end++;
hlipka 0:3fa97f2c0505 100
hlipka 0:3fa97f2c0505 101 piEvent->setData( begin, end - begin );
hlipka 0:3fa97f2c0505 102
hlipka 0:3fa97f2c0505 103 retEvent = piEvent;
hlipka 0:3fa97f2c0505 104 }
hlipka 0:3fa97f2c0505 105 }
hlipka 0:3fa97f2c0505 106
hlipka 0:3fa97f2c0505 107 return retEvent;
hlipka 0:3fa97f2c0505 108 }
hlipka 0:3fa97f2c0505 109
hlipka 0:3fa97f2c0505 110 SP_XmlPullEvent * SP_XmlPIReader :: parseDocDeclEvent( SP_XmlPullParser * parser,
hlipka 0:3fa97f2c0505 111 SP_XmlStringBuffer * buffer )
hlipka 0:3fa97f2c0505 112 {
hlipka 0:3fa97f2c0505 113 SP_XmlDocDeclEvent * retEvent = NULL;
hlipka 0:3fa97f2c0505 114
hlipka 0:3fa97f2c0505 115 SP_XmlSTagParser tagParser( parser->getEncoding() );
hlipka 0:3fa97f2c0505 116
hlipka 0:3fa97f2c0505 117 tagParser.append( buffer->getBuffer(), buffer->getSize() );
hlipka 0:3fa97f2c0505 118 tagParser.append( " ", 1 );
hlipka 0:3fa97f2c0505 119
hlipka 0:3fa97f2c0505 120 if( NULL == tagParser.getError() ) {
hlipka 0:3fa97f2c0505 121 SP_XmlStartTagEvent * event = tagParser.takeEvent();
hlipka 0:3fa97f2c0505 122
hlipka 0:3fa97f2c0505 123 const char * version = event->getAttrValue( "version" );
hlipka 0:3fa97f2c0505 124 const char * encoding = event->getAttrValue( "encoding" );
hlipka 0:3fa97f2c0505 125 const char * standalone = event->getAttrValue( "standalone" );
hlipka 0:3fa97f2c0505 126
hlipka 0:3fa97f2c0505 127 retEvent = new SP_XmlDocDeclEvent();
hlipka 0:3fa97f2c0505 128 retEvent->setVersion( NULL == version ? "" : version );
hlipka 0:3fa97f2c0505 129 retEvent->setEncoding( NULL == encoding ? "" : encoding );
hlipka 0:3fa97f2c0505 130 if( NULL != standalone ) {
hlipka 0:3fa97f2c0505 131 if( 0 == strcasecmp( "no", standalone ) ) {
hlipka 0:3fa97f2c0505 132 retEvent->setStandalone( 0 );
hlipka 0:3fa97f2c0505 133 } else {
hlipka 0:3fa97f2c0505 134 retEvent->setStandalone( 1 );
hlipka 0:3fa97f2c0505 135 }
hlipka 0:3fa97f2c0505 136 }
hlipka 0:3fa97f2c0505 137
hlipka 0:3fa97f2c0505 138 delete event;
hlipka 0:3fa97f2c0505 139 } else {
hlipka 0:3fa97f2c0505 140 setError( parser, tagParser.getError() );
hlipka 0:3fa97f2c0505 141 }
hlipka 0:3fa97f2c0505 142
hlipka 0:3fa97f2c0505 143 return retEvent;
hlipka 0:3fa97f2c0505 144 }
hlipka 0:3fa97f2c0505 145
hlipka 0:3fa97f2c0505 146 //=========================================================
hlipka 0:3fa97f2c0505 147
hlipka 0:3fa97f2c0505 148 SP_XmlStartTagReader :: SP_XmlStartTagReader()
hlipka 0:3fa97f2c0505 149 {
hlipka 0:3fa97f2c0505 150 mIsQuot = 0;
hlipka 0:3fa97f2c0505 151 }
hlipka 0:3fa97f2c0505 152
hlipka 0:3fa97f2c0505 153 SP_XmlStartTagReader :: ~SP_XmlStartTagReader()
hlipka 0:3fa97f2c0505 154 {
hlipka 0:3fa97f2c0505 155 }
hlipka 0:3fa97f2c0505 156
hlipka 0:3fa97f2c0505 157 void SP_XmlStartTagReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 158 {
hlipka 0:3fa97f2c0505 159 if( '>' == c && 0 == mIsQuot ) {
hlipka 0:3fa97f2c0505 160 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 161 } else if( '/' == c && 0 == mIsQuot ) {
hlipka 0:3fa97f2c0505 162 SP_XmlReader * reader = getReader( parser, SP_XmlReader::eETag );
hlipka 0:3fa97f2c0505 163 const char * pos = mBuffer->getBuffer();
hlipka 0:3fa97f2c0505 164 for( ; isspace( *pos ); ) pos++;
hlipka 0:3fa97f2c0505 165 for( ; 0 == isspace( *pos ) && '\0' != *pos; pos++ ) {
hlipka 0:3fa97f2c0505 166 reader->read( parser, *pos );
hlipka 0:3fa97f2c0505 167 }
hlipka 0:3fa97f2c0505 168 changeReader( parser, reader );
hlipka 0:3fa97f2c0505 169 } else if( '<' == c && 0 == mIsQuot ) {
hlipka 0:3fa97f2c0505 170 setError( parser, "illegal char" );
hlipka 0:3fa97f2c0505 171 } else {
hlipka 0:3fa97f2c0505 172 mBuffer->append( c );
hlipka 0:3fa97f2c0505 173
hlipka 0:3fa97f2c0505 174 if( 0 == mIsQuot ) {
hlipka 0:3fa97f2c0505 175 if( '\'' == c ) mIsQuot = 1;
hlipka 0:3fa97f2c0505 176 if( '"' == c ) mIsQuot = 2;
hlipka 0:3fa97f2c0505 177 } else {
hlipka 0:3fa97f2c0505 178 if( 1 == mIsQuot && '\'' == c ) mIsQuot = 0;
hlipka 0:3fa97f2c0505 179 if( 2 == mIsQuot && '"' == c ) mIsQuot = 0;
hlipka 0:3fa97f2c0505 180 }
hlipka 0:3fa97f2c0505 181 }
hlipka 0:3fa97f2c0505 182 }
hlipka 0:3fa97f2c0505 183
hlipka 0:3fa97f2c0505 184 SP_XmlPullEvent * SP_XmlStartTagReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 185 {
hlipka 0:3fa97f2c0505 186 SP_XmlStartTagEvent * retEvent = NULL;
hlipka 0:3fa97f2c0505 187
hlipka 0:3fa97f2c0505 188 SP_XmlSTagParser tagParser( parser->getEncoding() );
hlipka 0:3fa97f2c0505 189 tagParser.append( mBuffer->getBuffer(), mBuffer->getSize() );
hlipka 0:3fa97f2c0505 190 tagParser.append( " ", 1 );
hlipka 0:3fa97f2c0505 191
hlipka 0:3fa97f2c0505 192 if( NULL == tagParser.getError() ) {
hlipka 0:3fa97f2c0505 193 retEvent = tagParser.takeEvent();
hlipka 0:3fa97f2c0505 194 } else {
hlipka 0:3fa97f2c0505 195 setError( parser, tagParser.getError() );
hlipka 0:3fa97f2c0505 196 }
hlipka 0:3fa97f2c0505 197
hlipka 0:3fa97f2c0505 198 return retEvent;
hlipka 0:3fa97f2c0505 199 }
hlipka 0:3fa97f2c0505 200
hlipka 0:3fa97f2c0505 201 void SP_XmlStartTagReader :: reset()
hlipka 0:3fa97f2c0505 202 {
hlipka 0:3fa97f2c0505 203 SP_XmlReader::reset();
hlipka 0:3fa97f2c0505 204 mIsQuot = 0;
hlipka 0:3fa97f2c0505 205 }
hlipka 0:3fa97f2c0505 206
hlipka 0:3fa97f2c0505 207 //=========================================================
hlipka 0:3fa97f2c0505 208
hlipka 0:3fa97f2c0505 209 SP_XmlEndTagReader :: SP_XmlEndTagReader()
hlipka 0:3fa97f2c0505 210 {
hlipka 0:3fa97f2c0505 211 }
hlipka 0:3fa97f2c0505 212
hlipka 0:3fa97f2c0505 213 SP_XmlEndTagReader :: ~SP_XmlEndTagReader()
hlipka 0:3fa97f2c0505 214 {
hlipka 0:3fa97f2c0505 215 }
hlipka 0:3fa97f2c0505 216
hlipka 0:3fa97f2c0505 217 void SP_XmlEndTagReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 218 {
hlipka 0:3fa97f2c0505 219 if( '>' == c ) {
hlipka 0:3fa97f2c0505 220 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 221 } else if( '/' == c ) {
hlipka 0:3fa97f2c0505 222 setError( parser, "illegal name char" );
hlipka 0:3fa97f2c0505 223 } else {
hlipka 0:3fa97f2c0505 224 mBuffer->append( c );
hlipka 0:3fa97f2c0505 225 }
hlipka 0:3fa97f2c0505 226 }
hlipka 0:3fa97f2c0505 227
hlipka 0:3fa97f2c0505 228 SP_XmlPullEvent * SP_XmlEndTagReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 229 {
hlipka 0:3fa97f2c0505 230 const char * end = mBuffer->getBuffer() + mBuffer->getSize() - 1;
hlipka 0:3fa97f2c0505 231
hlipka 0:3fa97f2c0505 232 for( ; end > mBuffer->getBuffer() && isspace( *end ); ) end--;
hlipka 0:3fa97f2c0505 233
hlipka 0:3fa97f2c0505 234 SP_XmlEndTagEvent * retEvent = new SP_XmlEndTagEvent();
hlipka 0:3fa97f2c0505 235 retEvent->setText( mBuffer->getBuffer(), end - mBuffer->getBuffer() + 1 );
hlipka 0:3fa97f2c0505 236
hlipka 0:3fa97f2c0505 237 return retEvent;
hlipka 0:3fa97f2c0505 238 }
hlipka 0:3fa97f2c0505 239
hlipka 0:3fa97f2c0505 240 //=========================================================
hlipka 0:3fa97f2c0505 241
hlipka 0:3fa97f2c0505 242 SP_XmlPCDataReader :: SP_XmlPCDataReader()
hlipka 0:3fa97f2c0505 243 {
hlipka 0:3fa97f2c0505 244 }
hlipka 0:3fa97f2c0505 245
hlipka 0:3fa97f2c0505 246 SP_XmlPCDataReader :: ~SP_XmlPCDataReader()
hlipka 0:3fa97f2c0505 247 {
hlipka 0:3fa97f2c0505 248 }
hlipka 0:3fa97f2c0505 249
hlipka 0:3fa97f2c0505 250 void SP_XmlPCDataReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 251 {
hlipka 0:3fa97f2c0505 252 if( '<' == c ) {
hlipka 0:3fa97f2c0505 253 SP_XmlReader * reader = getReader( parser, SP_XmlReader::eLBracket );
hlipka 0:3fa97f2c0505 254 reader->read( parser, c );
hlipka 0:3fa97f2c0505 255 changeReader( parser, reader );
hlipka 0:3fa97f2c0505 256 } else {
hlipka 0:3fa97f2c0505 257 mBuffer->append( c );
hlipka 0:3fa97f2c0505 258 }
hlipka 0:3fa97f2c0505 259 }
hlipka 0:3fa97f2c0505 260
hlipka 0:3fa97f2c0505 261 SP_XmlPullEvent * SP_XmlPCDataReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 262 {
hlipka 0:3fa97f2c0505 263 SP_XmlCDataEvent * retEvent = NULL;
hlipka 0:3fa97f2c0505 264
hlipka 0:3fa97f2c0505 265 int ignore = 0;
hlipka 0:3fa97f2c0505 266
hlipka 0:3fa97f2c0505 267 if( 0 != parser->getIgnoreWhitespace() ) {
hlipka 0:3fa97f2c0505 268 ignore = 1;
hlipka 0:3fa97f2c0505 269 for( const char * pos = mBuffer->getBuffer(); '\0' != *pos; pos++ ) {
hlipka 0:3fa97f2c0505 270 if( !isspace( *pos ) ) {
hlipka 0:3fa97f2c0505 271 ignore = 0;
hlipka 0:3fa97f2c0505 272 break;
hlipka 0:3fa97f2c0505 273 }
hlipka 0:3fa97f2c0505 274 }
hlipka 0:3fa97f2c0505 275 }
hlipka 0:3fa97f2c0505 276
hlipka 0:3fa97f2c0505 277 if( 0 == ignore && mBuffer->getSize() > 0 ) {
hlipka 0:3fa97f2c0505 278 retEvent = new SP_XmlCDataEvent();
hlipka 0:3fa97f2c0505 279 SP_XmlStringBuffer buffer;
hlipka 0:3fa97f2c0505 280 SP_XmlStringCodec::decode( parser->getEncoding(), mBuffer->getBuffer(), &buffer );
hlipka 0:3fa97f2c0505 281 retEvent->setText( buffer.getBuffer(), buffer.getSize() );
hlipka 0:3fa97f2c0505 282 }
hlipka 0:3fa97f2c0505 283
hlipka 0:3fa97f2c0505 284 return retEvent;
hlipka 0:3fa97f2c0505 285 }
hlipka 0:3fa97f2c0505 286
hlipka 0:3fa97f2c0505 287 //=========================================================
hlipka 0:3fa97f2c0505 288
hlipka 0:3fa97f2c0505 289 SP_XmlCDataSectionReader :: SP_XmlCDataSectionReader()
hlipka 0:3fa97f2c0505 290 {
hlipka 0:3fa97f2c0505 291 }
hlipka 0:3fa97f2c0505 292
hlipka 0:3fa97f2c0505 293 SP_XmlCDataSectionReader :: ~SP_XmlCDataSectionReader()
hlipka 0:3fa97f2c0505 294 {
hlipka 0:3fa97f2c0505 295 }
hlipka 0:3fa97f2c0505 296
hlipka 0:3fa97f2c0505 297 void SP_XmlCDataSectionReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 298 {
hlipka 0:3fa97f2c0505 299 if( '>' == c && mBuffer->getSize() > 2 ) {
hlipka 0:3fa97f2c0505 300 char last1 = mBuffer->getBuffer()[ mBuffer->getSize() - 1 ];
hlipka 0:3fa97f2c0505 301 char last2 = mBuffer->getBuffer()[ mBuffer->getSize() - 2 ];
hlipka 0:3fa97f2c0505 302
hlipka 0:3fa97f2c0505 303 if( ']' == last1 && ']' == last2 ) {
hlipka 0:3fa97f2c0505 304 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 305 } else {
hlipka 0:3fa97f2c0505 306 mBuffer->append( c );
hlipka 0:3fa97f2c0505 307 }
hlipka 0:3fa97f2c0505 308 } else {
hlipka 0:3fa97f2c0505 309 mBuffer->append( c );
hlipka 0:3fa97f2c0505 310 }
hlipka 0:3fa97f2c0505 311 }
hlipka 0:3fa97f2c0505 312
hlipka 0:3fa97f2c0505 313 SP_XmlPullEvent * SP_XmlCDataSectionReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 314 {
hlipka 0:3fa97f2c0505 315 SP_XmlCDataEvent * retEvent = NULL;
hlipka 0:3fa97f2c0505 316
hlipka 0:3fa97f2c0505 317 int len = mBuffer->getSize();
hlipka 0:3fa97f2c0505 318 const char * data = mBuffer->getBuffer();
hlipka 0:3fa97f2c0505 319 if( 0 == strncmp( data, "CDATA[", strlen( "CDATA[" ) ) ) {
hlipka 0:3fa97f2c0505 320 data += strlen( "CDATA[" );
hlipka 0:3fa97f2c0505 321 len -= strlen( "CDATA[" );
hlipka 0:3fa97f2c0505 322 }
hlipka 0:3fa97f2c0505 323
hlipka 0:3fa97f2c0505 324 int ignore = 0;
hlipka 0:3fa97f2c0505 325 if( 0 != parser->getIgnoreWhitespace() ) {
hlipka 0:3fa97f2c0505 326 ignore = 1;
hlipka 0:3fa97f2c0505 327 for( int i = 0; i < len - 2; i++ ) {
hlipka 0:3fa97f2c0505 328 if( !isspace( data[i] ) ) {
hlipka 0:3fa97f2c0505 329 ignore = 0;
hlipka 0:3fa97f2c0505 330 break;
hlipka 0:3fa97f2c0505 331 }
hlipka 0:3fa97f2c0505 332 }
hlipka 0:3fa97f2c0505 333 }
hlipka 0:3fa97f2c0505 334
hlipka 0:3fa97f2c0505 335 if( 0 == ignore && len > 2 ) {
hlipka 0:3fa97f2c0505 336 retEvent = new SP_XmlCDataEvent();
hlipka 0:3fa97f2c0505 337 retEvent->setText( data, len - 2 );
hlipka 0:3fa97f2c0505 338 }
hlipka 0:3fa97f2c0505 339
hlipka 0:3fa97f2c0505 340 return retEvent;
hlipka 0:3fa97f2c0505 341 }
hlipka 0:3fa97f2c0505 342
hlipka 0:3fa97f2c0505 343 //=========================================================
hlipka 0:3fa97f2c0505 344
hlipka 0:3fa97f2c0505 345 SP_XmlCommentReader :: SP_XmlCommentReader()
hlipka 0:3fa97f2c0505 346 {
hlipka 0:3fa97f2c0505 347 }
hlipka 0:3fa97f2c0505 348
hlipka 0:3fa97f2c0505 349 SP_XmlCommentReader :: ~SP_XmlCommentReader()
hlipka 0:3fa97f2c0505 350 {
hlipka 0:3fa97f2c0505 351 }
hlipka 0:3fa97f2c0505 352
hlipka 0:3fa97f2c0505 353 void SP_XmlCommentReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 354 {
hlipka 0:3fa97f2c0505 355 if( '>' == c && mBuffer->getSize() >= 2 ) {
hlipka 0:3fa97f2c0505 356 int size = mBuffer->getSize();
hlipka 0:3fa97f2c0505 357 if( '-' == mBuffer->getBuffer()[ size - 1 ]
hlipka 0:3fa97f2c0505 358 && '-' == mBuffer->getBuffer()[ size - 2 ] ) {
hlipka 0:3fa97f2c0505 359 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 360 } else {
hlipka 0:3fa97f2c0505 361 mBuffer->append( c );
hlipka 0:3fa97f2c0505 362 }
hlipka 0:3fa97f2c0505 363 } else {
hlipka 0:3fa97f2c0505 364 mBuffer->append( c );
hlipka 0:3fa97f2c0505 365 }
hlipka 0:3fa97f2c0505 366 }
hlipka 0:3fa97f2c0505 367
hlipka 0:3fa97f2c0505 368 SP_XmlPullEvent * SP_XmlCommentReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 369 {
hlipka 0:3fa97f2c0505 370 SP_XmlCommentEvent * retEvent = new SP_XmlCommentEvent();
hlipka 0:3fa97f2c0505 371
hlipka 0:3fa97f2c0505 372 retEvent->setText( mBuffer->getBuffer(), mBuffer->getSize() - 2 );
hlipka 0:3fa97f2c0505 373
hlipka 0:3fa97f2c0505 374 return retEvent;
hlipka 0:3fa97f2c0505 375 }
hlipka 0:3fa97f2c0505 376
hlipka 0:3fa97f2c0505 377 //=========================================================
hlipka 0:3fa97f2c0505 378
hlipka 0:3fa97f2c0505 379 SP_XmlDocTypeReader :: SP_XmlDocTypeReader()
hlipka 0:3fa97f2c0505 380 {
hlipka 0:3fa97f2c0505 381 }
hlipka 0:3fa97f2c0505 382
hlipka 0:3fa97f2c0505 383 SP_XmlDocTypeReader :: ~SP_XmlDocTypeReader()
hlipka 0:3fa97f2c0505 384 {
hlipka 0:3fa97f2c0505 385 }
hlipka 0:3fa97f2c0505 386
hlipka 0:3fa97f2c0505 387 void SP_XmlDocTypeReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 388 {
hlipka 0:3fa97f2c0505 389 if( '>' == c ) {
hlipka 0:3fa97f2c0505 390 if( NULL != strchr( mBuffer->getBuffer(), '[' ) ) {
hlipka 0:3fa97f2c0505 391 char last = mBuffer->getBuffer()[ mBuffer->getSize() - 1 ];
hlipka 0:3fa97f2c0505 392 if( ']' == last ) {
hlipka 0:3fa97f2c0505 393 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 394 } else {
hlipka 0:3fa97f2c0505 395 mBuffer->append( c );
hlipka 0:3fa97f2c0505 396 }
hlipka 0:3fa97f2c0505 397 } else {
hlipka 0:3fa97f2c0505 398 changeReader( parser, getReader( parser, SP_XmlReader::ePCData ) );
hlipka 0:3fa97f2c0505 399 }
hlipka 0:3fa97f2c0505 400 } else {
hlipka 0:3fa97f2c0505 401 mBuffer->append( c );
hlipka 0:3fa97f2c0505 402 }
hlipka 0:3fa97f2c0505 403 }
hlipka 0:3fa97f2c0505 404
hlipka 0:3fa97f2c0505 405 SP_XmlPullEvent * SP_XmlDocTypeReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 406 {
hlipka 0:3fa97f2c0505 407 SP_XmlDocTypeEvent * retEvent = NULL;
hlipka 0:3fa97f2c0505 408
hlipka 0:3fa97f2c0505 409 SP_XmlSTagParser tagParser( parser->getEncoding() );
hlipka 0:3fa97f2c0505 410
hlipka 0:3fa97f2c0505 411 tagParser.append( "DOCTYPE ", strlen( "DOCTYPE " ) );
hlipka 0:3fa97f2c0505 412 tagParser.append( mBuffer->getBuffer(), mBuffer->getSize() );
hlipka 0:3fa97f2c0505 413 tagParser.append( " ", 1 );
hlipka 0:3fa97f2c0505 414 if( NULL == tagParser.getError() ) {
hlipka 0:3fa97f2c0505 415 SP_XmlStartTagEvent * event = tagParser.takeEvent();
hlipka 0:3fa97f2c0505 416
hlipka 0:3fa97f2c0505 417 retEvent = new SP_XmlDocTypeEvent();
hlipka 0:3fa97f2c0505 418
hlipka 0:3fa97f2c0505 419 for( int i = 0; i < event->getAttrCount(); i += 2 ) {
hlipka 0:3fa97f2c0505 420 const char * name = event->getAttr( i, NULL );
hlipka 0:3fa97f2c0505 421 if( 0 == strcmp( name, "DOCTYPE" ) ) {
hlipka 0:3fa97f2c0505 422 name = event->getAttr( i + 1, NULL );
hlipka 0:3fa97f2c0505 423 retEvent->setName( NULL == name ? "" : name );
hlipka 0:3fa97f2c0505 424 } else if( 0 == strcmp( name, "PUBLIC" ) ) {
hlipka 0:3fa97f2c0505 425 name = event->getAttr( i + 1, NULL );
hlipka 0:3fa97f2c0505 426 retEvent->setPublicID( NULL == name ? "" : name );
hlipka 0:3fa97f2c0505 427 } else if( 0 == strcmp( name, "SYSTEM" ) ) {
hlipka 0:3fa97f2c0505 428 name = event->getAttr( i + 1, NULL );
hlipka 0:3fa97f2c0505 429 retEvent->setSystemID( NULL == name ? "" : name );
hlipka 0:3fa97f2c0505 430 } else if( NULL != strstr( name, ".dtd" ) ) {
hlipka 0:3fa97f2c0505 431 retEvent->setDTD( name );
hlipka 0:3fa97f2c0505 432 }
hlipka 0:3fa97f2c0505 433 }
hlipka 0:3fa97f2c0505 434
hlipka 0:3fa97f2c0505 435 delete event;
hlipka 0:3fa97f2c0505 436 } else {
hlipka 0:3fa97f2c0505 437 //setError( parser, tagParser.getError() );
hlipka 0:3fa97f2c0505 438 }
hlipka 0:3fa97f2c0505 439
hlipka 0:3fa97f2c0505 440 return retEvent;
hlipka 0:3fa97f2c0505 441 }
hlipka 0:3fa97f2c0505 442
hlipka 0:3fa97f2c0505 443 //=========================================================
hlipka 0:3fa97f2c0505 444
hlipka 0:3fa97f2c0505 445 SP_XmlLeftBracketReader :: SP_XmlLeftBracketReader()
hlipka 0:3fa97f2c0505 446 {
hlipka 0:3fa97f2c0505 447 mHasReadBracket = 0;
hlipka 0:3fa97f2c0505 448 }
hlipka 0:3fa97f2c0505 449
hlipka 0:3fa97f2c0505 450 SP_XmlLeftBracketReader :: ~SP_XmlLeftBracketReader()
hlipka 0:3fa97f2c0505 451 {
hlipka 0:3fa97f2c0505 452 }
hlipka 0:3fa97f2c0505 453
hlipka 0:3fa97f2c0505 454 void SP_XmlLeftBracketReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 455 {
hlipka 0:3fa97f2c0505 456 if( 0 == mHasReadBracket ) {
hlipka 0:3fa97f2c0505 457 if( isspace( c ) ) {
hlipka 0:3fa97f2c0505 458 //skip
hlipka 0:3fa97f2c0505 459 } else if( '<' == c ) {
hlipka 0:3fa97f2c0505 460 mHasReadBracket = 1;
hlipka 0:3fa97f2c0505 461 }
hlipka 0:3fa97f2c0505 462 } else {
hlipka 0:3fa97f2c0505 463 if( '?' == c ) {
hlipka 0:3fa97f2c0505 464 changeReader( parser, getReader( parser, SP_XmlReader::ePI ) );
hlipka 0:3fa97f2c0505 465 } else if( '/' == c ) {
hlipka 0:3fa97f2c0505 466 changeReader( parser, getReader( parser, SP_XmlReader::eETag ) );
hlipka 0:3fa97f2c0505 467 } else if( '!' == c ) {
hlipka 0:3fa97f2c0505 468 changeReader( parser, getReader( parser, SP_XmlReader::eSign ) );
hlipka 0:3fa97f2c0505 469 } else if( SP_XmlStringCodec::isNameChar( parser->getEncoding(), c ) ) {
hlipka 0:3fa97f2c0505 470 SP_XmlReader * reader = getReader( parser, SP_XmlReader::eSTag );
hlipka 0:3fa97f2c0505 471 reader->read( parser, c );
hlipka 0:3fa97f2c0505 472 changeReader( parser, reader );
hlipka 0:3fa97f2c0505 473 } else {
hlipka 0:3fa97f2c0505 474 setError( parser, "not well-formed" );
hlipka 0:3fa97f2c0505 475 }
hlipka 0:3fa97f2c0505 476 }
hlipka 0:3fa97f2c0505 477 }
hlipka 0:3fa97f2c0505 478
hlipka 0:3fa97f2c0505 479 SP_XmlPullEvent * SP_XmlLeftBracketReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 480 {
hlipka 0:3fa97f2c0505 481 return NULL;
hlipka 0:3fa97f2c0505 482 }
hlipka 0:3fa97f2c0505 483
hlipka 0:3fa97f2c0505 484 void SP_XmlLeftBracketReader :: reset()
hlipka 0:3fa97f2c0505 485 {
hlipka 0:3fa97f2c0505 486 SP_XmlReader::reset();
hlipka 0:3fa97f2c0505 487 mHasReadBracket = 0;
hlipka 0:3fa97f2c0505 488 }
hlipka 0:3fa97f2c0505 489
hlipka 0:3fa97f2c0505 490 //=========================================================
hlipka 0:3fa97f2c0505 491
hlipka 0:3fa97f2c0505 492 SP_XmlSignReader :: SP_XmlSignReader()
hlipka 0:3fa97f2c0505 493 {
hlipka 0:3fa97f2c0505 494 }
hlipka 0:3fa97f2c0505 495
hlipka 0:3fa97f2c0505 496 SP_XmlSignReader :: ~SP_XmlSignReader()
hlipka 0:3fa97f2c0505 497 {
hlipka 0:3fa97f2c0505 498 }
hlipka 0:3fa97f2c0505 499
hlipka 0:3fa97f2c0505 500 void SP_XmlSignReader :: read( SP_XmlPullParser * parser, char c )
hlipka 0:3fa97f2c0505 501 {
hlipka 0:3fa97f2c0505 502 if( '[' == c ) {
hlipka 0:3fa97f2c0505 503 changeReader( parser, getReader( parser, SP_XmlReader::eCDataSection ) );
hlipka 0:3fa97f2c0505 504 } else if( '-' == c ) {
hlipka 0:3fa97f2c0505 505 changeReader( parser, getReader( parser, SP_XmlReader::eComment ) );
hlipka 0:3fa97f2c0505 506 } else if( isupper( c ) ) {
hlipka 0:3fa97f2c0505 507 SP_XmlReader * reader = getReader( parser, SP_XmlReader::eDocType );
hlipka 0:3fa97f2c0505 508 reader->read( parser, c );
hlipka 0:3fa97f2c0505 509 changeReader( parser, reader );
hlipka 0:3fa97f2c0505 510 } else {
hlipka 0:3fa97f2c0505 511 setError( parser, "not well-formed" );
hlipka 0:3fa97f2c0505 512 }
hlipka 0:3fa97f2c0505 513 }
hlipka 0:3fa97f2c0505 514
hlipka 0:3fa97f2c0505 515 SP_XmlPullEvent * SP_XmlSignReader :: getEvent( SP_XmlPullParser * parser )
hlipka 0:3fa97f2c0505 516 {
hlipka 0:3fa97f2c0505 517 return NULL;
hlipka 0:3fa97f2c0505 518 }
hlipka 0:3fa97f2c0505 519
hlipka 0:3fa97f2c0505 520 //=========================================================
hlipka 0:3fa97f2c0505 521
hlipka 0:3fa97f2c0505 522 SP_XmlReaderPool :: SP_XmlReaderPool()
hlipka 0:3fa97f2c0505 523 {
hlipka 0:3fa97f2c0505 524 mReaderList = (SP_XmlReader**)malloc( sizeof( void * ) * SP_XmlReader::MAX_READER );
hlipka 0:3fa97f2c0505 525 memset( mReaderList, 0, sizeof( void * ) * SP_XmlReader::MAX_READER );
hlipka 0:3fa97f2c0505 526 }
hlipka 0:3fa97f2c0505 527
hlipka 0:3fa97f2c0505 528 SP_XmlReaderPool :: ~SP_XmlReaderPool()
hlipka 0:3fa97f2c0505 529 {
hlipka 0:3fa97f2c0505 530 for( int i = 0; i < SP_XmlReader::MAX_READER; i++ ) {
hlipka 0:3fa97f2c0505 531 if( NULL != mReaderList[i] ) {
hlipka 0:3fa97f2c0505 532 delete mReaderList[i];
hlipka 0:3fa97f2c0505 533 }
hlipka 0:3fa97f2c0505 534 }
hlipka 0:3fa97f2c0505 535 free( mReaderList );
hlipka 0:3fa97f2c0505 536 }
hlipka 0:3fa97f2c0505 537
hlipka 0:3fa97f2c0505 538 SP_XmlReader * SP_XmlReaderPool :: borrow( int type )
hlipka 0:3fa97f2c0505 539 {
hlipka 0:3fa97f2c0505 540 SP_XmlReader * reader = NULL;
hlipka 0:3fa97f2c0505 541
hlipka 0:3fa97f2c0505 542 if( type >= 0 && type < SP_XmlReader::MAX_READER ) {
hlipka 0:3fa97f2c0505 543 reader = mReaderList[ type ];
hlipka 0:3fa97f2c0505 544 if( NULL == reader ) {
hlipka 0:3fa97f2c0505 545 switch( type ) {
hlipka 0:3fa97f2c0505 546 case SP_XmlReader::ePI: reader = new SP_XmlPIReader(); break;
hlipka 0:3fa97f2c0505 547 case SP_XmlReader::eSTag: reader = new SP_XmlStartTagReader(); break;
hlipka 0:3fa97f2c0505 548 case SP_XmlReader::eETag: reader = new SP_XmlEndTagReader(); break;
hlipka 0:3fa97f2c0505 549 case SP_XmlReader::ePCData: reader = new SP_XmlPCDataReader(); break;
hlipka 0:3fa97f2c0505 550 case SP_XmlReader::eCDataSection: reader = new SP_XmlCDataSectionReader(); break;
hlipka 0:3fa97f2c0505 551 case SP_XmlReader::eComment: reader = new SP_XmlCommentReader(); break;
hlipka 0:3fa97f2c0505 552 case SP_XmlReader::eDocType: reader = new SP_XmlDocTypeReader(); break;
hlipka 0:3fa97f2c0505 553 case SP_XmlReader::eLBracket: reader = new SP_XmlLeftBracketReader(); break;
hlipka 0:3fa97f2c0505 554 case SP_XmlReader::eSign: reader = new SP_XmlSignReader(); break;
hlipka 0:3fa97f2c0505 555 }
hlipka 0:3fa97f2c0505 556 mReaderList[ type ] = reader;
hlipka 0:3fa97f2c0505 557 }
hlipka 0:3fa97f2c0505 558 }
hlipka 0:3fa97f2c0505 559
hlipka 0:3fa97f2c0505 560 //printf( "\nborrow change: %s\n", typeid( *reader ).name() );
hlipka 0:3fa97f2c0505 561
hlipka 0:3fa97f2c0505 562 return reader;
hlipka 0:3fa97f2c0505 563 }
hlipka 0:3fa97f2c0505 564
hlipka 0:3fa97f2c0505 565 void SP_XmlReaderPool :: save( SP_XmlReader * reader )
hlipka 0:3fa97f2c0505 566 {
hlipka 0:3fa97f2c0505 567 //printf( "\nreturn change: %s\n", typeid( *reader ).name() );
hlipka 0:3fa97f2c0505 568 reader->reset();
hlipka 0:3fa97f2c0505 569 }
hlipka 0:3fa97f2c0505 570
hlipka 0:3fa97f2c0505 571 //=========================================================
hlipka 0:3fa97f2c0505 572