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 <stdlib.h>
hlipka 0:3fa97f2c0505 8 #include <string.h>
hlipka 0:3fa97f2c0505 9 #include <ctype.h>
hlipka 0:3fa97f2c0505 10 #include <typeinfo>
hlipka 0:3fa97f2c0505 11
hlipka 0:3fa97f2c0505 12 #include "mstring.h"
hlipka 0:3fa97f2c0505 13
hlipka 0:3fa97f2c0505 14 #include "spxmlstag.hpp"
hlipka 0:3fa97f2c0505 15 #include "spxmlutils.hpp"
hlipka 0:3fa97f2c0505 16 #include "spxmlevent.hpp"
hlipka 0:3fa97f2c0505 17 #include "spxmlcodec.hpp"
hlipka 0:3fa97f2c0505 18
hlipka 0:3fa97f2c0505 19 SP_XmlSTagParser :: SP_XmlSTagParser( const char * encoding )
hlipka 0:3fa97f2c0505 20 {
hlipka 0:3fa97f2c0505 21 mEvent = new SP_XmlStartTagEvent();
hlipka 0:3fa97f2c0505 22 mReader = new SP_XmlSTagNameReader();
hlipka 0:3fa97f2c0505 23 mStartTagName = new SP_XmlStringBuffer();
hlipka 0:3fa97f2c0505 24 mError = NULL;
hlipka 0:3fa97f2c0505 25
hlipka 0:3fa97f2c0505 26 snprintf( mEncoding, sizeof( mEncoding ), "%s", encoding );
hlipka 0:3fa97f2c0505 27 }
hlipka 0:3fa97f2c0505 28
hlipka 0:3fa97f2c0505 29 SP_XmlSTagParser :: ~SP_XmlSTagParser()
hlipka 0:3fa97f2c0505 30 {
hlipka 0:3fa97f2c0505 31 if( NULL != mEvent ) delete mEvent;
hlipka 0:3fa97f2c0505 32 mEvent = NULL;
hlipka 0:3fa97f2c0505 33
hlipka 0:3fa97f2c0505 34 if( NULL != mReader ) delete mReader;
hlipka 0:3fa97f2c0505 35 mReader = NULL;
hlipka 0:3fa97f2c0505 36
hlipka 0:3fa97f2c0505 37 if( NULL != mStartTagName ) delete mStartTagName;
hlipka 0:3fa97f2c0505 38 mStartTagName = NULL;
hlipka 0:3fa97f2c0505 39
hlipka 0:3fa97f2c0505 40 if( NULL != mError ) free( mError );
hlipka 0:3fa97f2c0505 41 mError = NULL;
hlipka 0:3fa97f2c0505 42 }
hlipka 0:3fa97f2c0505 43
hlipka 0:3fa97f2c0505 44 const char * SP_XmlSTagParser :: getEncoding()
hlipka 0:3fa97f2c0505 45 {
hlipka 0:3fa97f2c0505 46 return mEncoding;
hlipka 0:3fa97f2c0505 47 }
hlipka 0:3fa97f2c0505 48
hlipka 0:3fa97f2c0505 49 SP_XmlStartTagEvent * SP_XmlSTagParser :: takeEvent()
hlipka 0:3fa97f2c0505 50 {
hlipka 0:3fa97f2c0505 51 SP_XmlStartTagEvent * event = mEvent;
hlipka 0:3fa97f2c0505 52
hlipka 0:3fa97f2c0505 53 mEvent = NULL;
hlipka 0:3fa97f2c0505 54
hlipka 0:3fa97f2c0505 55 return event;
hlipka 0:3fa97f2c0505 56 }
hlipka 0:3fa97f2c0505 57
hlipka 0:3fa97f2c0505 58 const char * SP_XmlSTagParser :: getError()
hlipka 0:3fa97f2c0505 59 {
hlipka 0:3fa97f2c0505 60 return mError;
hlipka 0:3fa97f2c0505 61 }
hlipka 0:3fa97f2c0505 62
hlipka 0:3fa97f2c0505 63 void SP_XmlSTagParser :: changeReader( SP_XmlSTagReader * reader )
hlipka 0:3fa97f2c0505 64 {
hlipka 0:3fa97f2c0505 65 delete mReader;
hlipka 0:3fa97f2c0505 66 mReader = reader;
hlipka 0:3fa97f2c0505 67 }
hlipka 0:3fa97f2c0505 68
hlipka 0:3fa97f2c0505 69 void SP_XmlSTagParser :: setError( const char * error )
hlipka 0:3fa97f2c0505 70 {
hlipka 0:3fa97f2c0505 71 if( NULL != error ) {
hlipka 0:3fa97f2c0505 72 if( NULL != mError ) free( mError );
hlipka 0:3fa97f2c0505 73 mError = strdup( error );
hlipka 0:3fa97f2c0505 74 }
hlipka 0:3fa97f2c0505 75 }
hlipka 0:3fa97f2c0505 76
hlipka 0:3fa97f2c0505 77 void SP_XmlSTagParser :: append( const char * source, int len )
hlipka 0:3fa97f2c0505 78 {
hlipka 0:3fa97f2c0505 79 for( int i = 0; i < len && NULL == mError; i++ ) {
hlipka 0:3fa97f2c0505 80 mReader->read( this, source[ i ] );
hlipka 0:3fa97f2c0505 81 }
hlipka 0:3fa97f2c0505 82 }
hlipka 0:3fa97f2c0505 83
hlipka 0:3fa97f2c0505 84 //=========================================================
hlipka 0:3fa97f2c0505 85
hlipka 0:3fa97f2c0505 86 SP_XmlSTagReader :: SP_XmlSTagReader()
hlipka 0:3fa97f2c0505 87 {
hlipka 0:3fa97f2c0505 88 mBuffer = new SP_XmlStringBuffer();
hlipka 0:3fa97f2c0505 89 }
hlipka 0:3fa97f2c0505 90
hlipka 0:3fa97f2c0505 91 SP_XmlSTagReader :: ~SP_XmlSTagReader()
hlipka 0:3fa97f2c0505 92 {
hlipka 0:3fa97f2c0505 93 delete mBuffer;
hlipka 0:3fa97f2c0505 94 mBuffer = NULL;
hlipka 0:3fa97f2c0505 95 }
hlipka 0:3fa97f2c0505 96
hlipka 0:3fa97f2c0505 97 void SP_XmlSTagReader :: changeReader( SP_XmlSTagParser * parser,
hlipka 0:3fa97f2c0505 98 SP_XmlSTagReader * reader )
hlipka 0:3fa97f2c0505 99 {
hlipka 0:3fa97f2c0505 100 //printf( "\nchange: %s\n", typeid( *reader ).name() );
hlipka 0:3fa97f2c0505 101 parser->changeReader( reader );
hlipka 0:3fa97f2c0505 102 }
hlipka 0:3fa97f2c0505 103
hlipka 0:3fa97f2c0505 104 void SP_XmlSTagReader :: setError( SP_XmlSTagParser * parser, const char * error )
hlipka 0:3fa97f2c0505 105 {
hlipka 0:3fa97f2c0505 106 parser->setError( error );
hlipka 0:3fa97f2c0505 107 }
hlipka 0:3fa97f2c0505 108
hlipka 0:3fa97f2c0505 109 void SP_XmlSTagReader :: setName( SP_XmlSTagParser * parser, const char * name )
hlipka 0:3fa97f2c0505 110 {
hlipka 0:3fa97f2c0505 111 parser->mEvent->setName( name );
hlipka 0:3fa97f2c0505 112 }
hlipka 0:3fa97f2c0505 113
hlipka 0:3fa97f2c0505 114 void SP_XmlSTagReader :: addAttrName( SP_XmlSTagParser * parser, const char * name )
hlipka 0:3fa97f2c0505 115 {
hlipka 0:3fa97f2c0505 116 parser->mStartTagName->append( name );
hlipka 0:3fa97f2c0505 117 }
hlipka 0:3fa97f2c0505 118
hlipka 0:3fa97f2c0505 119 void SP_XmlSTagReader :: addAttrValue( SP_XmlSTagParser * parser, const char * value )
hlipka 0:3fa97f2c0505 120 {
hlipka 0:3fa97f2c0505 121 SP_XmlStringBuffer decodeValue;
hlipka 0:3fa97f2c0505 122 SP_XmlStringCodec::decode( parser->getEncoding(), value, &decodeValue );
hlipka 0:3fa97f2c0505 123
hlipka 0:3fa97f2c0505 124 parser->mEvent->addAttr( parser->mStartTagName->getBuffer(), decodeValue.getBuffer() );
hlipka 0:3fa97f2c0505 125 parser->mStartTagName->clean();
hlipka 0:3fa97f2c0505 126 }
hlipka 0:3fa97f2c0505 127
hlipka 0:3fa97f2c0505 128 //=========================================================
hlipka 0:3fa97f2c0505 129
hlipka 0:3fa97f2c0505 130 SP_XmlSTagNameReader :: SP_XmlSTagNameReader()
hlipka 0:3fa97f2c0505 131 {
hlipka 0:3fa97f2c0505 132 }
hlipka 0:3fa97f2c0505 133
hlipka 0:3fa97f2c0505 134 SP_XmlSTagNameReader :: ~SP_XmlSTagNameReader()
hlipka 0:3fa97f2c0505 135 {
hlipka 0:3fa97f2c0505 136 }
hlipka 0:3fa97f2c0505 137
hlipka 0:3fa97f2c0505 138 void SP_XmlSTagNameReader :: read( SP_XmlSTagParser * parser, char c )
hlipka 0:3fa97f2c0505 139 {
hlipka 0:3fa97f2c0505 140 if( isspace( c ) ) {
hlipka 0:3fa97f2c0505 141 if( 0 == mBuffer->getSize() ) {
hlipka 0:3fa97f2c0505 142 //leading space, skip
hlipka 0:3fa97f2c0505 143 } else {
hlipka 0:3fa97f2c0505 144 setName( parser, mBuffer->getBuffer() );
hlipka 0:3fa97f2c0505 145 changeReader( parser, new SP_XmlSTagAttrNameReader() );
hlipka 0:3fa97f2c0505 146 }
hlipka 0:3fa97f2c0505 147 } else {
hlipka 0:3fa97f2c0505 148 mBuffer->append( c );
hlipka 0:3fa97f2c0505 149 }
hlipka 0:3fa97f2c0505 150 }
hlipka 0:3fa97f2c0505 151
hlipka 0:3fa97f2c0505 152 //=========================================================
hlipka 0:3fa97f2c0505 153
hlipka 0:3fa97f2c0505 154 SP_XmlSTagAttrNameReader :: SP_XmlSTagAttrNameReader()
hlipka 0:3fa97f2c0505 155 {
hlipka 0:3fa97f2c0505 156 mWait4Quot = 0;
hlipka 0:3fa97f2c0505 157 }
hlipka 0:3fa97f2c0505 158
hlipka 0:3fa97f2c0505 159 SP_XmlSTagAttrNameReader :: ~SP_XmlSTagAttrNameReader()
hlipka 0:3fa97f2c0505 160 {
hlipka 0:3fa97f2c0505 161 }
hlipka 0:3fa97f2c0505 162
hlipka 0:3fa97f2c0505 163 void SP_XmlSTagAttrNameReader :: read( SP_XmlSTagParser * parser, char c )
hlipka 0:3fa97f2c0505 164 {
hlipka 0:3fa97f2c0505 165 if( 1 == mWait4Quot ) {
hlipka 0:3fa97f2c0505 166 if( '"' == c ) {
hlipka 0:3fa97f2c0505 167 addAttrName( parser, mBuffer->getBuffer() );
hlipka 0:3fa97f2c0505 168 changeReader( parser, new SP_XmlSTagEqualMarkReader() );
hlipka 0:3fa97f2c0505 169 } else {
hlipka 0:3fa97f2c0505 170 mBuffer->append( c );
hlipka 0:3fa97f2c0505 171 }
hlipka 0:3fa97f2c0505 172 } else {
hlipka 0:3fa97f2c0505 173 if( isspace( c ) ) {
hlipka 0:3fa97f2c0505 174 if( 0 == mBuffer->getSize() ) {
hlipka 0:3fa97f2c0505 175 //leading space, skip
hlipka 0:3fa97f2c0505 176 } else {
hlipka 0:3fa97f2c0505 177 addAttrName( parser, mBuffer->getBuffer() );
hlipka 0:3fa97f2c0505 178 changeReader( parser, new SP_XmlSTagEqualMarkReader() );
hlipka 0:3fa97f2c0505 179 }
hlipka 0:3fa97f2c0505 180 } else {
hlipka 0:3fa97f2c0505 181 if( '"' == c && 0 == mBuffer->getSize() ) {
hlipka 0:3fa97f2c0505 182 mWait4Quot = 1;
hlipka 0:3fa97f2c0505 183 } else if( '=' == c ) {
hlipka 0:3fa97f2c0505 184 addAttrName( parser, mBuffer->getBuffer() );
hlipka 0:3fa97f2c0505 185 SP_XmlSTagReader * reader = new SP_XmlSTagEqualMarkReader();
hlipka 0:3fa97f2c0505 186 changeReader( parser, reader );
hlipka 0:3fa97f2c0505 187 reader->read( parser, c );
hlipka 0:3fa97f2c0505 188 } else {
hlipka 0:3fa97f2c0505 189 mBuffer->append( c );
hlipka 0:3fa97f2c0505 190 }
hlipka 0:3fa97f2c0505 191 }
hlipka 0:3fa97f2c0505 192 }
hlipka 0:3fa97f2c0505 193 }
hlipka 0:3fa97f2c0505 194
hlipka 0:3fa97f2c0505 195 //=========================================================
hlipka 0:3fa97f2c0505 196
hlipka 0:3fa97f2c0505 197 SP_XmlSTagEqualMarkReader :: SP_XmlSTagEqualMarkReader()
hlipka 0:3fa97f2c0505 198 {
hlipka 0:3fa97f2c0505 199 }
hlipka 0:3fa97f2c0505 200
hlipka 0:3fa97f2c0505 201 SP_XmlSTagEqualMarkReader :: ~SP_XmlSTagEqualMarkReader()
hlipka 0:3fa97f2c0505 202 {
hlipka 0:3fa97f2c0505 203 }
hlipka 0:3fa97f2c0505 204
hlipka 0:3fa97f2c0505 205 void SP_XmlSTagEqualMarkReader :: read( SP_XmlSTagParser * parser, char c )
hlipka 0:3fa97f2c0505 206 {
hlipka 0:3fa97f2c0505 207 if( isspace( c ) ) {
hlipka 0:3fa97f2c0505 208 //skip
hlipka 0:3fa97f2c0505 209 } else if( '=' == c ) {
hlipka 0:3fa97f2c0505 210 changeReader( parser, new SP_XmlSTagAttrValueReader() );
hlipka 0:3fa97f2c0505 211 } else {
hlipka 0:3fa97f2c0505 212 addAttrValue( parser, "" );
hlipka 0:3fa97f2c0505 213 SP_XmlSTagReader * reader = new SP_XmlSTagAttrNameReader();
hlipka 0:3fa97f2c0505 214 changeReader( parser, reader );
hlipka 0:3fa97f2c0505 215 reader->read( parser, c );
hlipka 0:3fa97f2c0505 216
hlipka 0:3fa97f2c0505 217 //setError( parser, "miss '=' between name & value" );
hlipka 0:3fa97f2c0505 218 }
hlipka 0:3fa97f2c0505 219 }
hlipka 0:3fa97f2c0505 220
hlipka 0:3fa97f2c0505 221 //=========================================================
hlipka 0:3fa97f2c0505 222
hlipka 0:3fa97f2c0505 223 SP_XmlSTagAttrValueReader :: SP_XmlSTagAttrValueReader()
hlipka 0:3fa97f2c0505 224 {
hlipka 0:3fa97f2c0505 225 mHasReadQuot = 0;
hlipka 0:3fa97f2c0505 226 }
hlipka 0:3fa97f2c0505 227
hlipka 0:3fa97f2c0505 228 SP_XmlSTagAttrValueReader :: ~SP_XmlSTagAttrValueReader()
hlipka 0:3fa97f2c0505 229 {
hlipka 0:3fa97f2c0505 230 }
hlipka 0:3fa97f2c0505 231
hlipka 0:3fa97f2c0505 232 void SP_XmlSTagAttrValueReader :: read( SP_XmlSTagParser * parser, char c )
hlipka 0:3fa97f2c0505 233 {
hlipka 0:3fa97f2c0505 234 if( 0 == mHasReadQuot ) {
hlipka 0:3fa97f2c0505 235 if( isspace( c ) ) {
hlipka 0:3fa97f2c0505 236 //skip
hlipka 0:3fa97f2c0505 237 } else if( '"' == c ) {
hlipka 0:3fa97f2c0505 238 mHasReadQuot = 1;
hlipka 0:3fa97f2c0505 239 } else if( '\'' == c ) {
hlipka 0:3fa97f2c0505 240 mHasReadQuot = 2;
hlipka 0:3fa97f2c0505 241 } else {
hlipka 0:3fa97f2c0505 242 setError( parser, "unknown attribute value start" );
hlipka 0:3fa97f2c0505 243 }
hlipka 0:3fa97f2c0505 244 } else {
hlipka 0:3fa97f2c0505 245 if( ( 1 == mHasReadQuot && '"' == c )
hlipka 0:3fa97f2c0505 246 || ( 2 == mHasReadQuot && '\'' == c ) ) {
hlipka 0:3fa97f2c0505 247 addAttrValue( parser, mBuffer->getBuffer() );
hlipka 0:3fa97f2c0505 248 changeReader( parser, new SP_XmlSTagAttrNameReader() );
hlipka 0:3fa97f2c0505 249 } else {
hlipka 0:3fa97f2c0505 250 mBuffer->append( c );
hlipka 0:3fa97f2c0505 251 }
hlipka 0:3fa97f2c0505 252 }
hlipka 0:3fa97f2c0505 253 }
hlipka 0:3fa97f2c0505 254