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 <iostream>
00035 #include <ctype.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <assert.h>
00040
00041
00042 #if defined( _DEBUG ) && !defined( DEBUG )
00043 #define DEBUG
00044 #endif
00045
00046 #if defined( DEBUG ) && defined( _MSC_VER )
00047 #include <windows.h>
00048 #define TIXML_LOG OutputDebugString
00049 #else
00050 #define TIXML_LOG printf
00051 #endif
00052
00053
00054
00055 #define TIXML_USE_STL
00056
00057 #ifdef TIXML_USE_STL
00058 #include <string>
00059 #ifdef TIXML_NEED_STREAM
00060 #include <istream>
00061 #include <ostream>
00062 #endif
00063 #define TIXML_STRING std::string
00064 #define TIXML_ISTREAM std::istream
00065 #define TIXML_OSTREAM std::ostream
00066 #else
00067 #include "tinystr.h"
00068 #define TIXML_STRING TiXmlString
00069 #define TIXML_OSTREAM TiXmlOutStream
00070 #endif
00071
00072 class TiXmlDocument;
00073 class TiXmlElement;
00074 class TiXmlComment;
00075 class TiXmlUnknown;
00076 class TiXmlAttribute;
00077 class TiXmlText;
00078 class TiXmlDeclaration;
00079
00080
00103 class TiXmlBase
00104 {
00105 friend class TiXmlNode;
00106 friend class TiXmlElement;
00107 friend class TiXmlDocument;
00108
00109 public:
00110 TiXmlBase() {}
00111 virtual ~TiXmlBase() {}
00112
00118 virtual void Print( FILE* cfile, int depth ) const = 0;
00119
00126 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
00127
00129 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
00130
00131 protected:
00132
00133
00134 class StringToBuffer
00135 {
00136 public:
00137 StringToBuffer( const TIXML_STRING& str );
00138 ~StringToBuffer();
00139 char* buffer;
00140 };
00141
00142 static const char* SkipWhiteSpace( const char* );
00143 inline static bool IsWhiteSpace( int c ) { return ( isspace( c ) || c == '\n' || c == '\r' ); }
00144
00145 virtual void StreamOut (TIXML_OSTREAM *) const = 0;
00146
00147 #ifdef TIXML_USE_STL
00148 static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
00149 static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
00150 #endif
00151
00152
00153
00154
00155
00156 static const char* ReadName( const char* p, TIXML_STRING* name );
00157
00158
00159
00160
00161 static const char* ReadText( const char* in,
00162 TIXML_STRING* text,
00163 bool ignoreWhiteSpace,
00164 const char* endTag,
00165 bool ignoreCase );
00166 virtual const char* Parse( const char* p ) = 0;
00167
00168
00169 static const char* GetEntity( const char* in, char* value );
00170
00171
00172 inline static const char* GetChar( const char* p, char* value )
00173 {
00174 assert( p );
00175 if ( *p == '&' )
00176 {
00177 return GetEntity( p, value );
00178 }
00179 else
00180 {
00181 *value = *p;
00182 return p+1;
00183 }
00184 }
00185
00186
00187
00188 static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
00189
00190 static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00191
00192
00193 bool static StringEqual( const char* p,
00194 const char* endTag,
00195 bool ignoreCase );
00196
00197
00198 enum
00199 {
00200 TIXML_NO_ERROR = 0,
00201 TIXML_ERROR,
00202 TIXML_ERROR_OPENING_FILE,
00203 TIXML_ERROR_OUT_OF_MEMORY,
00204 TIXML_ERROR_PARSING_ELEMENT,
00205 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00206 TIXML_ERROR_READING_ELEMENT_VALUE,
00207 TIXML_ERROR_READING_ATTRIBUTES,
00208 TIXML_ERROR_PARSING_EMPTY,
00209 TIXML_ERROR_READING_END_TAG,
00210 TIXML_ERROR_PARSING_UNKNOWN,
00211 TIXML_ERROR_PARSING_COMMENT,
00212 TIXML_ERROR_PARSING_DECLARATION,
00213 TIXML_ERROR_DOCUMENT_EMPTY,
00214
00215 TIXML_ERROR_STRING_COUNT
00216 };
00217 static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00218
00219 private:
00220 struct Entity
00221 {
00222 const char* str;
00223 unsigned int strLength;
00224 char chr;
00225 };
00226 enum
00227 {
00228 NUM_ENTITY = 5,
00229 MAX_ENTITY_LENGTH = 6
00230
00231 };
00232 static Entity entity[ NUM_ENTITY ];
00233 static bool condenseWhiteSpace;
00234 };
00235
00236
00243 class TiXmlNode : public TiXmlBase
00244 {
00245 friend class TiXmlDocument;
00246 friend class TiXmlElement;
00247
00248 public:
00249 #ifdef TIXML_USE_STL
00250
00254 friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00255
00271 friend std::ostream & operator<< (std::ostream& out, const TiXmlNode& base);
00272
00273 #else
00274
00275 friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
00276 #endif
00277
00281 enum NodeType
00282 {
00283 DOCUMENT,
00284 ELEMENT,
00285 COMMENT,
00286 UNKNOWN,
00287 TEXT,
00288 DECLARATION,
00289 TYPECOUNT
00290 };
00291
00292 virtual ~TiXmlNode();
00293
00306 const char * Value () const { return value.c_str (); }
00307
00317 void SetValue (const char * _value) { value = _value;}
00318
00319 #ifdef TIXML_USE_STL
00320
00321 void SetValue( const std::string& value )
00322 {
00323 StringToBuffer buf( value );
00324 SetValue( buf.buffer ? buf.buffer : "" );
00325 }
00326 #endif
00327
00329 void Clear();
00330
00332 TiXmlNode* Parent() const { return parent; }
00333
00334 TiXmlNode* FirstChild() const { return firstChild; }
00335 TiXmlNode* FirstChild( const char * value ) const;
00336
00337 TiXmlNode* LastChild() const { return lastChild; }
00338 TiXmlNode* LastChild( const char * value ) const;
00339
00340 #ifdef TIXML_USE_STL
00341 TiXmlNode* FirstChild( const std::string& value ) const { return FirstChild (value.c_str ()); }
00342 TiXmlNode* LastChild( const std::string& value ) const { return LastChild (value.c_str ()); }
00343 #endif
00344
00361 TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
00362
00364 TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
00365
00366 #ifdef TIXML_USE_STL
00367 TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const { return IterateChildren (value.c_str (), previous); }
00368 #endif
00369
00373 TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00374
00375
00385 TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00386
00390 TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00391
00395 TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
00396
00400 TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00401
00403 bool RemoveChild( TiXmlNode* removeThis );
00404
00406 TiXmlNode* PreviousSibling() const { return prev; }
00407
00409 TiXmlNode* PreviousSibling( const char * ) const;
00410
00411 #ifdef TIXML_USE_STL
00412 TiXmlNode* PreviousSibling( const std::string& value ) const { return PreviousSibling (value.c_str ()); }
00413 TiXmlNode* NextSibling( const std::string& value) const { return NextSibling (value.c_str ()); }
00414 #endif
00415
00417 TiXmlNode* NextSibling() const { return next; }
00418
00420 TiXmlNode* NextSibling( const char * ) const;
00421
00426 TiXmlElement* NextSiblingElement() const;
00427
00432 TiXmlElement* NextSiblingElement( const char * ) const;
00433
00434 #ifdef TIXML_USE_STL
00435 TiXmlElement* NextSiblingElement( const std::string& value) const { return NextSiblingElement (value.c_str ()); }
00436 #endif
00437
00439 TiXmlElement* FirstChildElement() const;
00440
00442 TiXmlElement* FirstChildElement( const char * value ) const;
00443
00444 #ifdef TIXML_USE_STL
00445 TiXmlElement* FirstChildElement( const std::string& value ) const { return FirstChildElement (value.c_str ()); }
00446 #endif
00447
00449 virtual int Type() const { return type; }
00450
00454 TiXmlDocument* GetDocument() const;
00455
00457 bool NoChildren() const { return !firstChild; }
00458
00459 TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; }
00460 TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; }
00461 TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; }
00462 TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; }
00463 TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; }
00464 TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; }
00465
00466 virtual TiXmlNode* Clone() const = 0;
00467
00468 void SetUserData( void* user ) { userData = user; }
00469 void* GetUserData() { return userData; }
00470
00471 protected:
00472 TiXmlNode( NodeType type );
00473
00474 #ifdef TIXML_USE_STL
00475
00476 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
00477 #endif
00478
00479
00480 TiXmlNode* Identify( const char* start );
00481 void CopyToClone( TiXmlNode* target ) const { target->SetValue (value.c_str() );
00482 target->userData = userData; }
00483
00484
00485 TIXML_STRING SValue() const { return value ; }
00486
00487 TiXmlNode* parent;
00488 NodeType type;
00489
00490 TiXmlNode* firstChild;
00491 TiXmlNode* lastChild;
00492
00493 TIXML_STRING value;
00494
00495 TiXmlNode* prev;
00496 TiXmlNode* next;
00497 void* userData;
00498 };
00499
00500
00510 class TiXmlAttribute : public TiXmlBase
00511 {
00512 friend class TiXmlAttributeSet;
00513
00514 public:
00516 TiXmlAttribute() : prev( 0 ), next( 0 ) {}
00517
00518 #ifdef TIXML_USE_STL
00519
00520 TiXmlAttribute( const std::string& _name, const std::string& _value )
00521 {
00522 name = _name;
00523 value = _value;
00524 }
00525 #endif
00526
00528 TiXmlAttribute( const char * _name, const char * _value ): name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
00529 const char* Name() const { return name.c_str (); }
00530 const char* Value() const { return value.c_str (); }
00531 int IntValue() const;
00532 double DoubleValue() const;
00533
00534 void SetName( const char* _name ) { name = _name; }
00535 void SetValue( const char* _value ) { value = _value; }
00536
00537 void SetIntValue( int value );
00538 void SetDoubleValue( double value );
00539
00540 #ifdef TIXML_USE_STL
00541
00542 void SetName( const std::string& _name )
00543 {
00544 StringToBuffer buf( _name );
00545 SetName ( buf.buffer ? buf.buffer : "error" );
00546 }
00548 void SetValue( const std::string& _value )
00549 {
00550 StringToBuffer buf( _value );
00551 SetValue( buf.buffer ? buf.buffer : "error" );
00552 }
00553 #endif
00554
00556 TiXmlAttribute* Next() const;
00558 TiXmlAttribute* Previous() const;
00559
00560 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00561 bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
00562 bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
00563
00564
00565
00566
00567
00568 virtual const char* Parse( const char* p );
00569
00570
00571 virtual void Print( FILE* cfile, int depth ) const;
00572
00573 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00574
00575
00576 void SetDocument( TiXmlDocument* doc ) { document = doc; }
00577
00578 private:
00579 TiXmlDocument* document;
00580 TIXML_STRING name;
00581 TIXML_STRING value;
00582 TiXmlAttribute* prev;
00583 TiXmlAttribute* next;
00584 };
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 class TiXmlAttributeSet
00600 {
00601 public:
00602 TiXmlAttributeSet();
00603 ~TiXmlAttributeSet();
00604
00605 void Add( TiXmlAttribute* attribute );
00606 void Remove( TiXmlAttribute* attribute );
00607
00608 TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00609 TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00610 TiXmlAttribute* Find( const char * name ) const;
00611
00612 private:
00613 TiXmlAttribute sentinel;
00614 };
00615
00616
00621 class TiXmlElement : public TiXmlNode
00622 {
00623 public:
00625 TiXmlElement (const char * in_value);
00626
00627 #ifdef TIXML_USE_STL
00628
00629 TiXmlElement( const std::string& _value ) : TiXmlNode( TiXmlNode::ELEMENT )
00630 {
00631 firstChild = lastChild = 0;
00632 value = _value;
00633 }
00634 #endif
00635
00636 virtual ~TiXmlElement();
00637
00641 const char* Attribute( const char* name ) const;
00642
00649 const char* Attribute( const char* name, int* i ) const;
00650
00654 void SetAttribute( const char* name, const char * value );
00655
00656 #ifdef TIXML_USE_STL
00657 const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); }
00658 const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); }
00659
00661 void SetAttribute( const std::string& name, const std::string& value )
00662 {
00663 StringToBuffer n( name );
00664 StringToBuffer v( value );
00665 if ( n.buffer && v.buffer )
00666 SetAttribute (n.buffer, v.buffer );
00667 }
00669 void SetAttribute( const std::string& name, int value )
00670 {
00671 StringToBuffer n( name );
00672 if ( n.buffer )
00673 SetAttribute (n.buffer, value);
00674 }
00675 #endif
00676
00680 void SetAttribute( const char * name, int value );
00681
00684 void RemoveAttribute( const char * name );
00685 #ifdef TIXML_USE_STL
00686 void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); }
00687 #endif
00688
00689 TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); }
00690 TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); }
00691
00692
00693 virtual TiXmlNode* Clone() const;
00694
00695
00696 virtual void Print( FILE* cfile, int depth ) const;
00697
00698 protected:
00699
00700
00701 #ifdef TIXML_USE_STL
00702 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00703 #endif
00704 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00705
00706
00707
00708
00709
00710 virtual const char* Parse( const char* p );
00711
00712
00713
00714
00715
00716 const char* ReadValue( const char* in );
00717
00718 private:
00719 TiXmlAttributeSet attributeSet;
00720 };
00721
00722
00725 class TiXmlComment : public TiXmlNode
00726 {
00727 public:
00729 TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
00730 virtual ~TiXmlComment() {}
00731
00732
00733 virtual TiXmlNode* Clone() const;
00734
00735 virtual void Print( FILE* cfile, int depth ) const;
00736 protected:
00737
00738 #ifdef TIXML_USE_STL
00739 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00740 #endif
00741 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00742
00743
00744
00745
00746 virtual const char* Parse( const char* p );
00747 };
00748
00749
00752 class TiXmlText : public TiXmlNode
00753 {
00754 friend class TiXmlElement;
00755 public:
00757 TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
00758 {
00759 SetValue( initValue );
00760 }
00761 virtual ~TiXmlText() {}
00762
00763 #ifdef TIXML_USE_STL
00764
00765 TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
00766 {
00767 SetValue( initValue );
00768 }
00769 #endif
00770
00771
00772 virtual void Print( FILE* cfile, int depth ) const;
00773
00774 protected :
00775
00776 virtual TiXmlNode* Clone() const;
00777 virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00778
00779 bool Blank() const;
00780
00781
00782
00783
00784 virtual const char* Parse( const char* p );
00785
00786 #ifdef TIXML_USE_STL
00787 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00788 #endif
00789 };
00790
00791
00805 class TiXmlDeclaration : public TiXmlNode
00806 {
00807 public:
00809 TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
00810
00811 #ifdef TIXML_USE_STL
00812
00813 TiXmlDeclaration(
00814 const std::string& _version,
00815 const std::string& _encoding,
00816 const std::string& _standalone )
00817 : TiXmlNode( TiXmlNode::DECLARATION )
00818 {
00819 version = _version;
00820 encoding = _encoding;
00821 standalone = _standalone;
00822 }
00823 #endif
00824
00826 TiXmlDeclaration( const char * _version,
00827 const char * _encoding,
00828 const char * _standalone );
00829
00830 virtual ~TiXmlDeclaration() {}
00831
00833 const char * Version() const { return version.c_str (); }
00835 const char * Encoding() const { return encoding.c_str (); }
00837 const char * Standalone() const { return standalone.c_str (); }
00838
00839
00840 virtual TiXmlNode* Clone() const;
00841
00842 virtual void Print( FILE* cfile, int depth ) const;
00843
00844 protected:
00845
00846 #ifdef TIXML_USE_STL
00847 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00848 #endif
00849 virtual void StreamOut ( TIXML_OSTREAM * out) const;
00850
00851
00852
00853
00854 virtual const char* Parse( const char* p );
00855
00856 private:
00857 TIXML_STRING version;
00858 TIXML_STRING encoding;
00859 TIXML_STRING standalone;
00860 };
00861
00862
00868 class TiXmlUnknown : public TiXmlNode
00869 {
00870 public:
00871 TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
00872 virtual ~TiXmlUnknown() {}
00873
00874
00875 virtual TiXmlNode* Clone() const;
00876
00877 virtual void Print( FILE* cfile, int depth ) const;
00878 protected:
00879
00880 #ifdef TIXML_USE_STL
00881 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00882 #endif
00883 virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00884
00885
00886
00887
00888 virtual const char* Parse( const char* p );
00889 };
00890
00891
00896 class TiXmlDocument : public TiXmlNode
00897 {
00898 public:
00900 TiXmlDocument();
00902 TiXmlDocument( const char * documentName );
00903
00904 #ifdef TIXML_USE_STL
00905
00906 TiXmlDocument( const std::string& documentName ) :
00907 TiXmlNode( TiXmlNode::DOCUMENT )
00908 {
00909 value = documentName;
00910 error = false;
00911 }
00912 #endif
00913
00914 virtual ~TiXmlDocument() {}
00915
00920 bool LoadFile();
00922 bool SaveFile() const;
00924 bool LoadFile( const char * filename );
00926 bool SaveFile( const char * filename ) const;
00927
00928 #ifdef TIXML_USE_STL
00929 bool LoadFile( const std::string& filename )
00930 {
00931 StringToBuffer f( filename );
00932 return ( f.buffer && LoadFile( f.buffer ));
00933 }
00934 bool SaveFile( const std::string& filename ) const
00935 {
00936 StringToBuffer f( filename );
00937 return ( f.buffer && SaveFile( f.buffer ));
00938 }
00939 #endif
00940
00942 virtual const char* Parse( const char* p );
00943
00948 TiXmlElement* RootElement() const { return FirstChildElement(); }
00949
00951 bool Error() const { return error; }
00952
00954 const char * ErrorDesc() const { return errorDesc.c_str (); }
00955
00959 int ErrorId() const { return errorId; }
00960
00962 void ClearError() { error = false; errorId = 0; errorDesc = ""; }
00963
00965 void Print() const { Print( stdout, 0 ); }
00966
00967
00968 virtual void Print( FILE* cfile, int depth = 0 ) const;
00969
00970 void SetError( int err ) { assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
00971 error = true;
00972 errorId = err;
00973 errorDesc = errorString[ errorId ]; }
00974
00975 protected :
00976 virtual void StreamOut ( TIXML_OSTREAM * out) const;
00977
00978 virtual TiXmlNode* Clone() const;
00979 #ifdef TIXML_USE_STL
00980 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00981 #endif
00982
00983 private:
00984 bool error;
00985 int errorId;
00986 TIXML_STRING errorDesc;
00987 };
00988
00989 #endif
00990