tinyxml2.h
Go to the documentation of this file.
00001 /*
00002 Original code by Lee Thomason (www.grinninglizard.com)
00003 
00004 This software is provided 'as-is', without any express or implied
00005 warranty. In no event will the authors be held liable for any
00006 damages arising from the use of this software.
00007 
00008 Permission is granted to anyone to use this software for any
00009 purpose, including commercial applications, and to alter it and
00010 redistribute it freely, subject to the following restrictions:
00011 
00012 1. The origin of this software must not be misrepresented; you must
00013 not claim that you wrote the original software. If you use this
00014 software in a product, an acknowledgment in the product documentation
00015 would be appreciated but is not required.
00016 
00017 2. Altered source versions must be plainly marked as such, and
00018 must not be misrepresented as being the original software.
00019 
00020 3. This notice may not be removed or altered from any source
00021 distribution.
00022 */
00023 
00024 #ifndef TINYXML2_INCLUDED
00025 #define TINYXML2_INCLUDED
00026 
00027 #if defined(ANDROID_NDK) || defined(__BORLANDC__)
00028 #   include <ctype.h>
00029 #   include <limits.h>
00030 #   include <stdio.h>
00031 #   include <stdlib.h>
00032 #   include <string.h>
00033 #   include <stdarg.h>
00034 #else
00035 #   include <cctype>
00036 #   include <climits>
00037 #   include <cstdio>
00038 #   include <cstdlib>
00039 #   include <cstring>
00040 #   include <cstdarg>
00041 #endif
00042 
00043 /*
00044    TODO: intern strings instead of allocation.
00045 */
00046 /*
00047         gcc:
00048         g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
00049 
00050     Formatting, Artistic Style:
00051         AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
00052 */
00053 
00054 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
00055 #   ifndef DEBUG
00056 #       define DEBUG
00057 #   endif
00058 #endif
00059 
00060 
00061 #if defined(DEBUG)
00062 #   if defined(_MSC_VER)
00063 #       define TIXMLASSERT( x )           if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
00064 #   elif defined (ANDROID_NDK)
00065 #       include <android/log.h>
00066 #       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
00067 #   else
00068 #       include <assert.h>
00069 #       define TIXMLASSERT                assert
00070 #   endif
00071 #   else
00072 #       define TIXMLASSERT( x )           {}
00073 #endif
00074 
00075 
00076 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00077 // Microsoft visual studio, version 2005 and higher.
00078 /*int _snprintf_s(
00079    char *buffer,
00080    size_t sizeOfBuffer,
00081    size_t count,
00082    const char *format [,
00083           argument] ...
00084 );*/
00085 inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
00086 {
00087     va_list va;
00088     va_start( va, format );
00089     int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
00090     va_end( va );
00091     return result;
00092 }
00093 #define TIXML_SSCANF   sscanf_s
00094 #else
00095 // GCC version 3 and higher
00096 //#warning( "Using sn* functions." )
00097 #define TIXML_SNPRINTF snprintf
00098 #define TIXML_SSCANF   sscanf
00099 #endif
00100 
00101 static const int TIXML2_MAJOR_VERSION = 1;
00102 static const int TIXML2_MINOR_VERSION = 0;
00103 static const int TIXML2_PATCH_VERSION = 9;
00104 
00105 namespace tinyxml2
00106 {
00107 class XMLDocument;
00108 class XMLElement;
00109 class XMLAttribute;
00110 class XMLComment;
00111 class XMLNode;
00112 class XMLText;
00113 class XMLDeclaration;
00114 class XMLUnknown;
00115 
00116 class XMLPrinter;
00117 
00118 /*
00119         A class that wraps strings. Normally stores the start and end
00120         pointers into the XML file itself, and will apply normalization
00121         and entity translation if actually read. Can also store (and memory
00122         manage) a traditional char[]
00123 */
00124 class StrPair
00125 {
00126 public:
00127     enum {
00128         NEEDS_ENTITY_PROCESSING                 = 0x01,
00129         NEEDS_NEWLINE_NORMALIZATION             = 0x02,
00130         COLLAPSE_WHITESPACE                             = 0x04,
00131 
00132         TEXT_ELEMENT                        = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00133         TEXT_ELEMENT_LEAVE_ENTITIES             = NEEDS_NEWLINE_NORMALIZATION,
00134         ATTRIBUTE_NAME                      = 0,
00135         ATTRIBUTE_VALUE                     = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00136         ATTRIBUTE_VALUE_LEAVE_ENTITIES  = NEEDS_NEWLINE_NORMALIZATION,
00137         COMMENT                                     = NEEDS_NEWLINE_NORMALIZATION
00138     };
00139 
00140     StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
00141     ~StrPair();
00142 
00143     void Set( char* start, char* end, int flags ) {
00144         Reset();
00145         _start  = start;
00146         _end    = end;
00147         _flags  = flags | NEEDS_FLUSH;
00148     }
00149 
00150     const char* GetStr();
00151 
00152     bool Empty() const {
00153         return _start == _end;
00154     }
00155 
00156     void SetInternedStr( const char* str ) {
00157         Reset();
00158         _start = const_cast<char*>(str);
00159     }
00160 
00161     void SetStr( const char* str, int flags=0 );
00162 
00163     char* ParseText( char* in, const char* endTag, int strFlags );
00164     char* ParseName( char* in );
00165 
00166 private:
00167     void Reset();
00168     void CollapseWhitespace();
00169 
00170     enum {
00171         NEEDS_FLUSH = 0x100,
00172         NEEDS_DELETE = 0x200
00173     };
00174 
00175     // After parsing, if *end != 0, it can be set to zero.
00176     int     _flags;
00177     char*   _start;
00178     char*   _end;
00179 };
00180 
00181 
00182 /*
00183         A dynamic array of Plain Old Data. Doesn't support constructors, etc.
00184         Has a small initial memory pool, so that low or no usage will not
00185         cause a call to new/delete
00186 */
00187 template <class T, int INIT>
00188 class DynArray
00189 {
00190 public:
00191     DynArray< T, INIT >() {
00192         _mem = _pool;
00193         _allocated = INIT;
00194         _size = 0;
00195     }
00196 
00197     ~DynArray() {
00198         if ( _mem != _pool ) {
00199             delete [] _mem;
00200         }
00201     }
00202 
00203     void Push( T t ) {
00204         EnsureCapacity( _size+1 );
00205         _mem[_size++] = t;
00206     }
00207 
00208     T* PushArr( int count ) {
00209         EnsureCapacity( _size+count );
00210         T* ret = &_mem[_size];
00211         _size += count;
00212         return ret;
00213     }
00214 
00215     T Pop() {
00216         return _mem[--_size];
00217     }
00218 
00219     void PopArr( int count ) {
00220         TIXMLASSERT( _size >= count );
00221         _size -= count;
00222     }
00223 
00224     bool Empty() const                                  {
00225         return _size == 0;
00226     }
00227 
00228     T& operator[](int i)                                {
00229         TIXMLASSERT( i>= 0 && i < _size );
00230         return _mem[i];
00231     }
00232 
00233     const T& operator[](int i) const    {
00234         TIXMLASSERT( i>= 0 && i < _size );
00235         return _mem[i];
00236     }
00237 
00238     int Size() const                                    {
00239         return _size;
00240     }
00241 
00242     int Capacity() const                                {
00243         return _allocated;
00244     }
00245 
00246     const T* Mem() const                                {
00247         return _mem;
00248     }
00249 
00250     T* Mem()                                                    {
00251         return _mem;
00252     }
00253 
00254 private:
00255     void EnsureCapacity( int cap ) {
00256         if ( cap > _allocated ) {
00257             int newAllocated = cap * 2;
00258             T* newMem = new T[newAllocated];
00259             memcpy( newMem, _mem, sizeof(T)*_size );    // warning: not using constructors, only works for PODs
00260             if ( _mem != _pool ) {
00261                 delete [] _mem;
00262             }
00263             _mem = newMem;
00264             _allocated = newAllocated;
00265         }
00266     }
00267 
00268     T*  _mem;
00269     T   _pool[INIT];
00270     int _allocated;             // objects allocated
00271     int _size;                  // number objects in use
00272 };
00273 
00274 
00275 /*
00276         Parent virtual class of a pool for fast allocation
00277         and deallocation of objects.
00278 */
00279 class MemPool
00280 {
00281 public:
00282     MemPool() {}
00283     virtual ~MemPool() {}
00284 
00285     virtual int ItemSize() const = 0;
00286     virtual void* Alloc() = 0;
00287     virtual void Free( void* ) = 0;
00288     virtual void SetTracked() = 0;
00289 };
00290 
00291 
00292 /*
00293         Template child class to create pools of the correct type.
00294 */
00295 template< int SIZE >
00296 class MemPoolT : public MemPool
00297 {
00298 public:
00299     MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)        {}
00300     ~MemPoolT() {
00301         // Delete the blocks.
00302         for( int i=0; i<_blockPtrs.Size(); ++i ) {
00303             delete _blockPtrs[i];
00304         }
00305     }
00306 
00307     virtual int ItemSize() const        {
00308         return SIZE;
00309     }
00310     int CurrentAllocs() const           {
00311         return _currentAllocs;
00312     }
00313 
00314     virtual void* Alloc() {
00315         if ( !_root ) {
00316             // Need a new block.
00317             Block* block = new Block();
00318             _blockPtrs.Push( block );
00319 
00320             for( int i=0; i<COUNT-1; ++i ) {
00321                 block->chunk[i].next = &block->chunk[i+1];
00322             }
00323             block->chunk[COUNT-1].next = 0;
00324             _root = block->chunk;
00325         }
00326         void* result = _root;
00327         _root = _root->next;
00328 
00329         ++_currentAllocs;
00330         if ( _currentAllocs > _maxAllocs ) {
00331             _maxAllocs = _currentAllocs;
00332         }
00333         _nAllocs++;
00334         _nUntracked++;
00335         return result;
00336     }
00337     virtual void Free( void* mem ) {
00338         if ( !mem ) {
00339             return;
00340         }
00341         --_currentAllocs;
00342         Chunk* chunk = (Chunk*)mem;
00343 #ifdef DEBUG
00344         memset( chunk, 0xfe, sizeof(Chunk) );
00345 #endif
00346         chunk->next = _root;
00347         _root = chunk;
00348     }
00349     void Trace( const char* name ) {
00350         printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
00351                 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
00352     }
00353 
00354     void SetTracked() {
00355         _nUntracked--;
00356     }
00357 
00358     int Untracked() const {
00359         return _nUntracked;
00360     }
00361 
00362     enum { COUNT = 1024/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
00363 
00364 private:
00365     union Chunk {
00366         Chunk*  next;
00367         char    mem[SIZE];
00368     };
00369     struct Block {
00370         Chunk chunk[COUNT];
00371     };
00372     DynArray< Block*, 10 > _blockPtrs;
00373     Chunk* _root;
00374 
00375     int _currentAllocs;
00376     int _nAllocs;
00377     int _maxAllocs;
00378     int _nUntracked;
00379 };
00380 
00381 
00382 
00402 class XMLVisitor
00403 {
00404 public:
00405     virtual ~XMLVisitor() {}
00406 
00408     virtual bool VisitEnter( const XMLDocument& /*doc*/ )                       {
00409         return true;
00410     }
00412     virtual bool VisitExit( const XMLDocument& /*doc*/ )                        {
00413         return true;
00414     }
00415 
00417     virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )    {
00418         return true;
00419     }
00421     virtual bool VisitExit( const XMLElement& /*element*/ )                     {
00422         return true;
00423     }
00424 
00426     virtual bool Visit( const XMLDeclaration& /*declaration*/ )         {
00427         return true;
00428     }
00430     virtual bool Visit( const XMLText& /*text*/ )                                       {
00431         return true;
00432     }
00434     virtual bool Visit( const XMLComment& /*comment*/ )                         {
00435         return true;
00436     }
00438     virtual bool Visit( const XMLUnknown& /*unknown*/ )                         {
00439         return true;
00440     }
00441 };
00442 
00443 
00444 /*
00445         Utility functionality.
00446 */
00447 class XMLUtil
00448 {
00449 public:
00450     // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
00451     // correct, but simple, and usually works.
00452     static const char* SkipWhiteSpace( const char* p )  {
00453         while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) {
00454             ++p;
00455         }
00456         return p;
00457     }
00458     static char* SkipWhiteSpace( char* p )                              {
00459         while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<unsigned char*>(p) ) )             {
00460             ++p;
00461         }
00462         return p;
00463     }
00464     static bool IsWhiteSpace( char p )                                  {
00465         return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
00466     }
00467 
00468     inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
00469         int n = 0;
00470         if ( p == q ) {
00471             return true;
00472         }
00473         while( *p && *q && *p == *q && n<nChar ) {
00474             ++p;
00475             ++q;
00476             ++n;
00477         }
00478         if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
00479             return true;
00480         }
00481         return false;
00482     }
00483     inline static int IsUTF8Continuation( const char p ) {
00484         return p & 0x80;
00485     }
00486     inline static int IsAlphaNum( unsigned char anyByte )       {
00487         return ( anyByte < 128 ) ? isalnum( anyByte ) : 1;
00488     }
00489     inline static int IsAlpha( unsigned char anyByte )          {
00490         return ( anyByte < 128 ) ? isalpha( anyByte ) : 1;
00491     }
00492 
00493     static const char* ReadBOM( const char* p, bool* hasBOM );
00494     // p is the starting location,
00495     // the UTF-8 value of the entity will be placed in value, and length filled in.
00496     static const char* GetCharacterRef( const char* p, char* value, int* length );
00497     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00498 
00499     // converts primitive types to strings
00500     static void ToStr( int v, char* buffer, int bufferSize );
00501     static void ToStr( unsigned v, char* buffer, int bufferSize );
00502     static void ToStr( bool v, char* buffer, int bufferSize );
00503     static void ToStr( float v, char* buffer, int bufferSize );
00504     static void ToStr( double v, char* buffer, int bufferSize );
00505 
00506     // converts strings to primitive types
00507     static bool ToInt( const char* str, int* value );
00508     static bool ToUnsigned( const char* str, unsigned* value );
00509     static bool ToBool( const char* str, bool* value );
00510     static bool ToFloat( const char* str, float* value );
00511     static bool ToDouble( const char* str, double* value );
00512 };
00513 
00514 
00540 class XMLNode
00541 {
00542     friend class XMLDocument;
00543     friend class XMLElement;
00544 public:
00545 
00547     const XMLDocument* GetDocument() const      {
00548         return _document;
00549     }
00551     XMLDocument* GetDocument()                          {
00552         return _document;
00553     }
00554 
00556     virtual XMLElement*         ToElement()             {
00557         return 0;
00558     }
00560     virtual XMLText*            ToText()                {
00561         return 0;
00562     }
00564     virtual XMLComment*         ToComment()             {
00565         return 0;
00566     }
00568     virtual XMLDocument*        ToDocument()    {
00569         return 0;
00570     }
00572     virtual XMLDeclaration*     ToDeclaration() {
00573         return 0;
00574     }
00576     virtual XMLUnknown*         ToUnknown()             {
00577         return 0;
00578     }
00579 
00580     virtual const XMLElement*           ToElement() const               {
00581         return 0;
00582     }
00583     virtual const XMLText*                      ToText() const                  {
00584         return 0;
00585     }
00586     virtual const XMLComment*           ToComment() const               {
00587         return 0;
00588     }
00589     virtual const XMLDocument*          ToDocument() const              {
00590         return 0;
00591     }
00592     virtual const XMLDeclaration*       ToDeclaration() const   {
00593         return 0;
00594     }
00595     virtual const XMLUnknown*           ToUnknown() const               {
00596         return 0;
00597     }
00598 
00608     const char* Value() const                   {
00609         return _value.GetStr();
00610     }
00611 
00615     void SetValue( const char* val, bool staticMem=false );
00616 
00618     const XMLNode*      Parent() const                  {
00619         return _parent;
00620     }
00621 
00622     XMLNode* Parent()                                           {
00623         return _parent;
00624     }
00625 
00627     bool NoChildren() const                                     {
00628         return !_firstChild;
00629     }
00630 
00632     const XMLNode*  FirstChild() const          {
00633         return _firstChild;
00634     }
00635 
00636     XMLNode*            FirstChild()                    {
00637         return _firstChild;
00638     }
00639 
00643     const XMLElement* FirstChildElement( const char* value=0 ) const;
00644 
00645     XMLElement* FirstChildElement( const char* value=0 )        {
00646         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( value ));
00647     }
00648 
00650     const XMLNode*      LastChild() const                                               {
00651         return _lastChild;
00652     }
00653 
00654     XMLNode*            LastChild()                                                             {
00655         return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() );
00656     }
00657 
00661     const XMLElement* LastChildElement( const char* value=0 ) const;
00662 
00663     XMLElement* LastChildElement( const char* value=0 ) {
00664         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(value) );
00665     }
00666 
00668     const XMLNode*      PreviousSibling() const                                 {
00669         return _prev;
00670     }
00671 
00672     XMLNode*    PreviousSibling()                                                       {
00673         return _prev;
00674     }
00675 
00677     const XMLElement*   PreviousSiblingElement( const char* value=0 ) const ;
00678 
00679     XMLElement* PreviousSiblingElement( const char* value=0 ) {
00680         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) );
00681     }
00682 
00684     const XMLNode*      NextSibling() const                                             {
00685         return _next;
00686     }
00687 
00688     XMLNode*    NextSibling()                                                           {
00689         return _next;
00690     }
00691 
00693     const XMLElement*   NextSiblingElement( const char* value=0 ) const;
00694 
00695     XMLElement* NextSiblingElement( const char* value=0 )       {
00696         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) );
00697     }
00698 
00702     XMLNode* InsertEndChild( XMLNode* addThis );
00703 
00704     XMLNode* LinkEndChild( XMLNode* addThis )   {
00705         return InsertEndChild( addThis );
00706     }
00710     XMLNode* InsertFirstChild( XMLNode* addThis );
00714     XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
00715 
00719     void DeleteChildren();
00720 
00724     void DeleteChild( XMLNode* node );
00725 
00735     virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
00736 
00743     virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
00744 
00767     virtual bool Accept( XMLVisitor* visitor ) const = 0;
00768 
00769     // internal
00770     virtual char* ParseDeep( char*, StrPair* );
00771 
00772 protected:
00773     XMLNode( XMLDocument* );
00774     virtual ~XMLNode();
00775     XMLNode( const XMLNode& );  // not supported
00776     XMLNode& operator=( const XMLNode& );       // not supported
00777 
00778     XMLDocument*        _document;
00779     XMLNode*            _parent;
00780     mutable StrPair     _value;
00781 
00782     XMLNode*            _firstChild;
00783     XMLNode*            _lastChild;
00784 
00785     XMLNode*            _prev;
00786     XMLNode*            _next;
00787 
00788 private:
00789     MemPool*            _memPool;
00790     void Unlink( XMLNode* child );
00791 };
00792 
00793 
00806 class XMLText : public XMLNode
00807 {
00808     friend class XMLBase;
00809     friend class XMLDocument;
00810 public:
00811     virtual bool Accept( XMLVisitor* visitor ) const;
00812 
00813     virtual XMLText* ToText()                   {
00814         return this;
00815     }
00816     virtual const XMLText* ToText() const       {
00817         return this;
00818     }
00819 
00821     void SetCData( bool isCData )                       {
00822         _isCData = isCData;
00823     }
00825     bool CData() const                                          {
00826         return _isCData;
00827     }
00828 
00829     char* ParseDeep( char*, StrPair* endTag );
00830     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00831     virtual bool ShallowEqual( const XMLNode* compare ) const;
00832 
00833 protected:
00834     XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false )     {}
00835     virtual ~XMLText()                                                                                          {}
00836     XMLText( const XMLText& );  // not supported
00837     XMLText& operator=( const XMLText& );       // not supported
00838 
00839 private:
00840     bool _isCData;
00841 };
00842 
00843 
00845 class XMLComment : public XMLNode
00846 {
00847     friend class XMLDocument;
00848 public:
00849     virtual XMLComment* ToComment()                                     {
00850         return this;
00851     }
00852     virtual const XMLComment* ToComment() const         {
00853         return this;
00854     }
00855 
00856     virtual bool Accept( XMLVisitor* visitor ) const;
00857 
00858     char* ParseDeep( char*, StrPair* endTag );
00859     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00860     virtual bool ShallowEqual( const XMLNode* compare ) const;
00861 
00862 protected:
00863     XMLComment( XMLDocument* doc );
00864     virtual ~XMLComment();
00865     XMLComment( const XMLComment& );    // not supported
00866     XMLComment& operator=( const XMLComment& ); // not supported
00867 
00868 private:
00869 };
00870 
00871 
00883 class XMLDeclaration : public XMLNode
00884 {
00885     friend class XMLDocument;
00886 public:
00887     virtual XMLDeclaration*     ToDeclaration()                                 {
00888         return this;
00889     }
00890     virtual const XMLDeclaration* ToDeclaration() const         {
00891         return this;
00892     }
00893 
00894     virtual bool Accept( XMLVisitor* visitor ) const;
00895 
00896     char* ParseDeep( char*, StrPair* endTag );
00897     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00898     virtual bool ShallowEqual( const XMLNode* compare ) const;
00899 
00900 protected:
00901     XMLDeclaration( XMLDocument* doc );
00902     virtual ~XMLDeclaration();
00903     XMLDeclaration( const XMLDeclaration& );    // not supported
00904     XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
00905 };
00906 
00907 
00915 class XMLUnknown : public XMLNode
00916 {
00917     friend class XMLDocument;
00918 public:
00919     virtual XMLUnknown* ToUnknown()                                     {
00920         return this;
00921     }
00922     virtual const XMLUnknown* ToUnknown() const         {
00923         return this;
00924     }
00925 
00926     virtual bool Accept( XMLVisitor* visitor ) const;
00927 
00928     char* ParseDeep( char*, StrPair* endTag );
00929     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00930     virtual bool ShallowEqual( const XMLNode* compare ) const;
00931 
00932 protected:
00933     XMLUnknown( XMLDocument* doc );
00934     virtual ~XMLUnknown();
00935     XMLUnknown( const XMLUnknown& );    // not supported
00936     XMLUnknown& operator=( const XMLUnknown& ); // not supported
00937 };
00938 
00939 
00940 enum XMLError {
00941     XML_NO_ERROR = 0,
00942     XML_SUCCESS = 0,
00943 
00944     XML_NO_ATTRIBUTE,
00945     XML_WRONG_ATTRIBUTE_TYPE,
00946 
00947     XML_ERROR_FILE_NOT_FOUND,
00948     XML_ERROR_FILE_COULD_NOT_BE_OPENED,
00949     XML_ERROR_FILE_READ_ERROR,
00950     XML_ERROR_ELEMENT_MISMATCH,
00951     XML_ERROR_PARSING_ELEMENT,
00952     XML_ERROR_PARSING_ATTRIBUTE,
00953     XML_ERROR_IDENTIFYING_TAG,
00954     XML_ERROR_PARSING_TEXT,
00955     XML_ERROR_PARSING_CDATA,
00956     XML_ERROR_PARSING_COMMENT,
00957     XML_ERROR_PARSING_DECLARATION,
00958     XML_ERROR_PARSING_UNKNOWN,
00959     XML_ERROR_EMPTY_DOCUMENT,
00960     XML_ERROR_MISMATCHED_ELEMENT,
00961     XML_ERROR_PARSING,
00962 
00963     XML_CAN_NOT_CONVERT_TEXT,
00964     XML_NO_TEXT_NODE
00965 };
00966 
00967 
00974 class XMLAttribute
00975 {
00976     friend class XMLElement;
00977 public:
00979     const char* Name() const {
00980         return _name.GetStr();
00981     }
00983     const char* Value() const {
00984         return _value.GetStr();
00985     }
00987     const XMLAttribute* Next() const {
00988         return _next;
00989     }
00990 
00995     int          IntValue() const                               {
00996         int i=0;
00997         QueryIntValue( &i );
00998         return i;
00999     }
01001     unsigned UnsignedValue() const                      {
01002         unsigned i=0;
01003         QueryUnsignedValue( &i );
01004         return i;
01005     }
01007     bool         BoolValue() const                              {
01008         bool b=false;
01009         QueryBoolValue( &b );
01010         return b;
01011     }
01013     double       DoubleValue() const                    {
01014         double d=0;
01015         QueryDoubleValue( &d );
01016         return d;
01017     }
01019     float        FloatValue() const                             {
01020         float f=0;
01021         QueryFloatValue( &f );
01022         return f;
01023     }
01024 
01029     XMLError QueryIntValue( int* value ) const;
01031     XMLError QueryUnsignedValue( unsigned int* value ) const;
01033     XMLError QueryBoolValue( bool* value ) const;
01035     XMLError QueryDoubleValue( double* value ) const;
01037     XMLError QueryFloatValue( float* value ) const;
01038 
01040     void SetAttribute( const char* value );
01042     void SetAttribute( int value );
01044     void SetAttribute( unsigned value );
01046     void SetAttribute( bool value );
01048     void SetAttribute( double value );
01050     void SetAttribute( float value );
01051 
01052 private:
01053     enum { BUF_SIZE = 200 };
01054 
01055     XMLAttribute() : _next( 0 ) {}
01056     virtual ~XMLAttribute()     {}
01057 
01058     XMLAttribute( const XMLAttribute& );        // not supported
01059     void operator=( const XMLAttribute& );      // not supported
01060     void SetName( const char* name );
01061 
01062     char* ParseDeep( char* p, bool processEntities );
01063 
01064     mutable StrPair _name;
01065     mutable StrPair _value;
01066     XMLAttribute*   _next;
01067     MemPool*        _memPool;
01068 };
01069 
01070 
01075 class XMLElement : public XMLNode
01076 {
01077     friend class XMLBase;
01078     friend class XMLDocument;
01079 public:
01081     const char* Name() const            {
01082         return Value();
01083     }
01085     void SetName( const char* str, bool staticMem=false )       {
01086         SetValue( str, staticMem );
01087     }
01088 
01089     virtual XMLElement* ToElement()                             {
01090         return this;
01091     }
01092     virtual const XMLElement* ToElement() const {
01093         return this;
01094     }
01095     virtual bool Accept( XMLVisitor* visitor ) const;
01096 
01120     const char* Attribute( const char* name, const char* value=0 ) const;
01121 
01127     int          IntAttribute( const char* name ) const         {
01128         int i=0;
01129         QueryIntAttribute( name, &i );
01130         return i;
01131     }
01133     unsigned UnsignedAttribute( const char* name ) const {
01134         unsigned i=0;
01135         QueryUnsignedAttribute( name, &i );
01136         return i;
01137     }
01139     bool         BoolAttribute( const char* name ) const        {
01140         bool b=false;
01141         QueryBoolAttribute( name, &b );
01142         return b;
01143     }
01145     double       DoubleAttribute( const char* name ) const      {
01146         double d=0;
01147         QueryDoubleAttribute( name, &d );
01148         return d;
01149     }
01151     float        FloatAttribute( const char* name ) const       {
01152         float f=0;
01153         QueryFloatAttribute( name, &f );
01154         return f;
01155     }
01156 
01170     XMLError QueryIntAttribute( const char* name, int* value ) const                            {
01171         const XMLAttribute* a = FindAttribute( name );
01172         if ( !a ) {
01173             return XML_NO_ATTRIBUTE;
01174         }
01175         return a->QueryIntValue( value );
01176     }
01178     XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const      {
01179         const XMLAttribute* a = FindAttribute( name );
01180         if ( !a ) {
01181             return XML_NO_ATTRIBUTE;
01182         }
01183         return a->QueryUnsignedValue( value );
01184     }
01186     XMLError QueryBoolAttribute( const char* name, bool* value ) const                          {
01187         const XMLAttribute* a = FindAttribute( name );
01188         if ( !a ) {
01189             return XML_NO_ATTRIBUTE;
01190         }
01191         return a->QueryBoolValue( value );
01192     }
01194     XMLError QueryDoubleAttribute( const char* name, double* value ) const                      {
01195         const XMLAttribute* a = FindAttribute( name );
01196         if ( !a ) {
01197             return XML_NO_ATTRIBUTE;
01198         }
01199         return a->QueryDoubleValue( value );
01200     }
01202     XMLError QueryFloatAttribute( const char* name, float* value ) const                        {
01203         const XMLAttribute* a = FindAttribute( name );
01204         if ( !a ) {
01205             return XML_NO_ATTRIBUTE;
01206         }
01207         return a->QueryFloatValue( value );
01208     }
01209 
01211     void SetAttribute( const char* name, const char* value )    {
01212         XMLAttribute* a = FindOrCreateAttribute( name );
01213         a->SetAttribute( value );
01214     }
01216     void SetAttribute( const char* name, int value )                    {
01217         XMLAttribute* a = FindOrCreateAttribute( name );
01218         a->SetAttribute( value );
01219     }
01221     void SetAttribute( const char* name, unsigned value )               {
01222         XMLAttribute* a = FindOrCreateAttribute( name );
01223         a->SetAttribute( value );
01224     }
01226     void SetAttribute( const char* name, bool value )                   {
01227         XMLAttribute* a = FindOrCreateAttribute( name );
01228         a->SetAttribute( value );
01229     }
01231     void SetAttribute( const char* name, double value )         {
01232         XMLAttribute* a = FindOrCreateAttribute( name );
01233         a->SetAttribute( value );
01234     }
01235 
01239     void DeleteAttribute( const char* name );
01240 
01242     const XMLAttribute* FirstAttribute() const {
01243         return _rootAttribute;
01244     }
01246     const XMLAttribute* FindAttribute( const char* name ) const;
01247 
01276     const char* GetText() const;
01277 
01304     XMLError QueryIntText( int* ival ) const;
01306     XMLError QueryUnsignedText( unsigned* uval ) const;
01308     XMLError QueryBoolText( bool* bval ) const;
01310     XMLError QueryDoubleText( double* dval ) const;
01312     XMLError QueryFloatText( float* fval ) const;
01313 
01314     // internal:
01315     enum {
01316         OPEN,           // <foo>
01317         CLOSED,         // <foo/>
01318         CLOSING         // </foo>
01319     };
01320     int ClosingType() const {
01321         return _closingType;
01322     }
01323     char* ParseDeep( char* p, StrPair* endTag );
01324     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01325     virtual bool ShallowEqual( const XMLNode* compare ) const;
01326 
01327 private:
01328     XMLElement( XMLDocument* doc );
01329     virtual ~XMLElement();
01330     XMLElement( const XMLElement& );    // not supported
01331     void operator=( const XMLElement& );        // not supported
01332 
01333     XMLAttribute* FindAttribute( const char* name );
01334     XMLAttribute* FindOrCreateAttribute( const char* name );
01335     //void LinkAttribute( XMLAttribute* attrib );
01336     char* ParseAttributes( char* p );
01337 
01338     int _closingType;
01339     // The attribute list is ordered; there is no 'lastAttribute'
01340     // because the list needs to be scanned for dupes before adding
01341     // a new attribute.
01342     XMLAttribute* _rootAttribute;
01343 };
01344 
01345 
01346 enum Whitespace {
01347     PRESERVE_WHITESPACE,
01348     COLLAPSE_WHITESPACE
01349 };
01350 
01351 
01357 class XMLDocument : public XMLNode
01358 {
01359     friend class XMLElement;
01360 public:
01362     XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
01363     ~XMLDocument();
01364 
01365     virtual XMLDocument* ToDocument()                           {
01366         return this;
01367     }
01368     virtual const XMLDocument* ToDocument() const       {
01369         return this;
01370     }
01371 
01382     XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
01383 
01389     XMLError LoadFile( const char* filename );
01390 
01398     XMLError LoadFile( FILE* );
01399 
01405     XMLError SaveFile( const char* filename, bool compact = false );
01406 
01414     XMLError SaveFile( FILE* fp, bool compact = false );
01415 
01416     bool ProcessEntities() const                {
01417         return _processEntities;
01418     }
01419     Whitespace WhitespaceMode() const   {
01420         return _whitespace;
01421     }
01422 
01426     bool HasBOM() const {
01427         return _writeBOM;
01428     }
01431     void SetBOM( bool useBOM ) {
01432         _writeBOM = useBOM;
01433     }
01434 
01438     XMLElement* RootElement()                           {
01439         return FirstChildElement();
01440     }
01441     const XMLElement* RootElement() const       {
01442         return FirstChildElement();
01443     }
01444 
01459     void Print( XMLPrinter* streamer=0 );
01460     virtual bool Accept( XMLVisitor* visitor ) const;
01461 
01467     XMLElement* NewElement( const char* name );
01473     XMLComment* NewComment( const char* comment );
01479     XMLText* NewText( const char* text );
01491     XMLDeclaration* NewDeclaration( const char* text=0 );
01497     XMLUnknown* NewUnknown( const char* text );
01498 
01503     void DeleteNode( XMLNode* node )    {
01504         node->_parent->DeleteChild( node );
01505     }
01506 
01507     void SetError( XMLError error, const char* str1, const char* str2 );
01508 
01510     bool Error() const {
01511         return _errorID != XML_NO_ERROR;
01512     }
01514     XMLError  ErrorID() const {
01515         return _errorID;
01516     }
01518     const char* GetErrorStr1() const {
01519         return _errorStr1;
01520     }
01522     const char* GetErrorStr2() const {
01523         return _errorStr2;
01524     }
01526     void PrintError() const;
01527 
01528     // internal
01529     char* Identify( char* p, XMLNode** node );
01530 
01531     virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const    {
01532         return 0;
01533     }
01534     virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const       {
01535         return false;
01536     }
01537 
01538 private:
01539     XMLDocument( const XMLDocument& );  // not supported
01540     void operator=( const XMLDocument& );       // not supported
01541     void InitDocument();
01542 
01543     bool        _writeBOM;
01544     bool        _processEntities;
01545     XMLError    _errorID;
01546     Whitespace  _whitespace;
01547     const char* _errorStr1;
01548     const char* _errorStr2;
01549     char*       _charBuffer;
01550 
01551     MemPoolT< sizeof(XMLElement) >       _elementPool;
01552     MemPoolT< sizeof(XMLAttribute) > _attributePool;
01553     MemPoolT< sizeof(XMLText) >          _textPool;
01554     MemPoolT< sizeof(XMLComment) >       _commentPool;
01555 };
01556 
01557 
01613 class XMLHandle
01614 {
01615 public:
01617     XMLHandle( XMLNode* node )                                                                                          {
01618         _node = node;
01619     }
01621     XMLHandle( XMLNode& node )                                                                                          {
01622         _node = &node;
01623     }
01625     XMLHandle( const XMLHandle& ref )                                                                           {
01626         _node = ref._node;
01627     }
01629     XMLHandle& operator=( const XMLHandle& ref )                                                        {
01630         _node = ref._node;
01631         return *this;
01632     }
01633 
01635     XMLHandle FirstChild()                                                                                                      {
01636         return XMLHandle( _node ? _node->FirstChild() : 0 );
01637     }
01639     XMLHandle FirstChildElement( const char* value=0 )                                          {
01640         return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 );
01641     }
01643     XMLHandle LastChild()                                                                                                       {
01644         return XMLHandle( _node ? _node->LastChild() : 0 );
01645     }
01647     XMLHandle LastChildElement( const char* _value=0 )                                          {
01648         return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 );
01649     }
01651     XMLHandle PreviousSibling()                                                                                         {
01652         return XMLHandle( _node ? _node->PreviousSibling() : 0 );
01653     }
01655     XMLHandle PreviousSiblingElement( const char* _value=0 )                            {
01656         return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );
01657     }
01659     XMLHandle NextSibling()                                                                                                     {
01660         return XMLHandle( _node ? _node->NextSibling() : 0 );
01661     }
01663     XMLHandle NextSiblingElement( const char* _value=0 )                                        {
01664         return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 );
01665     }
01666 
01668     XMLNode* ToNode()                                                   {
01669         return _node;
01670     }
01672     XMLElement* ToElement()                                     {
01673         return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 );
01674     }
01676     XMLText* ToText()                                                   {
01677         return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 );
01678     }
01680     XMLUnknown* ToUnknown()                                     {
01681         return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 );
01682     }
01684     XMLDeclaration* ToDeclaration()                     {
01685         return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 );
01686     }
01687 
01688 private:
01689     XMLNode* _node;
01690 };
01691 
01692 
01697 class XMLConstHandle
01698 {
01699 public:
01700     XMLConstHandle( const XMLNode* node )                                                                                       {
01701         _node = node;
01702     }
01703     XMLConstHandle( const XMLNode& node )                                                                                       {
01704         _node = &node;
01705     }
01706     XMLConstHandle( const XMLConstHandle& ref )                                                                         {
01707         _node = ref._node;
01708     }
01709 
01710     XMLConstHandle& operator=( const XMLConstHandle& ref )                                                      {
01711         _node = ref._node;
01712         return *this;
01713     }
01714 
01715     const XMLConstHandle FirstChild() const                                                                                     {
01716         return XMLConstHandle( _node ? _node->FirstChild() : 0 );
01717     }
01718     const XMLConstHandle FirstChildElement( const char* value=0 ) const                         {
01719         return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 );
01720     }
01721     const XMLConstHandle LastChild()    const                                                                           {
01722         return XMLConstHandle( _node ? _node->LastChild() : 0 );
01723     }
01724     const XMLConstHandle LastChildElement( const char* _value=0 ) const                         {
01725         return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 );
01726     }
01727     const XMLConstHandle PreviousSibling() const                                                                        {
01728         return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
01729     }
01730     const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const           {
01731         return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );
01732     }
01733     const XMLConstHandle NextSibling() const                                                                            {
01734         return XMLConstHandle( _node ? _node->NextSibling() : 0 );
01735     }
01736     const XMLConstHandle NextSiblingElement( const char* _value=0 ) const                       {
01737         return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 );
01738     }
01739 
01740 
01741     const XMLNode* ToNode() const                               {
01742         return _node;
01743     }
01744     const XMLElement* ToElement() const                 {
01745         return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 );
01746     }
01747     const XMLText* ToText() const                               {
01748         return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 );
01749     }
01750     const XMLUnknown* ToUnknown() const                 {
01751         return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 );
01752     }
01753     const XMLDeclaration* ToDeclaration() const {
01754         return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 );
01755     }
01756 
01757 private:
01758     const XMLNode* _node;
01759 };
01760 
01761 
01804 class XMLPrinter : public XMLVisitor
01805 {
01806 public:
01813     XMLPrinter( FILE* file=0, bool compact = false );
01814     ~XMLPrinter()       {}
01815 
01817     void PushHeader( bool writeBOM, bool writeDeclaration );
01821     void OpenElement( const char* name );
01823     void PushAttribute( const char* name, const char* value );
01824     void PushAttribute( const char* name, int value );
01825     void PushAttribute( const char* name, unsigned value );
01826     void PushAttribute( const char* name, bool value );
01827     void PushAttribute( const char* name, double value );
01829     void CloseElement();
01830 
01832     void PushText( const char* text, bool cdata=false );
01834     void PushText( int value );
01836     void PushText( unsigned value );
01838     void PushText( bool value );
01840     void PushText( float value );
01842     void PushText( double value );
01843 
01845     void PushComment( const char* comment );
01846 
01847     void PushDeclaration( const char* value );
01848     void PushUnknown( const char* value );
01849 
01850     virtual bool VisitEnter( const XMLDocument& /*doc*/ );
01851     virtual bool VisitExit( const XMLDocument& /*doc*/ )                        {
01852         return true;
01853     }
01854 
01855     virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
01856     virtual bool VisitExit( const XMLElement& element );
01857 
01858     virtual bool Visit( const XMLText& text );
01859     virtual bool Visit( const XMLComment& comment );
01860     virtual bool Visit( const XMLDeclaration& declaration );
01861     virtual bool Visit( const XMLUnknown& unknown );
01862 
01867     const char* CStr() const {
01868         return _buffer.Mem();
01869     }
01875     int CStrSize() const {
01876         return _buffer.Size();
01877     }
01878 
01879 private:
01880     void SealElement();
01881     void PrintSpace( int depth );
01882     void PrintString( const char*, bool restrictedEntitySet );  // prints out, after detecting entities.
01883     void Print( const char* format, ... );
01884 
01885     bool _elementJustOpened;
01886     bool _firstElement;
01887     FILE* _fp;
01888     int _depth;
01889     int _textDepth;
01890     bool _processEntities;
01891     bool _compactMode;
01892 
01893     enum {
01894         ENTITY_RANGE = 64,
01895         BUF_SIZE = 200
01896     };
01897     bool _entityFlag[ENTITY_RANGE];
01898     bool _restrictedEntityFlag[ENTITY_RANGE];
01899 
01900     DynArray< const char*, 10 > _stack;
01901     DynArray< char, 20 > _buffer;
01902 #ifdef _MSC_VER
01903     DynArray< char, 20 > _accumulator;
01904 #endif
01905 };
01906 
01907 
01908 }       // tinyxml2
01909 
01910 
01911 #endif // TINYXML2_INCLUDED


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:19