00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028
00029 #ifdef _MSC_VER
00030 #pragma warning( disable : 4530 )
00031 #pragma warning( disable : 4786 )
00032 #endif
00033
00034 #include <ctype.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <assert.h>
00039
00040
00041 #if defined( _DEBUG ) && !defined( DEBUG )
00042 #define DEBUG
00043 #endif
00044
00045 #if defined( DEBUG ) && defined( _MSC_VER )
00046 #include <windows.h>
00047 #define TIXML_LOG OutputDebugString
00048 #else
00049 #define TIXML_LOG printf
00050 #endif
00051
00052
00053 #ifdef TIXML_USE_STL
00054 #include <string>
00055 #define TIXML_STRING std::string
00056 #define TIXML_ISTREAM std::istream
00057 #define TIXML_OSTREAM std::ostream
00058 #else
00059 #include "tinystr.h"
00060 #define TIXML_STRING TiXmlString
00061 #define TIXML_OSTREAM TiXmlOutStream
00062 #endif
00063
00064 class TiXmlDocument;
00065 class TiXmlElement;
00066 class TiXmlComment;
00067 class TiXmlUnknown;
00068 class TiXmlAttribute;
00069 class TiXmlText;
00070 class TiXmlDeclaration;
00071
00072
00095 class TiXmlBase
00096 {
00097 friend class TiXmlNode;
00098 friend class TiXmlElement;
00099 friend class TiXmlDocument;
00100
00101 public:
00102 TiXmlBase() {}
00103 virtual ~TiXmlBase() {}
00104
00110 virtual void Print( FILE* cfile, int depth ) const = 0;
00111
00118 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
00119
00121 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
00122
00123 protected:
00124
00125
00126 class StringToBuffer
00127 {
00128 public:
00129 StringToBuffer( const TIXML_STRING& str );
00130 ~StringToBuffer();
00131 char* buffer;
00132 };
00133
00134 static const char* SkipWhiteSpace( const char* );
00135 inline static bool IsWhiteSpace( int c ) { return ( isspace( c ) || c == '\n' || c == '\r' ); }
00136
00137 virtual void StreamOut (TIXML_OSTREAM *) const = 0;
00138
00139 #ifdef TIXML_USE_STL
00140 static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
00141 static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
00142 #endif
00143
00144
00145
00146
00147
00148 static const char* ReadName( const char* p, TIXML_STRING* name );
00149
00150
00151
00152
00153 static const char* ReadText( const char* in,
00154 TIXML_STRING* text,
00155 bool ignoreWhiteSpace,
00156 const char* endTag,
00157 bool ignoreCase );
00158 virtual const char* Parse( const char* p ) = 0;
00159
00160
00161 static const char* GetEntity( const char* in, char* value );
00162
00163
00164 inline static const char* GetChar( const char* p, char* value )
00165 {
00166 assert( p );
00167 if ( *p == '&' )
00168 {
00169 return GetEntity( p, value );
00170 }
00171 else
00172 {
00173 *value = *p;
00174 return p+1;
00175 }
00176 }
00177
00178
00179
00180 static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
00181
00182 static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00183
00184
00185 bool static StringEqual( const char* p,
00186 const char* endTag,
00187 bool ignoreCase );
00188
00189
00190 enum
00191 {
00192 TIXML_NO_ERROR = 0,
00193 TIXML_ERROR,
00194 TIXML_ERROR_OPENING_FILE,
00195 TIXML_ERROR_OUT_OF_MEMORY,
00196 TIXML_ERROR_PARSING_ELEMENT,
00197 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00198 TIXML_ERROR_READING_ELEMENT_VALUE,
00199 TIXML_ERROR_READING_ATTRIBUTES,
00200 TIXML_ERROR_PARSING_EMPTY,
00201 TIXML_ERROR_READING_END_TAG,
00202 TIXML_ERROR_PARSING_UNKNOWN,
00203 TIXML_ERROR_PARSING_COMMENT,
00204 TIXML_ERROR_PARSING_DECLARATION,
00205 TIXML_ERROR_DOCUMENT_EMPTY,
00206
00207 TIXML_ERROR_STRING_COUNT
00208 };
00209 static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00210
00211 private:
00212 struct Entity
00213 {
00214 const char* str;
00215 unsigned int strLength;
00216 char chr;
00217 };
00218 enum
00219 {
00220 NUM_ENTITY = 5,
00221 MAX_ENTITY_LENGTH = 6
00222
00223 };
00224 static Entity entity[ NUM_ENTITY ];
00225 static bool condenseWhiteSpace;
00226 };
00227
00228
00235 class TiXmlNode : public TiXmlBase
00236 {
00237 friend class TiXmlDocument;
00238 friend class TiXmlElement;
00239
00240 public:
00241 #ifdef TIXML_USE_STL
00242
00246 friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00247
00263 friend std::ostream & operator<< (std::ostream& out, const TiXmlNode& base);
00264
00265 #else
00266
00267 friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
00268 #endif
00269
00273 enum NodeType
00274 {
00275 DOCUMENT,
00276 ELEMENT,
00277 COMMENT,
00278 UNKNOWN,
00279 TEXT,
00280 DECLARATION,
00281 TYPECOUNT
00282 };
00283
00284 virtual ~TiXmlNode();
00285
00298 const char * Value () const { return value.c_str (); }
00299
00309 void SetValue (const char * _value) { value = _value;}
00310
00311 #ifdef TIXML_USE_STL
00312
00313 void SetValue( const std::string& value )
00314 {
00315 StringToBuffer buf( value );
00316 SetValue( buf.buffer ? buf.buffer : "" );
00317 }
00318 #endif
00319
00321 void Clear();
00322
00324 TiXmlNode* Parent() const { return parent; }
00325
00326 TiXmlNode* FirstChild() const { return firstChild; }
00327 TiXmlNode* FirstChild( const char * value ) const;
00328
00329 TiXmlNode* LastChild() const { return lastChild; }
00330 TiXmlNode* LastChild( const char * value ) const;
00331
00332 #ifdef TIXML_USE_STL
00333 TiXmlNode* FirstChild( const std::string& value ) const { return FirstChild (value.c_str ()); }
00334 TiXmlNode* LastChild( const std::string& value ) const { return LastChild (value.c_str ()); }
00335 #endif
00336
00353 TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
00354
00356 TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
00357
00358 #ifdef TIXML_USE_STL
00359 TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const { return IterateChildren (value.c_str (), previous); }
00360 #endif
00361
00365 TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00366
00370 TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00371
00375 TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
00376
00380 TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00381
00383 bool RemoveChild( TiXmlNode* removeThis );
00384
00386 TiXmlNode* PreviousSibling() const { return prev; }
00387
00389 TiXmlNode* PreviousSibling( const char * ) const;
00390
00391 #ifdef TIXML_USE_STL
00392 TiXmlNode* PreviousSibling( const std::string& value ) const { return PreviousSibling (value.c_str ()); }
00393 TiXmlNode* NextSibling( const std::string& value) const { return NextSibling (value.c_str ()); }
00394 #endif
00395
00397 TiXmlNode* NextSibling() const { return next; }
00398
00400 TiXmlNode* NextSibling( const char * ) const;
00401
00406 TiXmlElement* NextSiblingElement() const;
00407
00412 TiXmlElement* NextSiblingElement( const char * ) const;
00413
00414 #ifdef TIXML_USE_STL
00415 TiXmlElement* NextSiblingElement( const std::string& value) const { return NextSiblingElement (value.c_str ()); }
00416 #endif
00417
00419 TiXmlElement* FirstChildElement() const;
00420
00422 TiXmlElement* FirstChildElement( const char * value ) const;
00423
00424 #ifdef TIXML_USE_STL
00425 TiXmlElement* FirstChildElement( const std::string& value ) const { return FirstChildElement (value.c_str ()); }
00426 #endif
00427
00429 virtual int Type() const { return type; }
00430
00434 TiXmlDocument* GetDocument() const;
00435
00437 bool NoChildren() const { return !firstChild; }
00438
00439 TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; }
00440 TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; }
00441 TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; }
00442 TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; }
00443 TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; }
00444 TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; }
00445
00446 virtual TiXmlNode* Clone() const = 0;
00447
00448 void SetUserData( void* user ) { userData = user; }
00449 void* GetUserData() { return userData; }
00450
00451 protected:
00452 TiXmlNode( NodeType type );
00453
00454 #ifdef TIXML_USE_STL
00455
00456 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
00457 #endif
00458
00459
00460 TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00461
00462
00463 TiXmlNode* Identify( const char* start );
00464 void CopyToClone( TiXmlNode* target ) const { target->SetValue (value.c_str() );
00465 target->userData = userData; }
00466
00467
00468 TIXML_STRING SValue() const { return value ; }
00469
00470 TiXmlNode* parent;
00471 NodeType type;
00472
00473 TiXmlNode* firstChild;
00474 TiXmlNode* lastChild;
00475
00476 TIXML_STRING value;
00477
00478 TiXmlNode* prev;
00479 TiXmlNode* next;
00480 void* userData;
00481 };
00482
00483
00493 class TiXmlAttribute : public TiXmlBase
00494 {
00495 friend class TiXmlAttributeSet;
00496
00497 public:
00499 TiXmlAttribute() : prev( 0 ), next( 0 ) {}
00500
00501 #ifdef TIXML_USE_STL
00502
00503 TiXmlAttribute( const std::string& _name, const std::string& _value )
00504 {
00505 name = _name;
00506 value = _value;
00507 }
00508 #endif
00509
00511 TiXmlAttribute( const char * _name, const char * _value ): name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
00512 const char* Name() const { return name.c_str (); }
00513 const char* Value() const { return value.c_str (); }
00514 const int IntValue() const;
00515 const double DoubleValue() const;
00516
00517 void SetName( const char* _name ) { name = _name; }
00518 void SetValue( const char* _value ) { value = _value; }
00519
00520 void SetIntValue( int value );
00521 void SetDoubleValue( double value );
00522
00523 #ifdef TIXML_USE_STL
00524
00525 void SetName( const std::string& _name )
00526 {
00527 StringToBuffer buf( _name );
00528 SetName ( buf.buffer ? buf.buffer : "error" );
00529 }
00531 void SetValue( const std::string& _value )
00532 {
00533 StringToBuffer buf( _value );
00534 SetValue( buf.buffer ? buf.buffer : "error" );
00535 }
00536 #endif
00537
00539 TiXmlAttribute* Next() const;
00541 TiXmlAttribute* Previous() const;
00542
00543 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00544 bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
00545 bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
00546
00547
00548
00549
00550
00551 virtual const char* Parse( const char* p );
00552
00553
00554 virtual void Print( FILE* cfile, int depth ) const;
00555
00556 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00557
00558
00559 void SetDocument( TiXmlDocument* doc ) { document = doc; }
00560
00561 private:
00562 TiXmlDocument* document;
00563 TIXML_STRING name;
00564 TIXML_STRING value;
00565 TiXmlAttribute* prev;
00566 TiXmlAttribute* next;
00567 };
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 class TiXmlAttributeSet
00583 {
00584 public:
00585 TiXmlAttributeSet();
00586 ~TiXmlAttributeSet();
00587
00588 void Add( TiXmlAttribute* attribute );
00589 void Remove( TiXmlAttribute* attribute );
00590
00591 TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00592 TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00593 TiXmlAttribute* Find( const char * name ) const;
00594
00595 private:
00596 TiXmlAttribute sentinel;
00597 };
00598
00599
00604 class TiXmlElement : public TiXmlNode
00605 {
00606 public:
00608 TiXmlElement (const char * in_value);
00609
00610 #ifdef TIXML_USE_STL
00611
00612 TiXmlElement( const std::string& _value ) : TiXmlNode( TiXmlNode::ELEMENT )
00613 {
00614 firstChild = lastChild = 0;
00615 value = _value;
00616 }
00617 #endif
00618
00619 virtual ~TiXmlElement();
00620
00624 const char* Attribute( const char* name ) const;
00625
00632 const char* Attribute( const char* name, int* i ) const;
00633
00637 void SetAttribute( const char* name, const char * value );
00638
00639 #ifdef TIXML_USE_STL
00640 const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); }
00641 const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); }
00642
00644 void SetAttribute( const std::string& name, const std::string& value )
00645 {
00646 StringToBuffer n( name );
00647 StringToBuffer v( value );
00648 if ( n.buffer && v.buffer )
00649 SetAttribute (n.buffer, v.buffer );
00650 }
00652 void SetAttribute( const std::string& name, int value )
00653 {
00654 StringToBuffer n( name );
00655 if ( n.buffer )
00656 SetAttribute (n.buffer, value);
00657 }
00658 #endif
00659
00663 void SetAttribute( const char * name, int value );
00664
00667 void RemoveAttribute( const char * name );
00668 #ifdef TIXML_USE_STL
00669 void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); }
00670 #endif
00671
00672 TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); }
00673 TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); }
00674
00675
00676 virtual TiXmlNode* Clone() const;
00677
00678
00679 virtual void Print( FILE* cfile, int depth ) const;
00680
00681 protected:
00682
00683
00684 #ifdef TIXML_USE_STL
00685 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00686 #endif
00687 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00688
00689
00690
00691
00692
00693 virtual const char* Parse( const char* p );
00694
00695
00696
00697
00698
00699 const char* ReadValue( const char* in );
00700
00701 private:
00702 TiXmlAttributeSet attributeSet;
00703 };
00704
00705
00708 class TiXmlComment : public TiXmlNode
00709 {
00710 public:
00712 TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
00713 virtual ~TiXmlComment() {}
00714
00715
00716 virtual TiXmlNode* Clone() const;
00717
00718 virtual void Print( FILE* cfile, int depth ) const;
00719 protected:
00720
00721 #ifdef TIXML_USE_STL
00722 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00723 #endif
00724 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00725
00726
00727
00728
00729 virtual const char* Parse( const char* p );
00730 };
00731
00732
00735 class TiXmlText : public TiXmlNode
00736 {
00737 friend class TiXmlElement;
00738 public:
00740 TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
00741 {
00742 SetValue( initValue );
00743 }
00744 virtual ~TiXmlText() {}
00745
00746 #ifdef TIXML_USE_STL
00747
00748 TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
00749 {
00750 SetValue( initValue );
00751 }
00752 #endif
00753
00754 protected :
00755
00756 virtual TiXmlNode* Clone() const;
00757
00758 virtual void Print( FILE* cfile, int depth ) const;
00759 virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00760
00761 bool Blank() const;
00762
00763
00764
00765
00766 virtual const char* Parse( const char* p );
00767
00768 #ifdef TIXML_USE_STL
00769 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00770 #endif
00771 };
00772
00773
00787 class TiXmlDeclaration : public TiXmlNode
00788 {
00789 public:
00791 TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
00792
00793 #ifdef TIXML_USE_STL
00794
00795 TiXmlDeclaration(
00796 const std::string& _version,
00797 const std::string& _encoding,
00798 const std::string& _standalone )
00799 : TiXmlNode( TiXmlNode::DECLARATION )
00800 {
00801 version = _version;
00802 encoding = _encoding;
00803 standalone = _standalone;
00804 }
00805 #endif
00806
00808 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
00809 const char * _encoding,
00810 const char * _standalone );
00811
00812 virtual ~TiXmlDeclaration() {}
00813
00815 const char * Version() const { return version.c_str (); }
00817 const char * Encoding() const { return encoding.c_str (); }
00819 const char * Standalone() const { return standalone.c_str (); }
00820
00821
00822 virtual TiXmlNode* Clone() const;
00823
00824 virtual void Print( FILE* cfile, int depth ) const;
00825
00826 protected:
00827
00828 #ifdef TIXML_USE_STL
00829 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00830 #endif
00831 virtual void StreamOut ( TIXML_OSTREAM * out) const;
00832
00833
00834
00835
00836 virtual const char* Parse( const char* p );
00837
00838 private:
00839 TIXML_STRING version;
00840 TIXML_STRING encoding;
00841 TIXML_STRING standalone;
00842 };
00843
00844
00850 class TiXmlUnknown : public TiXmlNode
00851 {
00852 public:
00853 TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
00854 virtual ~TiXmlUnknown() {}
00855
00856
00857 virtual TiXmlNode* Clone() const;
00858
00859 virtual void Print( FILE* cfile, int depth ) const;
00860 protected:
00861
00862 #ifdef TIXML_USE_STL
00863 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00864 #endif
00865 virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00866
00867
00868
00869
00870 virtual const char* Parse( const char* p );
00871 };
00872
00873
00878 class TiXmlDocument : public TiXmlNode
00879 {
00880 public:
00882 TiXmlDocument();
00884 TiXmlDocument( const char * documentName );
00885
00886 #ifdef TIXML_USE_STL
00887
00888 TiXmlDocument( const std::string& documentName ) :
00889 TiXmlNode( TiXmlNode::DOCUMENT )
00890 {
00891 value = documentName;
00892 error = false;
00893 }
00894 #endif
00895
00896 virtual ~TiXmlDocument() {}
00897
00902 bool LoadFile();
00904 bool SaveFile() const;
00906 bool LoadFile( const char * filename );
00908 bool SaveFile( const char * filename ) const;
00909
00910 #ifdef TIXML_USE_STL
00911 bool LoadFile( const std::string& filename )
00912 {
00913 StringToBuffer f( filename );
00914 return ( f.buffer && LoadFile( f.buffer ));
00915 }
00916 bool SaveFile( const std::string& filename ) const
00917 {
00918 StringToBuffer f( filename );
00919 return ( f.buffer && SaveFile( f.buffer ));
00920 }
00921 #endif
00922
00924 virtual const char* Parse( const char* p );
00925
00930 TiXmlElement* RootElement() const { return FirstChildElement(); }
00931
00933 bool Error() const { return error; }
00934
00936 const char * ErrorDesc() const { return errorDesc.c_str (); }
00937
00941 const int ErrorId() const { return errorId; }
00942
00944 void ClearError() { error = false; errorId = 0; errorDesc = ""; }
00945
00947 void Print() const { Print( stdout, 0 ); }
00948
00949
00950 virtual void Print( FILE* cfile, int depth = 0 ) const;
00951
00952 void SetError( int err ) { assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
00953 error = true;
00954 errorId = err;
00955 errorDesc = errorString[ errorId ]; }
00956
00957 protected :
00958 virtual void StreamOut ( TIXML_OSTREAM * out) const;
00959
00960 virtual TiXmlNode* Clone() const;
00961 #ifdef TIXML_USE_STL
00962 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00963 #endif
00964
00965 private:
00966 bool error;
00967 int errorId;
00968 TIXML_STRING errorDesc;
00969 };
00970
00971 #endif
00972