00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef TINYXML2_INCLUDED
00025 #define TINYXML2_INCLUDED
00026
00027 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
00028 # include <ctype.h>
00029 # include <limits.h>
00030 # include <stdio.h>
00031 # include <stdlib.h>
00032 # include <string.h>
00033 #else
00034 # include <cctype>
00035 # include <climits>
00036 # include <cstdio>
00037 # include <cstdlib>
00038 # include <cstring>
00039 #endif
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
00053 # ifndef DEBUG
00054 # define DEBUG
00055 # endif
00056 #endif
00057
00058 #ifdef _MSC_VER
00059 # pragma warning(push)
00060 # pragma warning(disable: 4251)
00061 #endif
00062
00063 #ifdef _WIN32
00064 # ifdef TINYXML2_EXPORT
00065 # define TINYXML2_LIB __declspec(dllexport)
00066 # elif defined(TINYXML2_IMPORT)
00067 # define TINYXML2_LIB __declspec(dllimport)
00068 # else
00069 # define TINYXML2_LIB
00070 # endif
00071 #else
00072 # define TINYXML2_LIB
00073 #endif
00074
00075
00076 #if defined(DEBUG)
00077 # if defined(_MSC_VER)
00078 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
00079 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
00080 # elif defined (ANDROID_NDK)
00081 # include <android/log.h>
00082 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
00083 # else
00084 # include <assert.h>
00085 # define TIXMLASSERT assert
00086 # endif
00087 # else
00088 # define TIXMLASSERT( x ) {}
00089 #endif
00090
00091
00092
00093
00094
00095 static const int TIXML2_MAJOR_VERSION = 3;
00096 static const int TIXML2_MINOR_VERSION = 0;
00097 static const int TIXML2_PATCH_VERSION = 0;
00098
00099 namespace tinyxml2
00100 {
00101 class XMLDocument;
00102 class XMLElement;
00103 class XMLAttribute;
00104 class XMLComment;
00105 class XMLText;
00106 class XMLDeclaration;
00107 class XMLUnknown;
00108 class XMLPrinter;
00109
00110
00111
00112
00113
00114
00115
00116 class StrPair
00117 {
00118 public:
00119 enum {
00120 NEEDS_ENTITY_PROCESSING = 0x01,
00121 NEEDS_NEWLINE_NORMALIZATION = 0x02,
00122 NEEDS_WHITESPACE_COLLAPSING = 0x04,
00123
00124 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00125 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
00126 ATTRIBUTE_NAME = 0,
00127 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00128 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
00129 COMMENT = NEEDS_NEWLINE_NORMALIZATION
00130 };
00131
00132 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
00133 ~StrPair();
00134
00135 void Set( char* start, char* end, int flags ) {
00136 Reset();
00137 _start = start;
00138 _end = end;
00139 _flags = flags | NEEDS_FLUSH;
00140 }
00141
00142 const char* GetStr();
00143
00144 bool Empty() const {
00145 return _start == _end;
00146 }
00147
00148 void SetInternedStr( const char* str ) {
00149 Reset();
00150 _start = const_cast<char*>(str);
00151 }
00152
00153 void SetStr( const char* str, int flags=0 );
00154
00155 char* ParseText( char* in, const char* endTag, int strFlags );
00156 char* ParseName( char* in );
00157
00158 void TransferTo( StrPair* other );
00159
00160 private:
00161 void Reset();
00162 void CollapseWhitespace();
00163
00164 enum {
00165 NEEDS_FLUSH = 0x100,
00166 NEEDS_DELETE = 0x200
00167 };
00168
00169
00170 int _flags;
00171 char* _start;
00172 char* _end;
00173
00174 StrPair( const StrPair& other );
00175 void operator=( StrPair& other );
00176 };
00177
00178
00179
00180
00181
00182
00183
00184 template <class T, int INITIAL_SIZE>
00185 class DynArray
00186 {
00187 public:
00188 DynArray() {
00189 _mem = _pool;
00190 _allocated = INITIAL_SIZE;
00191 _size = 0;
00192 }
00193
00194 ~DynArray() {
00195 if ( _mem != _pool ) {
00196 delete [] _mem;
00197 }
00198 }
00199
00200 void Clear() {
00201 _size = 0;
00202 }
00203
00204 void Push( T t ) {
00205 TIXMLASSERT( _size < INT_MAX );
00206 EnsureCapacity( _size+1 );
00207 _mem[_size++] = t;
00208 }
00209
00210 T* PushArr( int count ) {
00211 TIXMLASSERT( count >= 0 );
00212 TIXMLASSERT( _size <= INT_MAX - count );
00213 EnsureCapacity( _size+count );
00214 T* ret = &_mem[_size];
00215 _size += count;
00216 return ret;
00217 }
00218
00219 T Pop() {
00220 TIXMLASSERT( _size > 0 );
00221 return _mem[--_size];
00222 }
00223
00224 void PopArr( int count ) {
00225 TIXMLASSERT( _size >= count );
00226 _size -= count;
00227 }
00228
00229 bool Empty() const {
00230 return _size == 0;
00231 }
00232
00233 T& operator[](int i) {
00234 TIXMLASSERT( i>= 0 && i < _size );
00235 return _mem[i];
00236 }
00237
00238 const T& operator[](int i) const {
00239 TIXMLASSERT( i>= 0 && i < _size );
00240 return _mem[i];
00241 }
00242
00243 const T& PeekTop() const {
00244 TIXMLASSERT( _size > 0 );
00245 return _mem[ _size - 1];
00246 }
00247
00248 int Size() const {
00249 TIXMLASSERT( _size >= 0 );
00250 return _size;
00251 }
00252
00253 int Capacity() const {
00254 TIXMLASSERT( _allocated >= INITIAL_SIZE );
00255 return _allocated;
00256 }
00257
00258 const T* Mem() const {
00259 TIXMLASSERT( _mem );
00260 return _mem;
00261 }
00262
00263 T* Mem() {
00264 TIXMLASSERT( _mem );
00265 return _mem;
00266 }
00267
00268 private:
00269 DynArray( const DynArray& );
00270 void operator=( const DynArray& );
00271
00272 void EnsureCapacity( int cap ) {
00273 TIXMLASSERT( cap > 0 );
00274 if ( cap > _allocated ) {
00275 TIXMLASSERT( cap <= INT_MAX / 2 );
00276 int newAllocated = cap * 2;
00277 T* newMem = new T[newAllocated];
00278 memcpy( newMem, _mem, sizeof(T)*_size );
00279 if ( _mem != _pool ) {
00280 delete [] _mem;
00281 }
00282 _mem = newMem;
00283 _allocated = newAllocated;
00284 }
00285 }
00286
00287 T* _mem;
00288 T _pool[INITIAL_SIZE];
00289 int _allocated;
00290 int _size;
00291 };
00292
00293
00294
00295
00296
00297
00298 class MemPool
00299 {
00300 public:
00301 MemPool() {}
00302 virtual ~MemPool() {}
00303
00304 virtual int ItemSize() const = 0;
00305 virtual void* Alloc() = 0;
00306 virtual void Free( void* ) = 0;
00307 virtual void SetTracked() = 0;
00308 virtual void Clear() = 0;
00309 };
00310
00311
00312
00313
00314
00315 template< int SIZE >
00316 class MemPoolT : public MemPool
00317 {
00318 public:
00319 MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
00320 ~MemPoolT() {
00321 Clear();
00322 }
00323
00324 void Clear() {
00325
00326 while( !_blockPtrs.Empty()) {
00327 Block* b = _blockPtrs.Pop();
00328 delete b;
00329 }
00330 _root = 0;
00331 _currentAllocs = 0;
00332 _nAllocs = 0;
00333 _maxAllocs = 0;
00334 _nUntracked = 0;
00335 }
00336
00337 virtual int ItemSize() const {
00338 return SIZE;
00339 }
00340 int CurrentAllocs() const {
00341 return _currentAllocs;
00342 }
00343
00344 virtual void* Alloc() {
00345 if ( !_root ) {
00346
00347 Block* block = new Block();
00348 _blockPtrs.Push( block );
00349
00350 for( int i=0; i<COUNT-1; ++i ) {
00351 block->chunk[i].next = &block->chunk[i+1];
00352 }
00353 block->chunk[COUNT-1].next = 0;
00354 _root = block->chunk;
00355 }
00356 void* result = _root;
00357 _root = _root->next;
00358
00359 ++_currentAllocs;
00360 if ( _currentAllocs > _maxAllocs ) {
00361 _maxAllocs = _currentAllocs;
00362 }
00363 _nAllocs++;
00364 _nUntracked++;
00365 return result;
00366 }
00367
00368 virtual void Free( void* mem ) {
00369 if ( !mem ) {
00370 return;
00371 }
00372 --_currentAllocs;
00373 Chunk* chunk = static_cast<Chunk*>( mem );
00374 #ifdef DEBUG
00375 memset( chunk, 0xfe, sizeof(Chunk) );
00376 #endif
00377 chunk->next = _root;
00378 _root = chunk;
00379 }
00380 void Trace( const char* name ) {
00381 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
00382 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
00383 }
00384
00385 void SetTracked() {
00386 _nUntracked--;
00387 }
00388
00389 int Untracked() const {
00390 return _nUntracked;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 enum { COUNT = (4*1024)/SIZE };
00403
00404 private:
00405 MemPoolT( const MemPoolT& );
00406 void operator=( const MemPoolT& );
00407
00408 union Chunk {
00409 Chunk* next;
00410 char mem[SIZE];
00411 };
00412 struct Block {
00413 Chunk chunk[COUNT];
00414 };
00415 DynArray< Block*, 10 > _blockPtrs;
00416 Chunk* _root;
00417
00418 int _currentAllocs;
00419 int _nAllocs;
00420 int _maxAllocs;
00421 int _nUntracked;
00422 };
00423
00424
00425
00445 class TINYXML2_LIB XMLVisitor
00446 {
00447 public:
00448 virtual ~XMLVisitor() {}
00449
00451 virtual bool VisitEnter( const XMLDocument& ) {
00452 return true;
00453 }
00455 virtual bool VisitExit( const XMLDocument& ) {
00456 return true;
00457 }
00458
00460 virtual bool VisitEnter( const XMLElement& , const XMLAttribute* ) {
00461 return true;
00462 }
00464 virtual bool VisitExit( const XMLElement& ) {
00465 return true;
00466 }
00467
00469 virtual bool Visit( const XMLDeclaration& ) {
00470 return true;
00471 }
00473 virtual bool Visit( const XMLText& ) {
00474 return true;
00475 }
00477 virtual bool Visit( const XMLComment& ) {
00478 return true;
00479 }
00481 virtual bool Visit( const XMLUnknown& ) {
00482 return true;
00483 }
00484 };
00485
00486
00487 enum XMLError {
00488 XML_SUCCESS = 0,
00489 XML_NO_ERROR = 0,
00490 XML_NO_ATTRIBUTE,
00491 XML_WRONG_ATTRIBUTE_TYPE,
00492 XML_ERROR_FILE_NOT_FOUND,
00493 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
00494 XML_ERROR_FILE_READ_ERROR,
00495 XML_ERROR_ELEMENT_MISMATCH,
00496 XML_ERROR_PARSING_ELEMENT,
00497 XML_ERROR_PARSING_ATTRIBUTE,
00498 XML_ERROR_IDENTIFYING_TAG,
00499 XML_ERROR_PARSING_TEXT,
00500 XML_ERROR_PARSING_CDATA,
00501 XML_ERROR_PARSING_COMMENT,
00502 XML_ERROR_PARSING_DECLARATION,
00503 XML_ERROR_PARSING_UNKNOWN,
00504 XML_ERROR_EMPTY_DOCUMENT,
00505 XML_ERROR_MISMATCHED_ELEMENT,
00506 XML_ERROR_PARSING,
00507 XML_CAN_NOT_CONVERT_TEXT,
00508 XML_NO_TEXT_NODE,
00509
00510 XML_ERROR_COUNT
00511 };
00512
00513
00514
00515
00516
00517 class XMLUtil
00518 {
00519 public:
00520 static const char* SkipWhiteSpace( const char* p ) {
00521 TIXMLASSERT( p );
00522 while( IsWhiteSpace(*p) ) {
00523 ++p;
00524 }
00525 TIXMLASSERT( p );
00526 return p;
00527 }
00528 static char* SkipWhiteSpace( char* p ) {
00529 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
00530 }
00531
00532
00533
00534 static bool IsWhiteSpace( char p ) {
00535 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
00536 }
00537
00538 inline static bool IsNameStartChar( unsigned char ch ) {
00539 if ( ch >= 128 ) {
00540
00541 return true;
00542 }
00543 if ( isalpha( ch ) ) {
00544 return true;
00545 }
00546 return ch == ':' || ch == '_';
00547 }
00548
00549 inline static bool IsNameChar( unsigned char ch ) {
00550 return IsNameStartChar( ch )
00551 || isdigit( ch )
00552 || ch == '.'
00553 || ch == '-';
00554 }
00555
00556 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
00557 if ( p == q ) {
00558 return true;
00559 }
00560 int n = 0;
00561 while( *p && *q && *p == *q && n<nChar ) {
00562 ++p;
00563 ++q;
00564 ++n;
00565 }
00566 if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
00567 return true;
00568 }
00569 return false;
00570 }
00571
00572 inline static bool IsUTF8Continuation( char p ) {
00573 return ( p & 0x80 ) != 0;
00574 }
00575
00576 static const char* ReadBOM( const char* p, bool* hasBOM );
00577
00578
00579 static const char* GetCharacterRef( const char* p, char* value, int* length );
00580 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00581
00582
00583 static void ToStr( int v, char* buffer, int bufferSize );
00584 static void ToStr( unsigned v, char* buffer, int bufferSize );
00585 static void ToStr( bool v, char* buffer, int bufferSize );
00586 static void ToStr( float v, char* buffer, int bufferSize );
00587 static void ToStr( double v, char* buffer, int bufferSize );
00588
00589
00590 static bool ToInt( const char* str, int* value );
00591 static bool ToUnsigned( const char* str, unsigned* value );
00592 static bool ToBool( const char* str, bool* value );
00593 static bool ToFloat( const char* str, float* value );
00594 static bool ToDouble( const char* str, double* value );
00595 };
00596
00597
00623 class TINYXML2_LIB XMLNode
00624 {
00625 friend class XMLDocument;
00626 friend class XMLElement;
00627 public:
00628
00630 const XMLDocument* GetDocument() const {
00631 TIXMLASSERT( _document );
00632 return _document;
00633 }
00635 XMLDocument* GetDocument() {
00636 TIXMLASSERT( _document );
00637 return _document;
00638 }
00639
00641 virtual XMLElement* ToElement() {
00642 return 0;
00643 }
00645 virtual XMLText* ToText() {
00646 return 0;
00647 }
00649 virtual XMLComment* ToComment() {
00650 return 0;
00651 }
00653 virtual XMLDocument* ToDocument() {
00654 return 0;
00655 }
00657 virtual XMLDeclaration* ToDeclaration() {
00658 return 0;
00659 }
00661 virtual XMLUnknown* ToUnknown() {
00662 return 0;
00663 }
00664
00665 virtual const XMLElement* ToElement() const {
00666 return 0;
00667 }
00668 virtual const XMLText* ToText() const {
00669 return 0;
00670 }
00671 virtual const XMLComment* ToComment() const {
00672 return 0;
00673 }
00674 virtual const XMLDocument* ToDocument() const {
00675 return 0;
00676 }
00677 virtual const XMLDeclaration* ToDeclaration() const {
00678 return 0;
00679 }
00680 virtual const XMLUnknown* ToUnknown() const {
00681 return 0;
00682 }
00683
00693 const char* Value() const;
00694
00698 void SetValue( const char* val, bool staticMem=false );
00699
00701 const XMLNode* Parent() const {
00702 return _parent;
00703 }
00704
00705 XMLNode* Parent() {
00706 return _parent;
00707 }
00708
00710 bool NoChildren() const {
00711 return !_firstChild;
00712 }
00713
00715 const XMLNode* FirstChild() const {
00716 return _firstChild;
00717 }
00718
00719 XMLNode* FirstChild() {
00720 return _firstChild;
00721 }
00722
00726 const XMLElement* FirstChildElement( const char* name = 0 ) const;
00727
00728 XMLElement* FirstChildElement( const char* name = 0 ) {
00729 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
00730 }
00731
00733 const XMLNode* LastChild() const {
00734 return _lastChild;
00735 }
00736
00737 XMLNode* LastChild() {
00738 return _lastChild;
00739 }
00740
00744 const XMLElement* LastChildElement( const char* name = 0 ) const;
00745
00746 XMLElement* LastChildElement( const char* name = 0 ) {
00747 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
00748 }
00749
00751 const XMLNode* PreviousSibling() const {
00752 return _prev;
00753 }
00754
00755 XMLNode* PreviousSibling() {
00756 return _prev;
00757 }
00758
00760 const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
00761
00762 XMLElement* PreviousSiblingElement( const char* name = 0 ) {
00763 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
00764 }
00765
00767 const XMLNode* NextSibling() const {
00768 return _next;
00769 }
00770
00771 XMLNode* NextSibling() {
00772 return _next;
00773 }
00774
00776 const XMLElement* NextSiblingElement( const char* name = 0 ) const;
00777
00778 XMLElement* NextSiblingElement( const char* name = 0 ) {
00779 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
00780 }
00781
00789 XMLNode* InsertEndChild( XMLNode* addThis );
00790
00791 XMLNode* LinkEndChild( XMLNode* addThis ) {
00792 return InsertEndChild( addThis );
00793 }
00801 XMLNode* InsertFirstChild( XMLNode* addThis );
00810 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
00811
00815 void DeleteChildren();
00816
00820 void DeleteChild( XMLNode* node );
00821
00831 virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
00832
00839 virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
00840
00863 virtual bool Accept( XMLVisitor* visitor ) const = 0;
00864
00865 protected:
00866 XMLNode( XMLDocument* );
00867 virtual ~XMLNode();
00868
00869 virtual char* ParseDeep( char*, StrPair* );
00870
00871 XMLDocument* _document;
00872 XMLNode* _parent;
00873 mutable StrPair _value;
00874
00875 XMLNode* _firstChild;
00876 XMLNode* _lastChild;
00877
00878 XMLNode* _prev;
00879 XMLNode* _next;
00880
00881 private:
00882 MemPool* _memPool;
00883 void Unlink( XMLNode* child );
00884 static void DeleteNode( XMLNode* node );
00885 void InsertChildPreamble( XMLNode* insertThis ) const;
00886
00887 XMLNode( const XMLNode& );
00888 XMLNode& operator=( const XMLNode& );
00889 };
00890
00891
00904 class TINYXML2_LIB XMLText : public XMLNode
00905 {
00906 friend class XMLBase;
00907 friend class XMLDocument;
00908 public:
00909 virtual bool Accept( XMLVisitor* visitor ) const;
00910
00911 virtual XMLText* ToText() {
00912 return this;
00913 }
00914 virtual const XMLText* ToText() const {
00915 return this;
00916 }
00917
00919 void SetCData( bool isCData ) {
00920 _isCData = isCData;
00921 }
00923 bool CData() const {
00924 return _isCData;
00925 }
00926
00927 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00928 virtual bool ShallowEqual( const XMLNode* compare ) const;
00929
00930 protected:
00931 XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
00932 virtual ~XMLText() {}
00933
00934 char* ParseDeep( char*, StrPair* endTag );
00935
00936 private:
00937 bool _isCData;
00938
00939 XMLText( const XMLText& );
00940 XMLText& operator=( const XMLText& );
00941 };
00942
00943
00945 class TINYXML2_LIB XMLComment : public XMLNode
00946 {
00947 friend class XMLDocument;
00948 public:
00949 virtual XMLComment* ToComment() {
00950 return this;
00951 }
00952 virtual const XMLComment* ToComment() const {
00953 return this;
00954 }
00955
00956 virtual bool Accept( XMLVisitor* visitor ) const;
00957
00958 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00959 virtual bool ShallowEqual( const XMLNode* compare ) const;
00960
00961 protected:
00962 XMLComment( XMLDocument* doc );
00963 virtual ~XMLComment();
00964
00965 char* ParseDeep( char*, StrPair* endTag );
00966
00967 private:
00968 XMLComment( const XMLComment& );
00969 XMLComment& operator=( const XMLComment& );
00970 };
00971
00972
00984 class TINYXML2_LIB XMLDeclaration : public XMLNode
00985 {
00986 friend class XMLDocument;
00987 public:
00988 virtual XMLDeclaration* ToDeclaration() {
00989 return this;
00990 }
00991 virtual const XMLDeclaration* ToDeclaration() const {
00992 return this;
00993 }
00994
00995 virtual bool Accept( XMLVisitor* visitor ) const;
00996
00997 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
00998 virtual bool ShallowEqual( const XMLNode* compare ) const;
00999
01000 protected:
01001 XMLDeclaration( XMLDocument* doc );
01002 virtual ~XMLDeclaration();
01003
01004 char* ParseDeep( char*, StrPair* endTag );
01005
01006 private:
01007 XMLDeclaration( const XMLDeclaration& );
01008 XMLDeclaration& operator=( const XMLDeclaration& );
01009 };
01010
01011
01019 class TINYXML2_LIB XMLUnknown : public XMLNode
01020 {
01021 friend class XMLDocument;
01022 public:
01023 virtual XMLUnknown* ToUnknown() {
01024 return this;
01025 }
01026 virtual const XMLUnknown* ToUnknown() const {
01027 return this;
01028 }
01029
01030 virtual bool Accept( XMLVisitor* visitor ) const;
01031
01032 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01033 virtual bool ShallowEqual( const XMLNode* compare ) const;
01034
01035 protected:
01036 XMLUnknown( XMLDocument* doc );
01037 virtual ~XMLUnknown();
01038
01039 char* ParseDeep( char*, StrPair* endTag );
01040
01041 private:
01042 XMLUnknown( const XMLUnknown& );
01043 XMLUnknown& operator=( const XMLUnknown& );
01044 };
01045
01046
01047
01054 class TINYXML2_LIB XMLAttribute
01055 {
01056 friend class XMLElement;
01057 public:
01059 const char* Name() const;
01060
01062 const char* Value() const;
01063
01065 const XMLAttribute* Next() const {
01066 return _next;
01067 }
01068
01073 int IntValue() const {
01074 int i=0;
01075 QueryIntValue( &i );
01076 return i;
01077 }
01079 unsigned UnsignedValue() const {
01080 unsigned i=0;
01081 QueryUnsignedValue( &i );
01082 return i;
01083 }
01085 bool BoolValue() const {
01086 bool b=false;
01087 QueryBoolValue( &b );
01088 return b;
01089 }
01091 double DoubleValue() const {
01092 double d=0;
01093 QueryDoubleValue( &d );
01094 return d;
01095 }
01097 float FloatValue() const {
01098 float f=0;
01099 QueryFloatValue( &f );
01100 return f;
01101 }
01102
01107 XMLError QueryIntValue( int* value ) const;
01109 XMLError QueryUnsignedValue( unsigned int* value ) const;
01111 XMLError QueryBoolValue( bool* value ) const;
01113 XMLError QueryDoubleValue( double* value ) const;
01115 XMLError QueryFloatValue( float* value ) const;
01116
01118 void SetAttribute( const char* value );
01120 void SetAttribute( int value );
01122 void SetAttribute( unsigned value );
01124 void SetAttribute( bool value );
01126 void SetAttribute( double value );
01128 void SetAttribute( float value );
01129
01130 private:
01131 enum { BUF_SIZE = 200 };
01132
01133 XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
01134 virtual ~XMLAttribute() {}
01135
01136 XMLAttribute( const XMLAttribute& );
01137 void operator=( const XMLAttribute& );
01138 void SetName( const char* name );
01139
01140 char* ParseDeep( char* p, bool processEntities );
01141
01142 mutable StrPair _name;
01143 mutable StrPair _value;
01144 XMLAttribute* _next;
01145 MemPool* _memPool;
01146 };
01147
01148
01153 class TINYXML2_LIB XMLElement : public XMLNode
01154 {
01155 friend class XMLBase;
01156 friend class XMLDocument;
01157 public:
01159 const char* Name() const {
01160 return Value();
01161 }
01163 void SetName( const char* str, bool staticMem=false ) {
01164 SetValue( str, staticMem );
01165 }
01166
01167 virtual XMLElement* ToElement() {
01168 return this;
01169 }
01170 virtual const XMLElement* ToElement() const {
01171 return this;
01172 }
01173 virtual bool Accept( XMLVisitor* visitor ) const;
01174
01198 const char* Attribute( const char* name, const char* value=0 ) const;
01199
01205 int IntAttribute( const char* name ) const {
01206 int i=0;
01207 QueryIntAttribute( name, &i );
01208 return i;
01209 }
01211 unsigned UnsignedAttribute( const char* name ) const {
01212 unsigned i=0;
01213 QueryUnsignedAttribute( name, &i );
01214 return i;
01215 }
01217 bool BoolAttribute( const char* name ) const {
01218 bool b=false;
01219 QueryBoolAttribute( name, &b );
01220 return b;
01221 }
01223 double DoubleAttribute( const char* name ) const {
01224 double d=0;
01225 QueryDoubleAttribute( name, &d );
01226 return d;
01227 }
01229 float FloatAttribute( const char* name ) const {
01230 float f=0;
01231 QueryFloatAttribute( name, &f );
01232 return f;
01233 }
01234
01248 XMLError QueryIntAttribute( const char* name, int* value ) const {
01249 const XMLAttribute* a = FindAttribute( name );
01250 if ( !a ) {
01251 return XML_NO_ATTRIBUTE;
01252 }
01253 return a->QueryIntValue( value );
01254 }
01256 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
01257 const XMLAttribute* a = FindAttribute( name );
01258 if ( !a ) {
01259 return XML_NO_ATTRIBUTE;
01260 }
01261 return a->QueryUnsignedValue( value );
01262 }
01264 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
01265 const XMLAttribute* a = FindAttribute( name );
01266 if ( !a ) {
01267 return XML_NO_ATTRIBUTE;
01268 }
01269 return a->QueryBoolValue( value );
01270 }
01272 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
01273 const XMLAttribute* a = FindAttribute( name );
01274 if ( !a ) {
01275 return XML_NO_ATTRIBUTE;
01276 }
01277 return a->QueryDoubleValue( value );
01278 }
01280 XMLError QueryFloatAttribute( const char* name, float* value ) const {
01281 const XMLAttribute* a = FindAttribute( name );
01282 if ( !a ) {
01283 return XML_NO_ATTRIBUTE;
01284 }
01285 return a->QueryFloatValue( value );
01286 }
01287
01288
01306 int QueryAttribute( const char* name, int* value ) const {
01307 return QueryIntAttribute( name, value );
01308 }
01309
01310 int QueryAttribute( const char* name, unsigned int* value ) const {
01311 return QueryUnsignedAttribute( name, value );
01312 }
01313
01314 int QueryAttribute( const char* name, bool* value ) const {
01315 return QueryBoolAttribute( name, value );
01316 }
01317
01318 int QueryAttribute( const char* name, double* value ) const {
01319 return QueryDoubleAttribute( name, value );
01320 }
01321
01322 int QueryAttribute( const char* name, float* value ) const {
01323 return QueryFloatAttribute( name, value );
01324 }
01325
01327 void SetAttribute( const char* name, const char* value ) {
01328 XMLAttribute* a = FindOrCreateAttribute( name );
01329 a->SetAttribute( value );
01330 }
01332 void SetAttribute( const char* name, int value ) {
01333 XMLAttribute* a = FindOrCreateAttribute( name );
01334 a->SetAttribute( value );
01335 }
01337 void SetAttribute( const char* name, unsigned value ) {
01338 XMLAttribute* a = FindOrCreateAttribute( name );
01339 a->SetAttribute( value );
01340 }
01342 void SetAttribute( const char* name, bool value ) {
01343 XMLAttribute* a = FindOrCreateAttribute( name );
01344 a->SetAttribute( value );
01345 }
01347 void SetAttribute( const char* name, double value ) {
01348 XMLAttribute* a = FindOrCreateAttribute( name );
01349 a->SetAttribute( value );
01350 }
01352 void SetAttribute( const char* name, float value ) {
01353 XMLAttribute* a = FindOrCreateAttribute( name );
01354 a->SetAttribute( value );
01355 }
01356
01360 void DeleteAttribute( const char* name );
01361
01363 const XMLAttribute* FirstAttribute() const {
01364 return _rootAttribute;
01365 }
01367 const XMLAttribute* FindAttribute( const char* name ) const;
01368
01397 const char* GetText() const;
01398
01433 void SetText( const char* inText );
01435 void SetText( int value );
01437 void SetText( unsigned value );
01439 void SetText( bool value );
01441 void SetText( double value );
01443 void SetText( float value );
01444
01471 XMLError QueryIntText( int* ival ) const;
01473 XMLError QueryUnsignedText( unsigned* uval ) const;
01475 XMLError QueryBoolText( bool* bval ) const;
01477 XMLError QueryDoubleText( double* dval ) const;
01479 XMLError QueryFloatText( float* fval ) const;
01480
01481
01482 enum {
01483 OPEN,
01484 CLOSED,
01485 CLOSING
01486 };
01487 int ClosingType() const {
01488 return _closingType;
01489 }
01490 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01491 virtual bool ShallowEqual( const XMLNode* compare ) const;
01492
01493 protected:
01494 char* ParseDeep( char* p, StrPair* endTag );
01495
01496 private:
01497 XMLElement( XMLDocument* doc );
01498 virtual ~XMLElement();
01499 XMLElement( const XMLElement& );
01500 void operator=( const XMLElement& );
01501
01502 XMLAttribute* FindAttribute( const char* name ) {
01503 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
01504 }
01505 XMLAttribute* FindOrCreateAttribute( const char* name );
01506
01507 char* ParseAttributes( char* p );
01508 static void DeleteAttribute( XMLAttribute* attribute );
01509
01510 enum { BUF_SIZE = 200 };
01511 int _closingType;
01512
01513
01514
01515 XMLAttribute* _rootAttribute;
01516 };
01517
01518
01519 enum Whitespace {
01520 PRESERVE_WHITESPACE,
01521 COLLAPSE_WHITESPACE
01522 };
01523
01524
01530 class TINYXML2_LIB XMLDocument : public XMLNode
01531 {
01532 friend class XMLElement;
01533 public:
01535 XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
01536 ~XMLDocument();
01537
01538 virtual XMLDocument* ToDocument() {
01539 TIXMLASSERT( this == _document );
01540 return this;
01541 }
01542 virtual const XMLDocument* ToDocument() const {
01543 TIXMLASSERT( this == _document );
01544 return this;
01545 }
01546
01557 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
01558
01564 XMLError LoadFile( const char* filename );
01565
01577 XMLError LoadFile( FILE* );
01578
01584 XMLError SaveFile( const char* filename, bool compact = false );
01585
01593 XMLError SaveFile( FILE* fp, bool compact = false );
01594
01595 bool ProcessEntities() const {
01596 return _processEntities;
01597 }
01598 Whitespace WhitespaceMode() const {
01599 return _whitespace;
01600 }
01601
01605 bool HasBOM() const {
01606 return _writeBOM;
01607 }
01610 void SetBOM( bool useBOM ) {
01611 _writeBOM = useBOM;
01612 }
01613
01617 XMLElement* RootElement() {
01618 return FirstChildElement();
01619 }
01620 const XMLElement* RootElement() const {
01621 return FirstChildElement();
01622 }
01623
01638 void Print( XMLPrinter* streamer=0 ) const;
01639 virtual bool Accept( XMLVisitor* visitor ) const;
01640
01646 XMLElement* NewElement( const char* name );
01652 XMLComment* NewComment( const char* comment );
01658 XMLText* NewText( const char* text );
01670 XMLDeclaration* NewDeclaration( const char* text=0 );
01676 XMLUnknown* NewUnknown( const char* text );
01677
01682 void DeleteNode( XMLNode* node );
01683
01684 void SetError( XMLError error, const char* str1, const char* str2 );
01685
01687 bool Error() const {
01688 return _errorID != XML_NO_ERROR;
01689 }
01691 XMLError ErrorID() const {
01692 return _errorID;
01693 }
01694 const char* ErrorName() const;
01695
01697 const char* GetErrorStr1() const {
01698 return _errorStr1;
01699 }
01701 const char* GetErrorStr2() const {
01702 return _errorStr2;
01703 }
01705 void PrintError() const;
01706
01708 void Clear();
01709
01710
01711 char* Identify( char* p, XMLNode** node );
01712
01713 virtual XMLNode* ShallowClone( XMLDocument* ) const {
01714 return 0;
01715 }
01716 virtual bool ShallowEqual( const XMLNode* ) const {
01717 return false;
01718 }
01719
01720 private:
01721 XMLDocument( const XMLDocument& );
01722 void operator=( const XMLDocument& );
01723
01724 bool _writeBOM;
01725 bool _processEntities;
01726 XMLError _errorID;
01727 Whitespace _whitespace;
01728 const char* _errorStr1;
01729 const char* _errorStr2;
01730 char* _charBuffer;
01731
01732 MemPoolT< sizeof(XMLElement) > _elementPool;
01733 MemPoolT< sizeof(XMLAttribute) > _attributePool;
01734 MemPoolT< sizeof(XMLText) > _textPool;
01735 MemPoolT< sizeof(XMLComment) > _commentPool;
01736
01737 static const char* _errorNames[XML_ERROR_COUNT];
01738
01739 void Parse();
01740 };
01741
01742
01798 class TINYXML2_LIB XMLHandle
01799 {
01800 public:
01802 XMLHandle( XMLNode* node ) {
01803 _node = node;
01804 }
01806 XMLHandle( XMLNode& node ) {
01807 _node = &node;
01808 }
01810 XMLHandle( const XMLHandle& ref ) {
01811 _node = ref._node;
01812 }
01814 XMLHandle& operator=( const XMLHandle& ref ) {
01815 _node = ref._node;
01816 return *this;
01817 }
01818
01820 XMLHandle FirstChild() {
01821 return XMLHandle( _node ? _node->FirstChild() : 0 );
01822 }
01824 XMLHandle FirstChildElement( const char* name = 0 ) {
01825 return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
01826 }
01828 XMLHandle LastChild() {
01829 return XMLHandle( _node ? _node->LastChild() : 0 );
01830 }
01832 XMLHandle LastChildElement( const char* name = 0 ) {
01833 return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
01834 }
01836 XMLHandle PreviousSibling() {
01837 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
01838 }
01840 XMLHandle PreviousSiblingElement( const char* name = 0 ) {
01841 return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
01842 }
01844 XMLHandle NextSibling() {
01845 return XMLHandle( _node ? _node->NextSibling() : 0 );
01846 }
01848 XMLHandle NextSiblingElement( const char* name = 0 ) {
01849 return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
01850 }
01851
01853 XMLNode* ToNode() {
01854 return _node;
01855 }
01857 XMLElement* ToElement() {
01858 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
01859 }
01861 XMLText* ToText() {
01862 return ( ( _node == 0 ) ? 0 : _node->ToText() );
01863 }
01865 XMLUnknown* ToUnknown() {
01866 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
01867 }
01869 XMLDeclaration* ToDeclaration() {
01870 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
01871 }
01872
01873 private:
01874 XMLNode* _node;
01875 };
01876
01877
01882 class TINYXML2_LIB XMLConstHandle
01883 {
01884 public:
01885 XMLConstHandle( const XMLNode* node ) {
01886 _node = node;
01887 }
01888 XMLConstHandle( const XMLNode& node ) {
01889 _node = &node;
01890 }
01891 XMLConstHandle( const XMLConstHandle& ref ) {
01892 _node = ref._node;
01893 }
01894
01895 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
01896 _node = ref._node;
01897 return *this;
01898 }
01899
01900 const XMLConstHandle FirstChild() const {
01901 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
01902 }
01903 const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
01904 return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
01905 }
01906 const XMLConstHandle LastChild() const {
01907 return XMLConstHandle( _node ? _node->LastChild() : 0 );
01908 }
01909 const XMLConstHandle LastChildElement( const char* name = 0 ) const {
01910 return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
01911 }
01912 const XMLConstHandle PreviousSibling() const {
01913 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
01914 }
01915 const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
01916 return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
01917 }
01918 const XMLConstHandle NextSibling() const {
01919 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
01920 }
01921 const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
01922 return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
01923 }
01924
01925
01926 const XMLNode* ToNode() const {
01927 return _node;
01928 }
01929 const XMLElement* ToElement() const {
01930 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
01931 }
01932 const XMLText* ToText() const {
01933 return ( ( _node == 0 ) ? 0 : _node->ToText() );
01934 }
01935 const XMLUnknown* ToUnknown() const {
01936 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
01937 }
01938 const XMLDeclaration* ToDeclaration() const {
01939 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
01940 }
01941
01942 private:
01943 const XMLNode* _node;
01944 };
01945
01946
01989 class TINYXML2_LIB XMLPrinter : public XMLVisitor
01990 {
01991 public:
01998 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
01999 virtual ~XMLPrinter() {}
02000
02002 void PushHeader( bool writeBOM, bool writeDeclaration );
02006 void OpenElement( const char* name, bool compactMode=false );
02008 void PushAttribute( const char* name, const char* value );
02009 void PushAttribute( const char* name, int value );
02010 void PushAttribute( const char* name, unsigned value );
02011 void PushAttribute( const char* name, bool value );
02012 void PushAttribute( const char* name, double value );
02014 virtual void CloseElement( bool compactMode=false );
02015
02017 void PushText( const char* text, bool cdata=false );
02019 void PushText( int value );
02021 void PushText( unsigned value );
02023 void PushText( bool value );
02025 void PushText( float value );
02027 void PushText( double value );
02028
02030 void PushComment( const char* comment );
02031
02032 void PushDeclaration( const char* value );
02033 void PushUnknown( const char* value );
02034
02035 virtual bool VisitEnter( const XMLDocument& );
02036 virtual bool VisitExit( const XMLDocument& ) {
02037 return true;
02038 }
02039
02040 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
02041 virtual bool VisitExit( const XMLElement& element );
02042
02043 virtual bool Visit( const XMLText& text );
02044 virtual bool Visit( const XMLComment& comment );
02045 virtual bool Visit( const XMLDeclaration& declaration );
02046 virtual bool Visit( const XMLUnknown& unknown );
02047
02052 const char* CStr() const {
02053 return _buffer.Mem();
02054 }
02060 int CStrSize() const {
02061 return _buffer.Size();
02062 }
02067 void ClearBuffer() {
02068 _buffer.Clear();
02069 _buffer.Push(0);
02070 }
02071
02072 protected:
02073 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
02074
02078 virtual void PrintSpace( int depth );
02079 void Print( const char* format, ... );
02080
02081 void SealElementIfJustOpened();
02082 bool _elementJustOpened;
02083 DynArray< const char*, 10 > _stack;
02084
02085 private:
02086 void PrintString( const char*, bool restrictedEntitySet );
02087
02088 bool _firstElement;
02089 FILE* _fp;
02090 int _depth;
02091 int _textDepth;
02092 bool _processEntities;
02093 bool _compactMode;
02094
02095 enum {
02096 ENTITY_RANGE = 64,
02097 BUF_SIZE = 200
02098 };
02099 bool _entityFlag[ENTITY_RANGE];
02100 bool _restrictedEntityFlag[ENTITY_RANGE];
02101
02102 DynArray< char, 20 > _buffer;
02103 };
02104
02105
02106 }
02107
02108 #if defined(_MSC_VER)
02109 # pragma warning(pop)
02110 #endif
02111
02112 #endif // TINYXML2_INCLUDED