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 # if defined(__PS3__)
00034 # include <stddef.h>
00035 # endif
00036 #else
00037 # include <cctype>
00038 # include <climits>
00039 # include <cstdio>
00040 # include <cstdlib>
00041 # include <cstring>
00042 #endif
00043 #include <stdint.h>
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #if defined( _DEBUG ) || defined (__DEBUG__)
00057 # ifndef TINYXML2_DEBUG
00058 # define TINYXML2_DEBUG
00059 # endif
00060 #endif
00061
00062 #ifdef _MSC_VER
00063 # pragma warning(push)
00064 # pragma warning(disable: 4251)
00065 #endif
00066
00067
00068 #ifdef _WIN32
00069 # define TINYXML2_LIB // TODO?
00070 #else
00071 # define TINYXML2_LIB __attribute__((visibility("hidden")))
00072 #endif
00073
00074 #if defined(TINYXML2_DEBUG)
00075 # if defined(_MSC_VER)
00076 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
00077 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); }
00078 # elif defined (ANDROID_NDK)
00079 # include <android/log.h>
00080 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
00081 # else
00082 # include <assert.h>
00083 # define TIXMLASSERT assert
00084 # endif
00085 #else
00086 # define TIXMLASSERT( x ) {}
00087 #endif
00088
00089
00090
00091
00092
00093 static const int TIXML2_MAJOR_VERSION = 6;
00094 static const int TIXML2_MINOR_VERSION = 2;
00095 static const int TIXML2_PATCH_VERSION = 0;
00096
00097 #define TINYXML2_MAJOR_VERSION 6
00098 #define TINYXML2_MINOR_VERSION 2
00099 #define TINYXML2_PATCH_VERSION 0
00100
00101
00102
00103
00104
00105
00106 static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
00107
00108 namespace tinyxml2
00109 {
00110 class XMLDocument;
00111 class XMLElement;
00112 class XMLAttribute;
00113 class XMLComment;
00114 class XMLText;
00115 class XMLDeclaration;
00116 class XMLUnknown;
00117 class XMLPrinter;
00118
00119
00120
00121
00122
00123
00124
00125 class StrPair
00126 {
00127 public:
00128 enum {
00129 NEEDS_ENTITY_PROCESSING = 0x01,
00130 NEEDS_NEWLINE_NORMALIZATION = 0x02,
00131 NEEDS_WHITESPACE_COLLAPSING = 0x04,
00132
00133 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00134 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
00135 ATTRIBUTE_NAME = 0,
00136 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00137 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
00138 COMMENT = NEEDS_NEWLINE_NORMALIZATION
00139 };
00140
00141 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
00142 ~StrPair();
00143
00144 void Set( char* start, char* end, int flags ) {
00145 TIXMLASSERT( start );
00146 TIXMLASSERT( end );
00147 Reset();
00148 _start = start;
00149 _end = end;
00150 _flags = flags | NEEDS_FLUSH;
00151 }
00152
00153 const char* GetStr();
00154
00155 bool Empty() const {
00156 return _start == _end;
00157 }
00158
00159 void SetInternedStr( const char* str ) {
00160 Reset();
00161 _start = const_cast<char*>(str);
00162 }
00163
00164 void SetStr( const char* str, int flags=0 );
00165
00166 char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
00167 char* ParseName( char* in );
00168
00169 void TransferTo( StrPair* other );
00170 void Reset();
00171
00172 private:
00173 void CollapseWhitespace();
00174
00175 enum {
00176 NEEDS_FLUSH = 0x100,
00177 NEEDS_DELETE = 0x200
00178 };
00179
00180 int _flags;
00181 char* _start;
00182 char* _end;
00183
00184 StrPair( const StrPair& other );
00185 void operator=( StrPair& other );
00186 };
00187
00188
00189
00190
00191
00192
00193
00194 template <class T, int INITIAL_SIZE>
00195 class DynArray
00196 {
00197 public:
00198 DynArray() :
00199 _mem( _pool ),
00200 _allocated( INITIAL_SIZE ),
00201 _size( 0 )
00202 {
00203 }
00204
00205 ~DynArray() {
00206 if ( _mem != _pool ) {
00207 delete [] _mem;
00208 }
00209 }
00210
00211 void Clear() {
00212 _size = 0;
00213 }
00214
00215 void Push( T t ) {
00216 TIXMLASSERT( _size < INT_MAX );
00217 EnsureCapacity( _size+1 );
00218 _mem[_size] = t;
00219 ++_size;
00220 }
00221
00222 T* PushArr( int count ) {
00223 TIXMLASSERT( count >= 0 );
00224 TIXMLASSERT( _size <= INT_MAX - count );
00225 EnsureCapacity( _size+count );
00226 T* ret = &_mem[_size];
00227 _size += count;
00228 return ret;
00229 }
00230
00231 T Pop() {
00232 TIXMLASSERT( _size > 0 );
00233 --_size;
00234 return _mem[_size];
00235 }
00236
00237 void PopArr( int count ) {
00238 TIXMLASSERT( _size >= count );
00239 _size -= count;
00240 }
00241
00242 bool Empty() const {
00243 return _size == 0;
00244 }
00245
00246 T& operator[](int i) {
00247 TIXMLASSERT( i>= 0 && i < _size );
00248 return _mem[i];
00249 }
00250
00251 const T& operator[](int i) const {
00252 TIXMLASSERT( i>= 0 && i < _size );
00253 return _mem[i];
00254 }
00255
00256 const T& PeekTop() const {
00257 TIXMLASSERT( _size > 0 );
00258 return _mem[ _size - 1];
00259 }
00260
00261 int Size() const {
00262 TIXMLASSERT( _size >= 0 );
00263 return _size;
00264 }
00265
00266 int Capacity() const {
00267 TIXMLASSERT( _allocated >= INITIAL_SIZE );
00268 return _allocated;
00269 }
00270
00271 void SwapRemove(int i) {
00272 TIXMLASSERT(i >= 0 && i < _size);
00273 TIXMLASSERT(_size > 0);
00274 _mem[i] = _mem[_size - 1];
00275 --_size;
00276 }
00277
00278 const T* Mem() const {
00279 TIXMLASSERT( _mem );
00280 return _mem;
00281 }
00282
00283 T* Mem() {
00284 TIXMLASSERT( _mem );
00285 return _mem;
00286 }
00287
00288 private:
00289 DynArray( const DynArray& );
00290 void operator=( const DynArray& );
00291
00292 void EnsureCapacity( int cap ) {
00293 TIXMLASSERT( cap > 0 );
00294 if ( cap > _allocated ) {
00295 TIXMLASSERT( cap <= INT_MAX / 2 );
00296 int newAllocated = cap * 2;
00297 T* newMem = new T[newAllocated];
00298 TIXMLASSERT( newAllocated >= _size );
00299 memcpy( newMem, _mem, sizeof(T)*_size );
00300 if ( _mem != _pool ) {
00301 delete [] _mem;
00302 }
00303 _mem = newMem;
00304 _allocated = newAllocated;
00305 }
00306 }
00307
00308 T* _mem;
00309 T _pool[INITIAL_SIZE];
00310 int _allocated;
00311 int _size;
00312 };
00313
00314
00315
00316
00317
00318
00319 class MemPool
00320 {
00321 public:
00322 MemPool() {}
00323 virtual ~MemPool() {}
00324
00325 virtual int ItemSize() const = 0;
00326 virtual void* Alloc() = 0;
00327 virtual void Free( void* ) = 0;
00328 virtual void SetTracked() = 0;
00329 virtual void Clear() = 0;
00330 };
00331
00332
00333
00334
00335
00336 template< int ITEM_SIZE >
00337 class MemPoolT : public MemPool
00338 {
00339 public:
00340 MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
00341 ~MemPoolT() {
00342 Clear();
00343 }
00344
00345 void Clear() {
00346
00347 while( !_blockPtrs.Empty()) {
00348 Block* lastBlock = _blockPtrs.Pop();
00349 delete lastBlock;
00350 }
00351 _root = 0;
00352 _currentAllocs = 0;
00353 _nAllocs = 0;
00354 _maxAllocs = 0;
00355 _nUntracked = 0;
00356 }
00357
00358 virtual int ItemSize() const {
00359 return ITEM_SIZE;
00360 }
00361 int CurrentAllocs() const {
00362 return _currentAllocs;
00363 }
00364
00365 virtual void* Alloc() {
00366 if ( !_root ) {
00367
00368 Block* block = new Block();
00369 _blockPtrs.Push( block );
00370
00371 Item* blockItems = block->items;
00372 for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
00373 blockItems[i].next = &(blockItems[i + 1]);
00374 }
00375 blockItems[ITEMS_PER_BLOCK - 1].next = 0;
00376 _root = blockItems;
00377 }
00378 Item* const result = _root;
00379 TIXMLASSERT( result != 0 );
00380 _root = _root->next;
00381
00382 ++_currentAllocs;
00383 if ( _currentAllocs > _maxAllocs ) {
00384 _maxAllocs = _currentAllocs;
00385 }
00386 ++_nAllocs;
00387 ++_nUntracked;
00388 return result;
00389 }
00390
00391 virtual void Free( void* mem ) {
00392 if ( !mem ) {
00393 return;
00394 }
00395 --_currentAllocs;
00396 Item* item = static_cast<Item*>( mem );
00397 #ifdef TINYXML2_DEBUG
00398 memset( item, 0xfe, sizeof( *item ) );
00399 #endif
00400 item->next = _root;
00401 _root = item;
00402 }
00403 void Trace( const char* name ) {
00404 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
00405 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
00406 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
00407 }
00408
00409 void SetTracked() {
00410 --_nUntracked;
00411 }
00412
00413 int Untracked() const {
00414 return _nUntracked;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
00429
00430 private:
00431 MemPoolT( const MemPoolT& );
00432 void operator=( const MemPoolT& );
00433
00434 union Item {
00435 Item* next;
00436 char itemData[ITEM_SIZE];
00437 };
00438 struct Block {
00439 Item items[ITEMS_PER_BLOCK];
00440 };
00441 DynArray< Block*, 10 > _blockPtrs;
00442 Item* _root;
00443
00444 int _currentAllocs;
00445 int _nAllocs;
00446 int _maxAllocs;
00447 int _nUntracked;
00448 };
00449
00450
00451
00471 class TINYXML2_LIB XMLVisitor
00472 {
00473 public:
00474 virtual ~XMLVisitor() {}
00475
00477 virtual bool VisitEnter( const XMLDocument& ) {
00478 return true;
00479 }
00481 virtual bool VisitExit( const XMLDocument& ) {
00482 return true;
00483 }
00484
00486 virtual bool VisitEnter( const XMLElement& , const XMLAttribute* ) {
00487 return true;
00488 }
00490 virtual bool VisitExit( const XMLElement& ) {
00491 return true;
00492 }
00493
00495 virtual bool Visit( const XMLDeclaration& ) {
00496 return true;
00497 }
00499 virtual bool Visit( const XMLText& ) {
00500 return true;
00501 }
00503 virtual bool Visit( const XMLComment& ) {
00504 return true;
00505 }
00507 virtual bool Visit( const XMLUnknown& ) {
00508 return true;
00509 }
00510 };
00511
00512
00513 enum XMLError {
00514 XML_SUCCESS = 0,
00515 XML_NO_ATTRIBUTE,
00516 XML_WRONG_ATTRIBUTE_TYPE,
00517 XML_ERROR_FILE_NOT_FOUND,
00518 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
00519 XML_ERROR_FILE_READ_ERROR,
00520 UNUSED_XML_ERROR_ELEMENT_MISMATCH,
00521 XML_ERROR_PARSING_ELEMENT,
00522 XML_ERROR_PARSING_ATTRIBUTE,
00523 UNUSED_XML_ERROR_IDENTIFYING_TAG,
00524 XML_ERROR_PARSING_TEXT,
00525 XML_ERROR_PARSING_CDATA,
00526 XML_ERROR_PARSING_COMMENT,
00527 XML_ERROR_PARSING_DECLARATION,
00528 XML_ERROR_PARSING_UNKNOWN,
00529 XML_ERROR_EMPTY_DOCUMENT,
00530 XML_ERROR_MISMATCHED_ELEMENT,
00531 XML_ERROR_PARSING,
00532 XML_CAN_NOT_CONVERT_TEXT,
00533 XML_NO_TEXT_NODE,
00534 XML_ELEMENT_DEPTH_EXCEEDED,
00535
00536 XML_ERROR_COUNT
00537 };
00538
00539
00540
00541
00542
00543 class TINYXML2_LIB XMLUtil
00544 {
00545 public:
00546 static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
00547 TIXMLASSERT( p );
00548
00549 while( IsWhiteSpace(*p) ) {
00550 if (curLineNumPtr && *p == '\n') {
00551 ++(*curLineNumPtr);
00552 }
00553 ++p;
00554 }
00555 TIXMLASSERT( p );
00556 return p;
00557 }
00558 static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) {
00559 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
00560 }
00561
00562
00563
00564 static bool IsWhiteSpace( char p ) {
00565 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
00566 }
00567
00568 inline static bool IsNameStartChar( unsigned char ch ) {
00569 if ( ch >= 128 ) {
00570
00571 return true;
00572 }
00573 if ( isalpha( ch ) ) {
00574 return true;
00575 }
00576 return ch == ':' || ch == '_';
00577 }
00578
00579 inline static bool IsNameChar( unsigned char ch ) {
00580 return IsNameStartChar( ch )
00581 || isdigit( ch )
00582 || ch == '.'
00583 || ch == '-';
00584 }
00585
00586 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
00587 if ( p == q ) {
00588 return true;
00589 }
00590 TIXMLASSERT( p );
00591 TIXMLASSERT( q );
00592 TIXMLASSERT( nChar >= 0 );
00593 return strncmp( p, q, nChar ) == 0;
00594 }
00595
00596 inline static bool IsUTF8Continuation( char p ) {
00597 return ( p & 0x80 ) != 0;
00598 }
00599
00600 static const char* ReadBOM( const char* p, bool* hasBOM );
00601
00602
00603 static const char* GetCharacterRef( const char* p, char* value, int* length );
00604 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00605
00606
00607 static void ToStr( int v, char* buffer, int bufferSize );
00608 static void ToStr( unsigned v, char* buffer, int bufferSize );
00609 static void ToStr( bool v, char* buffer, int bufferSize );
00610 static void ToStr( float v, char* buffer, int bufferSize );
00611 static void ToStr( double v, char* buffer, int bufferSize );
00612 static void ToStr(int64_t v, char* buffer, int bufferSize);
00613
00614
00615 static bool ToInt( const char* str, int* value );
00616 static bool ToUnsigned( const char* str, unsigned* value );
00617 static bool ToBool( const char* str, bool* value );
00618 static bool ToFloat( const char* str, float* value );
00619 static bool ToDouble( const char* str, double* value );
00620 static bool ToInt64(const char* str, int64_t* value);
00621
00622
00623
00624
00625
00626
00627 static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
00628
00629 private:
00630 static const char* writeBoolTrue;
00631 static const char* writeBoolFalse;
00632 };
00633
00634
00660 class TINYXML2_LIB XMLNode
00661 {
00662 friend class XMLDocument;
00663 friend class XMLElement;
00664 public:
00665
00667 const XMLDocument* GetDocument() const {
00668 TIXMLASSERT( _document );
00669 return _document;
00670 }
00672 XMLDocument* GetDocument() {
00673 TIXMLASSERT( _document );
00674 return _document;
00675 }
00676
00678 virtual XMLElement* ToElement() {
00679 return 0;
00680 }
00682 virtual XMLText* ToText() {
00683 return 0;
00684 }
00686 virtual XMLComment* ToComment() {
00687 return 0;
00688 }
00690 virtual XMLDocument* ToDocument() {
00691 return 0;
00692 }
00694 virtual XMLDeclaration* ToDeclaration() {
00695 return 0;
00696 }
00698 virtual XMLUnknown* ToUnknown() {
00699 return 0;
00700 }
00701
00702 virtual const XMLElement* ToElement() const {
00703 return 0;
00704 }
00705 virtual const XMLText* ToText() const {
00706 return 0;
00707 }
00708 virtual const XMLComment* ToComment() const {
00709 return 0;
00710 }
00711 virtual const XMLDocument* ToDocument() const {
00712 return 0;
00713 }
00714 virtual const XMLDeclaration* ToDeclaration() const {
00715 return 0;
00716 }
00717 virtual const XMLUnknown* ToUnknown() const {
00718 return 0;
00719 }
00720
00730 const char* Value() const;
00731
00735 void SetValue( const char* val, bool staticMem=false );
00736
00738 int GetLineNum() const { return _parseLineNum; }
00739
00741 const XMLNode* Parent() const {
00742 return _parent;
00743 }
00744
00745 XMLNode* Parent() {
00746 return _parent;
00747 }
00748
00750 bool NoChildren() const {
00751 return !_firstChild;
00752 }
00753
00755 const XMLNode* FirstChild() const {
00756 return _firstChild;
00757 }
00758
00759 XMLNode* FirstChild() {
00760 return _firstChild;
00761 }
00762
00766 const XMLElement* FirstChildElement( const char* name = 0 ) const;
00767
00768 XMLElement* FirstChildElement( const char* name = 0 ) {
00769 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
00770 }
00771
00773 const XMLNode* LastChild() const {
00774 return _lastChild;
00775 }
00776
00777 XMLNode* LastChild() {
00778 return _lastChild;
00779 }
00780
00784 const XMLElement* LastChildElement( const char* name = 0 ) const;
00785
00786 XMLElement* LastChildElement( const char* name = 0 ) {
00787 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
00788 }
00789
00791 const XMLNode* PreviousSibling() const {
00792 return _prev;
00793 }
00794
00795 XMLNode* PreviousSibling() {
00796 return _prev;
00797 }
00798
00800 const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
00801
00802 XMLElement* PreviousSiblingElement( const char* name = 0 ) {
00803 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
00804 }
00805
00807 const XMLNode* NextSibling() const {
00808 return _next;
00809 }
00810
00811 XMLNode* NextSibling() {
00812 return _next;
00813 }
00814
00816 const XMLElement* NextSiblingElement( const char* name = 0 ) const;
00817
00818 XMLElement* NextSiblingElement( const char* name = 0 ) {
00819 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
00820 }
00821
00829 XMLNode* InsertEndChild( XMLNode* addThis );
00830
00831 XMLNode* LinkEndChild( XMLNode* addThis ) {
00832 return InsertEndChild( addThis );
00833 }
00841 XMLNode* InsertFirstChild( XMLNode* addThis );
00850 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
00851
00855 void DeleteChildren();
00856
00860 void DeleteChild( XMLNode* node );
00861
00871 virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
00872
00886 XMLNode* DeepClone( XMLDocument* target ) const;
00887
00894 virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
00895
00918 virtual bool Accept( XMLVisitor* visitor ) const = 0;
00919
00925 void SetUserData(void* userData) { _userData = userData; }
00926
00932 void* GetUserData() const { return _userData; }
00933
00934 protected:
00935 XMLNode( XMLDocument* );
00936 virtual ~XMLNode();
00937
00938 virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
00939
00940 XMLDocument* _document;
00941 XMLNode* _parent;
00942 mutable StrPair _value;
00943 int _parseLineNum;
00944
00945 XMLNode* _firstChild;
00946 XMLNode* _lastChild;
00947
00948 XMLNode* _prev;
00949 XMLNode* _next;
00950
00951 void* _userData;
00952
00953 private:
00954 MemPool* _memPool;
00955 void Unlink( XMLNode* child );
00956 static void DeleteNode( XMLNode* node );
00957 void InsertChildPreamble( XMLNode* insertThis ) const;
00958 const XMLElement* ToElementWithName( const char* name ) const;
00959
00960 XMLNode( const XMLNode& );
00961 XMLNode& operator=( const XMLNode& );
00962 };
00963
00964
00977 class TINYXML2_LIB XMLText : public XMLNode
00978 {
00979 friend class XMLDocument;
00980 public:
00981 virtual bool Accept( XMLVisitor* visitor ) const;
00982
00983 virtual XMLText* ToText() {
00984 return this;
00985 }
00986 virtual const XMLText* ToText() const {
00987 return this;
00988 }
00989
00991 void SetCData( bool isCData ) {
00992 _isCData = isCData;
00993 }
00995 bool CData() const {
00996 return _isCData;
00997 }
00998
00999 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01000 virtual bool ShallowEqual( const XMLNode* compare ) const;
01001
01002 protected:
01003 XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
01004 virtual ~XMLText() {}
01005
01006 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01007
01008 private:
01009 bool _isCData;
01010
01011 XMLText( const XMLText& );
01012 XMLText& operator=( const XMLText& );
01013 };
01014
01015
01017 class TINYXML2_LIB XMLComment : public XMLNode
01018 {
01019 friend class XMLDocument;
01020 public:
01021 virtual XMLComment* ToComment() {
01022 return this;
01023 }
01024 virtual const XMLComment* ToComment() const {
01025 return this;
01026 }
01027
01028 virtual bool Accept( XMLVisitor* visitor ) const;
01029
01030 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01031 virtual bool ShallowEqual( const XMLNode* compare ) const;
01032
01033 protected:
01034 XMLComment( XMLDocument* doc );
01035 virtual ~XMLComment();
01036
01037 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
01038
01039 private:
01040 XMLComment( const XMLComment& );
01041 XMLComment& operator=( const XMLComment& );
01042 };
01043
01044
01056 class TINYXML2_LIB XMLDeclaration : public XMLNode
01057 {
01058 friend class XMLDocument;
01059 public:
01060 virtual XMLDeclaration* ToDeclaration() {
01061 return this;
01062 }
01063 virtual const XMLDeclaration* ToDeclaration() const {
01064 return this;
01065 }
01066
01067 virtual bool Accept( XMLVisitor* visitor ) const;
01068
01069 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01070 virtual bool ShallowEqual( const XMLNode* compare ) const;
01071
01072 protected:
01073 XMLDeclaration( XMLDocument* doc );
01074 virtual ~XMLDeclaration();
01075
01076 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01077
01078 private:
01079 XMLDeclaration( const XMLDeclaration& );
01080 XMLDeclaration& operator=( const XMLDeclaration& );
01081 };
01082
01083
01091 class TINYXML2_LIB XMLUnknown : public XMLNode
01092 {
01093 friend class XMLDocument;
01094 public:
01095 virtual XMLUnknown* ToUnknown() {
01096 return this;
01097 }
01098 virtual const XMLUnknown* ToUnknown() const {
01099 return this;
01100 }
01101
01102 virtual bool Accept( XMLVisitor* visitor ) const;
01103
01104 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01105 virtual bool ShallowEqual( const XMLNode* compare ) const;
01106
01107 protected:
01108 XMLUnknown( XMLDocument* doc );
01109 virtual ~XMLUnknown();
01110
01111 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01112
01113 private:
01114 XMLUnknown( const XMLUnknown& );
01115 XMLUnknown& operator=( const XMLUnknown& );
01116 };
01117
01118
01119
01126 class TINYXML2_LIB XMLAttribute
01127 {
01128 friend class XMLElement;
01129 public:
01131 const char* Name() const;
01132
01134 const char* Value() const;
01135
01137 int GetLineNum() const { return _parseLineNum; }
01138
01140 const XMLAttribute* Next() const {
01141 return _next;
01142 }
01143
01148 int IntValue() const {
01149 int i = 0;
01150 QueryIntValue(&i);
01151 return i;
01152 }
01153
01154 int64_t Int64Value() const {
01155 int64_t i = 0;
01156 QueryInt64Value(&i);
01157 return i;
01158 }
01159
01161 unsigned UnsignedValue() const {
01162 unsigned i=0;
01163 QueryUnsignedValue( &i );
01164 return i;
01165 }
01167 bool BoolValue() const {
01168 bool b=false;
01169 QueryBoolValue( &b );
01170 return b;
01171 }
01173 double DoubleValue() const {
01174 double d=0;
01175 QueryDoubleValue( &d );
01176 return d;
01177 }
01179 float FloatValue() const {
01180 float f=0;
01181 QueryFloatValue( &f );
01182 return f;
01183 }
01184
01189 XMLError QueryIntValue( int* value ) const;
01191 XMLError QueryUnsignedValue( unsigned int* value ) const;
01193 XMLError QueryInt64Value(int64_t* value) const;
01195 XMLError QueryBoolValue( bool* value ) const;
01197 XMLError QueryDoubleValue( double* value ) const;
01199 XMLError QueryFloatValue( float* value ) const;
01200
01202 void SetAttribute( const char* value );
01204 void SetAttribute( int value );
01206 void SetAttribute( unsigned value );
01208 void SetAttribute(int64_t value);
01210 void SetAttribute( bool value );
01212 void SetAttribute( double value );
01214 void SetAttribute( float value );
01215
01216 private:
01217 enum { BUF_SIZE = 200 };
01218
01219 XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
01220 virtual ~XMLAttribute() {}
01221
01222 XMLAttribute( const XMLAttribute& );
01223 void operator=( const XMLAttribute& );
01224 void SetName( const char* name );
01225
01226 char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
01227
01228 mutable StrPair _name;
01229 mutable StrPair _value;
01230 int _parseLineNum;
01231 XMLAttribute* _next;
01232 MemPool* _memPool;
01233 };
01234
01235
01240 class TINYXML2_LIB XMLElement : public XMLNode
01241 {
01242 friend class XMLDocument;
01243 public:
01245 const char* Name() const {
01246 return Value();
01247 }
01249 void SetName( const char* str, bool staticMem=false ) {
01250 SetValue( str, staticMem );
01251 }
01252
01253 virtual XMLElement* ToElement() {
01254 return this;
01255 }
01256 virtual const XMLElement* ToElement() const {
01257 return this;
01258 }
01259 virtual bool Accept( XMLVisitor* visitor ) const;
01260
01284 const char* Attribute( const char* name, const char* value=0 ) const;
01285
01292 int IntAttribute(const char* name, int defaultValue = 0) const;
01294 unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
01296 int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
01298 bool BoolAttribute(const char* name, bool defaultValue = false) const;
01300 double DoubleAttribute(const char* name, double defaultValue = 0) const;
01302 float FloatAttribute(const char* name, float defaultValue = 0) const;
01303
01317 XMLError QueryIntAttribute( const char* name, int* value ) const {
01318 const XMLAttribute* a = FindAttribute( name );
01319 if ( !a ) {
01320 return XML_NO_ATTRIBUTE;
01321 }
01322 return a->QueryIntValue( value );
01323 }
01324
01326 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
01327 const XMLAttribute* a = FindAttribute( name );
01328 if ( !a ) {
01329 return XML_NO_ATTRIBUTE;
01330 }
01331 return a->QueryUnsignedValue( value );
01332 }
01333
01335 XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
01336 const XMLAttribute* a = FindAttribute(name);
01337 if (!a) {
01338 return XML_NO_ATTRIBUTE;
01339 }
01340 return a->QueryInt64Value(value);
01341 }
01342
01344 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
01345 const XMLAttribute* a = FindAttribute( name );
01346 if ( !a ) {
01347 return XML_NO_ATTRIBUTE;
01348 }
01349 return a->QueryBoolValue( value );
01350 }
01352 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
01353 const XMLAttribute* a = FindAttribute( name );
01354 if ( !a ) {
01355 return XML_NO_ATTRIBUTE;
01356 }
01357 return a->QueryDoubleValue( value );
01358 }
01360 XMLError QueryFloatAttribute( const char* name, float* value ) const {
01361 const XMLAttribute* a = FindAttribute( name );
01362 if ( !a ) {
01363 return XML_NO_ATTRIBUTE;
01364 }
01365 return a->QueryFloatValue( value );
01366 }
01367
01369 XMLError QueryStringAttribute(const char* name, const char** value) const {
01370 const XMLAttribute* a = FindAttribute(name);
01371 if (!a) {
01372 return XML_NO_ATTRIBUTE;
01373 }
01374 *value = a->Value();
01375 return XML_SUCCESS;
01376 }
01377
01378
01379
01397 int QueryAttribute( const char* name, int* value ) const {
01398 return QueryIntAttribute( name, value );
01399 }
01400
01401 int QueryAttribute( const char* name, unsigned int* value ) const {
01402 return QueryUnsignedAttribute( name, value );
01403 }
01404
01405 int QueryAttribute(const char* name, int64_t* value) const {
01406 return QueryInt64Attribute(name, value);
01407 }
01408
01409 int QueryAttribute( const char* name, bool* value ) const {
01410 return QueryBoolAttribute( name, value );
01411 }
01412
01413 int QueryAttribute( const char* name, double* value ) const {
01414 return QueryDoubleAttribute( name, value );
01415 }
01416
01417 int QueryAttribute( const char* name, float* value ) const {
01418 return QueryFloatAttribute( name, value );
01419 }
01420
01422 void SetAttribute( const char* name, const char* value ) {
01423 XMLAttribute* a = FindOrCreateAttribute( name );
01424 a->SetAttribute( value );
01425 }
01427 void SetAttribute( const char* name, int value ) {
01428 XMLAttribute* a = FindOrCreateAttribute( name );
01429 a->SetAttribute( value );
01430 }
01432 void SetAttribute( const char* name, unsigned value ) {
01433 XMLAttribute* a = FindOrCreateAttribute( name );
01434 a->SetAttribute( value );
01435 }
01436
01438 void SetAttribute(const char* name, int64_t value) {
01439 XMLAttribute* a = FindOrCreateAttribute(name);
01440 a->SetAttribute(value);
01441 }
01442
01444 void SetAttribute( const char* name, bool value ) {
01445 XMLAttribute* a = FindOrCreateAttribute( name );
01446 a->SetAttribute( value );
01447 }
01449 void SetAttribute( const char* name, double value ) {
01450 XMLAttribute* a = FindOrCreateAttribute( name );
01451 a->SetAttribute( value );
01452 }
01454 void SetAttribute( const char* name, float value ) {
01455 XMLAttribute* a = FindOrCreateAttribute( name );
01456 a->SetAttribute( value );
01457 }
01458
01462 void DeleteAttribute( const char* name );
01463
01465 const XMLAttribute* FirstAttribute() const {
01466 return _rootAttribute;
01467 }
01469 const XMLAttribute* FindAttribute( const char* name ) const;
01470
01499 const char* GetText() const;
01500
01535 void SetText( const char* inText );
01537 void SetText( int value );
01539 void SetText( unsigned value );
01541 void SetText(int64_t value);
01543 void SetText( bool value );
01545 void SetText( double value );
01547 void SetText( float value );
01548
01575 XMLError QueryIntText( int* ival ) const;
01577 XMLError QueryUnsignedText( unsigned* uval ) const;
01579 XMLError QueryInt64Text(int64_t* uval) const;
01581 XMLError QueryBoolText( bool* bval ) const;
01583 XMLError QueryDoubleText( double* dval ) const;
01585 XMLError QueryFloatText( float* fval ) const;
01586
01587 int IntText(int defaultValue = 0) const;
01588
01590 unsigned UnsignedText(unsigned defaultValue = 0) const;
01592 int64_t Int64Text(int64_t defaultValue = 0) const;
01594 bool BoolText(bool defaultValue = false) const;
01596 double DoubleText(double defaultValue = 0) const;
01598 float FloatText(float defaultValue = 0) const;
01599
01600
01601 enum ElementClosingType {
01602 OPEN,
01603 CLOSED,
01604 CLOSING
01605 };
01606 ElementClosingType ClosingType() const {
01607 return _closingType;
01608 }
01609 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01610 virtual bool ShallowEqual( const XMLNode* compare ) const;
01611
01612 protected:
01613 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01614
01615 private:
01616 XMLElement( XMLDocument* doc );
01617 virtual ~XMLElement();
01618 XMLElement( const XMLElement& );
01619 void operator=( const XMLElement& );
01620
01621 XMLAttribute* FindAttribute( const char* name ) {
01622 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
01623 }
01624 XMLAttribute* FindOrCreateAttribute( const char* name );
01625
01626 char* ParseAttributes( char* p, int* curLineNumPtr );
01627 static void DeleteAttribute( XMLAttribute* attribute );
01628 XMLAttribute* CreateAttribute();
01629
01630 enum { BUF_SIZE = 200 };
01631 ElementClosingType _closingType;
01632
01633
01634
01635 XMLAttribute* _rootAttribute;
01636 };
01637
01638
01639 enum Whitespace {
01640 PRESERVE_WHITESPACE,
01641 COLLAPSE_WHITESPACE
01642 };
01643
01644
01650 class TINYXML2_LIB XMLDocument : public XMLNode
01651 {
01652 friend class XMLElement;
01653
01654
01655 friend class XMLNode;
01656 friend class XMLText;
01657 friend class XMLComment;
01658 friend class XMLDeclaration;
01659 friend class XMLUnknown;
01660 public:
01662 XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
01663 ~XMLDocument();
01664
01665 virtual XMLDocument* ToDocument() {
01666 TIXMLASSERT( this == _document );
01667 return this;
01668 }
01669 virtual const XMLDocument* ToDocument() const {
01670 TIXMLASSERT( this == _document );
01671 return this;
01672 }
01673
01684 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
01685
01691 XMLError LoadFile( const char* filename );
01692
01704 XMLError LoadFile( FILE* );
01705
01711 XMLError SaveFile( const char* filename, bool compact = false );
01712
01720 XMLError SaveFile( FILE* fp, bool compact = false );
01721
01722 bool ProcessEntities() const {
01723 return _processEntities;
01724 }
01725 Whitespace WhitespaceMode() const {
01726 return _whitespaceMode;
01727 }
01728
01732 bool HasBOM() const {
01733 return _writeBOM;
01734 }
01737 void SetBOM( bool useBOM ) {
01738 _writeBOM = useBOM;
01739 }
01740
01744 XMLElement* RootElement() {
01745 return FirstChildElement();
01746 }
01747 const XMLElement* RootElement() const {
01748 return FirstChildElement();
01749 }
01750
01765 void Print( XMLPrinter* streamer=0 ) const;
01766 virtual bool Accept( XMLVisitor* visitor ) const;
01767
01773 XMLElement* NewElement( const char* name );
01779 XMLComment* NewComment( const char* comment );
01785 XMLText* NewText( const char* text );
01797 XMLDeclaration* NewDeclaration( const char* text=0 );
01803 XMLUnknown* NewUnknown( const char* text );
01804
01809 void DeleteNode( XMLNode* node );
01810
01811 void ClearError() {
01812 SetError(XML_SUCCESS, 0, 0);
01813 }
01814
01816 bool Error() const {
01817 return _errorID != XML_SUCCESS;
01818 }
01820 XMLError ErrorID() const {
01821 return _errorID;
01822 }
01823 const char* ErrorName() const;
01824 static const char* ErrorIDToName(XMLError errorID);
01825
01829 const char* ErrorStr() const;
01830
01832 void PrintError() const;
01833
01835 int ErrorLineNum() const
01836 {
01837 return _errorLineNum;
01838 }
01839
01841 void Clear();
01842
01850 void DeepCopy(XMLDocument* target) const;
01851
01852
01853 char* Identify( char* p, XMLNode** node );
01854
01855
01856 void MarkInUse(XMLNode*);
01857
01858 virtual XMLNode* ShallowClone( XMLDocument* ) const {
01859 return 0;
01860 }
01861 virtual bool ShallowEqual( const XMLNode* ) const {
01862 return false;
01863 }
01864
01865 private:
01866 XMLDocument( const XMLDocument& );
01867 void operator=( const XMLDocument& );
01868
01869 bool _writeBOM;
01870 bool _processEntities;
01871 XMLError _errorID;
01872 Whitespace _whitespaceMode;
01873 mutable StrPair _errorStr;
01874 int _errorLineNum;
01875 char* _charBuffer;
01876 int _parseCurLineNum;
01877 int _parsingDepth;
01878
01879
01880
01881
01882
01883
01884 DynArray<XMLNode*, 10> _unlinked;
01885
01886 MemPoolT< sizeof(XMLElement) > _elementPool;
01887 MemPoolT< sizeof(XMLAttribute) > _attributePool;
01888 MemPoolT< sizeof(XMLText) > _textPool;
01889 MemPoolT< sizeof(XMLComment) > _commentPool;
01890
01891 static const char* _errorNames[XML_ERROR_COUNT];
01892
01893 void Parse();
01894
01895 void SetError( XMLError error, int lineNum, const char* format, ... );
01896
01897
01898
01899
01900 class DepthTracker {
01901 public:
01902 DepthTracker(XMLDocument * document) {
01903 this->_document = document;
01904 document->PushDepth();
01905 }
01906 ~DepthTracker() {
01907 _document->PopDepth();
01908 }
01909 private:
01910 XMLDocument * _document;
01911 };
01912 void PushDepth();
01913 void PopDepth();
01914
01915 template<class NodeType, int PoolElementSize>
01916 NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
01917 };
01918
01919 template<class NodeType, int PoolElementSize>
01920 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
01921 {
01922 TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
01923 TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
01924 NodeType* returnNode = new (pool.Alloc()) NodeType( this );
01925 TIXMLASSERT( returnNode );
01926 returnNode->_memPool = &pool;
01927
01928 _unlinked.Push(returnNode);
01929 return returnNode;
01930 }
01931
01987 class TINYXML2_LIB XMLHandle
01988 {
01989 public:
01991 XMLHandle( XMLNode* node ) : _node( node ) {
01992 }
01994 XMLHandle( XMLNode& node ) : _node( &node ) {
01995 }
01997 XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
01998 }
02000 XMLHandle& operator=( const XMLHandle& ref ) {
02001 _node = ref._node;
02002 return *this;
02003 }
02004
02006 XMLHandle FirstChild() {
02007 return XMLHandle( _node ? _node->FirstChild() : 0 );
02008 }
02010 XMLHandle FirstChildElement( const char* name = 0 ) {
02011 return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
02012 }
02014 XMLHandle LastChild() {
02015 return XMLHandle( _node ? _node->LastChild() : 0 );
02016 }
02018 XMLHandle LastChildElement( const char* name = 0 ) {
02019 return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
02020 }
02022 XMLHandle PreviousSibling() {
02023 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
02024 }
02026 XMLHandle PreviousSiblingElement( const char* name = 0 ) {
02027 return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02028 }
02030 XMLHandle NextSibling() {
02031 return XMLHandle( _node ? _node->NextSibling() : 0 );
02032 }
02034 XMLHandle NextSiblingElement( const char* name = 0 ) {
02035 return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02036 }
02037
02039 XMLNode* ToNode() {
02040 return _node;
02041 }
02043 XMLElement* ToElement() {
02044 return ( _node ? _node->ToElement() : 0 );
02045 }
02047 XMLText* ToText() {
02048 return ( _node ? _node->ToText() : 0 );
02049 }
02051 XMLUnknown* ToUnknown() {
02052 return ( _node ? _node->ToUnknown() : 0 );
02053 }
02055 XMLDeclaration* ToDeclaration() {
02056 return ( _node ? _node->ToDeclaration() : 0 );
02057 }
02058
02059 private:
02060 XMLNode* _node;
02061 };
02062
02063
02068 class TINYXML2_LIB XMLConstHandle
02069 {
02070 public:
02071 XMLConstHandle( const XMLNode* node ) : _node( node ) {
02072 }
02073 XMLConstHandle( const XMLNode& node ) : _node( &node ) {
02074 }
02075 XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
02076 }
02077
02078 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
02079 _node = ref._node;
02080 return *this;
02081 }
02082
02083 const XMLConstHandle FirstChild() const {
02084 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
02085 }
02086 const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
02087 return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
02088 }
02089 const XMLConstHandle LastChild() const {
02090 return XMLConstHandle( _node ? _node->LastChild() : 0 );
02091 }
02092 const XMLConstHandle LastChildElement( const char* name = 0 ) const {
02093 return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
02094 }
02095 const XMLConstHandle PreviousSibling() const {
02096 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
02097 }
02098 const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
02099 return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02100 }
02101 const XMLConstHandle NextSibling() const {
02102 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
02103 }
02104 const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
02105 return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02106 }
02107
02108
02109 const XMLNode* ToNode() const {
02110 return _node;
02111 }
02112 const XMLElement* ToElement() const {
02113 return ( _node ? _node->ToElement() : 0 );
02114 }
02115 const XMLText* ToText() const {
02116 return ( _node ? _node->ToText() : 0 );
02117 }
02118 const XMLUnknown* ToUnknown() const {
02119 return ( _node ? _node->ToUnknown() : 0 );
02120 }
02121 const XMLDeclaration* ToDeclaration() const {
02122 return ( _node ? _node->ToDeclaration() : 0 );
02123 }
02124
02125 private:
02126 const XMLNode* _node;
02127 };
02128
02129
02172 class TINYXML2_LIB XMLPrinter : public XMLVisitor
02173 {
02174 public:
02181 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
02182 virtual ~XMLPrinter() {}
02183
02185 void PushHeader( bool writeBOM, bool writeDeclaration );
02189 void OpenElement( const char* name, bool compactMode=false );
02191 void PushAttribute( const char* name, const char* value );
02192 void PushAttribute( const char* name, int value );
02193 void PushAttribute( const char* name, unsigned value );
02194 void PushAttribute(const char* name, int64_t value);
02195 void PushAttribute( const char* name, bool value );
02196 void PushAttribute( const char* name, double value );
02198 virtual void CloseElement( bool compactMode=false );
02199
02201 void PushText( const char* text, bool cdata=false );
02203 void PushText( int value );
02205 void PushText( unsigned value );
02207 void PushText(int64_t value);
02209 void PushText( bool value );
02211 void PushText( float value );
02213 void PushText( double value );
02214
02216 void PushComment( const char* comment );
02217
02218 void PushDeclaration( const char* value );
02219 void PushUnknown( const char* value );
02220
02221 virtual bool VisitEnter( const XMLDocument& );
02222 virtual bool VisitExit( const XMLDocument& ) {
02223 return true;
02224 }
02225
02226 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
02227 virtual bool VisitExit( const XMLElement& element );
02228
02229 virtual bool Visit( const XMLText& text );
02230 virtual bool Visit( const XMLComment& comment );
02231 virtual bool Visit( const XMLDeclaration& declaration );
02232 virtual bool Visit( const XMLUnknown& unknown );
02233
02238 const char* CStr() const {
02239 return _buffer.Mem();
02240 }
02246 int CStrSize() const {
02247 return _buffer.Size();
02248 }
02253 void ClearBuffer() {
02254 _buffer.Clear();
02255 _buffer.Push(0);
02256 _firstElement = true;
02257 }
02258
02259 protected:
02260 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
02261
02265 virtual void PrintSpace( int depth );
02266 void Print( const char* format, ... );
02267 void Write( const char* data, size_t size );
02268 inline void Write( const char* data ) { Write( data, strlen( data ) ); }
02269 void Putc( char ch );
02270
02271 void SealElementIfJustOpened();
02272 bool _elementJustOpened;
02273 DynArray< const char*, 10 > _stack;
02274
02275 private:
02276 void PrintString( const char*, bool restrictedEntitySet );
02277
02278 bool _firstElement;
02279 FILE* _fp;
02280 int _depth;
02281 int _textDepth;
02282 bool _processEntities;
02283 bool _compactMode;
02284
02285 enum {
02286 ENTITY_RANGE = 64,
02287 BUF_SIZE = 200
02288 };
02289 bool _entityFlag[ENTITY_RANGE];
02290 bool _restrictedEntityFlag[ENTITY_RANGE];
02291
02292 DynArray< char, 20 > _buffer;
02293
02294
02295 XMLPrinter( const XMLPrinter& );
02296 XMLPrinter& operator=( const XMLPrinter& );
02297 };
02298
02299
02300 }
02301
02302 #if defined(_MSC_VER)
02303 # pragma warning(pop)
02304 #endif
02305
02306 #endif // TINYXML2_INCLUDED