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 <stdio.h>
hlipka 0:3fa97f2c0505 8 #include <stdlib.h>
hlipka 0:3fa97f2c0505 9 #include <string.h>
hlipka 0:3fa97f2c0505 10 #include <assert.h>
hlipka 0:3fa97f2c0505 11 #include <stdarg.h>
hlipka 0:3fa97f2c0505 12 #include <ctype.h>
hlipka 0:3fa97f2c0505 13
hlipka 0:3fa97f2c0505 14 #include "spxmlutils.hpp"
hlipka 0:3fa97f2c0505 15
hlipka 0:3fa97f2c0505 16 //=========================================================
hlipka 0:3fa97f2c0505 17
hlipka 0:3fa97f2c0505 18 const int SP_XmlArrayList::LAST_INDEX = -1;
hlipka 0:3fa97f2c0505 19
hlipka 0:3fa97f2c0505 20 SP_XmlArrayList :: SP_XmlArrayList( int initCount )
hlipka 0:3fa97f2c0505 21 {
hlipka 0:3fa97f2c0505 22 mMaxCount = initCount <= 0 ? 2 : initCount;
hlipka 0:3fa97f2c0505 23 mCount = 0;
hlipka 0:3fa97f2c0505 24 mFirst = (void**)malloc( sizeof( void * ) * mMaxCount );
hlipka 0:3fa97f2c0505 25 }
hlipka 0:3fa97f2c0505 26
hlipka 0:3fa97f2c0505 27 SP_XmlArrayList :: ~SP_XmlArrayList()
hlipka 0:3fa97f2c0505 28 {
hlipka 0:3fa97f2c0505 29 free( mFirst );
hlipka 0:3fa97f2c0505 30 mFirst = NULL;
hlipka 0:3fa97f2c0505 31 }
hlipka 0:3fa97f2c0505 32
hlipka 0:3fa97f2c0505 33 int SP_XmlArrayList :: getCount() const
hlipka 0:3fa97f2c0505 34 {
hlipka 0:3fa97f2c0505 35 return mCount;
hlipka 0:3fa97f2c0505 36 }
hlipka 0:3fa97f2c0505 37
hlipka 0:3fa97f2c0505 38 int SP_XmlArrayList :: append( void * value )
hlipka 0:3fa97f2c0505 39 {
hlipka 0:3fa97f2c0505 40 if( NULL == value ) return -1;
hlipka 0:3fa97f2c0505 41
hlipka 0:3fa97f2c0505 42 if( mCount >= mMaxCount ) {
hlipka 0:3fa97f2c0505 43 mMaxCount = ( mMaxCount * 3 ) / 2 + 1;
hlipka 0:3fa97f2c0505 44 mFirst = (void**)realloc( mFirst, sizeof( void * ) * mMaxCount );
hlipka 0:3fa97f2c0505 45 assert( NULL != mFirst );
hlipka 0:3fa97f2c0505 46 memset( mFirst + mCount, 0, ( mMaxCount - mCount ) * sizeof( void * ) );
hlipka 0:3fa97f2c0505 47 }
hlipka 0:3fa97f2c0505 48
hlipka 0:3fa97f2c0505 49 mFirst[ mCount++ ] = value;
hlipka 0:3fa97f2c0505 50
hlipka 0:3fa97f2c0505 51 return 0;
hlipka 0:3fa97f2c0505 52 }
hlipka 0:3fa97f2c0505 53
hlipka 0:3fa97f2c0505 54 void * SP_XmlArrayList :: takeItem( int index )
hlipka 0:3fa97f2c0505 55 {
hlipka 0:3fa97f2c0505 56 void * ret = NULL;
hlipka 0:3fa97f2c0505 57
hlipka 0:3fa97f2c0505 58 if( LAST_INDEX == index ) index = mCount -1;
hlipka 0:3fa97f2c0505 59 if( index < 0 || index >= mCount ) return ret;
hlipka 0:3fa97f2c0505 60
hlipka 0:3fa97f2c0505 61 ret = mFirst[ index ];
hlipka 0:3fa97f2c0505 62
hlipka 0:3fa97f2c0505 63 mCount--;
hlipka 0:3fa97f2c0505 64
hlipka 0:3fa97f2c0505 65 if( ( index + 1 ) < mMaxCount ) {
hlipka 0:3fa97f2c0505 66 memmove( mFirst + index, mFirst + index + 1,
hlipka 0:3fa97f2c0505 67 ( mMaxCount - index - 1 ) * sizeof( void * ) );
hlipka 0:3fa97f2c0505 68 } else {
hlipka 0:3fa97f2c0505 69 mFirst[ index ] = NULL;
hlipka 0:3fa97f2c0505 70 }
hlipka 0:3fa97f2c0505 71
hlipka 0:3fa97f2c0505 72 return ret;
hlipka 0:3fa97f2c0505 73 }
hlipka 0:3fa97f2c0505 74
hlipka 0:3fa97f2c0505 75 const void * SP_XmlArrayList :: getItem( int index ) const
hlipka 0:3fa97f2c0505 76 {
hlipka 0:3fa97f2c0505 77 const void * ret = NULL;
hlipka 0:3fa97f2c0505 78
hlipka 0:3fa97f2c0505 79 if( LAST_INDEX == index ) index = mCount - 1;
hlipka 0:3fa97f2c0505 80 if( index < 0 || index >= mCount ) return ret;
hlipka 0:3fa97f2c0505 81
hlipka 0:3fa97f2c0505 82 ret = mFirst[ index ];
hlipka 0:3fa97f2c0505 83
hlipka 0:3fa97f2c0505 84 return ret;
hlipka 0:3fa97f2c0505 85 }
hlipka 0:3fa97f2c0505 86
hlipka 0:3fa97f2c0505 87 void SP_XmlArrayList :: sort( int ( * cmpFunc )( const void *, const void * ) )
hlipka 0:3fa97f2c0505 88 {
hlipka 0:3fa97f2c0505 89 for( int i = 0; i < mCount - 1; i++ ) {
hlipka 0:3fa97f2c0505 90 int min = i;
hlipka 0:3fa97f2c0505 91 for( int j = i + 1; j < mCount; j++ ) {
hlipka 0:3fa97f2c0505 92 if( cmpFunc( mFirst[ min ], mFirst[ j ] ) > 0 ) {
hlipka 0:3fa97f2c0505 93 min = j;
hlipka 0:3fa97f2c0505 94 }
hlipka 0:3fa97f2c0505 95 }
hlipka 0:3fa97f2c0505 96
hlipka 0:3fa97f2c0505 97 if( min != i ) {
hlipka 0:3fa97f2c0505 98 void * temp = mFirst[ i ];
hlipka 0:3fa97f2c0505 99 mFirst[ i ] = mFirst[ min ];
hlipka 0:3fa97f2c0505 100 mFirst[ min ] = temp;
hlipka 0:3fa97f2c0505 101 }
hlipka 0:3fa97f2c0505 102 }
hlipka 0:3fa97f2c0505 103 }
hlipka 0:3fa97f2c0505 104
hlipka 0:3fa97f2c0505 105 //=========================================================
hlipka 0:3fa97f2c0505 106
hlipka 0:3fa97f2c0505 107 SP_XmlQueue :: SP_XmlQueue()
hlipka 0:3fa97f2c0505 108 {
hlipka 0:3fa97f2c0505 109 mMaxCount = 8;
hlipka 0:3fa97f2c0505 110 mEntries = (void**)malloc( sizeof( void * ) * mMaxCount );
hlipka 0:3fa97f2c0505 111
hlipka 0:3fa97f2c0505 112 mHead = mTail = mCount = 0;
hlipka 0:3fa97f2c0505 113 }
hlipka 0:3fa97f2c0505 114
hlipka 0:3fa97f2c0505 115 SP_XmlQueue :: ~SP_XmlQueue()
hlipka 0:3fa97f2c0505 116 {
hlipka 0:3fa97f2c0505 117 free( mEntries );
hlipka 0:3fa97f2c0505 118 mEntries = NULL;
hlipka 0:3fa97f2c0505 119 }
hlipka 0:3fa97f2c0505 120
hlipka 0:3fa97f2c0505 121 void SP_XmlQueue :: push( void * item )
hlipka 0:3fa97f2c0505 122 {
hlipka 0:3fa97f2c0505 123 if( mCount >= mMaxCount ) {
hlipka 0:3fa97f2c0505 124 mMaxCount = ( mMaxCount * 3 ) / 2 + 1;
hlipka 0:3fa97f2c0505 125 void ** newEntries = (void**)malloc( sizeof( void * ) * mMaxCount );
hlipka 0:3fa97f2c0505 126
hlipka 0:3fa97f2c0505 127 unsigned int headLen = 0, tailLen = 0;
hlipka 0:3fa97f2c0505 128 if( mHead < mTail ) {
hlipka 0:3fa97f2c0505 129 headLen = mTail - mHead;
hlipka 0:3fa97f2c0505 130 } else {
hlipka 0:3fa97f2c0505 131 headLen = mCount - mTail;
hlipka 0:3fa97f2c0505 132 tailLen = mTail;
hlipka 0:3fa97f2c0505 133 }
hlipka 0:3fa97f2c0505 134
hlipka 0:3fa97f2c0505 135 memcpy( newEntries, &( mEntries[ mHead ] ), sizeof( void * ) * headLen );
hlipka 0:3fa97f2c0505 136 if( tailLen ) {
hlipka 0:3fa97f2c0505 137 memcpy( &( newEntries[ headLen ] ), mEntries, sizeof( void * ) * tailLen );
hlipka 0:3fa97f2c0505 138 }
hlipka 0:3fa97f2c0505 139
hlipka 0:3fa97f2c0505 140 mHead = 0;
hlipka 0:3fa97f2c0505 141 mTail = headLen + tailLen;
hlipka 0:3fa97f2c0505 142
hlipka 0:3fa97f2c0505 143 free( mEntries );
hlipka 0:3fa97f2c0505 144 mEntries = newEntries;
hlipka 0:3fa97f2c0505 145 }
hlipka 0:3fa97f2c0505 146
hlipka 0:3fa97f2c0505 147 mEntries[ mTail++ ] = item;
hlipka 0:3fa97f2c0505 148 mTail = mTail % mMaxCount;
hlipka 0:3fa97f2c0505 149 mCount++;
hlipka 0:3fa97f2c0505 150 }
hlipka 0:3fa97f2c0505 151
hlipka 0:3fa97f2c0505 152 void * SP_XmlQueue :: pop()
hlipka 0:3fa97f2c0505 153 {
hlipka 0:3fa97f2c0505 154 void * ret = NULL;
hlipka 0:3fa97f2c0505 155
hlipka 0:3fa97f2c0505 156 if( mCount > 0 ) {
hlipka 0:3fa97f2c0505 157 ret = mEntries[ mHead++ ];
hlipka 0:3fa97f2c0505 158 mHead = mHead % mMaxCount;
hlipka 0:3fa97f2c0505 159 mCount--;
hlipka 0:3fa97f2c0505 160 }
hlipka 0:3fa97f2c0505 161
hlipka 0:3fa97f2c0505 162 return ret;
hlipka 0:3fa97f2c0505 163 }
hlipka 0:3fa97f2c0505 164
hlipka 0:3fa97f2c0505 165 void * SP_XmlQueue :: top()
hlipka 0:3fa97f2c0505 166 {
hlipka 0:3fa97f2c0505 167 return mCount > 0 ? mEntries[ mHead ] : NULL;
hlipka 0:3fa97f2c0505 168 }
hlipka 0:3fa97f2c0505 169
hlipka 0:3fa97f2c0505 170 //=========================================================
hlipka 0:3fa97f2c0505 171
hlipka 0:3fa97f2c0505 172 SP_XmlStringBuffer :: SP_XmlStringBuffer()
hlipka 0:3fa97f2c0505 173 {
hlipka 0:3fa97f2c0505 174 init();
hlipka 0:3fa97f2c0505 175 }
hlipka 0:3fa97f2c0505 176
hlipka 0:3fa97f2c0505 177 void SP_XmlStringBuffer :: init()
hlipka 0:3fa97f2c0505 178 {
hlipka 0:3fa97f2c0505 179 mSize = 0;
hlipka 0:3fa97f2c0505 180 mMaxSize = 8;
hlipka 0:3fa97f2c0505 181 mBuffer = (char*)malloc( mMaxSize );
hlipka 0:3fa97f2c0505 182 memset( mBuffer, 0, mMaxSize );
hlipka 0:3fa97f2c0505 183 }
hlipka 0:3fa97f2c0505 184
hlipka 0:3fa97f2c0505 185 SP_XmlStringBuffer :: ~SP_XmlStringBuffer()
hlipka 0:3fa97f2c0505 186 {
hlipka 0:3fa97f2c0505 187 free( mBuffer );
hlipka 0:3fa97f2c0505 188 }
hlipka 0:3fa97f2c0505 189
hlipka 0:3fa97f2c0505 190 int SP_XmlStringBuffer :: append( char c )
hlipka 0:3fa97f2c0505 191 {
hlipka 0:3fa97f2c0505 192 if( mSize >= ( mMaxSize - 1 ) ) {
hlipka 0:3fa97f2c0505 193 mMaxSize += ( mMaxSize * 3 ) / 2 + 1;
hlipka 0:3fa97f2c0505 194 mBuffer = (char*)realloc( mBuffer, mMaxSize );
hlipka 0:3fa97f2c0505 195 assert( NULL != mBuffer );
hlipka 0:3fa97f2c0505 196 memset( mBuffer + mSize, 0, mMaxSize - mSize );
hlipka 0:3fa97f2c0505 197 }
hlipka 0:3fa97f2c0505 198 mBuffer[ mSize++ ] = c;
hlipka 0:3fa97f2c0505 199
hlipka 0:3fa97f2c0505 200 return 0;
hlipka 0:3fa97f2c0505 201 }
hlipka 0:3fa97f2c0505 202
hlipka 0:3fa97f2c0505 203 int SP_XmlStringBuffer :: append( const char * value, int size )
hlipka 0:3fa97f2c0505 204 {
hlipka 0:3fa97f2c0505 205 if( NULL == value ) return -1;
hlipka 0:3fa97f2c0505 206
hlipka 0:3fa97f2c0505 207 size = ( size <= 0 ? strlen( value ) : size );
hlipka 0:3fa97f2c0505 208 if( size <= 0 ) return -1;
hlipka 0:3fa97f2c0505 209
hlipka 0:3fa97f2c0505 210 if( ( size + mSize ) > ( mMaxSize - 1 ) ) {
hlipka 0:3fa97f2c0505 211 mMaxSize += size;
hlipka 0:3fa97f2c0505 212 mBuffer = (char*)realloc( mBuffer, mMaxSize );
hlipka 0:3fa97f2c0505 213 assert( NULL != mBuffer );
hlipka 0:3fa97f2c0505 214 memset( mBuffer + mSize, 0, mMaxSize - mSize );
hlipka 0:3fa97f2c0505 215 }
hlipka 0:3fa97f2c0505 216
hlipka 0:3fa97f2c0505 217 memcpy( mBuffer + mSize, value, size );
hlipka 0:3fa97f2c0505 218 mSize += size;
hlipka 0:3fa97f2c0505 219
hlipka 0:3fa97f2c0505 220 return 0;
hlipka 0:3fa97f2c0505 221 }
hlipka 0:3fa97f2c0505 222
hlipka 0:3fa97f2c0505 223 int SP_XmlStringBuffer :: getSize() const
hlipka 0:3fa97f2c0505 224 {
hlipka 0:3fa97f2c0505 225 return mSize;
hlipka 0:3fa97f2c0505 226 }
hlipka 0:3fa97f2c0505 227
hlipka 0:3fa97f2c0505 228 const char * SP_XmlStringBuffer :: getBuffer() const
hlipka 0:3fa97f2c0505 229 {
hlipka 0:3fa97f2c0505 230 return mBuffer;
hlipka 0:3fa97f2c0505 231 }
hlipka 0:3fa97f2c0505 232
hlipka 0:3fa97f2c0505 233 char * SP_XmlStringBuffer :: takeBuffer()
hlipka 0:3fa97f2c0505 234 {
hlipka 0:3fa97f2c0505 235 char * ret = mBuffer;
hlipka 0:3fa97f2c0505 236
hlipka 0:3fa97f2c0505 237 mBuffer = NULL;
hlipka 0:3fa97f2c0505 238 init();
hlipka 0:3fa97f2c0505 239
hlipka 0:3fa97f2c0505 240 return ret;
hlipka 0:3fa97f2c0505 241 }
hlipka 0:3fa97f2c0505 242
hlipka 0:3fa97f2c0505 243 void SP_XmlStringBuffer :: clean()
hlipka 0:3fa97f2c0505 244 {
hlipka 0:3fa97f2c0505 245 memset( mBuffer, 0, mMaxSize );
hlipka 0:3fa97f2c0505 246 mSize = 0;
hlipka 0:3fa97f2c0505 247 }
hlipka 0:3fa97f2c0505 248