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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spxmlutils.cpp Source File

spxmlutils.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 <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <assert.h>
00011 #include <stdarg.h>
00012 #include <ctype.h>
00013 
00014 #include "spxmlutils.hpp"
00015 
00016 //=========================================================
00017 
00018 const int SP_XmlArrayList::LAST_INDEX = -1;
00019 
00020 SP_XmlArrayList :: SP_XmlArrayList( int initCount )
00021 {
00022     mMaxCount = initCount <= 0 ? 2 : initCount;
00023     mCount = 0;
00024     mFirst = (void**)malloc( sizeof( void * ) * mMaxCount );
00025 }
00026 
00027 SP_XmlArrayList :: ~SP_XmlArrayList()
00028 {
00029     free( mFirst );
00030     mFirst = NULL;
00031 }
00032 
00033 int SP_XmlArrayList :: getCount() const
00034 {
00035     return mCount;
00036 }
00037 
00038 int SP_XmlArrayList :: append( void * value )
00039 {
00040     if( NULL == value ) return -1;
00041 
00042     if( mCount >= mMaxCount ) {
00043         mMaxCount = ( mMaxCount * 3 ) / 2 + 1;
00044         mFirst = (void**)realloc( mFirst, sizeof( void * ) * mMaxCount );
00045         assert( NULL != mFirst );
00046         memset( mFirst + mCount, 0, ( mMaxCount - mCount ) * sizeof( void * ) );
00047     }
00048 
00049     mFirst[ mCount++ ] = value;
00050 
00051     return 0;
00052 }
00053 
00054 void * SP_XmlArrayList :: takeItem( int index )
00055 {
00056     void * ret = NULL;
00057 
00058     if( LAST_INDEX == index ) index = mCount -1;
00059     if( index < 0 || index >= mCount ) return ret;
00060 
00061     ret = mFirst[ index ];
00062 
00063     mCount--;
00064 
00065     if( ( index + 1 ) < mMaxCount ) {
00066         memmove( mFirst + index, mFirst + index + 1,
00067             ( mMaxCount - index - 1 ) * sizeof( void * ) );
00068     } else {
00069         mFirst[ index ] = NULL;
00070     }
00071 
00072     return ret;
00073 }
00074 
00075 const void * SP_XmlArrayList :: getItem( int index ) const
00076 {
00077     const void * ret = NULL;
00078 
00079     if( LAST_INDEX == index ) index = mCount - 1;
00080     if( index < 0 || index >= mCount ) return ret;
00081 
00082     ret = mFirst[ index ];
00083 
00084     return ret;
00085 }
00086 
00087 void SP_XmlArrayList :: sort( int ( * cmpFunc )( const void *, const void * ) )
00088 {
00089     for( int i = 0; i < mCount - 1; i++ ) {
00090         int min = i;
00091         for( int j = i + 1; j < mCount; j++ ) {
00092             if( cmpFunc( mFirst[ min ], mFirst[ j ] ) > 0 ) {
00093                 min = j;
00094             }
00095         }
00096 
00097         if( min != i ) {
00098             void * temp = mFirst[ i ];
00099             mFirst[ i ] = mFirst[ min ];
00100             mFirst[ min ] = temp;
00101         }
00102     }
00103 }
00104 
00105 //=========================================================
00106 
00107 SP_XmlQueue :: SP_XmlQueue()
00108 {
00109     mMaxCount = 8;
00110     mEntries = (void**)malloc( sizeof( void * ) * mMaxCount );
00111 
00112     mHead = mTail = mCount = 0;
00113 }
00114 
00115 SP_XmlQueue :: ~SP_XmlQueue()
00116 {
00117     free( mEntries );
00118     mEntries = NULL;
00119 }
00120 
00121 void SP_XmlQueue :: push( void * item )
00122 {
00123     if( mCount >= mMaxCount ) {
00124         mMaxCount = ( mMaxCount * 3 ) / 2 + 1;
00125         void ** newEntries = (void**)malloc( sizeof( void * ) * mMaxCount );
00126 
00127         unsigned int headLen = 0, tailLen = 0;
00128         if( mHead < mTail ) {
00129             headLen = mTail - mHead;
00130         } else {
00131             headLen = mCount - mTail;
00132             tailLen = mTail;
00133         }
00134 
00135         memcpy( newEntries, &( mEntries[ mHead ] ), sizeof( void * ) * headLen );
00136         if( tailLen ) {
00137             memcpy( &( newEntries[ headLen ] ), mEntries, sizeof( void * ) * tailLen );
00138         }
00139 
00140         mHead = 0;
00141         mTail = headLen + tailLen;
00142 
00143         free( mEntries );
00144         mEntries = newEntries;
00145     }
00146 
00147     mEntries[ mTail++ ] = item;
00148     mTail = mTail % mMaxCount;
00149     mCount++;
00150 }
00151 
00152 void * SP_XmlQueue :: pop()
00153 {
00154     void * ret = NULL;
00155 
00156     if( mCount > 0 ) {
00157         ret = mEntries[ mHead++ ];
00158         mHead = mHead % mMaxCount;
00159         mCount--;
00160     }
00161 
00162     return ret;
00163 }
00164 
00165 void * SP_XmlQueue :: top()
00166 {
00167     return mCount > 0 ? mEntries[ mHead ] : NULL;
00168 }
00169 
00170 //=========================================================
00171 
00172 SP_XmlStringBuffer :: SP_XmlStringBuffer()
00173 {
00174     init();
00175 }
00176 
00177 void SP_XmlStringBuffer :: init()
00178 {
00179     mSize = 0;
00180     mMaxSize = 8;
00181     mBuffer = (char*)malloc( mMaxSize );
00182     memset( mBuffer, 0, mMaxSize );
00183 }
00184 
00185 SP_XmlStringBuffer :: ~SP_XmlStringBuffer()
00186 {
00187     free( mBuffer );
00188 }
00189 
00190 int SP_XmlStringBuffer :: append( char c )
00191 {
00192     if( mSize >= ( mMaxSize - 1 ) ) {
00193         mMaxSize += ( mMaxSize * 3 ) / 2 + 1;
00194         mBuffer = (char*)realloc( mBuffer, mMaxSize );
00195         assert( NULL != mBuffer );
00196         memset( mBuffer + mSize, 0, mMaxSize - mSize );
00197     }
00198     mBuffer[ mSize++ ] = c;
00199 
00200     return 0;
00201 }
00202 
00203 int SP_XmlStringBuffer :: append( const char * value, int size )
00204 {
00205     if( NULL == value ) return -1;
00206 
00207     size = ( size <= 0 ? strlen( value ) : size );
00208     if( size <= 0 ) return -1;
00209 
00210     if( ( size + mSize ) > ( mMaxSize - 1 ) ) {
00211         mMaxSize += size;
00212         mBuffer = (char*)realloc( mBuffer, mMaxSize );
00213         assert( NULL != mBuffer );
00214         memset( mBuffer + mSize, 0, mMaxSize - mSize );
00215     }
00216 
00217     memcpy( mBuffer + mSize, value, size );
00218     mSize += size;
00219 
00220     return 0;
00221 }
00222 
00223 int SP_XmlStringBuffer :: getSize() const
00224 {
00225     return mSize;
00226 }
00227 
00228 const char * SP_XmlStringBuffer :: getBuffer() const
00229 {
00230     return mBuffer;
00231 }
00232 
00233 char * SP_XmlStringBuffer :: takeBuffer()
00234 {
00235     char * ret = mBuffer;
00236 
00237     mBuffer = NULL;
00238     init();
00239 
00240     return ret;
00241 }
00242 
00243 void SP_XmlStringBuffer :: clean()
00244 {
00245     memset( mBuffer, 0, mMaxSize );
00246     mSize = 0;
00247 }
00248