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__)
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
00045
00046
00047
00048
00049
00050
00051
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
00078
00079
00080
00081
00082
00083
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
00096
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
00120
00121
00122
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
00176 int _flags;
00177 char* _start;
00178 char* _end;
00179 };
00180
00181
00182
00183
00184
00185
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 );
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;
00271 int _size;
00272 };
00273
00274
00275
00276
00277
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
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
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
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 };
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& ) {
00409 return true;
00410 }
00412 virtual bool VisitExit( const XMLDocument& ) {
00413 return true;
00414 }
00415
00417 virtual bool VisitEnter( const XMLElement& , const XMLAttribute* ) {
00418 return true;
00419 }
00421 virtual bool VisitExit( const XMLElement& ) {
00422 return true;
00423 }
00424
00426 virtual bool Visit( const XMLDeclaration& ) {
00427 return true;
00428 }
00430 virtual bool Visit( const XMLText& ) {
00431 return true;
00432 }
00434 virtual bool Visit( const XMLComment& ) {
00435 return true;
00436 }
00438 virtual bool Visit( const XMLUnknown& ) {
00439 return true;
00440 }
00441 };
00442
00443
00444
00445
00446
00447 class XMLUtil
00448 {
00449 public:
00450
00451
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
00495
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
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
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
00770 virtual char* ParseDeep( char*, StrPair* );
00771
00772 protected:
00773 XMLNode( XMLDocument* );
00774 virtual ~XMLNode();
00775 XMLNode( const XMLNode& );
00776 XMLNode& operator=( const XMLNode& );
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& );
00837 XMLText& operator=( const XMLText& );
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& );
00866 XMLComment& operator=( const XMLComment& );
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& );
00904 XMLDeclaration& operator=( const XMLDeclaration& );
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& );
00936 XMLUnknown& operator=( const XMLUnknown& );
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& );
01059 void operator=( const XMLAttribute& );
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
01315 enum {
01316 OPEN,
01317 CLOSED,
01318 CLOSING
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& );
01331 void operator=( const XMLElement& );
01332
01333 XMLAttribute* FindAttribute( const char* name );
01334 XMLAttribute* FindOrCreateAttribute( const char* name );
01335
01336 char* ParseAttributes( char* p );
01337
01338 int _closingType;
01339
01340
01341
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
01529 char* Identify( char* p, XMLNode** node );
01530
01531 virtual XMLNode* ShallowClone( XMLDocument* ) const {
01532 return 0;
01533 }
01534 virtual bool ShallowEqual( const XMLNode* ) const {
01535 return false;
01536 }
01537
01538 private:
01539 XMLDocument( const XMLDocument& );
01540 void operator=( const XMLDocument& );
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& );
01851 virtual bool VisitExit( const XMLDocument& ) {
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 );
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 }
01909
01910
01911 #endif // TINYXML2_INCLUDED