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 BT_TINYXML2_INCLUDED
00025 #define BT_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 #ifdef _WIN32
00068 # ifdef TINYXML2_EXPORT
00069 # define TINYXML2_LIB __declspec(dllexport)
00070 # elif defined(TINYXML2_IMPORT)
00071 # define TINYXML2_LIB __declspec(dllimport)
00072 # else
00073 # define TINYXML2_LIB
00074 # endif
00075 #elif __GNUC__ >= 4
00076 # define TINYXML2_LIB __attribute__((visibility("hidden")))
00077 #else
00078 # define TINYXML2_LIB
00079 #endif
00080
00081
00082 #if defined(TINYXML2_DEBUG)
00083 # if defined(_MSC_VER)
00084 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
00085 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); }
00086 # elif defined (ANDROID_NDK)
00087 # include <android/log.h>
00088 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
00089 # else
00090 # include <assert.h>
00091 # define TIXMLASSERT assert
00092 # endif
00093 #else
00094 # define TIXMLASSERT( x ) {}
00095 #endif
00096
00097
00098
00099
00100
00101 static const int TIXML2_MAJOR_VERSION = 7;
00102 static const int TIXML2_MINOR_VERSION = 0;
00103 static const int TIXML2_PATCH_VERSION = 1;
00104
00105 #define TINYXML2_MAJOR_VERSION 7
00106 #define TINYXML2_MINOR_VERSION 0
00107 #define TINYXML2_PATCH_VERSION 1
00108
00109
00110
00111
00112
00113
00114 static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
00115
00116 namespace BT_TinyXML2
00117 {
00118 class XMLDocument;
00119 class XMLElement;
00120 class XMLAttribute;
00121 class XMLComment;
00122 class XMLText;
00123 class XMLDeclaration;
00124 class XMLUnknown;
00125 class XMLPrinter;
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 class TINYXML2_LIB StrPair
00136 {
00137 public:
00138 enum {
00139 NEEDS_ENTITY_PROCESSING = 0x01,
00140 NEEDS_NEWLINE_NORMALIZATION = 0x02,
00141 NEEDS_WHITESPACE_COLLAPSING = 0x04,
00142
00143 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00144 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
00145 ATTRIBUTE_NAME = 0,
00146 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00147 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
00148 COMMENT = NEEDS_NEWLINE_NORMALIZATION
00149 };
00150
00151 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
00152 ~StrPair();
00153
00154 void Set( char* start, char* end, int flags ) {
00155 TIXMLASSERT( start );
00156 TIXMLASSERT( end );
00157 Reset();
00158 _start = start;
00159 _end = end;
00160 _flags = flags | NEEDS_FLUSH;
00161 }
00162
00163 const char* GetStr();
00164
00165 bool Empty() const {
00166 return _start == _end;
00167 }
00168
00169 void SetInternedStr( const char* str ) {
00170 Reset();
00171 _start = const_cast<char*>(str);
00172 }
00173
00174 void SetStr( const char* str, int flags=0 );
00175
00176 char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
00177 char* ParseName( char* in );
00178
00179 void TransferTo( StrPair* other );
00180 void Reset();
00181
00182 private:
00183 void CollapseWhitespace();
00184
00185 enum {
00186 NEEDS_FLUSH = 0x100,
00187 NEEDS_DELETE = 0x200
00188 };
00189
00190 int _flags;
00191 char* _start;
00192 char* _end;
00193
00194 StrPair( const StrPair& other );
00195 void operator=( const StrPair& other );
00196 };
00197
00198
00199
00200
00201
00202
00203
00204 template <class T, int INITIAL_SIZE>
00205 class DynArray
00206 {
00207 public:
00208 DynArray() :
00209 _mem( _pool ),
00210 _allocated( INITIAL_SIZE ),
00211 _size( 0 )
00212 {
00213 }
00214
00215 ~DynArray() {
00216 if ( _mem != _pool ) {
00217 delete [] _mem;
00218 }
00219 }
00220
00221 void Clear() {
00222 _size = 0;
00223 }
00224
00225 void Push( T t ) {
00226 TIXMLASSERT( _size < INT_MAX );
00227 EnsureCapacity( _size+1 );
00228 _mem[_size] = t;
00229 ++_size;
00230 }
00231
00232 T* PushArr( int count ) {
00233 TIXMLASSERT( count >= 0 );
00234 TIXMLASSERT( _size <= INT_MAX - count );
00235 EnsureCapacity( _size+count );
00236 T* ret = &_mem[_size];
00237 _size += count;
00238 return ret;
00239 }
00240
00241 T Pop() {
00242 TIXMLASSERT( _size > 0 );
00243 --_size;
00244 return _mem[_size];
00245 }
00246
00247 void PopArr( int count ) {
00248 TIXMLASSERT( _size >= count );
00249 _size -= count;
00250 }
00251
00252 bool Empty() const {
00253 return _size == 0;
00254 }
00255
00256 T& operator[](int i) {
00257 TIXMLASSERT( i>= 0 && i < _size );
00258 return _mem[i];
00259 }
00260
00261 const T& operator[](int i) const {
00262 TIXMLASSERT( i>= 0 && i < _size );
00263 return _mem[i];
00264 }
00265
00266 const T& PeekTop() const {
00267 TIXMLASSERT( _size > 0 );
00268 return _mem[ _size - 1];
00269 }
00270
00271 int Size() const {
00272 TIXMLASSERT( _size >= 0 );
00273 return _size;
00274 }
00275
00276 int Capacity() const {
00277 TIXMLASSERT( _allocated >= INITIAL_SIZE );
00278 return _allocated;
00279 }
00280
00281 void SwapRemove(int i) {
00282 TIXMLASSERT(i >= 0 && i < _size);
00283 TIXMLASSERT(_size > 0);
00284 _mem[i] = _mem[_size - 1];
00285 --_size;
00286 }
00287
00288 const T* Mem() const {
00289 TIXMLASSERT( _mem );
00290 return _mem;
00291 }
00292
00293 T* Mem() {
00294 TIXMLASSERT( _mem );
00295 return _mem;
00296 }
00297
00298 private:
00299 DynArray( const DynArray& );
00300 void operator=( const DynArray& );
00301
00302 void EnsureCapacity( int cap ) {
00303 TIXMLASSERT( cap > 0 );
00304 if ( cap > _allocated ) {
00305 TIXMLASSERT( cap <= INT_MAX / 2 );
00306 int newAllocated = cap * 2;
00307 T* newMem = new T[newAllocated];
00308 TIXMLASSERT( newAllocated >= _size );
00309 memcpy( newMem, _mem, sizeof(T)*_size );
00310 if ( _mem != _pool ) {
00311 delete [] _mem;
00312 }
00313 _mem = newMem;
00314 _allocated = newAllocated;
00315 }
00316 }
00317
00318 T* _mem;
00319 T _pool[INITIAL_SIZE];
00320 int _allocated;
00321 int _size;
00322 };
00323
00324
00325
00326
00327
00328
00329 class MemPool
00330 {
00331 public:
00332 MemPool() {}
00333 virtual ~MemPool() {}
00334
00335 virtual int ItemSize() const = 0;
00336 virtual void* Alloc() = 0;
00337 virtual void Free( void* ) = 0;
00338 virtual void SetTracked() = 0;
00339 };
00340
00341
00342
00343
00344
00345 template< int ITEM_SIZE >
00346 class MemPoolT : public MemPool
00347 {
00348 public:
00349 MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
00350 ~MemPoolT() {
00351 MemPoolT< ITEM_SIZE >::Clear();
00352 }
00353
00354 void Clear() {
00355
00356 while( !_blockPtrs.Empty()) {
00357 Block* lastBlock = _blockPtrs.Pop();
00358 delete lastBlock;
00359 }
00360 _root = 0;
00361 _currentAllocs = 0;
00362 _nAllocs = 0;
00363 _maxAllocs = 0;
00364 _nUntracked = 0;
00365 }
00366
00367 virtual int ItemSize() const {
00368 return ITEM_SIZE;
00369 }
00370 int CurrentAllocs() const {
00371 return _currentAllocs;
00372 }
00373
00374 virtual void* Alloc() {
00375 if ( !_root ) {
00376
00377 Block* block = new Block();
00378 _blockPtrs.Push( block );
00379
00380 Item* blockItems = block->items;
00381 for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
00382 blockItems[i].next = &(blockItems[i + 1]);
00383 }
00384 blockItems[ITEMS_PER_BLOCK - 1].next = 0;
00385 _root = blockItems;
00386 }
00387 Item* const result = _root;
00388 TIXMLASSERT( result != 0 );
00389 _root = _root->next;
00390
00391 ++_currentAllocs;
00392 if ( _currentAllocs > _maxAllocs ) {
00393 _maxAllocs = _currentAllocs;
00394 }
00395 ++_nAllocs;
00396 ++_nUntracked;
00397 return result;
00398 }
00399
00400 virtual void Free( void* mem ) {
00401 if ( !mem ) {
00402 return;
00403 }
00404 --_currentAllocs;
00405 Item* item = static_cast<Item*>( mem );
00406 #ifdef TINYXML2_DEBUG
00407 memset( item, 0xfe, sizeof( *item ) );
00408 #endif
00409 item->next = _root;
00410 _root = item;
00411 }
00412 void Trace( const char* name ) {
00413 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
00414 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
00415 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
00416 }
00417
00418 void SetTracked() {
00419 --_nUntracked;
00420 }
00421
00422 int Untracked() const {
00423 return _nUntracked;
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
00438
00439 private:
00440 MemPoolT( const MemPoolT& );
00441 void operator=( const MemPoolT& );
00442
00443 union Item {
00444 Item* next;
00445 char itemData[ITEM_SIZE];
00446 };
00447 struct Block {
00448 Item items[ITEMS_PER_BLOCK];
00449 };
00450 DynArray< Block*, 10 > _blockPtrs;
00451 Item* _root;
00452
00453 int _currentAllocs;
00454 int _nAllocs;
00455 int _maxAllocs;
00456 int _nUntracked;
00457 };
00458
00459
00460
00480 class TINYXML2_LIB XMLVisitor
00481 {
00482 public:
00483 virtual ~XMLVisitor() {}
00484
00486 virtual bool VisitEnter( const XMLDocument& ) {
00487 return true;
00488 }
00490 virtual bool VisitExit( const XMLDocument& ) {
00491 return true;
00492 }
00493
00495 virtual bool VisitEnter( const XMLElement& , const XMLAttribute* ) {
00496 return true;
00497 }
00499 virtual bool VisitExit( const XMLElement& ) {
00500 return true;
00501 }
00502
00504 virtual bool Visit( const XMLDeclaration& ) {
00505 return true;
00506 }
00508 virtual bool Visit( const XMLText& ) {
00509 return true;
00510 }
00512 virtual bool Visit( const XMLComment& ) {
00513 return true;
00514 }
00516 virtual bool Visit( const XMLUnknown& ) {
00517 return true;
00518 }
00519 };
00520
00521
00522 enum XMLError {
00523 XML_SUCCESS = 0,
00524 XML_NO_ATTRIBUTE,
00525 XML_WRONG_ATTRIBUTE_TYPE,
00526 XML_ERROR_FILE_NOT_FOUND,
00527 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
00528 XML_ERROR_FILE_READ_ERROR,
00529 XML_ERROR_PARSING_ELEMENT,
00530 XML_ERROR_PARSING_ATTRIBUTE,
00531 XML_ERROR_PARSING_TEXT,
00532 XML_ERROR_PARSING_CDATA,
00533 XML_ERROR_PARSING_COMMENT,
00534 XML_ERROR_PARSING_DECLARATION,
00535 XML_ERROR_PARSING_UNKNOWN,
00536 XML_ERROR_EMPTY_DOCUMENT,
00537 XML_ERROR_MISMATCHED_ELEMENT,
00538 XML_ERROR_PARSING,
00539 XML_CAN_NOT_CONVERT_TEXT,
00540 XML_NO_TEXT_NODE,
00541 XML_ELEMENT_DEPTH_EXCEEDED,
00542
00543 XML_ERROR_COUNT
00544 };
00545
00546
00547
00548
00549
00550 class TINYXML2_LIB XMLUtil
00551 {
00552 public:
00553 static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
00554 TIXMLASSERT( p );
00555
00556 while( IsWhiteSpace(*p) ) {
00557 if (curLineNumPtr && *p == '\n') {
00558 ++(*curLineNumPtr);
00559 }
00560 ++p;
00561 }
00562 TIXMLASSERT( p );
00563 return p;
00564 }
00565 static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) {
00566 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
00567 }
00568
00569
00570
00571 static bool IsWhiteSpace( char p ) {
00572 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
00573 }
00574
00575 inline static bool IsNameStartChar( unsigned char ch ) {
00576 if ( ch >= 128 ) {
00577
00578 return true;
00579 }
00580 if ( isalpha( ch ) ) {
00581 return true;
00582 }
00583 return ch == ':' || ch == '_';
00584 }
00585
00586 inline static bool IsNameChar( unsigned char ch ) {
00587 return IsNameStartChar( ch )
00588 || isdigit( ch )
00589 || ch == '.'
00590 || ch == '-';
00591 }
00592
00593 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
00594 if ( p == q ) {
00595 return true;
00596 }
00597 TIXMLASSERT( p );
00598 TIXMLASSERT( q );
00599 TIXMLASSERT( nChar >= 0 );
00600 return strncmp( p, q, nChar ) == 0;
00601 }
00602
00603 inline static bool IsUTF8Continuation( char p ) {
00604 return ( p & 0x80 ) != 0;
00605 }
00606
00607 static const char* ReadBOM( const char* p, bool* hasBOM );
00608
00609
00610 static const char* GetCharacterRef( const char* p, char* value, int* length );
00611 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00612
00613
00614 static void ToStr( int v, char* buffer, int bufferSize );
00615 static void ToStr( unsigned v, char* buffer, int bufferSize );
00616 static void ToStr( bool v, char* buffer, int bufferSize );
00617 static void ToStr( float v, char* buffer, int bufferSize );
00618 static void ToStr( double v, char* buffer, int bufferSize );
00619 static void ToStr(int64_t v, char* buffer, int bufferSize);
00620
00621
00622 static bool ToInt( const char* str, int* value );
00623 static bool ToUnsigned( const char* str, unsigned* value );
00624 static bool ToBool( const char* str, bool* value );
00625 static bool ToFloat( const char* str, float* value );
00626 static bool ToDouble( const char* str, double* value );
00627 static bool ToInt64(const char* str, int64_t* value);
00628
00629
00630
00631
00632
00633
00634 static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
00635
00636 private:
00637 static const char* writeBoolTrue;
00638 static const char* writeBoolFalse;
00639 };
00640
00641
00667 class TINYXML2_LIB XMLNode
00668 {
00669 friend class XMLDocument;
00670 friend class XMLElement;
00671 public:
00672
00674 const XMLDocument* GetDocument() const {
00675 TIXMLASSERT( _document );
00676 return _document;
00677 }
00679 XMLDocument* GetDocument() {
00680 TIXMLASSERT( _document );
00681 return _document;
00682 }
00683
00685 virtual XMLElement* ToElement() {
00686 return 0;
00687 }
00689 virtual XMLText* ToText() {
00690 return 0;
00691 }
00693 virtual XMLComment* ToComment() {
00694 return 0;
00695 }
00697 virtual XMLDocument* ToDocument() {
00698 return 0;
00699 }
00701 virtual XMLDeclaration* ToDeclaration() {
00702 return 0;
00703 }
00705 virtual XMLUnknown* ToUnknown() {
00706 return 0;
00707 }
00708
00709 virtual const XMLElement* ToElement() const {
00710 return 0;
00711 }
00712 virtual const XMLText* ToText() const {
00713 return 0;
00714 }
00715 virtual const XMLComment* ToComment() const {
00716 return 0;
00717 }
00718 virtual const XMLDocument* ToDocument() const {
00719 return 0;
00720 }
00721 virtual const XMLDeclaration* ToDeclaration() const {
00722 return 0;
00723 }
00724 virtual const XMLUnknown* ToUnknown() const {
00725 return 0;
00726 }
00727
00737 const char* Value() const;
00738
00742 void SetValue( const char* val, bool staticMem=false );
00743
00745 int GetLineNum() const { return _parseLineNum; }
00746
00748 const XMLNode* Parent() const {
00749 return _parent;
00750 }
00751
00752 XMLNode* Parent() {
00753 return _parent;
00754 }
00755
00757 bool NoChildren() const {
00758 return !_firstChild;
00759 }
00760
00762 const XMLNode* FirstChild() const {
00763 return _firstChild;
00764 }
00765
00766 XMLNode* FirstChild() {
00767 return _firstChild;
00768 }
00769
00773 const XMLElement* FirstChildElement( const char* name = 0 ) const;
00774
00775 XMLElement* FirstChildElement( const char* name = 0 ) {
00776 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
00777 }
00778
00780 const XMLNode* LastChild() const {
00781 return _lastChild;
00782 }
00783
00784 XMLNode* LastChild() {
00785 return _lastChild;
00786 }
00787
00791 const XMLElement* LastChildElement( const char* name = 0 ) const;
00792
00793 XMLElement* LastChildElement( const char* name = 0 ) {
00794 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
00795 }
00796
00798 const XMLNode* PreviousSibling() const {
00799 return _prev;
00800 }
00801
00802 XMLNode* PreviousSibling() {
00803 return _prev;
00804 }
00805
00807 const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
00808
00809 XMLElement* PreviousSiblingElement( const char* name = 0 ) {
00810 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
00811 }
00812
00814 const XMLNode* NextSibling() const {
00815 return _next;
00816 }
00817
00818 XMLNode* NextSibling() {
00819 return _next;
00820 }
00821
00823 const XMLElement* NextSiblingElement( const char* name = 0 ) const;
00824
00825 XMLElement* NextSiblingElement( const char* name = 0 ) {
00826 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
00827 }
00828
00836 XMLNode* InsertEndChild( XMLNode* addThis );
00837
00838 XMLNode* LinkEndChild( XMLNode* addThis ) {
00839 return InsertEndChild( addThis );
00840 }
00848 XMLNode* InsertFirstChild( XMLNode* addThis );
00857 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
00858
00862 void DeleteChildren();
00863
00867 void DeleteChild( XMLNode* node );
00868
00878 virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
00879
00893 XMLNode* DeepClone( XMLDocument* target ) const;
00894
00901 virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
00902
00925 virtual bool Accept( XMLVisitor* visitor ) const = 0;
00926
00932 void SetUserData(void* userData) { _userData = userData; }
00933
00939 void* GetUserData() const { return _userData; }
00940
00941 protected:
00942 explicit XMLNode( XMLDocument* );
00943 virtual ~XMLNode();
00944
00945 virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
00946
00947 XMLDocument* _document;
00948 XMLNode* _parent;
00949 mutable StrPair _value;
00950 int _parseLineNum;
00951
00952 XMLNode* _firstChild;
00953 XMLNode* _lastChild;
00954
00955 XMLNode* _prev;
00956 XMLNode* _next;
00957
00958 void* _userData;
00959
00960 private:
00961 MemPool* _memPool;
00962 void Unlink( XMLNode* child );
00963 static void DeleteNode( XMLNode* node );
00964 void InsertChildPreamble( XMLNode* insertThis ) const;
00965 const XMLElement* ToElementWithName( const char* name ) const;
00966
00967 XMLNode( const XMLNode& );
00968 XMLNode& operator=( const XMLNode& );
00969 };
00970
00971
00984 class TINYXML2_LIB XMLText : public XMLNode
00985 {
00986 friend class XMLDocument;
00987 public:
00988 virtual bool Accept( XMLVisitor* visitor ) const;
00989
00990 virtual XMLText* ToText() {
00991 return this;
00992 }
00993 virtual const XMLText* ToText() const {
00994 return this;
00995 }
00996
00998 void SetCData( bool isCData ) {
00999 _isCData = isCData;
01000 }
01002 bool CData() const {
01003 return _isCData;
01004 }
01005
01006 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01007 virtual bool ShallowEqual( const XMLNode* compare ) const;
01008
01009 protected:
01010 explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
01011 virtual ~XMLText() {}
01012
01013 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01014
01015 private:
01016 bool _isCData;
01017
01018 XMLText( const XMLText& );
01019 XMLText& operator=( const XMLText& );
01020 };
01021
01022
01024 class TINYXML2_LIB XMLComment : public XMLNode
01025 {
01026 friend class XMLDocument;
01027 public:
01028 virtual XMLComment* ToComment() {
01029 return this;
01030 }
01031 virtual const XMLComment* ToComment() const {
01032 return this;
01033 }
01034
01035 virtual bool Accept( XMLVisitor* visitor ) const;
01036
01037 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01038 virtual bool ShallowEqual( const XMLNode* compare ) const;
01039
01040 protected:
01041 explicit XMLComment( XMLDocument* doc );
01042 virtual ~XMLComment();
01043
01044 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
01045
01046 private:
01047 XMLComment( const XMLComment& );
01048 XMLComment& operator=( const XMLComment& );
01049 };
01050
01051
01063 class TINYXML2_LIB XMLDeclaration : public XMLNode
01064 {
01065 friend class XMLDocument;
01066 public:
01067 virtual XMLDeclaration* ToDeclaration() {
01068 return this;
01069 }
01070 virtual const XMLDeclaration* ToDeclaration() const {
01071 return this;
01072 }
01073
01074 virtual bool Accept( XMLVisitor* visitor ) const;
01075
01076 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01077 virtual bool ShallowEqual( const XMLNode* compare ) const;
01078
01079 protected:
01080 explicit XMLDeclaration( XMLDocument* doc );
01081 virtual ~XMLDeclaration();
01082
01083 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01084
01085 private:
01086 XMLDeclaration( const XMLDeclaration& );
01087 XMLDeclaration& operator=( const XMLDeclaration& );
01088 };
01089
01090
01098 class TINYXML2_LIB XMLUnknown : public XMLNode
01099 {
01100 friend class XMLDocument;
01101 public:
01102 virtual XMLUnknown* ToUnknown() {
01103 return this;
01104 }
01105 virtual const XMLUnknown* ToUnknown() const {
01106 return this;
01107 }
01108
01109 virtual bool Accept( XMLVisitor* visitor ) const;
01110
01111 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01112 virtual bool ShallowEqual( const XMLNode* compare ) const;
01113
01114 protected:
01115 explicit XMLUnknown( XMLDocument* doc );
01116 virtual ~XMLUnknown();
01117
01118 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01119
01120 private:
01121 XMLUnknown( const XMLUnknown& );
01122 XMLUnknown& operator=( const XMLUnknown& );
01123 };
01124
01125
01126
01133 class TINYXML2_LIB XMLAttribute
01134 {
01135 friend class XMLElement;
01136 public:
01138 const char* Name() const;
01139
01141 const char* Value() const;
01142
01144 int GetLineNum() const { return _parseLineNum; }
01145
01147 const XMLAttribute* Next() const {
01148 return _next;
01149 }
01150
01155 int IntValue() const {
01156 int i = 0;
01157 QueryIntValue(&i);
01158 return i;
01159 }
01160
01161 int64_t Int64Value() const {
01162 int64_t i = 0;
01163 QueryInt64Value(&i);
01164 return i;
01165 }
01166
01168 unsigned UnsignedValue() const {
01169 unsigned i=0;
01170 QueryUnsignedValue( &i );
01171 return i;
01172 }
01174 bool BoolValue() const {
01175 bool b=false;
01176 QueryBoolValue( &b );
01177 return b;
01178 }
01180 double DoubleValue() const {
01181 double d=0;
01182 QueryDoubleValue( &d );
01183 return d;
01184 }
01186 float FloatValue() const {
01187 float f=0;
01188 QueryFloatValue( &f );
01189 return f;
01190 }
01191
01196 XMLError QueryIntValue( int* value ) const;
01198 XMLError QueryUnsignedValue( unsigned int* value ) const;
01200 XMLError QueryInt64Value(int64_t* value) const;
01202 XMLError QueryBoolValue( bool* value ) const;
01204 XMLError QueryDoubleValue( double* value ) const;
01206 XMLError QueryFloatValue( float* value ) const;
01207
01209 void SetAttribute( const char* value );
01211 void SetAttribute( int value );
01213 void SetAttribute( unsigned value );
01215 void SetAttribute(int64_t value);
01217 void SetAttribute( bool value );
01219 void SetAttribute( double value );
01221 void SetAttribute( float value );
01222
01223 private:
01224 enum { BUF_SIZE = 200 };
01225
01226 XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
01227 virtual ~XMLAttribute() {}
01228
01229 XMLAttribute( const XMLAttribute& );
01230 void operator=( const XMLAttribute& );
01231 void SetName( const char* name );
01232
01233 char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
01234
01235 mutable StrPair _name;
01236 mutable StrPair _value;
01237 int _parseLineNum;
01238 XMLAttribute* _next;
01239 MemPool* _memPool;
01240 };
01241
01242
01247 class TINYXML2_LIB XMLElement : public XMLNode
01248 {
01249 friend class XMLDocument;
01250 public:
01252 const char* Name() const {
01253 return Value();
01254 }
01256 void SetName( const char* str, bool staticMem=false ) {
01257 SetValue( str, staticMem );
01258 }
01259
01260 virtual XMLElement* ToElement() {
01261 return this;
01262 }
01263 virtual const XMLElement* ToElement() const {
01264 return this;
01265 }
01266 virtual bool Accept( XMLVisitor* visitor ) const;
01267
01291 const char* Attribute( const char* name, const char* value=0 ) const;
01292
01299 int IntAttribute(const char* name, int defaultValue = 0) const;
01301 unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
01303 int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
01305 bool BoolAttribute(const char* name, bool defaultValue = false) const;
01307 double DoubleAttribute(const char* name, double defaultValue = 0) const;
01309 float FloatAttribute(const char* name, float defaultValue = 0) const;
01310
01324 XMLError QueryIntAttribute( const char* name, int* value ) const {
01325 const XMLAttribute* a = FindAttribute( name );
01326 if ( !a ) {
01327 return XML_NO_ATTRIBUTE;
01328 }
01329 return a->QueryIntValue( value );
01330 }
01331
01333 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
01334 const XMLAttribute* a = FindAttribute( name );
01335 if ( !a ) {
01336 return XML_NO_ATTRIBUTE;
01337 }
01338 return a->QueryUnsignedValue( value );
01339 }
01340
01342 XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
01343 const XMLAttribute* a = FindAttribute(name);
01344 if (!a) {
01345 return XML_NO_ATTRIBUTE;
01346 }
01347 return a->QueryInt64Value(value);
01348 }
01349
01351 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
01352 const XMLAttribute* a = FindAttribute( name );
01353 if ( !a ) {
01354 return XML_NO_ATTRIBUTE;
01355 }
01356 return a->QueryBoolValue( value );
01357 }
01359 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
01360 const XMLAttribute* a = FindAttribute( name );
01361 if ( !a ) {
01362 return XML_NO_ATTRIBUTE;
01363 }
01364 return a->QueryDoubleValue( value );
01365 }
01367 XMLError QueryFloatAttribute( const char* name, float* value ) const {
01368 const XMLAttribute* a = FindAttribute( name );
01369 if ( !a ) {
01370 return XML_NO_ATTRIBUTE;
01371 }
01372 return a->QueryFloatValue( value );
01373 }
01374
01376 XMLError QueryStringAttribute(const char* name, const char** value) const {
01377 const XMLAttribute* a = FindAttribute(name);
01378 if (!a) {
01379 return XML_NO_ATTRIBUTE;
01380 }
01381 *value = a->Value();
01382 return XML_SUCCESS;
01383 }
01384
01385
01386
01404 XMLError QueryAttribute( const char* name, int* value ) const {
01405 return QueryIntAttribute( name, value );
01406 }
01407
01408 XMLError QueryAttribute( const char* name, unsigned int* value ) const {
01409 return QueryUnsignedAttribute( name, value );
01410 }
01411
01412 XMLError QueryAttribute(const char* name, int64_t* value) const {
01413 return QueryInt64Attribute(name, value);
01414 }
01415
01416 XMLError QueryAttribute( const char* name, bool* value ) const {
01417 return QueryBoolAttribute( name, value );
01418 }
01419
01420 XMLError QueryAttribute( const char* name, double* value ) const {
01421 return QueryDoubleAttribute( name, value );
01422 }
01423
01424 XMLError QueryAttribute( const char* name, float* value ) const {
01425 return QueryFloatAttribute( name, value );
01426 }
01427
01429 void SetAttribute( const char* name, const char* value ) {
01430 XMLAttribute* a = FindOrCreateAttribute( name );
01431 a->SetAttribute( value );
01432 }
01434 void SetAttribute( const char* name, int value ) {
01435 XMLAttribute* a = FindOrCreateAttribute( name );
01436 a->SetAttribute( value );
01437 }
01439 void SetAttribute( const char* name, unsigned value ) {
01440 XMLAttribute* a = FindOrCreateAttribute( name );
01441 a->SetAttribute( value );
01442 }
01443
01445 void SetAttribute(const char* name, int64_t value) {
01446 XMLAttribute* a = FindOrCreateAttribute(name);
01447 a->SetAttribute(value);
01448 }
01449
01451 void SetAttribute( const char* name, bool value ) {
01452 XMLAttribute* a = FindOrCreateAttribute( name );
01453 a->SetAttribute( value );
01454 }
01456 void SetAttribute( const char* name, double value ) {
01457 XMLAttribute* a = FindOrCreateAttribute( name );
01458 a->SetAttribute( value );
01459 }
01461 void SetAttribute( const char* name, float value ) {
01462 XMLAttribute* a = FindOrCreateAttribute( name );
01463 a->SetAttribute( value );
01464 }
01465
01469 void DeleteAttribute( const char* name );
01470
01472 const XMLAttribute* FirstAttribute() const {
01473 return _rootAttribute;
01474 }
01476 const XMLAttribute* FindAttribute( const char* name ) const;
01477
01506 const char* GetText() const;
01507
01542 void SetText( const char* inText );
01544 void SetText( int value );
01546 void SetText( unsigned value );
01548 void SetText(int64_t value);
01550 void SetText( bool value );
01552 void SetText( double value );
01554 void SetText( float value );
01555
01582 XMLError QueryIntText( int* ival ) const;
01584 XMLError QueryUnsignedText( unsigned* uval ) const;
01586 XMLError QueryInt64Text(int64_t* uval) const;
01588 XMLError QueryBoolText( bool* bval ) const;
01590 XMLError QueryDoubleText( double* dval ) const;
01592 XMLError QueryFloatText( float* fval ) const;
01593
01594 int IntText(int defaultValue = 0) const;
01595
01597 unsigned UnsignedText(unsigned defaultValue = 0) const;
01599 int64_t Int64Text(int64_t defaultValue = 0) const;
01601 bool BoolText(bool defaultValue = false) const;
01603 double DoubleText(double defaultValue = 0) const;
01605 float FloatText(float defaultValue = 0) const;
01606
01607
01608 enum ElementClosingType {
01609 OPEN,
01610 CLOSED,
01611 CLOSING
01612 };
01613 ElementClosingType ClosingType() const {
01614 return _closingType;
01615 }
01616 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01617 virtual bool ShallowEqual( const XMLNode* compare ) const;
01618
01619 protected:
01620 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01621
01622 private:
01623 XMLElement( XMLDocument* doc );
01624 virtual ~XMLElement();
01625 XMLElement( const XMLElement& );
01626 void operator=( const XMLElement& );
01627
01628 XMLAttribute* FindOrCreateAttribute( const char* name );
01629 char* ParseAttributes( char* p, int* curLineNumPtr );
01630 static void DeleteAttribute( XMLAttribute* attribute );
01631 XMLAttribute* CreateAttribute();
01632
01633 enum { BUF_SIZE = 200 };
01634 ElementClosingType _closingType;
01635
01636
01637
01638 XMLAttribute* _rootAttribute;
01639 };
01640
01641
01642 enum Whitespace {
01643 PRESERVE_WHITESPACE,
01644 COLLAPSE_WHITESPACE
01645 };
01646
01647
01653 class TINYXML2_LIB XMLDocument : public XMLNode
01654 {
01655 friend class XMLElement;
01656
01657
01658 friend class XMLNode;
01659 friend class XMLText;
01660 friend class XMLComment;
01661 friend class XMLDeclaration;
01662 friend class XMLUnknown;
01663 public:
01665 XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
01666 ~XMLDocument();
01667
01668 virtual XMLDocument* ToDocument() {
01669 TIXMLASSERT( this == _document );
01670 return this;
01671 }
01672 virtual const XMLDocument* ToDocument() const {
01673 TIXMLASSERT( this == _document );
01674 return this;
01675 }
01676
01687 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
01688
01694 XMLError LoadFile( const char* filename );
01695
01707 XMLError LoadFile( FILE* );
01708
01714 XMLError SaveFile( const char* filename, bool compact = false );
01715
01723 XMLError SaveFile( FILE* fp, bool compact = false );
01724
01725 bool ProcessEntities() const {
01726 return _processEntities;
01727 }
01728 Whitespace WhitespaceMode() const {
01729 return _whitespaceMode;
01730 }
01731
01735 bool HasBOM() const {
01736 return _writeBOM;
01737 }
01740 void SetBOM( bool useBOM ) {
01741 _writeBOM = useBOM;
01742 }
01743
01747 XMLElement* RootElement() {
01748 return FirstChildElement();
01749 }
01750 const XMLElement* RootElement() const {
01751 return FirstChildElement();
01752 }
01753
01768 void Print( XMLPrinter* streamer=0 ) const;
01769 virtual bool Accept( XMLVisitor* visitor ) const;
01770
01776 XMLElement* NewElement( const char* name );
01782 XMLComment* NewComment( const char* comment );
01788 XMLText* NewText( const char* text );
01800 XMLDeclaration* NewDeclaration( const char* text=0 );
01806 XMLUnknown* NewUnknown( const char* text );
01807
01812 void DeleteNode( XMLNode* node );
01813
01814 void ClearError() {
01815 SetError(XML_SUCCESS, 0, 0);
01816 }
01817
01819 bool Error() const {
01820 return _errorID != XML_SUCCESS;
01821 }
01823 XMLError ErrorID() const {
01824 return _errorID;
01825 }
01826 const char* ErrorName() const;
01827 static const char* ErrorIDToName(XMLError errorID);
01828
01832 const char* ErrorStr() const;
01833
01835 void PrintError() const;
01836
01838 int ErrorLineNum() const
01839 {
01840 return _errorLineNum;
01841 }
01842
01844 void Clear();
01845
01853 void DeepCopy(XMLDocument* target) const;
01854
01855
01856 char* Identify( char* p, XMLNode** node );
01857
01858
01859 void MarkInUse(XMLNode*);
01860
01861 virtual XMLNode* ShallowClone( XMLDocument* ) const {
01862 return 0;
01863 }
01864 virtual bool ShallowEqual( const XMLNode* ) const {
01865 return false;
01866 }
01867
01868 private:
01869 XMLDocument( const XMLDocument& );
01870 void operator=( const XMLDocument& );
01871
01872 bool _writeBOM;
01873 bool _processEntities;
01874 XMLError _errorID;
01875 Whitespace _whitespaceMode;
01876 mutable StrPair _errorStr;
01877 int _errorLineNum;
01878 char* _charBuffer;
01879 int _parseCurLineNum;
01880 int _parsingDepth;
01881
01882
01883
01884
01885
01886
01887 DynArray<XMLNode*, 10> _unlinked;
01888
01889 MemPoolT< sizeof(XMLElement) > _elementPool;
01890 MemPoolT< sizeof(XMLAttribute) > _attributePool;
01891 MemPoolT< sizeof(XMLText) > _textPool;
01892 MemPoolT< sizeof(XMLComment) > _commentPool;
01893
01894 static const char* _errorNames[XML_ERROR_COUNT];
01895
01896 void Parse();
01897
01898 void SetError( XMLError error, int lineNum, const char* format, ... );
01899
01900
01901
01902
01903 class DepthTracker {
01904 public:
01905 explicit DepthTracker(XMLDocument * document) {
01906 this->_document = document;
01907 document->PushDepth();
01908 }
01909 ~DepthTracker() {
01910 _document->PopDepth();
01911 }
01912 private:
01913 XMLDocument * _document;
01914 };
01915 void PushDepth();
01916 void PopDepth();
01917
01918 template<class NodeType, int PoolElementSize>
01919 NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
01920 };
01921
01922 template<class NodeType, int PoolElementSize>
01923 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
01924 {
01925 TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
01926 TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
01927 NodeType* returnNode = new (pool.Alloc()) NodeType( this );
01928 TIXMLASSERT( returnNode );
01929 returnNode->_memPool = &pool;
01930
01931 _unlinked.Push(returnNode);
01932 return returnNode;
01933 }
01934
01990 class TINYXML2_LIB XMLHandle
01991 {
01992 public:
01994 explicit XMLHandle( XMLNode* node ) : _node( node ) {
01995 }
01997 explicit XMLHandle( XMLNode& node ) : _node( &node ) {
01998 }
02000 XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
02001 }
02003 XMLHandle& operator=( const XMLHandle& ref ) {
02004 _node = ref._node;
02005 return *this;
02006 }
02007
02009 XMLHandle FirstChild() {
02010 return XMLHandle( _node ? _node->FirstChild() : 0 );
02011 }
02013 XMLHandle FirstChildElement( const char* name = 0 ) {
02014 return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
02015 }
02017 XMLHandle LastChild() {
02018 return XMLHandle( _node ? _node->LastChild() : 0 );
02019 }
02021 XMLHandle LastChildElement( const char* name = 0 ) {
02022 return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
02023 }
02025 XMLHandle PreviousSibling() {
02026 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
02027 }
02029 XMLHandle PreviousSiblingElement( const char* name = 0 ) {
02030 return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02031 }
02033 XMLHandle NextSibling() {
02034 return XMLHandle( _node ? _node->NextSibling() : 0 );
02035 }
02037 XMLHandle NextSiblingElement( const char* name = 0 ) {
02038 return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02039 }
02040
02042 XMLNode* ToNode() {
02043 return _node;
02044 }
02046 XMLElement* ToElement() {
02047 return ( _node ? _node->ToElement() : 0 );
02048 }
02050 XMLText* ToText() {
02051 return ( _node ? _node->ToText() : 0 );
02052 }
02054 XMLUnknown* ToUnknown() {
02055 return ( _node ? _node->ToUnknown() : 0 );
02056 }
02058 XMLDeclaration* ToDeclaration() {
02059 return ( _node ? _node->ToDeclaration() : 0 );
02060 }
02061
02062 private:
02063 XMLNode* _node;
02064 };
02065
02066
02071 class TINYXML2_LIB XMLConstHandle
02072 {
02073 public:
02074 explicit XMLConstHandle( const XMLNode* node ) : _node( node ) {
02075 }
02076 explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) {
02077 }
02078 XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
02079 }
02080
02081 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
02082 _node = ref._node;
02083 return *this;
02084 }
02085
02086 const XMLConstHandle FirstChild() const {
02087 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
02088 }
02089 const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
02090 return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
02091 }
02092 const XMLConstHandle LastChild() const {
02093 return XMLConstHandle( _node ? _node->LastChild() : 0 );
02094 }
02095 const XMLConstHandle LastChildElement( const char* name = 0 ) const {
02096 return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
02097 }
02098 const XMLConstHandle PreviousSibling() const {
02099 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
02100 }
02101 const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
02102 return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02103 }
02104 const XMLConstHandle NextSibling() const {
02105 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
02106 }
02107 const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
02108 return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02109 }
02110
02111
02112 const XMLNode* ToNode() const {
02113 return _node;
02114 }
02115 const XMLElement* ToElement() const {
02116 return ( _node ? _node->ToElement() : 0 );
02117 }
02118 const XMLText* ToText() const {
02119 return ( _node ? _node->ToText() : 0 );
02120 }
02121 const XMLUnknown* ToUnknown() const {
02122 return ( _node ? _node->ToUnknown() : 0 );
02123 }
02124 const XMLDeclaration* ToDeclaration() const {
02125 return ( _node ? _node->ToDeclaration() : 0 );
02126 }
02127
02128 private:
02129 const XMLNode* _node;
02130 };
02131
02132
02175 class TINYXML2_LIB XMLPrinter : public XMLVisitor
02176 {
02177 public:
02184 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
02185 virtual ~XMLPrinter() {}
02186
02188 void PushHeader( bool writeBOM, bool writeDeclaration );
02192 void OpenElement( const char* name, bool compactMode=false );
02194 void PushAttribute( const char* name, const char* value );
02195 void PushAttribute( const char* name, int value );
02196 void PushAttribute( const char* name, unsigned value );
02197 void PushAttribute(const char* name, int64_t value);
02198 void PushAttribute( const char* name, bool value );
02199 void PushAttribute( const char* name, double value );
02201 virtual void CloseElement( bool compactMode=false );
02202
02204 void PushText( const char* text, bool cdata=false );
02206 void PushText( int value );
02208 void PushText( unsigned value );
02210 void PushText(int64_t value);
02212 void PushText( bool value );
02214 void PushText( float value );
02216 void PushText( double value );
02217
02219 void PushComment( const char* comment );
02220
02221 void PushDeclaration( const char* value );
02222 void PushUnknown( const char* value );
02223
02224 virtual bool VisitEnter( const XMLDocument& );
02225 virtual bool VisitExit( const XMLDocument& ) {
02226 return true;
02227 }
02228
02229 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
02230 virtual bool VisitExit( const XMLElement& element );
02231
02232 virtual bool Visit( const XMLText& text );
02233 virtual bool Visit( const XMLComment& comment );
02234 virtual bool Visit( const XMLDeclaration& declaration );
02235 virtual bool Visit( const XMLUnknown& unknown );
02236
02241 const char* CStr() const {
02242 return _buffer.Mem();
02243 }
02249 int CStrSize() const {
02250 return _buffer.Size();
02251 }
02256 void ClearBuffer() {
02257 _buffer.Clear();
02258 _buffer.Push(0);
02259 _firstElement = true;
02260 }
02261
02262 protected:
02263 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
02264
02268 virtual void PrintSpace( int depth );
02269 void Print( const char* format, ... );
02270 void Write( const char* data, size_t size );
02271 inline void Write( const char* data ) { Write( data, strlen( data ) ); }
02272 void Putc( char ch );
02273
02274 void SealElementIfJustOpened();
02275 bool _elementJustOpened;
02276 DynArray< const char*, 10 > _stack;
02277
02278 private:
02279 void PrintString( const char*, bool restrictedEntitySet );
02280
02281 bool _firstElement;
02282 FILE* _fp;
02283 int _depth;
02284 int _textDepth;
02285 bool _processEntities;
02286 bool _compactMode;
02287
02288 enum {
02289 ENTITY_RANGE = 64,
02290 BUF_SIZE = 200
02291 };
02292 bool _entityFlag[ENTITY_RANGE];
02293 bool _restrictedEntityFlag[ENTITY_RANGE];
02294
02295 DynArray< char, 20 > _buffer;
02296
02297
02298 XMLPrinter( const XMLPrinter& );
02299 XMLPrinter& operator=( const XMLPrinter& );
02300 };
02301
02302
02303 }
02304
02305 #if defined(_MSC_VER)
02306 # pragma warning(pop)
02307 #endif
02308
02309 #endif // BT_TINYXML2_INCLUDED