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
spxmlstag.cpp
00001 /* 00002 * Copyright 2007 Stephen Liu 00003 * LGPL, see http://code.google.com/p/spxml/ 00004 * For license terms, see the file COPYING along with this library. 00005 */ 00006 00007 #include <stdlib.h> 00008 #include <string.h> 00009 #include <ctype.h> 00010 #include <typeinfo> 00011 00012 #include "mstring.h" 00013 00014 #include "spxmlstag.hpp" 00015 #include "spxmlutils.hpp" 00016 #include "spxmlevent.hpp" 00017 #include "spxmlcodec.hpp" 00018 00019 SP_XmlSTagParser :: SP_XmlSTagParser( const char * encoding ) 00020 { 00021 mEvent = new SP_XmlStartTagEvent(); 00022 mReader = new SP_XmlSTagNameReader(); 00023 mStartTagName = new SP_XmlStringBuffer(); 00024 mError = NULL; 00025 00026 snprintf( mEncoding, sizeof( mEncoding ), "%s", encoding ); 00027 } 00028 00029 SP_XmlSTagParser :: ~SP_XmlSTagParser() 00030 { 00031 if( NULL != mEvent ) delete mEvent; 00032 mEvent = NULL; 00033 00034 if( NULL != mReader ) delete mReader; 00035 mReader = NULL; 00036 00037 if( NULL != mStartTagName ) delete mStartTagName; 00038 mStartTagName = NULL; 00039 00040 if( NULL != mError ) free( mError ); 00041 mError = NULL; 00042 } 00043 00044 const char * SP_XmlSTagParser :: getEncoding() 00045 { 00046 return mEncoding; 00047 } 00048 00049 SP_XmlStartTagEvent * SP_XmlSTagParser :: takeEvent() 00050 { 00051 SP_XmlStartTagEvent * event = mEvent; 00052 00053 mEvent = NULL; 00054 00055 return event; 00056 } 00057 00058 const char * SP_XmlSTagParser :: getError() 00059 { 00060 return mError; 00061 } 00062 00063 void SP_XmlSTagParser :: changeReader( SP_XmlSTagReader * reader ) 00064 { 00065 delete mReader; 00066 mReader = reader; 00067 } 00068 00069 void SP_XmlSTagParser :: setError( const char * error ) 00070 { 00071 if( NULL != error ) { 00072 if( NULL != mError ) free( mError ); 00073 mError = strdup( error ); 00074 } 00075 } 00076 00077 void SP_XmlSTagParser :: append( const char * source, int len ) 00078 { 00079 for( int i = 0; i < len && NULL == mError; i++ ) { 00080 mReader->read( this, source[ i ] ); 00081 } 00082 } 00083 00084 //========================================================= 00085 00086 SP_XmlSTagReader :: SP_XmlSTagReader() 00087 { 00088 mBuffer = new SP_XmlStringBuffer(); 00089 } 00090 00091 SP_XmlSTagReader :: ~SP_XmlSTagReader() 00092 { 00093 delete mBuffer; 00094 mBuffer = NULL; 00095 } 00096 00097 void SP_XmlSTagReader :: changeReader( SP_XmlSTagParser * parser, 00098 SP_XmlSTagReader * reader ) 00099 { 00100 //printf( "\nchange: %s\n", typeid( *reader ).name() ); 00101 parser->changeReader( reader ); 00102 } 00103 00104 void SP_XmlSTagReader :: setError( SP_XmlSTagParser * parser, const char * error ) 00105 { 00106 parser->setError( error ); 00107 } 00108 00109 void SP_XmlSTagReader :: setName( SP_XmlSTagParser * parser, const char * name ) 00110 { 00111 parser->mEvent->setName( name ); 00112 } 00113 00114 void SP_XmlSTagReader :: addAttrName( SP_XmlSTagParser * parser, const char * name ) 00115 { 00116 parser->mStartTagName->append( name ); 00117 } 00118 00119 void SP_XmlSTagReader :: addAttrValue( SP_XmlSTagParser * parser, const char * value ) 00120 { 00121 SP_XmlStringBuffer decodeValue; 00122 SP_XmlStringCodec::decode( parser->getEncoding(), value, &decodeValue ); 00123 00124 parser->mEvent->addAttr( parser->mStartTagName->getBuffer(), decodeValue.getBuffer() ); 00125 parser->mStartTagName->clean(); 00126 } 00127 00128 //========================================================= 00129 00130 SP_XmlSTagNameReader :: SP_XmlSTagNameReader() 00131 { 00132 } 00133 00134 SP_XmlSTagNameReader :: ~SP_XmlSTagNameReader() 00135 { 00136 } 00137 00138 void SP_XmlSTagNameReader :: read( SP_XmlSTagParser * parser, char c ) 00139 { 00140 if( isspace( c ) ) { 00141 if( 0 == mBuffer->getSize() ) { 00142 //leading space, skip 00143 } else { 00144 setName( parser, mBuffer->getBuffer() ); 00145 changeReader( parser, new SP_XmlSTagAttrNameReader() ); 00146 } 00147 } else { 00148 mBuffer->append( c ); 00149 } 00150 } 00151 00152 //========================================================= 00153 00154 SP_XmlSTagAttrNameReader :: SP_XmlSTagAttrNameReader() 00155 { 00156 mWait4Quot = 0; 00157 } 00158 00159 SP_XmlSTagAttrNameReader :: ~SP_XmlSTagAttrNameReader() 00160 { 00161 } 00162 00163 void SP_XmlSTagAttrNameReader :: read( SP_XmlSTagParser * parser, char c ) 00164 { 00165 if( 1 == mWait4Quot ) { 00166 if( '"' == c ) { 00167 addAttrName( parser, mBuffer->getBuffer() ); 00168 changeReader( parser, new SP_XmlSTagEqualMarkReader() ); 00169 } else { 00170 mBuffer->append( c ); 00171 } 00172 } else { 00173 if( isspace( c ) ) { 00174 if( 0 == mBuffer->getSize() ) { 00175 //leading space, skip 00176 } else { 00177 addAttrName( parser, mBuffer->getBuffer() ); 00178 changeReader( parser, new SP_XmlSTagEqualMarkReader() ); 00179 } 00180 } else { 00181 if( '"' == c && 0 == mBuffer->getSize() ) { 00182 mWait4Quot = 1; 00183 } else if( '=' == c ) { 00184 addAttrName( parser, mBuffer->getBuffer() ); 00185 SP_XmlSTagReader * reader = new SP_XmlSTagEqualMarkReader(); 00186 changeReader( parser, reader ); 00187 reader->read( parser, c ); 00188 } else { 00189 mBuffer->append( c ); 00190 } 00191 } 00192 } 00193 } 00194 00195 //========================================================= 00196 00197 SP_XmlSTagEqualMarkReader :: SP_XmlSTagEqualMarkReader() 00198 { 00199 } 00200 00201 SP_XmlSTagEqualMarkReader :: ~SP_XmlSTagEqualMarkReader() 00202 { 00203 } 00204 00205 void SP_XmlSTagEqualMarkReader :: read( SP_XmlSTagParser * parser, char c ) 00206 { 00207 if( isspace( c ) ) { 00208 //skip 00209 } else if( '=' == c ) { 00210 changeReader( parser, new SP_XmlSTagAttrValueReader() ); 00211 } else { 00212 addAttrValue( parser, "" ); 00213 SP_XmlSTagReader * reader = new SP_XmlSTagAttrNameReader(); 00214 changeReader( parser, reader ); 00215 reader->read( parser, c ); 00216 00217 //setError( parser, "miss '=' between name & value" ); 00218 } 00219 } 00220 00221 //========================================================= 00222 00223 SP_XmlSTagAttrValueReader :: SP_XmlSTagAttrValueReader() 00224 { 00225 mHasReadQuot = 0; 00226 } 00227 00228 SP_XmlSTagAttrValueReader :: ~SP_XmlSTagAttrValueReader() 00229 { 00230 } 00231 00232 void SP_XmlSTagAttrValueReader :: read( SP_XmlSTagParser * parser, char c ) 00233 { 00234 if( 0 == mHasReadQuot ) { 00235 if( isspace( c ) ) { 00236 //skip 00237 } else if( '"' == c ) { 00238 mHasReadQuot = 1; 00239 } else if( '\'' == c ) { 00240 mHasReadQuot = 2; 00241 } else { 00242 setError( parser, "unknown attribute value start" ); 00243 } 00244 } else { 00245 if( ( 1 == mHasReadQuot && '"' == c ) 00246 || ( 2 == mHasReadQuot && '\'' == c ) ) { 00247 addAttrValue( parser, mBuffer->getBuffer() ); 00248 changeReader( parser, new SP_XmlSTagAttrNameReader() ); 00249 } else { 00250 mBuffer->append( c ); 00251 } 00252 } 00253 } 00254
Generated on Sun Jul 17 2022 09:10:11 by 1.7.2