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
00054
00055 #ifdef TIXML_USE_STL
00056 #include <string>
00057 #ifdef TIXML_NEED_STREAM
00058 #include <istream>
00059 #include <ostream>
00060 #endif
00061 #define TIXML_STRING std::string
00062 #define TIXML_ISTREAM std::istream
00063 #define TIXML_OSTREAM std::ostream
00064 #else
00065 #include "tinystr.h"
00066 #define TIXML_STRING TiXmlString
00067 #define TIXML_OSTREAM TiXmlOutStream
00068 #endif
00069
00070 class TiXmlDocument;
00071 class TiXmlElement;
00072 class TiXmlComment;
00073 class TiXmlUnknown;
00074 class TiXmlAttribute;
00075 class TiXmlText;
00076 class TiXmlDeclaration;
00077
00078
00101 class TiXmlBase
00102 {
00103 friend class TiXmlNode;
00104 friend class TiXmlElement;
00105 friend class TiXmlDocument;
00106
00107 public:
00108 TiXmlBase() {}
00109 virtual ~TiXmlBase() {}
00110
00116 virtual void Print( FILE* cfile, int depth ) const = 0;
00117
00124 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
00125
00127 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
00128
00129 protected:
00130
00131
00132 class StringToBuffer
00133 {
00134 public:
00135 StringToBuffer( const TIXML_STRING& str );
00136 ~StringToBuffer();
00137 char* buffer;
00138 };
00139
00140 static const char* SkipWhiteSpace( const char* );
00141 inline static bool IsWhiteSpace( int c ) { return ( isspace( c ) || c == '\n' || c == '\r' ); }
00142
00143 virtual void StreamOut (TIXML_OSTREAM *) const = 0;
00144
00145 #ifdef TIXML_USE_STL
00146 static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
00147 static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
00148 #endif
00149
00150
00151
00152
00153
00154 static const char* ReadName( const char* p, TIXML_STRING* name );
00155
00156
00157
00158
00159 static const char* ReadText( const char* in,
00160 TIXML_STRING* text,
00161 bool ignoreWhiteSpace,
00162 const char* endTag,
00163 bool ignoreCase );
00164 virtual const char* Parse( const char* p ) = 0;
00165
00166
00167 static const char* GetEntity( const char* in, char* value );
00168
00169
00170 inline static const char* GetChar( const char* p, char* value )
00171 {
00172 assert( p );
00173 if ( *p == '&' )
00174 {
00175 return GetEntity( p, value );
00176 }
00177 else
00178 {
00179 *value = *p;
00180 return p+1;
00181 }
00182 }
00183
00184
00185
00186 static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
00187
00188 static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00189
00190
00191 bool static StringEqual( const char* p,
00192 const char* endTag,
00193 bool ignoreCase );
00194
00195
00196 enum
00197 {
00198 TIXML_NO_ERROR = 0,
00199 TIXML_ERROR,
00200 TIXML_ERROR_OPENING_FILE,
00201 TIXML_ERROR_OUT_OF_MEMORY,
00202 TIXML_ERROR_PARSING_ELEMENT,
00203 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00204 TIXML_ERROR_READING_ELEMENT_VALUE,
00205 TIXML_ERROR_READING_ATTRIBUTES,
00206 TIXML_ERROR_PARSING_EMPTY,
00207 TIXML_ERROR_READING_END_TAG,
00208 TIXML_ERROR_PARSING_UNKNOWN,
00209 TIXML_ERROR_PARSING_COMMENT,
00210 TIXML_ERROR_PARSING_DECLARATION,
00211 TIXML_ERROR_DOCUMENT_EMPTY,
00212
00213 TIXML_ERROR_STRING_COUNT
00214 };
00215 static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00216
00217 private:
00218 struct Entity
00219 {
00220 const char* str;
00221 unsigned int strLength;
00222 char chr;
00223 };
00224 enum
00225 {
00226 NUM_ENTITY = 5,
00227 MAX_ENTITY_LENGTH = 6
00228
00229 };
00230 static Entity entity[ NUM_ENTITY ];
00231 static bool condenseWhiteSpace;
00232 };
00233
00234
00241 class TiXmlNode : public TiXmlBase
00242 {
00243 friend class TiXmlDocument;
00244 friend class TiXmlElement;
00245
00246 public:
00247 #ifdef TIXML_USE_STL
00248
00252 friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00253
00269 friend std::ostream & operator<< (std::ostream& out, const TiXmlNode& base);
00270
00271 #else
00272
00273 friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
00274 #endif
00275
00279 enum NodeType
00280 {
00281 DOCUMENT,
00282 ELEMENT,
00283 COMMENT,
00284 UNKNOWN,
00285 TEXT,
00286 DECLARATION,
00287 TYPECOUNT
00288 };
00289
00290 virtual ~TiXmlNode();
00291
00304 const char * Value () const { return value.c_str (); }
00305
00315 void SetValue (const char * _value) { value = _value;}
00316
00317 #ifdef TIXML_USE_STL
00318
00319 void SetValue( const std::string& value )
00320 {
00321 StringToBuffer buf( value );
00322 SetValue( buf.buffer ? buf.buffer : "" );
00323 }
00324 #endif
00325
00327 void Clear();
00328
00330 TiXmlNode* Parent() const { return parent; }
00331
00332 TiXmlNode* FirstChild() const { return firstChild; }
00333 TiXmlNode* FirstChild( const char * value ) const;
00334
00335 TiXmlNode* LastChild() const { return lastChild; }
00336 TiXmlNode* LastChild( const char * value ) const;
00337
00338 #ifdef TIXML_USE_STL
00339 TiXmlNode* FirstChild( const std::string& value ) const { return FirstChild (value.c_str ()); }
00340 TiXmlNode* LastChild( const std::string& value ) const { return LastChild (value.c_str ()); }
00341 #endif
00342
00359 TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
00360
00362 TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
00363
00364 #ifdef TIXML_USE_STL
00365 TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const { return IterateChildren (value.c_str (), previous); }
00366 #endif
00367
00371 TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00372
00373
00383 TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00384
00388 TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00389
00393 TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
00394
00398 TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00399
00401 bool RemoveChild( TiXmlNode* removeThis );
00402
00404 TiXmlNode* PreviousSibling() const { return prev; }
00405
00407 TiXmlNode* PreviousSibling( const char * ) const;
00408
00409 #ifdef TIXML_USE_STL
00410 TiXmlNode* PreviousSibling( const std::string& value ) const { return PreviousSibling (value.c_str ()); }
00411 TiXmlNode* NextSibling( const std::string& value) const { return NextSibling (value.c_str ()); }
00412 #endif
00413
00415 TiXmlNode* NextSibling() const { return next; }
00416
00418 TiXmlNode* NextSibling( const char * ) const;
00419
00424 TiXmlElement* NextSiblingElement() const;
00425
00430 TiXmlElement* NextSiblingElement( const char * ) const;
00431
00432 #ifdef TIXML_USE_STL
00433 TiXmlElement* NextSiblingElement( const std::string& value) const { return NextSiblingElement (value.c_str ()); }
00434 #endif
00435
00437 TiXmlElement* FirstChildElement() const;
00438
00440 TiXmlElement* FirstChildElement( const char * value ) const;
00441
00442 #ifdef TIXML_USE_STL
00443 TiXmlElement* FirstChildElement( const std::string& value ) const { return FirstChildElement (value.c_str ()); }
00444 #endif
00445
00447 virtual int Type() const { return type; }
00448
00452 TiXmlDocument* GetDocument() const;
00453
00455 bool NoChildren() const { return !firstChild; }
00456
00457 TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; }
00458 TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; }
00459 TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; }
00460 TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; }
00461 TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; }
00462 TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; }
00463
00464 virtual TiXmlNode* Clone() const = 0;
00465
00466 void SetUserData( void* user ) { userData = user; }
00467 void* GetUserData() { return userData; }
00468
00469 protected:
00470 TiXmlNode( NodeType type );
00471
00472 #ifdef TIXML_USE_STL
00473
00474 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
00475 #endif
00476
00477
00478 TiXmlNode* Identify( const char* start );
00479 void CopyToClone( TiXmlNode* target ) const { target->SetValue (value.c_str() );
00480 target->userData = userData; }
00481
00482
00483 TIXML_STRING SValue() const { return value ; }
00484
00485 TiXmlNode* parent;
00486 NodeType type;
00487
00488 TiXmlNode* firstChild;
00489 TiXmlNode* lastChild;
00490
00491 TIXML_STRING value;
00492
00493 TiXmlNode* prev;
00494 TiXmlNode* next;
00495 void* userData;
00496 };
00497
00498
00508 class TiXmlAttribute : public TiXmlBase
00509 {
00510 friend class TiXmlAttributeSet;
00511
00512 public:
00514 TiXmlAttribute() : prev( 0 ), next( 0 ) {}
00515
00516 #ifdef TIXML_USE_STL
00517
00518 TiXmlAttribute( const std::string& _name, const std::string& _value )
00519 {
00520 name = _name;
00521 value = _value;
00522 }
00523 #endif
00524
00526 TiXmlAttribute( const char * _name, const char * _value ): name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
00527 const char* Name() const { return name.c_str (); }
00528 const char* Value() const { return value.c_str (); }
00529 const int IntValue() const;
00530 const double DoubleValue() const;
00531
00532 void SetName( const char* _name ) { name = _name; }
00533 void SetValue( const char* _value ) { value = _value; }
00534
00535 void SetIntValue( int value );
00536 void SetDoubleValue( double value );
00537
00538 #ifdef TIXML_USE_STL
00539
00540 void SetName( const std::string& _name )
00541 {
00542 StringToBuffer buf( _name );
00543 SetName ( buf.buffer ? buf.buffer : "error" );
00544 }
00546 void SetValue( const std::string& _value )
00547 {
00548 StringToBuffer buf( _value );
00549 SetValue( buf.buffer ? buf.buffer : "error" );
00550 }
00551 #endif
00552
00554 TiXmlAttribute* Next() const;
00556 TiXmlAttribute* Previous() const;
00557
00558 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00559 bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
00560 bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
00561
00562
00563
00564
00565
00566 virtual const char* Parse( const char* p );
00567
00568
00569 virtual void Print( FILE* cfile, int depth ) const;
00570
00571 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00572
00573
00574 void SetDocument( TiXmlDocument* doc ) { document = doc; }
00575
00576 private:
00577 TiXmlDocument* document;
00578 TIXML_STRING name;
00579 TIXML_STRING value;
00580 TiXmlAttribute* prev;
00581 TiXmlAttribute* next;
00582 };
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 class TiXmlAttributeSet
00598 {
00599 public:
00600 TiXmlAttributeSet();
00601 ~TiXmlAttributeSet();
00602
00603 void Add( TiXmlAttribute* attribute );
00604 void Remove( TiXmlAttribute* attribute );
00605
00606 TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00607 TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00608 TiXmlAttribute* Find( const char * name ) const;
00609
00610 private:
00611 TiXmlAttribute sentinel;
00612 };
00613
00614
00619 class TiXmlElement : public TiXmlNode
00620 {
00621 public:
00623 TiXmlElement (const char * in_value);
00624
00625 #ifdef TIXML_USE_STL
00626
00627 TiXmlElement( const std::string& _value ) : TiXmlNode( TiXmlNode::ELEMENT )
00628 {
00629 firstChild = lastChild = 0;
00630 value = _value;
00631 }
00632 #endif
00633
00634 virtual ~TiXmlElement();
00635
00639 const char* Attribute( const char* name ) const;
00640
00647 const char* Attribute( const char* name, int* i ) const;
00648
00652 void SetAttribute( const char* name, const char * value );
00653
00654 #ifdef TIXML_USE_STL
00655 const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); }
00656 const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); }
00657
00659 void SetAttribute( const std::string& name, const std::string& value )
00660 {
00661 StringToBuffer n( name );
00662 StringToBuffer v( value );
00663 if ( n.buffer && v.buffer )
00664 SetAttribute (n.buffer, v.buffer );
00665 }
00667 void SetAttribute( const std::string& name, int value )
00668 {
00669 StringToBuffer n( name );
00670 if ( n.buffer )
00671 SetAttribute (n.buffer, value);
00672 }
00673 #endif
00674
00678 void SetAttribute( const char * name, int value );
00679
00682 void RemoveAttribute( const char * name );
00683 #ifdef TIXML_USE_STL
00684 void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); }
00685 #endif
00686
00687 TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); }
00688 TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); }
00689
00690
00691 virtual TiXmlNode* Clone() const;
00692
00693
00694 virtual void Print( FILE* cfile, int depth ) const;
00695
00696 protected:
00697
00698
00699 #ifdef TIXML_USE_STL
00700 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00701 #endif
00702 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00703
00704
00705
00706
00707
00708 virtual const char* Parse( const char* p );
00709
00710
00711
00712
00713
00714 const char* ReadValue( const char* in );
00715
00716 private:
00717 TiXmlAttributeSet attributeSet;
00718 };
00719
00720
00723 class TiXmlComment : public TiXmlNode
00724 {
00725 public:
00727 TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
00728 virtual ~TiXmlComment() {}
00729
00730
00731 virtual TiXmlNode* Clone() const;
00732
00733 virtual void Print( FILE* cfile, int depth ) const;
00734 protected:
00735
00736 #ifdef TIXML_USE_STL
00737 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00738 #endif
00739 virtual void StreamOut( TIXML_OSTREAM * out ) const;
00740
00741
00742
00743
00744 virtual const char* Parse( const char* p );
00745 };
00746
00747
00750 class TiXmlText : public TiXmlNode
00751 {
00752 friend class TiXmlElement;
00753 public:
00755 TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
00756 {
00757 SetValue( initValue );
00758 }
00759 virtual ~TiXmlText() {}
00760
00761 #ifdef TIXML_USE_STL
00762
00763 TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
00764 {
00765 SetValue( initValue );
00766 }
00767 #endif
00768
00769
00770 virtual void Print( FILE* cfile, int depth ) const;
00771
00772 protected :
00773
00774 virtual TiXmlNode* Clone() const;
00775 virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00776
00777 bool Blank() const;
00778
00779
00780
00781
00782 virtual const char* Parse( const char* p );
00783
00784 #ifdef TIXML_USE_STL
00785 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00786 #endif
00787 };
00788
00789
00803 class TiXmlDeclaration : public TiXmlNode
00804 {
00805 public:
00807 TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
00808
00809 #ifdef TIXML_USE_STL
00810
00811 TiXmlDeclaration(
00812 const std::string& _version,
00813 const std::string& _encoding,
00814 const std::string& _standalone )
00815 : TiXmlNode( TiXmlNode::DECLARATION )
00816 {
00817 version = _version;
00818 encoding = _encoding;
00819 standalone = _standalone;
00820 }
00821 #endif
00822
00824 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
00825 const char * _encoding,
00826 const char * _standalone );
00827
00828 virtual ~TiXmlDeclaration() {}
00829
00831 const char * Version() const { return version.c_str (); }
00833 const char * Encoding() const { return encoding.c_str (); }
00835 const char * Standalone() const { return standalone.c_str (); }
00836
00837
00838 virtual TiXmlNode* Clone() const;
00839
00840 virtual void Print( FILE* cfile, int depth ) const;
00841
00842 protected:
00843
00844 #ifdef TIXML_USE_STL
00845 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00846 #endif
00847 virtual void StreamOut ( TIXML_OSTREAM * out) const;
00848
00849
00850
00851
00852 virtual const char* Parse( const char* p );
00853
00854 private:
00855 TIXML_STRING version;
00856 TIXML_STRING encoding;
00857 TIXML_STRING standalone;
00858 };
00859
00860
00866 class TiXmlUnknown : public TiXmlNode
00867 {
00868 public:
00869 TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
00870 virtual ~TiXmlUnknown() {}
00871
00872
00873 virtual TiXmlNode* Clone() const;
00874
00875 virtual void Print( FILE* cfile, int depth ) const;
00876 protected:
00877
00878 #ifdef TIXML_USE_STL
00879 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00880 #endif
00881 virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00882
00883
00884
00885
00886 virtual const char* Parse( const char* p );
00887 };
00888
00889
00894 class TiXmlDocument : public TiXmlNode
00895 {
00896 public:
00898 TiXmlDocument();
00900 TiXmlDocument( const char * documentName );
00901
00902 #ifdef TIXML_USE_STL
00903
00904 TiXmlDocument( const std::string& documentName ) :
00905 TiXmlNode( TiXmlNode::DOCUMENT )
00906 {
00907 value = documentName;
00908 error = false;
00909 }
00910 #endif
00911
00912 virtual ~TiXmlDocument() {}
00913
00918 bool LoadFile();
00920 bool SaveFile() const;
00922 bool LoadFile( const char * filename );
00924 bool SaveFile( const char * filename ) const;
00925
00926 #ifdef TIXML_USE_STL
00927 bool LoadFile( const std::string& filename )
00928 {
00929 StringToBuffer f( filename );
00930 return ( f.buffer && LoadFile( f.buffer ));
00931 }
00932 bool SaveFile( const std::string& filename ) const
00933 {
00934 StringToBuffer f( filename );
00935 return ( f.buffer && SaveFile( f.buffer ));
00936 }
00937 #endif
00938
00940 virtual const char* Parse( const char* p );
00941
00946 TiXmlElement* RootElement() const { return FirstChildElement(); }
00947
00949 bool Error() const { return error; }
00950
00952 const char * ErrorDesc() const { return errorDesc.c_str (); }
00953
00957 const int ErrorId() const { return errorId; }
00958
00960 void ClearError() { error = false; errorId = 0; errorDesc = ""; }
00961
00963 void Print() const { Print( stdout, 0 ); }
00964
00965
00966 virtual void Print( FILE* cfile, int depth = 0 ) const;
00967
00968 void SetError( int err ) { assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
00969 error = true;
00970 errorId = err;
00971 errorDesc = errorString[ errorId ]; }
00972
00973 protected :
00974 virtual void StreamOut ( TIXML_OSTREAM * out) const;
00975
00976 virtual TiXmlNode* Clone() const;
00977 #ifdef TIXML_USE_STL
00978 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00979 #endif
00980
00981 private:
00982 bool error;
00983 int errorId;
00984 TIXML_STRING errorDesc;
00985 };
00986
00987 #endif
00988